1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_OBJECTS_BODY_DESCRIPTORS_H_ 6 #define V8_OBJECTS_BODY_DESCRIPTORS_H_ 7 8 #include "src/objects.h" 9 10 namespace v8 { 11 namespace internal { 12 13 // This is the base class for object's body descriptors. 14 // 15 // Each BodyDescriptor subclass must provide the following methods: 16 // 17 // 1) Returns true if the object contains a tagged value at given offset. 18 // It is used for invalid slots filtering. If the offset points outside 19 // of the object or to the map word, the result is UNDEFINED (!!!). 20 // 21 // static bool IsValidSlot(HeapObject* obj, int offset); 22 // 23 // 24 // 2) Iterate object's body using stateful object visitor. 25 // 26 // template <typename ObjectVisitor> 27 // static inline void IterateBody(HeapObject* obj, int object_size, 28 // ObjectVisitor* v); 29 // 30 // 31 // 3) Iterate object's body using stateless object visitor. 32 // 33 // template <typename StaticVisitor> 34 // static inline void IterateBody(HeapObject* obj, int object_size); 35 // 36 class BodyDescriptorBase BASE_EMBEDDED { 37 public: 38 template <typename ObjectVisitor> 39 static inline void IteratePointers(HeapObject* obj, int start_offset, 40 int end_offset, ObjectVisitor* v); 41 42 template <typename StaticVisitor> 43 static inline void IteratePointers(Heap* heap, HeapObject* obj, 44 int start_offset, int end_offset); 45 46 template <typename ObjectVisitor> 47 static inline void IteratePointer(HeapObject* obj, int offset, 48 ObjectVisitor* v); 49 50 template <typename StaticVisitor> 51 static inline void IteratePointer(Heap* heap, HeapObject* obj, int offset); 52 53 protected: 54 // Returns true for all header and internal fields. 55 static inline bool IsValidSlotImpl(HeapObject* obj, int offset); 56 57 // Treats all header and internal fields in the range as tagged. 58 template <typename ObjectVisitor> 59 static inline void IterateBodyImpl(HeapObject* obj, int start_offset, 60 int end_offset, ObjectVisitor* v); 61 62 // Treats all header and internal fields in the range as tagged. 63 template <typename StaticVisitor> 64 static inline void IterateBodyImpl(Heap* heap, HeapObject* obj, 65 int start_offset, int end_offset); 66 }; 67 68 69 // This class describes a body of an object of a fixed size 70 // in which all pointer fields are located in the [start_offset, end_offset) 71 // interval. 72 template <int start_offset, int end_offset, int size> 73 class FixedBodyDescriptor final : public BodyDescriptorBase { 74 public: 75 static const int kStartOffset = start_offset; 76 static const int kEndOffset = end_offset; 77 static const int kSize = size; 78 IsValidSlot(HeapObject * obj,int offset)79 static bool IsValidSlot(HeapObject* obj, int offset) { 80 return offset >= kStartOffset && offset < kEndOffset; 81 } 82 83 template <typename ObjectVisitor> IterateBody(HeapObject * obj,ObjectVisitor * v)84 static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) { 85 IterateBodyImpl(obj, start_offset, end_offset, v); 86 } 87 88 template <typename ObjectVisitor> IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)89 static inline void IterateBody(HeapObject* obj, int object_size, 90 ObjectVisitor* v) { 91 IterateBody(obj, v); 92 } 93 94 template <typename StaticVisitor> IterateBody(HeapObject * obj)95 static inline void IterateBody(HeapObject* obj) { 96 Heap* heap = obj->GetHeap(); 97 IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, end_offset); 98 } 99 100 template <typename StaticVisitor> IterateBody(HeapObject * obj,int object_size)101 static inline void IterateBody(HeapObject* obj, int object_size) { 102 IterateBody(obj); 103 } 104 }; 105 106 107 // This class describes a body of an object of a variable size 108 // in which all pointer fields are located in the [start_offset, object_size) 109 // interval. 110 template <int start_offset> 111 class FlexibleBodyDescriptor final : public BodyDescriptorBase { 112 public: 113 static const int kStartOffset = start_offset; 114 IsValidSlot(HeapObject * obj,int offset)115 static bool IsValidSlot(HeapObject* obj, int offset) { 116 if (offset < kStartOffset) return false; 117 return IsValidSlotImpl(obj, offset); 118 } 119 120 template <typename ObjectVisitor> IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)121 static inline void IterateBody(HeapObject* obj, int object_size, 122 ObjectVisitor* v) { 123 IterateBodyImpl(obj, start_offset, object_size, v); 124 } 125 126 template <typename StaticVisitor> IterateBody(HeapObject * obj,int object_size)127 static inline void IterateBody(HeapObject* obj, int object_size) { 128 Heap* heap = obj->GetHeap(); 129 IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, object_size); 130 } 131 132 static inline int SizeOf(Map* map, HeapObject* object); 133 }; 134 135 136 typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor; 137 138 } // namespace internal 139 } // namespace v8 140 141 #endif // V8_OBJECTS_BODY_DESCRIPTORS_H_ 142