Line data Source code
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 : #include "src/objects/map.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 :
78 : // This class describes a body of an object of a fixed size
79 : // in which all pointer fields are located in the [start_offset, end_offset)
80 : // interval.
81 : template <int start_offset, int end_offset, int size>
82 : class FixedBodyDescriptor final : public BodyDescriptorBase {
83 : public:
84 : static const int kStartOffset = start_offset;
85 : static const int kEndOffset = end_offset;
86 : static const int kSize = size;
87 :
88 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
89 15 : return offset >= kStartOffset && offset < kEndOffset;
90 : }
91 :
92 : template <typename ObjectVisitor>
93 : static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
94 72503376 : IteratePointers(obj, start_offset, end_offset, v);
95 : }
96 :
97 : template <typename ObjectVisitor>
98 22727673 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
99 : ObjectVisitor* v) {
100 : IterateBody(map, obj, v);
101 22696854 : }
102 :
103 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
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 :
115 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
116 10 : return (offset >= kStartOffset);
117 : }
118 :
119 : template <typename ObjectVisitor>
120 2485822 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
121 : ObjectVisitor* v) {
122 35409754 : IteratePointers(obj, start_offset, object_size, v);
123 2485822 : }
124 :
125 : static inline int SizeOf(Map map, HeapObject object);
126 : };
127 :
128 : typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
129 :
130 : template <int start_offset>
131 : class FlexibleWeakBodyDescriptor final : public BodyDescriptorBase {
132 : public:
133 : static const int kStartOffset = start_offset;
134 :
135 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
136 0 : return (offset >= kStartOffset);
137 : }
138 :
139 : template <typename ObjectVisitor>
140 844763 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
141 : ObjectVisitor* v) {
142 6164372 : IterateMaybeWeakPointers(obj, start_offset, object_size, v);
143 844763 : }
144 :
145 : static inline int SizeOf(Map map, HeapObject object);
146 : };
147 :
148 : // This class describes a body of an object which has a parent class that also
149 : // has a body descriptor. This represents a union of the parent's body
150 : // descriptor, and a new descriptor for the child -- so, both parent and child's
151 : // slots are iterated. The parent must be fixed size, and its slots be disjoint
152 : // with the child's.
153 : template <class ParentBodyDescriptor, class ChildBodyDescriptor>
154 : class SubclassBodyDescriptor final : public BodyDescriptorBase {
155 : public:
156 : // The parent must end be before the child's start offset, to make sure that
157 : // their slots are disjoint.
158 : STATIC_ASSERT(ParentBodyDescriptor::kSize <=
159 : ChildBodyDescriptor::kStartOffset);
160 :
161 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
162 : return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
163 0 : ChildBodyDescriptor::IsValidSlot(map, obj, offset);
164 : }
165 :
166 : template <typename ObjectVisitor>
167 : static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
168 : ParentBodyDescriptor::IterateBody(map, obj, v);
169 : ChildBodyDescriptor::IterateBody(map, obj, v);
170 : }
171 :
172 : template <typename ObjectVisitor>
173 55975 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
174 : ObjectVisitor* v) {
175 : ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
176 : ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
177 56040 : }
178 :
179 43607 : static inline int SizeOf(Map map, HeapObject object) {
180 : // The child should know its full size.
181 43607 : return ChildBodyDescriptor::SizeOf(map, object);
182 : }
183 : };
184 :
185 : } // namespace internal
186 : } // namespace v8
187 :
188 : #endif // V8_OBJECTS_BODY_DESCRIPTORS_H_
|