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 56923588 : IteratePointers(obj, start_offset, end_offset, v);
95 : }
96 :
97 : template <typename ObjectVisitor>
98 25191180 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
99 : ObjectVisitor* v) {
100 : IterateBody(map, obj, v);
101 25159996 : }
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 25 : return (offset >= kStartOffset);
117 : }
118 :
119 : template <typename ObjectVisitor>
120 2760488 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
121 : ObjectVisitor* v) {
122 29867475 : IteratePointers(obj, start_offset, object_size, v);
123 2760488 : }
124 :
125 : static inline int SizeOf(Map map, HeapObject object);
126 : };
127 :
128 :
129 : typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
130 :
131 : template <int start_offset>
132 : class FlexibleWeakBodyDescriptor final : public BodyDescriptorBase {
133 : public:
134 : static const int kStartOffset = start_offset;
135 :
136 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
137 0 : return (offset >= kStartOffset);
138 : }
139 :
140 : template <typename ObjectVisitor>
141 911213 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
142 : ObjectVisitor* v) {
143 5529520 : IterateMaybeWeakPointers(obj, start_offset, object_size, v);
144 911213 : }
145 :
146 : static inline int SizeOf(Map map, HeapObject object);
147 : };
148 :
149 : // This class describes a body of an object which has a parent class that also
150 : // has a body descriptor. This represents a union of the parent's body
151 : // descriptor, and a new descriptor for the child -- so, both parent and child's
152 : // slots are iterated. The parent must be fixed size, and its slots be disjoint
153 : // with the child's.
154 : template <class ParentBodyDescriptor, class ChildBodyDescriptor>
155 : class SubclassBodyDescriptor final : public BodyDescriptorBase {
156 : public:
157 : // The parent must end be before the child's start offset, to make sure that
158 : // their slots are disjoint.
159 : STATIC_ASSERT(ParentBodyDescriptor::kSize <=
160 : ChildBodyDescriptor::kStartOffset);
161 :
162 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
163 : return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
164 0 : ChildBodyDescriptor::IsValidSlot(map, obj, offset);
165 : }
166 :
167 : template <typename ObjectVisitor>
168 : static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
169 : ParentBodyDescriptor::IterateBody(map, obj, v);
170 : ChildBodyDescriptor::IterateBody(map, obj, v);
171 : }
172 :
173 : template <typename ObjectVisitor>
174 52986 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
175 : ObjectVisitor* v) {
176 : ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
177 : ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
178 53050 : }
179 :
180 40186 : static inline int SizeOf(Map map, HeapObject object) {
181 : // The child should know its full size.
182 40186 : return ChildBodyDescriptor::SizeOf(map, object);
183 : }
184 : };
185 :
186 : } // namespace internal
187 : } // namespace v8
188 :
189 : #endif // V8_OBJECTS_BODY_DESCRIPTORS_H_
|