• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_OBJECTS_BODY_DESCRIPTORS_H_
6 #define V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
7 
8 #include "src/objects/map.h"
9 #include "src/objects/objects.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // This is the base class for object's body descriptors.
15 //
16 // Each BodyDescriptor subclass must provide the following methods:
17 //
18 // 1) Returns true if the object contains a tagged value at given offset.
19 //    It is used for invalid slots filtering. If the offset points outside
20 //    of the object or to the map word, the result is UNDEFINED (!!!).
21 //
22 //   static bool IsValidSlot(Map map, HeapObject obj, int offset);
23 //
24 //
25 // 2) Iterate object's body using stateful object visitor.
26 //
27 //   template <typename ObjectVisitor>
28 //   static inline void IterateBody(Map map, HeapObject obj, int object_size,
29 //                                  ObjectVisitor* v);
30 class BodyDescriptorBase {
31  public:
32   template <typename ObjectVisitor>
33   static inline void IteratePointers(HeapObject obj, int start_offset,
34                                      int end_offset, ObjectVisitor* v);
35 
36   template <typename ObjectVisitor>
37   static inline void IteratePointer(HeapObject obj, int offset,
38                                     ObjectVisitor* v);
39 
40   template <typename ObjectVisitor>
41   static inline void IterateCustomWeakPointers(HeapObject obj, int start_offset,
42                                                int end_offset,
43                                                ObjectVisitor* v);
44 
45   template <typename ObjectVisitor>
46   static inline void IterateCustomWeakPointer(HeapObject obj, int offset,
47                                               ObjectVisitor* v);
48 
49   template <typename ObjectVisitor>
50   static inline void IterateEphemeron(HeapObject obj, int index, int key_offset,
51                                       int value_offset, ObjectVisitor* v);
52 
53   template <typename ObjectVisitor>
54   static inline void IterateMaybeWeakPointers(HeapObject obj, int start_offset,
55                                               int end_offset, ObjectVisitor* v);
56 
57   template <typename ObjectVisitor>
58   static inline void IterateMaybeWeakPointer(HeapObject obj, int offset,
59                                              ObjectVisitor* v);
60 
61  protected:
62   // Returns true for all header and embedder fields.
63   static inline bool IsValidJSObjectSlotImpl(Map map, HeapObject obj,
64                                              int offset);
65 
66   // Returns true for all header and embedder fields.
67   static inline bool IsValidEmbedderJSObjectSlotImpl(Map map, HeapObject obj,
68                                                      int offset);
69 
70   // Treats all header and embedder fields in the range as tagged.
71   template <typename ObjectVisitor>
72   static inline void IterateJSObjectBodyImpl(Map map, HeapObject obj,
73                                              int start_offset, int end_offset,
74                                              ObjectVisitor* v);
75 };
76 
77 // This class describes a body of an object in which all pointer fields are
78 // located in the [start_offset, end_offset) interval.
79 // All pointers have to be strong.
80 template <int start_offset, int end_offset>
81 class FixedRangeBodyDescriptor : public BodyDescriptorBase {
82  public:
83   static const int kStartOffset = start_offset;
84   static const int kEndOffset = end_offset;
85 
IsValidSlot(Map map,HeapObject obj,int offset)86   static bool IsValidSlot(Map map, HeapObject obj, int offset) {
87     return offset >= kStartOffset && offset < kEndOffset;
88   }
89 
90   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,ObjectVisitor * v)91   static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
92     IteratePointers(obj, start_offset, end_offset, v);
93   }
94 
95   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)96   static inline void IterateBody(Map map, HeapObject obj, int object_size,
97                                  ObjectVisitor* v) {
98     IterateBody(map, obj, v);
99   }
100 
101  private:
SizeOf(Map map,HeapObject object)102   static inline int SizeOf(Map map, HeapObject object) {
103     // Has to be implemented by the subclass.
104     UNREACHABLE();
105   }
106 };
107 
108 // This class describes a body of an object of a fixed size
109 // in which all pointer fields are located in the [start_offset, end_offset)
110 // interval.
111 // All pointers have to be strong.
112 template <int start_offset, int end_offset, int size>
113 class FixedBodyDescriptor
114     : public FixedRangeBodyDescriptor<start_offset, end_offset> {
115  public:
116   static const int kSize = size;
SizeOf(Map map,HeapObject object)117   static inline int SizeOf(Map map, HeapObject object) { return kSize; }
118 };
119 
120 // This class describes a body of an object in which all pointer fields are
121 // located in the [start_offset, object_size) interval.
122 // All pointers have to be strong.
123 template <int start_offset>
124 class SuffixRangeBodyDescriptor : public BodyDescriptorBase {
125  public:
126   static const int kStartOffset = start_offset;
127 
IsValidSlot(Map map,HeapObject obj,int offset)128   static bool IsValidSlot(Map map, HeapObject obj, int offset) {
129     return (offset >= kStartOffset);
130   }
131 
132   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)133   static inline void IterateBody(Map map, HeapObject obj, int object_size,
134                                  ObjectVisitor* v) {
135     IteratePointers(obj, start_offset, object_size, v);
136   }
137 
138  private:
SizeOf(Map map,HeapObject object)139   static inline int SizeOf(Map map, HeapObject object) {
140     // Has to be implemented by the subclass.
141     UNREACHABLE();
142   }
143 };
144 
145 // This class describes a body of an object of a variable size
146 // in which all pointer fields are located in the [start_offset, object_size)
147 // interval.
148 // All pointers have to be strong.
149 template <int start_offset>
150 class FlexibleBodyDescriptor : public SuffixRangeBodyDescriptor<start_offset> {
151  public:
152   static inline int SizeOf(Map map, HeapObject object);
153 };
154 
155 // A forward-declacable descriptor body alias for most of the Struct successors.
156 class StructBodyDescriptor
157     : public FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
158  public:
159 };
160 
161 // This class describes a body of an object in which all pointer fields are
162 // located in the [start_offset, object_size) interval.
163 // Pointers may be strong or may be MaybeObject-style weak pointers.
164 template <int start_offset>
165 class SuffixRangeWeakBodyDescriptor : public BodyDescriptorBase {
166  public:
167   static const int kStartOffset = start_offset;
168 
IsValidSlot(Map map,HeapObject obj,int offset)169   static bool IsValidSlot(Map map, HeapObject obj, int offset) {
170     return (offset >= kStartOffset);
171   }
172 
173   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)174   static inline void IterateBody(Map map, HeapObject obj, int object_size,
175                                  ObjectVisitor* v) {
176     IterateMaybeWeakPointers(obj, start_offset, object_size, v);
177   }
178 
179  private:
SizeOf(Map map,HeapObject object)180   static inline int SizeOf(Map map, HeapObject object) {
181     // Has to be implemented by the subclass.
182     UNREACHABLE();
183   }
184 };
185 
186 // This class describes a body of an object of a variable size
187 // in which all pointer fields are located in the [start_offset, object_size)
188 // interval.
189 // Pointers may be strong or may be MaybeObject-style weak pointers.
190 template <int start_offset>
191 class FlexibleWeakBodyDescriptor
192     : public SuffixRangeWeakBodyDescriptor<start_offset> {
193  public:
194   static inline int SizeOf(Map map, HeapObject object);
195 };
196 
197 // This class describes a body of an object without any pointers.
198 class DataOnlyBodyDescriptor : public BodyDescriptorBase {
199  public:
IsValidSlot(Map map,HeapObject obj,int offset)200   static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
201 
202   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)203   static inline void IterateBody(Map map, HeapObject obj, int object_size,
204                                  ObjectVisitor* v) {}
205 
206  private:
SizeOf(Map map,HeapObject object)207   static inline int SizeOf(Map map, HeapObject object) {
208     // Has to be implemented by the subclass.
209     UNREACHABLE();
210   }
211 };
212 
213 // This class describes a body of an object which has a parent class that also
214 // has a body descriptor. This represents a union of the parent's body
215 // descriptor, and a new descriptor for the child -- so, both parent and child's
216 // slots are iterated. The parent must be fixed size, and its slots be disjoint
217 // with the child's.
218 template <class ParentBodyDescriptor, class ChildBodyDescriptor>
219 class SubclassBodyDescriptor final : public BodyDescriptorBase {
220  public:
221   // The parent must end be before the child's start offset, to make sure that
222   // their slots are disjoint.
223   STATIC_ASSERT(ParentBodyDescriptor::kSize <=
224                 ChildBodyDescriptor::kStartOffset);
225 
IsValidSlot(Map map,HeapObject obj,int offset)226   static bool IsValidSlot(Map map, HeapObject obj, int offset) {
227     return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
228            ChildBodyDescriptor::IsValidSlot(map, obj, offset);
229   }
230 
231   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,ObjectVisitor * v)232   static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
233     ParentBodyDescriptor::IterateBody(map, obj, v);
234     ChildBodyDescriptor::IterateBody(map, obj, v);
235   }
236 
237   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)238   static inline void IterateBody(Map map, HeapObject obj, int object_size,
239                                  ObjectVisitor* v) {
240     ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
241     ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
242   }
243 
SizeOf(Map map,HeapObject object)244   static inline int SizeOf(Map map, HeapObject object) {
245     // The child should know its full size.
246     return ChildBodyDescriptor::SizeOf(map, object);
247   }
248 };
249 
250 }  // namespace internal
251 }  // namespace v8
252 
253 #endif  // V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
254