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 IterateMaybeWeakPointers(HeapObject obj, int start_offset,
51 : int end_offset, ObjectVisitor* v);
52 :
53 : template <typename ObjectVisitor>
54 : static inline void IterateMaybeWeakPointer(HeapObject obj, int offset,
55 : ObjectVisitor* v);
56 :
57 : protected:
58 : // Returns true for all header and embedder fields.
59 : static inline bool IsValidJSObjectSlotImpl(Map map, HeapObject obj,
60 : int offset);
61 :
62 : // Returns true for all header and embedder fields.
63 : static inline bool IsValidEmbedderJSObjectSlotImpl(Map map, HeapObject obj,
64 : int offset);
65 :
66 : // Treats all header and embedder fields in the range as tagged.
67 : template <typename ObjectVisitor>
68 : static inline void IterateJSObjectBodyImpl(Map map, HeapObject obj,
69 : int start_offset, int end_offset,
70 : ObjectVisitor* v);
71 : };
72 :
73 :
74 : // This class describes a body of an object of a fixed size
75 : // in which all pointer fields are located in the [start_offset, end_offset)
76 : // interval.
77 : template <int start_offset, int end_offset, int size>
78 : class FixedBodyDescriptor final : public BodyDescriptorBase {
79 : public:
80 : static const int kStartOffset = start_offset;
81 : static const int kEndOffset = end_offset;
82 : static const int kSize = size;
83 :
84 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
85 20 : return offset >= kStartOffset && offset < kEndOffset;
86 : }
87 :
88 : template <typename ObjectVisitor>
89 : static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
90 105553109 : IteratePointers(obj, start_offset, end_offset, v);
91 : }
92 :
93 : template <typename ObjectVisitor>
94 74456290 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
95 : ObjectVisitor* v) {
96 : IterateBody(map, obj, v);
97 74488710 : }
98 :
99 58860422 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
100 : };
101 :
102 :
103 : // This class describes a body of an object of a variable size
104 : // in which all pointer fields are located in the [start_offset, object_size)
105 : // interval.
106 : template <int start_offset>
107 : class FlexibleBodyDescriptor final : public BodyDescriptorBase {
108 : public:
109 : static const int kStartOffset = start_offset;
110 :
111 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
112 49 : return (offset >= kStartOffset);
113 : }
114 :
115 : template <typename ObjectVisitor>
116 41480610 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
117 : ObjectVisitor* v) {
118 59088290 : IteratePointers(obj, start_offset, object_size, v);
119 41455542 : }
120 :
121 : static inline int SizeOf(Map map, HeapObject object);
122 : };
123 :
124 :
125 : typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
126 :
127 : template <int start_offset>
128 : class FlexibleWeakBodyDescriptor final : public BodyDescriptorBase {
129 : public:
130 : static const int kStartOffset = start_offset;
131 :
132 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
133 0 : return (offset >= kStartOffset);
134 : }
135 :
136 : template <typename ObjectVisitor>
137 5742124 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
138 : ObjectVisitor* v) {
139 12724049 : IterateMaybeWeakPointers(obj, start_offset, object_size, v);
140 5741411 : }
141 :
142 : static inline int SizeOf(Map map, HeapObject object);
143 : };
144 :
145 : // This class describes a body of an object which has a parent class that also
146 : // has a body descriptor. This represents a union of the parent's body
147 : // descriptor, and a new descriptor for the child -- so, both parent and child's
148 : // slots are iterated. The parent must be fixed size, and its slots be disjoint
149 : // with the child's.
150 : template <class ParentBodyDescriptor, class ChildBodyDescriptor>
151 : class SubclassBodyDescriptor final : public BodyDescriptorBase {
152 : public:
153 : // The parent must end be before the child's start offset, to make sure that
154 : // their slots are disjoint.
155 : STATIC_ASSERT(ParentBodyDescriptor::kSize <=
156 : ChildBodyDescriptor::kStartOffset);
157 :
158 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
159 : return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
160 0 : ChildBodyDescriptor::IsValidSlot(map, obj, offset);
161 : }
162 :
163 : template <typename ObjectVisitor>
164 : static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
165 : ParentBodyDescriptor::IterateBody(map, obj, v);
166 : ChildBodyDescriptor::IterateBody(map, obj, v);
167 : }
168 :
169 : template <typename ObjectVisitor>
170 59689 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
171 : ObjectVisitor* v) {
172 : ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
173 : ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
174 59689 : }
175 :
176 57681 : static inline int SizeOf(Map map, HeapObject object) {
177 : // The child should know its full size.
178 57681 : return ChildBodyDescriptor::SizeOf(map, object);
179 : }
180 : };
181 :
182 : } // namespace internal
183 : } // namespace v8
184 :
185 : #endif // V8_OBJECTS_BODY_DESCRIPTORS_H_
|