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