• 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 using StructBodyDescriptor = FlexibleBodyDescriptor<HeapObject::kHeaderSize>;
156 
157 // This class describes a body of an object in which all pointer fields are
158 // located in the [start_offset, object_size) interval.
159 // Pointers may be strong or may be MaybeObject-style weak pointers.
160 template <int start_offset>
161 class SuffixRangeWeakBodyDescriptor : public BodyDescriptorBase {
162  public:
163   static const int kStartOffset = start_offset;
164 
IsValidSlot(Map map,HeapObject obj,int offset)165   static bool IsValidSlot(Map map, HeapObject obj, int offset) {
166     return (offset >= kStartOffset);
167   }
168 
169   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)170   static inline void IterateBody(Map map, HeapObject obj, int object_size,
171                                  ObjectVisitor* v) {
172     IterateMaybeWeakPointers(obj, start_offset, object_size, v);
173   }
174 
175  private:
SizeOf(Map map,HeapObject object)176   static inline int SizeOf(Map map, HeapObject object) {
177     // Has to be implemented by the subclass.
178     UNREACHABLE();
179   }
180 };
181 
182 // This class describes a body of an object of a variable size
183 // in which all pointer fields are located in the [start_offset, object_size)
184 // interval.
185 // Pointers may be strong or may be MaybeObject-style weak pointers.
186 template <int start_offset>
187 class FlexibleWeakBodyDescriptor
188     : public SuffixRangeWeakBodyDescriptor<start_offset> {
189  public:
190   static inline int SizeOf(Map map, HeapObject object);
191 };
192 
193 // This class describes a body of an object without any pointers.
194 class DataOnlyBodyDescriptor : public BodyDescriptorBase {
195  public:
IsValidSlot(Map map,HeapObject obj,int offset)196   static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
197 
198   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)199   static inline void IterateBody(Map map, HeapObject obj, int object_size,
200                                  ObjectVisitor* v) {}
201 
202  private:
SizeOf(Map map,HeapObject object)203   static inline int SizeOf(Map map, HeapObject object) {
204     // Has to be implemented by the subclass.
205     UNREACHABLE();
206   }
207 };
208 
209 // This class describes a body of an object which has a parent class that also
210 // has a body descriptor. This represents a union of the parent's body
211 // descriptor, and a new descriptor for the child -- so, both parent and child's
212 // slots are iterated. The parent must be fixed size, and its slots be disjoint
213 // with the child's.
214 template <class ParentBodyDescriptor, class ChildBodyDescriptor>
215 class SubclassBodyDescriptor final : public BodyDescriptorBase {
216  public:
217   // The parent must end be before the child's start offset, to make sure that
218   // their slots are disjoint.
219   STATIC_ASSERT(ParentBodyDescriptor::kSize <=
220                 ChildBodyDescriptor::kStartOffset);
221 
IsValidSlot(Map map,HeapObject obj,int offset)222   static bool IsValidSlot(Map map, HeapObject obj, int offset) {
223     return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
224            ChildBodyDescriptor::IsValidSlot(map, obj, offset);
225   }
226 
227   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,ObjectVisitor * v)228   static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
229     ParentBodyDescriptor::IterateBody(map, obj, v);
230     ChildBodyDescriptor::IterateBody(map, obj, v);
231   }
232 
233   template <typename ObjectVisitor>
IterateBody(Map map,HeapObject obj,int object_size,ObjectVisitor * v)234   static inline void IterateBody(Map map, HeapObject obj, int object_size,
235                                  ObjectVisitor* v) {
236     ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
237     ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
238   }
239 
SizeOf(Map map,HeapObject object)240   static inline int SizeOf(Map map, HeapObject object) {
241     // The child should know its full size.
242     return ChildBodyDescriptor::SizeOf(map, object);
243   }
244 };
245 
246 }  // namespace internal
247 }  // namespace v8
248 
249 #endif  // V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
250