v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
objects-body-descriptors.h
Go to the documentation of this file.
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"
10
11namespace v8::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) Iterate object's body using stateful object visitor.
18//
19// template <typename ObjectVisitor>
20// static inline void IterateBody(Tagged<Map> map, HeapObject obj, int
21// object_size,
22// ObjectVisitor* v);
24 public:
25 template <typename ObjectVisitor>
26 static inline void IteratePointers(Tagged<HeapObject> obj, int start_offset,
27 int end_offset, ObjectVisitor* v);
28
29 template <typename ObjectVisitor>
30 static inline void IteratePointer(Tagged<HeapObject> obj, int offset,
31 ObjectVisitor* v);
32
33 template <typename ObjectVisitor>
35 int start_offset, int end_offset,
36 ObjectVisitor* v);
37
38 template <typename ObjectVisitor>
39 static inline void IterateCustomWeakPointer(Tagged<HeapObject> obj,
40 int offset, ObjectVisitor* v);
41
42 template <typename ObjectVisitor>
43 static inline void IterateEphemeron(Tagged<HeapObject> obj, int index,
44 int key_offset, int value_offset,
45 ObjectVisitor* v);
46
47 template <typename ObjectVisitor>
49 int start_offset, int end_offset,
50 ObjectVisitor* v);
51
52 template <typename ObjectVisitor>
53 static inline void IterateMaybeWeakPointer(Tagged<HeapObject> obj, int offset,
54 ObjectVisitor* v);
55
56 template <typename ObjectVisitor>
57 static inline void IterateTrustedPointer(Tagged<HeapObject> obj, int offset,
58 ObjectVisitor* visitor,
61 template <typename ObjectVisitor>
62 static inline void IterateCodePointer(Tagged<HeapObject> obj, int offset,
63 ObjectVisitor* visitor,
65 template <typename ObjectVisitor>
68 ObjectVisitor* v);
69
70 template <typename ObjectVisitor>
71 static inline void IterateProtectedPointer(Tagged<HeapObject> obj, int offset,
72 ObjectVisitor* v);
73#ifdef V8_ENABLE_LEAPTIERING
74 template <typename ObjectVisitor>
75 static inline void IterateJSDispatchEntry(Tagged<HeapObject> obj, int offset,
76 ObjectVisitor* v);
77#endif // V8_ENABLE_LEAPTIERING
78
79 protected:
80 // Returns true for all header and embedder fields.
83 int offset);
84
85 // Treats all header and in-object fields in the range as tagged. Figures out
86 // dynamically whether the object has embedder fields and visits them
87 // accordingly (as tagged fields and as external pointers).
88 template <typename ObjectVisitor>
89 static inline void IterateJSObjectBodyImpl(Tagged<Map> map,
91 int start_offset, int end_offset,
92 ObjectVisitor* v);
93
94 // Treats all header and in-object fields in the range as tagged.
95 template <typename ObjectVisitor>
97 Tagged<Map> map, Tagged<HeapObject> obj, int start_offset, int end_offset,
98 ObjectVisitor* v);
99};
100
101// This class describes a body of an object without any pointers.
103 public:
104 template <typename ObjectVisitor>
105 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
106 int object_size, ObjectVisitor* v) {}
107
108 private:
109 // Note: {SizeOf} is not implemented here; sub-classes will have to implement
110 // it.
111};
112
113// This class describes a body of an object in which all pointer fields are
114// located in the [start_offset, end_offset) interval.
115// All pointers have to be strong.
116template <int start_offset, int end_offset>
118 public:
119 static const int kStartOffset = start_offset;
120 static const int kEndOffset = end_offset;
121
122 template <typename ObjectVisitor>
123 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
124 ObjectVisitor* v) {
125 IteratePointers(obj, start_offset, end_offset, v);
126 }
127
128 template <typename ObjectVisitor>
129 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
130 int object_size, ObjectVisitor* v) {
131 IterateBody(map, obj, v);
132 }
133
134 // Note: {SizeOf} is not implemented here; sub-classes will have to implement
135 // it.
136};
137
138// This class describes a body of an object of a fixed size
139// in which all pointer fields are located in the [start_offset, end_offset)
140// interval.
141// All pointers have to be strong.
142template <int start_offset, int end_offset, int size>
143class FixedBodyDescriptor
144 : public std::conditional_t<
145 start_offset == end_offset, DataOnlyBodyDescriptor,
146 FixedRangeBodyDescriptor<start_offset, end_offset>> {
147 public:
148 static constexpr int kSize = size;
149
150 static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) {
151 DCHECK_EQ(kSize, map->instance_size());
152 return kSize;
153 }
154};
155
156template <typename T>
158 FixedBodyDescriptor<T::kStartOfStrongFieldsOffset,
159 T::kEndOfStrongFieldsOffset, T::kSize>;
160
161// This class describes a body of an object in which all pointer fields are
162// located in the [start_offset, object_size) interval.
163// All pointers have to be strong.
164template <int start_offset>
166 public:
167 static const int kStartOffset = start_offset;
168
169 template <typename ObjectVisitor>
170 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
171 int object_size, ObjectVisitor* v) {
172 IteratePointers(obj, start_offset, object_size, v);
173 }
174
175 // Note: {SizeOf} is not implemented here; sub-classes will have to implement
176 // it.
177};
178
179// This class describes a body of an object of a variable size
180// in which all pointer fields are located in the [start_offset, object_size)
181// interval.
182// All pointers have to be strong.
183template <int start_offset>
184class FlexibleBodyDescriptor : public SuffixRangeBodyDescriptor<start_offset> {
185 public:
186 static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object);
187};
188
189// A forward-declarable descriptor body alias for most of the Struct successors.
191 : public FlexibleBodyDescriptor<HeapObject::kHeaderSize> {};
192
193// This class describes a body of an object in which all pointer fields are
194// located in the [start_offset, object_size) interval.
195// Pointers may be strong or may be Tagged<MaybeObject>-style weak pointers.
196template <int start_offset>
198 public:
199 static const int kStartOffset = start_offset;
200
201 template <typename ObjectVisitor>
202 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
203 int object_size, ObjectVisitor* v) {
204 IterateMaybeWeakPointers(obj, start_offset, object_size, v);
205 }
206
207 // Note: {SizeOf} is not implemented here; sub-classes will have to implement
208 // it.
209};
210
211// This class describes a body of an object of a variable size
212// in which all pointer fields are located in the [start_offset, object_size)
213// interval.
214// Pointers may be strong or may be Tagged<MaybeObject>-style weak pointers.
215template <int start_offset>
216class FlexibleWeakBodyDescriptor
217 : public SuffixRangeWeakBodyDescriptor<start_offset> {
218 public:
219 static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object);
220};
221
222// This class describes a body of an object which has a parent class that also
223// has a body descriptor. This represents a union of the parent's body
224// descriptor, and a new descriptor for the child -- so, both parent and child's
225// slots are iterated. The parent must be fixed size, and its slots be disjoint
226// with the child's.
227template <class ParentBodyDescriptor, class ChildBodyDescriptor>
228class SubclassBodyDescriptor : public BodyDescriptorBase {
229 public:
230 // The parent must end be before the child's start offset, to make sure that
231 // their slots are disjoint.
232 static_assert(ParentBodyDescriptor::kSize <=
233 ChildBodyDescriptor::kStartOffset);
234
235 template <typename ObjectVisitor>
236 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
237 ObjectVisitor* v) {
238 ParentBodyDescriptor::IterateBody(map, obj, v);
239 ChildBodyDescriptor::IterateBody(map, obj, v);
240 }
241
242 template <typename ObjectVisitor>
243 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
244 int object_size, ObjectVisitor* v) {
245 ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
246 ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
247 }
248
249 static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) {
250 // The child should know its full size.
251 return ChildBodyDescriptor::SizeOf(map, object);
252 }
253};
254
255// Visitor for exposed trusted objects with fixed layout according to
256// FixedBodyDescriptor.
257template <typename T, IndirectPointerTag kTag>
259 : public FixedBodyDescriptorFor<T> {
260 static_assert(std::is_base_of_v<ExposedTrustedObject, T>);
262
263 public:
264 template <typename ObjectVisitor>
265 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
266 int object_size, ObjectVisitor* v) {
267 Base::IterateSelfIndirectPointer(obj, kTag, v);
268 Base::IterateBody(map, obj, object_size, v);
269 }
270};
271
272// A mix-in for visiting a trusted pointer field.
273template <size_t kFieldOffset, IndirectPointerTag kTag>
275 template <typename Base>
276 class BodyDescriptor : public Base {
277 public:
278 template <typename ObjectVisitor>
279 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
280 int object_size, ObjectVisitor* v) {
281 Base::IterateBody(map, obj, object_size, v);
282 Base::IterateTrustedPointer(obj, kFieldOffset, v,
284 }
285 };
286};
287
288template <size_t kFieldOffset>
291
292// A mix-in for visiting an external pointer field.
293template <size_t kFieldOffset, ExternalPointerTagRange kTagRange>
295 template <typename Base>
296 class BodyDescriptor : public Base {
297 public:
298 template <typename ObjectVisitor>
299 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
300 int object_size, ObjectVisitor* v) {
301 Base::IterateBody(map, obj, object_size, v);
303 obj, obj->RawExternalPointerField(kFieldOffset, kTagRange));
304 }
305 };
306};
307
308// A mix-in for visiting an external pointer field.
309template <size_t kFieldOffset>
311 template <typename Base>
312 class BodyDescriptor : public Base {
313 public:
314 template <typename ObjectVisitor>
315 static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
316 int object_size, ObjectVisitor* v) {
317 Base::IterateBody(map, obj, object_size, v);
318 Base::IterateProtectedPointer(obj, kFieldOffset, v);
319 }
320 };
321};
322
323// Stack multiple body descriptors; the first template argument is the base,
324// followed by mix-ins.
325template <typename Base, typename FirstMixin, typename... MoreMixins>
327 : public StackedBodyDescriptor<
328 typename FirstMixin::template BodyDescriptor<Base>, MoreMixins...> {};
329
330// Define a specialization for the base case of only one mixin.
331template <typename Base, typename FirstMixin>
332class StackedBodyDescriptor<Base, FirstMixin>
333 : public FirstMixin::template BodyDescriptor<Base> {};
334
335} // namespace v8::internal
336
337#endif // V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
static void IteratePointer(Tagged< HeapObject > obj, int offset, ObjectVisitor *v)
static bool IsValidEmbedderJSObjectSlotImpl(Tagged< Map > map, Tagged< HeapObject > obj, int offset)
static void IterateCustomWeakPointer(Tagged< HeapObject > obj, int offset, ObjectVisitor *v)
static void IterateSelfIndirectPointer(Tagged< HeapObject > obj, IndirectPointerTag tag, ObjectVisitor *v)
static void IterateMaybeWeakPointers(Tagged< HeapObject > obj, int start_offset, int end_offset, ObjectVisitor *v)
static void IterateJSObjectBodyImpl(Tagged< Map > map, Tagged< HeapObject > obj, int start_offset, int end_offset, ObjectVisitor *v)
static void IterateCodePointer(Tagged< HeapObject > obj, int offset, ObjectVisitor *visitor, IndirectPointerMode mode)
static void IterateTrustedPointer(Tagged< HeapObject > obj, int offset, ObjectVisitor *visitor, IndirectPointerMode mode, IndirectPointerTag tag)
static void IterateProtectedPointer(Tagged< HeapObject > obj, int offset, ObjectVisitor *v)
static void IterateJSObjectBodyWithoutEmbedderFieldsImpl(Tagged< Map > map, Tagged< HeapObject > obj, int start_offset, int end_offset, ObjectVisitor *v)
static void IteratePointers(Tagged< HeapObject > obj, int start_offset, int end_offset, ObjectVisitor *v)
static void IterateMaybeWeakPointer(Tagged< HeapObject > obj, int offset, ObjectVisitor *v)
static void IterateCustomWeakPointers(Tagged< HeapObject > obj, int start_offset, int end_offset, ObjectVisitor *v)
static void IterateEphemeron(Tagged< HeapObject > obj, int index, int key_offset, int value_offset, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static int SizeOf(Tagged< Map > map, Tagged< HeapObject > object)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static int SizeOf(Tagged< Map > map, Tagged< HeapObject > object)
static int SizeOf(Tagged< Map > map, Tagged< HeapObject > object)
virtual void VisitExternalPointer(Tagged< HeapObject > host, ExternalPointerSlot slot)
Definition visitors.h:188
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, ObjectVisitor *v)
static int SizeOf(Tagged< Map > map, Tagged< HeapObject > object)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
static void IterateBody(Tagged< Map > map, Tagged< HeapObject > obj, int object_size, ObjectVisitor *v)
int32_t offset
kInterpreterTrampolineOffset Tagged< HeapObject >
#define DCHECK_EQ(v1, v2)
Definition logging.h:485