/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/objects/objects-body-descriptors.h
358 строк
14 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_ #define V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_ #include "src/objects/map.h" #include "src/objects/objects.h" namespace v8::internal { // This is the base class for object's body descriptors. // // Each BodyDescriptor subclass must provide the following methods: // // 1) Iterate object's body using stateful object visitor. // // template <typename ObjectVisitor> // static inline void IterateBody(Tagged<Map> map, HeapObject obj, int // object_size, // ObjectVisitor* v); class BodyDescriptorBase { public: template <typename ObjectVisitor> static inline void IteratePointers(Tagged<HeapObject> obj, int start_offset, int end_offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IteratePointer(Tagged<HeapObject> obj, int offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateCustomWeakPointers(Tagged<HeapObject> obj, int start_offset, int end_offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateCustomWeakPointer(Tagged<HeapObject> obj, int offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateEphemeron(Tagged<HeapObject> obj, int index, int key_offset, int value_offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateMaybeWeakPointers(Tagged<HeapObject> obj, int start_offset, int end_offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateMaybeWeakPointer(Tagged<HeapObject> obj, int offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateTrustedPointer(Tagged<HeapObject> obj, int offset, ObjectVisitor* visitor, IndirectPointerMode mode, IndirectPointerTagRange tag_range); template <typename ObjectVisitor> static inline void IterateCodePointer(Tagged<HeapObject> obj, int offset, ObjectVisitor* visitor, IndirectPointerMode mode); template <typename ObjectVisitor> static inline void IterateSelfIndirectPointer( Tagged<HeapObject> obj, IndirectPointerTagRange tag_range, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateProtectedPointer(Tagged<HeapObject> obj, int offset, ObjectVisitor* v); template <typename ObjectVisitor> static inline void IterateJSDispatchEntry(Tagged<HeapObject> obj, int offset, ObjectVisitor* v); protected: // Returns true for all header and embedder fields. static inline bool IsValidEmbedderJSObjectSlotImpl(Tagged<Map> map, Tagged<HeapObject> obj, int offset); // Treats all header and in-object fields in the range as tagged. Figures out // dynamically whether the object has embedder fields and visits them // accordingly (as tagged fields and as external pointers). template <typename ObjectVisitor> static inline void IterateJSObjectBodyImpl(Tagged<Map> map, Tagged<HeapObject> obj, int start_offset, int end_offset, ObjectVisitor* v); // Treats all header and in-object fields in the range as tagged. template <typename ObjectVisitor> static inline void IterateJSObjectBodyWithoutEmbedderFieldsImpl( Tagged<Map> map, Tagged<HeapObject> obj, int start_offset, int end_offset, ObjectVisitor* v); }; // This class describes a body of an object without any pointers. class DataOnlyBodyDescriptor : public BodyDescriptorBase { public: template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) {} private: // Note: {SizeOf} is not implemented here; sub-classes will have to implement // it. }; // This class describes a body of an object in which all pointer fields are // located in the [start_offset, end_offset) interval. // All pointers have to be strong. template <int start_offset, int end_offset> class FixedRangeBodyDescriptor : public BodyDescriptorBase { public: static const int kStartOffset = start_offset; static const int kEndOffset = end_offset; template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, ObjectVisitor* v) { IteratePointers(obj, start_offset, end_offset, v); } template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { IterateBody(map, obj, v); } // Note: {SizeOf} is not implemented here; sub-classes will have to implement // it. }; // This class describes a body of an object of a fixed size // in which all pointer fields are located in the [start_offset, end_offset) // interval. // All pointers have to be strong. template <int start_offset, int end_offset, int size> class FixedBodyDescriptor : public std::conditional_t< start_offset == end_offset, DataOnlyBodyDescriptor, FixedRangeBodyDescriptor<start_offset, end_offset>> { public: static constexpr int kSize = size; static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) { DCHECK_EQ(kSize, map->instance_size()); return kSize; } }; template <typename T> using FixedBodyDescriptorFor = FixedBodyDescriptor<T::kStartOfStrongFieldsOffset, T::kEndOfStrongFieldsOffset, T::kSize>; // This class describes a body of an object in which all pointer fields are // located in the [start_offset, object_size) interval. // All pointers have to be strong. template <int start_offset> class SuffixRangeBodyDescriptor : public BodyDescriptorBase { public: static const int kStartOffset = start_offset; template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { IteratePointers(obj, start_offset, object_size, v); } // Note: {SizeOf} is not implemented here; sub-classes will have to implement // it. }; // This class describes a body of an object of a variable size // in which all pointer fields are located in the [start_offset, object_size) // interval. // All pointers have to be strong. template <int start_offset> class FlexibleBodyDescriptor : public SuffixRangeBodyDescriptor<start_offset> { public: static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object); }; // A forward-declarable descriptor body alias for most of the Struct successors. class StructBodyDescriptor : public FlexibleBodyDescriptor<HeapObject::kHeaderSize> {}; // This class describes a body of an object in which all pointer fields are // located in the [start_offset, object_size) interval. // Pointers may be strong or may be Tagged<MaybeObject>-style weak pointers. template <int start_offset> class SuffixRangeWeakBodyDescriptor : public BodyDescriptorBase { public: static const int kStartOffset = start_offset; template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { IterateMaybeWeakPointers(obj, start_offset, object_size, v); } // Note: {SizeOf} is not implemented here; sub-classes will have to implement // it. }; // This class describes a body of an object of a fixed size // in which all pointer fields are located in the [start_offset, end_offset) // interval. template <int start_offset, int end_offset, int size> class FixedWeakBodyDescriptor : public BodyDescriptorBase { public: static constexpr int kSize = size; template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { IterateMaybeWeakPointers(obj, start_offset, end_offset, v); } static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) { DCHECK_EQ(kSize, map->instance_size()); return kSize; } }; // This class describes a body of an object of a variable size // in which all pointer fields are located in the [start_offset, object_size) // interval. // Pointers may be strong or may be Tagged<MaybeObject>-style weak pointers. template <int start_offset> class FlexibleWeakBodyDescriptor : public SuffixRangeWeakBodyDescriptor<start_offset> { public: static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object); }; // This class describes a body of an object which has a parent class that also // has a body descriptor. This represents a union of the parent's body // descriptor, and a new descriptor for the child -- so, both parent and child's // slots are iterated. The parent must be fixed size, and its slots be disjoint // with the child's. template <class ParentBodyDescriptor, class ChildBodyDescriptor> class SubclassBodyDescriptor : public BodyDescriptorBase { public: template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, ObjectVisitor* v) { if constexpr (!std::is_same_v<DataOnlyBodyDescriptor, ChildBodyDescriptor>) { // The parent must end before the child's start offset, to make sure that // their slots are disjoint. static_assert(ParentBodyDescriptor::kSize <= ChildBodyDescriptor::kStartOffset); } ParentBodyDescriptor::IterateBody(map, obj, v); ChildBodyDescriptor::IterateBody(map, obj, v); } template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { ParentBodyDescriptor::IterateBody(map, obj, object_size, v); ChildBodyDescriptor::IterateBody(map, obj, object_size, v); } static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) { // The child should know its full size. return ChildBodyDescriptor::SizeOf(map, object); } }; // Visitor for exposed trusted objects with fixed layout according to // FixedBodyDescriptor. template <typename T, IndirectPointerTagRange kTagRange> class FixedExposedTrustedObjectBodyDescriptor : public FixedBodyDescriptorFor<T> { static_assert(std::is_base_of_v<ExposedTrustedObject, T>); using Base = FixedBodyDescriptorFor<T>; public: template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { Base::IterateSelfIndirectPointer(obj, kTagRange, v); Base::IterateBody(map, obj, object_size, v); } }; // A mix-in for visiting a trusted pointer field. template <size_t kFieldOffset, IndirectPointerTagRange kTagRange> struct WithStrongTrustedPointer { template <typename Base> class BodyDescriptor : public Base { public: template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { Base::IterateBody(map, obj, object_size, v); Base::IterateTrustedPointer(obj, kFieldOffset, v, IndirectPointerMode::kStrong, kTagRange); } }; }; template <size_t kFieldOffset> using WithStrongCodePointer = WithStrongTrustedPointer<kFieldOffset, kCodeIndirectPointerTag>; // A mix-in for visiting an external pointer field. template <size_t kFieldOffset, ExternalPointerTagRange kTagRange> struct WithExternalPointer { template <typename Base> class BodyDescriptor : public Base { public: template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { Base::IterateBody(map, obj, object_size, v); v->VisitExternalPointer( obj, obj->RawExternalPointerField(kFieldOffset, kTagRange)); } }; }; // A mix-in for visiting an external pointer field. template <size_t kFieldOffset> struct WithProtectedPointer { template <typename Base> class BodyDescriptor : public Base { public: template <typename ObjectVisitor> static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj, int object_size, ObjectVisitor* v) { Base::IterateBody(map, obj, object_size, v); Base::IterateProtectedPointer(obj, kFieldOffset, v); } }; }; // Stack multiple body descriptors; the first template argument is the base, // followed by mix-ins. template <typename Base, typename FirstMixin, typename... MoreMixins> class StackedBodyDescriptor : public StackedBodyDescriptor< typename FirstMixin::template BodyDescriptor<Base>, MoreMixins...> {}; // Define a specialization for the base case of only one mixin. template <typename Base, typename FirstMixin> class StackedBodyDescriptor<Base, FirstMixin> : public FirstMixin::template BodyDescriptor<Base> {}; } // namespace v8::internal #endif // V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_