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_INL_H_
6 : #define V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
7 :
8 : #include "src/feedback-vector.h"
9 : #include "src/objects-body-descriptors.h"
10 : #include "src/objects/cell.h"
11 : #include "src/objects/foreign-inl.h"
12 : #include "src/objects/hash-table.h"
13 : #include "src/objects/js-collection.h"
14 : #include "src/objects/js-weak-refs.h"
15 : #include "src/objects/oddball.h"
16 : #include "src/objects/slots.h"
17 : #include "src/reloc-info.h"
18 : #include "src/transitions.h"
19 : #include "src/wasm/wasm-objects-inl.h"
20 :
21 : namespace v8 {
22 : namespace internal {
23 :
24 : template <int start_offset>
25 20466446 : int FlexibleBodyDescriptor<start_offset>::SizeOf(Map map, HeapObject object) {
26 20481414 : return object->SizeFromMap(map);
27 : }
28 :
29 : template <int start_offset>
30 10328484 : int FlexibleWeakBodyDescriptor<start_offset>::SizeOf(Map map,
31 : HeapObject object) {
32 10931038 : return object->SizeFromMap(map);
33 : }
34 :
35 32 : bool BodyDescriptorBase::IsValidJSObjectSlotImpl(Map map, HeapObject obj,
36 : int offset) {
37 : #ifdef V8_COMPRESS_POINTERS
38 : STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kTaggedSize);
39 : int embedder_fields_offset = JSObject::GetEmbedderFieldsStartOffset(map);
40 : int inobject_fields_offset = map->GetInObjectPropertyOffset(0);
41 : // |embedder_fields_offset| may be greater than |inobject_fields_offset| if
42 : // the object does not have embedder fields but the check handles this
43 : // case properly.
44 : if (embedder_fields_offset <= offset && offset < inobject_fields_offset) {
45 : // offset points to embedder fields area:
46 : // [embedder_fields_offset, inobject_fields_offset).
47 : STATIC_ASSERT(base::bits::IsPowerOfTwo(kEmbedderDataSlotSize));
48 : return ((offset - embedder_fields_offset) & (kEmbedderDataSlotSize - 1)) ==
49 : EmbedderDataSlot::kTaggedPayloadOffset;
50 : }
51 : #else
52 : // We store raw aligned pointers as Smis, so it's safe to treat the whole
53 : // embedder field area as tagged slots.
54 : STATIC_ASSERT(kEmbedderDataSlotSize == kTaggedSize);
55 : #endif
56 32 : if (!FLAG_unbox_double_fields || map->HasFastPointerLayout()) {
57 : return true;
58 : } else {
59 : DCHECK(FLAG_unbox_double_fields);
60 : DCHECK(IsAligned(offset, kSystemPointerSize));
61 :
62 10 : LayoutDescriptorHelper helper(map);
63 : DCHECK(!helper.all_fields_tagged());
64 10 : return helper.IsTagged(offset);
65 : }
66 : }
67 :
68 : template <typename ObjectVisitor>
69 25969682 : void BodyDescriptorBase::IterateJSObjectBodyImpl(Map map, HeapObject obj,
70 : int start_offset,
71 : int end_offset,
72 : ObjectVisitor* v) {
73 : #ifdef V8_COMPRESS_POINTERS
74 : STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kTaggedSize);
75 : int header_size = JSObject::GetHeaderSize(map);
76 : int inobject_fields_offset = map->GetInObjectPropertyOffset(0);
77 : // We are always requested to process header and embedder fields.
78 : DCHECK_LE(inobject_fields_offset, end_offset);
79 : // Embedder fields are located between header rouned up to the system pointer
80 : // size and inobject properties.
81 : if (header_size < inobject_fields_offset) {
82 : // There are embedder fields.
83 : IteratePointers(obj, start_offset, header_size, v);
84 : // Iterate only tagged payload of the embedder slots and skip raw payload.
85 : int embedder_fields_offset = RoundUp(header_size, kSystemPointerSize);
86 : DCHECK_EQ(embedder_fields_offset,
87 : JSObject::GetEmbedderFieldsStartOffset(map));
88 : for (int offset =
89 : embedder_fields_offset + EmbedderDataSlot::kTaggedPayloadOffset;
90 : offset < inobject_fields_offset; offset += kEmbedderDataSlotSize) {
91 : IteratePointer(obj, offset, v);
92 : }
93 : // Proceed processing inobject properties.
94 : start_offset = inobject_fields_offset;
95 : }
96 : #else
97 : // We store raw aligned pointers as Smis, so it's safe to iterate the whole
98 : // embedder field area as tagged slots.
99 : STATIC_ASSERT(kEmbedderDataSlotSize == kTaggedSize);
100 : #endif
101 25969682 : if (!FLAG_unbox_double_fields || map->HasFastPointerLayout()) {
102 17273016 : IteratePointers(obj, start_offset, end_offset, v);
103 : } else {
104 : DCHECK(FLAG_unbox_double_fields);
105 : DCHECK(IsAligned(start_offset, kSystemPointerSize) &&
106 : IsAligned(end_offset, kSystemPointerSize));
107 :
108 271507 : LayoutDescriptorHelper helper(map);
109 : DCHECK(!helper.all_fields_tagged());
110 1143964 : for (int offset = start_offset; offset < end_offset;) {
111 : int end_of_region_offset;
112 601838 : if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
113 331784 : IteratePointers(obj, offset, end_of_region_offset, v);
114 : }
115 602438 : offset = end_of_region_offset;
116 : }
117 : }
118 25772118 : }
119 :
120 : template <typename ObjectVisitor>
121 705176244 : DISABLE_CFI_PERF void BodyDescriptorBase::IteratePointers(HeapObject obj,
122 : int start_offset,
123 : int end_offset,
124 : ObjectVisitor* v) {
125 469046849 : v->VisitPointers(obj, HeapObject::RawField(obj, start_offset),
126 : HeapObject::RawField(obj, end_offset));
127 706962735 : }
128 :
129 : template <typename ObjectVisitor>
130 6901128 : void BodyDescriptorBase::IteratePointer(HeapObject obj, int offset,
131 : ObjectVisitor* v) {
132 48691692 : v->VisitPointer(obj, HeapObject::RawField(obj, offset));
133 6901129 : }
134 :
135 : template <typename ObjectVisitor>
136 19741056 : DISABLE_CFI_PERF void BodyDescriptorBase::IterateMaybeWeakPointers(
137 : HeapObject obj, int start_offset, int end_offset, ObjectVisitor* v) {
138 7097716 : v->VisitPointers(obj, HeapObject::RawMaybeWeakField(obj, start_offset),
139 : HeapObject::RawMaybeWeakField(obj, end_offset));
140 19710773 : }
141 :
142 : template <typename ObjectVisitor>
143 14828943 : void BodyDescriptorBase::IterateMaybeWeakPointer(HeapObject obj, int offset,
144 : ObjectVisitor* v) {
145 73886888 : v->VisitPointer(obj, HeapObject::RawMaybeWeakField(obj, offset));
146 14828944 : }
147 :
148 : template <typename ObjectVisitor>
149 : DISABLE_CFI_PERF void BodyDescriptorBase::IterateCustomWeakPointers(
150 : HeapObject obj, int start_offset, int end_offset, ObjectVisitor* v) {
151 6141050 : v->VisitCustomWeakPointers(obj, HeapObject::RawField(obj, start_offset),
152 : HeapObject::RawField(obj, end_offset));
153 : }
154 :
155 : template <typename ObjectVisitor>
156 : void BodyDescriptorBase::IterateCustomWeakPointer(HeapObject obj, int offset,
157 : ObjectVisitor* v) {
158 139678348 : v->VisitCustomWeakPointer(obj, HeapObject::RawField(obj, offset));
159 : }
160 :
161 : class JSObject::BodyDescriptor final : public BodyDescriptorBase {
162 : public:
163 : static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
164 :
165 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
166 32 : if (offset < kStartOffset) return false;
167 32 : return IsValidJSObjectSlotImpl(map, obj, offset);
168 : }
169 :
170 : template <typename ObjectVisitor>
171 196494 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
172 : ObjectVisitor* v) {
173 18202431 : IterateJSObjectBodyImpl(map, obj, kStartOffset, object_size, v);
174 196486 : }
175 :
176 196498 : static inline int SizeOf(Map map, HeapObject object) {
177 196498 : return map->instance_size();
178 : }
179 : };
180 :
181 : class JSObject::FastBodyDescriptor final : public BodyDescriptorBase {
182 : public:
183 : static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
184 :
185 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
186 : return offset >= kStartOffset;
187 : }
188 :
189 : template <typename ObjectVisitor>
190 45352103 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
191 : ObjectVisitor* v) {
192 100975480 : IteratePointers(obj, kStartOffset, object_size, v);
193 45299629 : }
194 :
195 45348762 : static inline int SizeOf(Map map, HeapObject object) {
196 45348762 : return map->instance_size();
197 : }
198 : };
199 :
200 : class JSFunction::BodyDescriptor final : public BodyDescriptorBase {
201 : public:
202 0 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
203 0 : if (offset < kSizeWithoutPrototype) return true;
204 0 : if (offset < kSizeWithPrototype && map->has_prototype_slot()) {
205 : return true;
206 : }
207 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
208 : }
209 :
210 : template <typename ObjectVisitor>
211 6828431 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
212 : ObjectVisitor* v) {
213 : int header_size = JSFunction::GetHeaderSize(map->has_prototype_slot());
214 : DCHECK_EQ(header_size, JSObject::GetHeaderSize(map));
215 4192549 : IteratePointers(obj, kPropertiesOrHashOffset, header_size, v);
216 6795625 : IterateJSObjectBodyImpl(map, obj, header_size, object_size, v);
217 6807250 : }
218 :
219 : static inline int SizeOf(Map map, HeapObject object) {
220 : return map->instance_size();
221 : }
222 : };
223 :
224 : class JSWeakCell::BodyDescriptor final : public BodyDescriptorBase {
225 : public:
226 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
227 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
228 : }
229 :
230 : template <typename ObjectVisitor>
231 396 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
232 : ObjectVisitor* v) {
233 396 : IteratePointers(obj, JSReceiver::kPropertiesOrHashOffset, kTargetOffset, v);
234 : IterateCustomWeakPointer(obj, kTargetOffset, v);
235 396 : IterateJSObjectBodyImpl(map, obj, kTargetOffset + kTaggedSize, object_size,
236 : v);
237 396 : }
238 :
239 168 : static inline int SizeOf(Map map, HeapObject object) {
240 168 : return map->instance_size();
241 : }
242 : };
243 :
244 : class JSWeakRef::BodyDescriptor final : public BodyDescriptorBase {
245 : public:
246 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
247 : return JSObject::BodyDescriptor::IsValidSlot(map, obj, offset);
248 : }
249 :
250 : template <typename ObjectVisitor>
251 350 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
252 : ObjectVisitor* v) {
253 276 : IteratePointers(obj, JSReceiver::kPropertiesOrHashOffset, kTargetOffset, v);
254 : IterateCustomWeakPointer(obj, kTargetOffset, v);
255 276 : IteratePointers(obj, kTargetOffset + kPointerSize, object_size, v);
256 350 : }
257 :
258 157 : static inline int SizeOf(Map map, HeapObject object) {
259 157 : return map->instance_size();
260 : }
261 : };
262 :
263 : class SharedFunctionInfo::BodyDescriptor final : public BodyDescriptorBase {
264 : public:
265 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
266 : return FixedBodyDescriptor<kStartOfPointerFieldsOffset,
267 : kEndOfTaggedFieldsOffset,
268 : kAlignedSize>::IsValidSlot(map, obj, offset);
269 : }
270 :
271 : template <typename ObjectVisitor>
272 69838465 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
273 : ObjectVisitor* v) {
274 : IterateCustomWeakPointer(obj, kFunctionDataOffset, v);
275 68323104 : IteratePointers(obj,
276 : SharedFunctionInfo::kStartOfAlwaysStrongPointerFieldsOffset,
277 : SharedFunctionInfo::kEndOfTaggedFieldsOffset, v);
278 69892703 : }
279 :
280 19495519 : static inline int SizeOf(Map map, HeapObject object) {
281 19495519 : return map->instance_size();
282 : }
283 : };
284 :
285 : class AllocationSite::BodyDescriptor final : public BodyDescriptorBase {
286 : public:
287 : STATIC_ASSERT(AllocationSite::kCommonPointerFieldEndOffset ==
288 : AllocationSite::kPretenureDataOffset);
289 : STATIC_ASSERT(AllocationSite::kPretenureDataOffset + kInt32Size ==
290 : AllocationSite::kPretenureCreateCountOffset);
291 : STATIC_ASSERT(AllocationSite::kPretenureCreateCountOffset + kInt32Size ==
292 : AllocationSite::kWeakNextOffset);
293 :
294 0 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
295 0 : if (offset >= AllocationSite::kStartOffset &&
296 : offset < AllocationSite::kCommonPointerFieldEndOffset) {
297 : return true;
298 : }
299 : // check for weak_next offset
300 0 : if (map->instance_size() == AllocationSite::kSizeWithWeakNext &&
301 : offset == AllocationSite::kWeakNextOffset) {
302 : return true;
303 : }
304 : return false;
305 : }
306 :
307 : template <typename ObjectVisitor>
308 4117385 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
309 : ObjectVisitor* v) {
310 : // Iterate over all the common pointer fields
311 4115141 : IteratePointers(obj, AllocationSite::kStartOffset,
312 : AllocationSite::kCommonPointerFieldEndOffset, v);
313 : // Skip PretenureDataOffset and PretenureCreateCount which are Int32 fields.
314 : // Visit weak_next only if it has weak_next field.
315 125547 : if (object_size == AllocationSite::kSizeWithWeakNext) {
316 : IterateCustomWeakPointers(obj, AllocationSite::kWeakNextOffset,
317 : AllocationSite::kSizeWithWeakNext, v);
318 : }
319 4114490 : }
320 :
321 4002050 : static inline int SizeOf(Map map, HeapObject object) {
322 4002050 : return map->instance_size();
323 : }
324 : };
325 :
326 : class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase {
327 : public:
328 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
329 0 : if (offset < kEndOfTaggedFieldsOffset) return true;
330 0 : if (offset < kHeaderSize) return false;
331 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
332 : }
333 :
334 : template <typename ObjectVisitor>
335 539683 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
336 : ObjectVisitor* v) {
337 : // JSArrayBuffer instances contain raw data that the GC does not know about.
338 513292 : IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
339 539680 : IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v);
340 539863 : }
341 :
342 140754 : static inline int SizeOf(Map map, HeapObject object) {
343 140754 : return map->instance_size();
344 : }
345 : };
346 :
347 : class JSArrayBufferView::BodyDescriptor final : public BodyDescriptorBase {
348 : public:
349 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
350 0 : if (offset < kEndOfTaggedFieldsOffset) return true;
351 0 : if (offset < kHeaderSize) return false;
352 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
353 : }
354 :
355 : template <typename ObjectVisitor>
356 276764 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
357 : ObjectVisitor* v) {
358 : // JSArrayBufferView contains raw data that the GC does not know about.
359 257695 : IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
360 276136 : IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v);
361 275919 : }
362 :
363 127582 : static inline int SizeOf(Map map, HeapObject object) {
364 127582 : return map->instance_size();
365 : }
366 : };
367 :
368 : template <typename Derived>
369 : class SmallOrderedHashTable<Derived>::BodyDescriptor final
370 : : public BodyDescriptorBase {
371 : public:
372 0 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
373 : Derived table = Derived::cast(obj);
374 : // Only data table part contains tagged values.
375 : return (offset >= DataTableStartOffset()) &&
376 0 : (offset < table->GetBucketsStartOffset());
377 : }
378 :
379 : template <typename ObjectVisitor>
380 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
381 : ObjectVisitor* v) {
382 : Derived table = Derived::cast(obj);
383 : int start_offset = DataTableStartOffset();
384 : int end_offset = table->GetBucketsStartOffset();
385 0 : IteratePointers(obj, start_offset, end_offset, v);
386 0 : }
387 :
388 0 : static inline int SizeOf(Map map, HeapObject obj) {
389 : Derived table = Derived::cast(obj);
390 0 : return table->SizeFor(table->Capacity());
391 : }
392 : };
393 :
394 : class ByteArray::BodyDescriptor final : public BodyDescriptorBase {
395 : public:
396 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
397 :
398 : template <typename ObjectVisitor>
399 7524010 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
400 7524010 : ObjectVisitor* v) {}
401 :
402 11214008 : static inline int SizeOf(Map map, HeapObject obj) {
403 22425719 : return ByteArray::SizeFor(ByteArray::cast(obj)->synchronized_length());
404 : }
405 : };
406 :
407 : class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase {
408 : public:
409 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
410 0 : return offset >= kConstantPoolOffset &&
411 0 : offset <= kSourcePositionTableOffset;
412 : }
413 :
414 : template <typename ObjectVisitor>
415 5660595 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
416 : ObjectVisitor* v) {
417 1789328 : IteratePointer(obj, kConstantPoolOffset, v);
418 1789328 : IteratePointer(obj, kHandlerTableOffset, v);
419 1789328 : IteratePointer(obj, kSourcePositionTableOffset, v);
420 5677222 : }
421 :
422 5477592 : static inline int SizeOf(Map map, HeapObject obj) {
423 : return BytecodeArray::SizeFor(
424 10952817 : BytecodeArray::cast(obj)->synchronized_length());
425 : }
426 : };
427 :
428 : class BigInt::BodyDescriptor final : public BodyDescriptorBase {
429 : public:
430 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
431 :
432 : template <typename ObjectVisitor>
433 2350 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
434 2350 : ObjectVisitor* v) {}
435 :
436 3555 : static inline int SizeOf(Map map, HeapObject obj) {
437 3556 : return BigInt::SizeFor(BigInt::cast(obj)->synchronized_length());
438 : }
439 : };
440 :
441 : class FixedDoubleArray::BodyDescriptor final : public BodyDescriptorBase {
442 : public:
443 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
444 :
445 : template <typename ObjectVisitor>
446 35673 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
447 35673 : ObjectVisitor* v) {}
448 :
449 110397 : static inline int SizeOf(Map map, HeapObject obj) {
450 : return FixedDoubleArray::SizeFor(
451 220794 : FixedDoubleArray::cast(obj)->synchronized_length());
452 : }
453 : };
454 :
455 : class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase {
456 : public:
457 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
458 0 : return offset == kBasePointerOffset;
459 : }
460 :
461 : template <typename ObjectVisitor>
462 193853 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
463 : ObjectVisitor* v) {
464 52073 : IteratePointer(obj, kBasePointerOffset, v);
465 193875 : }
466 :
467 193908 : static inline int SizeOf(Map map, HeapObject object) {
468 387788 : return FixedTypedArrayBase::cast(object)->size();
469 : }
470 : };
471 :
472 : class FeedbackMetadata::BodyDescriptor final : public BodyDescriptorBase {
473 : public:
474 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
475 :
476 : template <typename ObjectVisitor>
477 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
478 : ObjectVisitor* v) {}
479 :
480 : static inline int SizeOf(Map map, HeapObject obj) {
481 : return FeedbackMetadata::SizeFor(
482 : FeedbackMetadata::cast(obj)->synchronized_slot_count());
483 : }
484 : };
485 :
486 : class FeedbackVector::BodyDescriptor final : public BodyDescriptorBase {
487 : public:
488 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
489 0 : return offset == kSharedFunctionInfoOffset ||
490 0 : offset == kOptimizedCodeOffset || offset >= kFeedbackSlotsOffset;
491 : }
492 :
493 : template <typename ObjectVisitor>
494 4952605 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
495 : ObjectVisitor* v) {
496 1481072 : IteratePointer(obj, kSharedFunctionInfoOffset, v);
497 1481072 : IterateMaybeWeakPointer(obj, kOptimizedCodeOffset, v);
498 4938667 : IterateMaybeWeakPointers(obj, kFeedbackSlotsOffset, object_size, v);
499 4962305 : }
500 :
501 4799139 : static inline int SizeOf(Map map, HeapObject obj) {
502 4798114 : return FeedbackVector::SizeFor(FeedbackVector::cast(obj)->length());
503 : }
504 : };
505 :
506 : class PreparseData::BodyDescriptor final : public BodyDescriptorBase {
507 : public:
508 0 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
509 0 : return offset >= PreparseData::cast(obj)->inner_start_offset();
510 : }
511 :
512 : template <typename ObjectVisitor>
513 68086 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
514 : ObjectVisitor* v) {
515 : PreparseData data = PreparseData::cast(obj);
516 : int start_offset = data->inner_start_offset();
517 68086 : int end_offset = start_offset + data->children_length() * kTaggedSize;
518 66336 : IteratePointers(obj, start_offset, end_offset, v);
519 68086 : }
520 :
521 66103 : static inline int SizeOf(Map map, HeapObject obj) {
522 : PreparseData data = PreparseData::cast(obj);
523 66103 : return PreparseData::SizeFor(data->data_length(), data->children_length());
524 : }
525 : };
526 :
527 : class PrototypeInfo::BodyDescriptor final : public BodyDescriptorBase {
528 : public:
529 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
530 0 : return offset >= HeapObject::kHeaderSize;
531 : }
532 :
533 : template <typename ObjectVisitor>
534 5658928 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
535 : ObjectVisitor* v) {
536 5541236 : IteratePointers(obj, HeapObject::kHeaderSize, kObjectCreateMapOffset, v);
537 1715167 : IterateMaybeWeakPointer(obj, kObjectCreateMapOffset, v);
538 5541222 : IteratePointers(obj, kObjectCreateMapOffset + kTaggedSize, object_size, v);
539 5658892 : }
540 :
541 5387583 : static inline int SizeOf(Map map, HeapObject obj) {
542 5387583 : return obj->SizeFromMap(map);
543 : }
544 : };
545 :
546 : class JSWeakCollection::BodyDescriptorImpl final : public BodyDescriptorBase {
547 : public:
548 : STATIC_ASSERT(kTableOffset + kTaggedSize == kSize);
549 :
550 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
551 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
552 : }
553 :
554 : template <typename ObjectVisitor>
555 47050 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
556 : ObjectVisitor* v) {
557 125115 : IterateJSObjectBodyImpl(map, obj, kPropertiesOrHashOffset, object_size, v);
558 47050 : }
559 :
560 47050 : static inline int SizeOf(Map map, HeapObject object) {
561 47050 : return map->instance_size();
562 : }
563 : };
564 :
565 : class Foreign::BodyDescriptor final : public BodyDescriptorBase {
566 : public:
567 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
568 :
569 : template <typename ObjectVisitor>
570 4599572 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
571 : ObjectVisitor* v) {
572 9910965 : v->VisitExternalReference(
573 : Foreign::cast(obj),
574 : reinterpret_cast<Address*>(
575 : HeapObject::RawField(obj, kForeignAddressOffset).address()));
576 4599571 : }
577 :
578 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
579 : };
580 :
581 : class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase {
582 : public:
583 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
584 :
585 : template <typename ObjectVisitor>
586 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
587 : ObjectVisitor* v) {}
588 :
589 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
590 : };
591 :
592 : class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
593 : public:
594 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
595 :
596 : template <typename ObjectVisitor>
597 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
598 : ObjectVisitor* v) {}
599 :
600 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
601 : };
602 :
603 : class Code::BodyDescriptor final : public BodyDescriptorBase {
604 : public:
605 : STATIC_ASSERT(kRelocationInfoOffset + kTaggedSize ==
606 : kDeoptimizationDataOffset);
607 : STATIC_ASSERT(kDeoptimizationDataOffset + kTaggedSize ==
608 : kSourcePositionTableOffset);
609 : STATIC_ASSERT(kSourcePositionTableOffset + kTaggedSize ==
610 : kCodeDataContainerOffset);
611 : STATIC_ASSERT(kCodeDataContainerOffset + kTaggedSize == kDataStart);
612 :
613 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
614 : // Slots in code can't be invalid because we never trim code objects.
615 : return true;
616 : }
617 :
618 : template <typename ObjectVisitor>
619 127948374 : static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
620 : int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
621 : RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
622 : RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
623 : RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
624 : RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
625 : RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
626 : RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
627 :
628 : // GC does not visit data/code in the header and in the body directly.
629 125018497 : IteratePointers(obj, kRelocationInfoOffset, kDataStart, v);
630 :
631 129038351 : RelocIterator it(Code::cast(obj), mode_mask);
632 128548206 : v->VisitRelocInfo(&it);
633 128308917 : }
634 :
635 : template <typename ObjectVisitor>
636 125006039 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
637 : ObjectVisitor* v) {
638 127936000 : IterateBody(map, obj, v);
639 125323920 : }
640 :
641 125464117 : static inline int SizeOf(Map map, HeapObject object) {
642 250907612 : return Code::unchecked_cast(object)->CodeSize();
643 : }
644 : };
645 :
646 : class SeqOneByteString::BodyDescriptor final : public BodyDescriptorBase {
647 : public:
648 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
649 :
650 : template <typename ObjectVisitor>
651 4092730 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
652 4092730 : ObjectVisitor* v) {}
653 :
654 24957341 : static inline int SizeOf(Map map, HeapObject obj) {
655 : SeqOneByteString string = SeqOneByteString::cast(obj);
656 24956775 : return string->SizeFor(string->synchronized_length());
657 : }
658 : };
659 :
660 : class SeqTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
661 : public:
662 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
663 :
664 : template <typename ObjectVisitor>
665 1254432 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
666 1254432 : ObjectVisitor* v) {}
667 :
668 24268494 : static inline int SizeOf(Map map, HeapObject obj) {
669 : SeqTwoByteString string = SeqTwoByteString::cast(obj);
670 24268494 : return string->SizeFor(string->synchronized_length());
671 : }
672 : };
673 :
674 : class WasmInstanceObject::BodyDescriptor final : public BodyDescriptorBase {
675 : public:
676 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
677 0 : if (offset < kMemoryStartOffset) return true;
678 0 : if (offset < kModuleObjectOffset) return false;
679 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
680 : }
681 :
682 : template <typename ObjectVisitor>
683 37458 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
684 : ObjectVisitor* v) {
685 37458 : IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
686 37473 : IterateJSObjectBodyImpl(map, obj, kSize, object_size, v);
687 37468 : }
688 :
689 9934 : static inline int SizeOf(Map map, HeapObject object) {
690 9934 : return map->instance_size();
691 : }
692 : };
693 :
694 : class Map::BodyDescriptor final : public BodyDescriptorBase {
695 : public:
696 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
697 0 : return offset >= Map::kPointerFieldsBeginOffset &&
698 0 : offset < Map::kPointerFieldsEndOffset;
699 : }
700 :
701 : template <typename ObjectVisitor>
702 41829963 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
703 : ObjectVisitor* v) {
704 40889597 : IteratePointers(obj, Map::kPointerFieldsBeginOffset,
705 : Map::kTransitionsOrPrototypeInfoOffset, v);
706 11632704 : IterateMaybeWeakPointer(obj, kTransitionsOrPrototypeInfoOffset, v);
707 40819314 : IteratePointers(obj, Map::kTransitionsOrPrototypeInfoOffset + kTaggedSize,
708 : Map::kPointerFieldsEndOffset, v);
709 41699694 : }
710 :
711 2127795 : static inline int SizeOf(Map map, HeapObject obj) { return Map::kSize; }
712 : };
713 :
714 : class DataHandler::BodyDescriptor final : public BodyDescriptorBase {
715 : public:
716 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
717 0 : return offset >= HeapObject::kHeaderSize;
718 : }
719 :
720 : template <typename ObjectVisitor>
721 1218376 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
722 : ObjectVisitor* v) {
723 : static_assert(kSmiHandlerOffset < kData1Offset,
724 : "Field order must be in sync with this iteration code");
725 : static_assert(kData1Offset < kSizeWithData1,
726 : "Field order must be in sync with this iteration code");
727 1209980 : IteratePointers(obj, kSmiHandlerOffset, kData1Offset, v);
728 1210055 : IterateMaybeWeakPointers(obj, kData1Offset, object_size, v);
729 1218899 : }
730 :
731 1098656 : static inline int SizeOf(Map map, HeapObject object) {
732 1098656 : return object->SizeFromMap(map);
733 : }
734 : };
735 :
736 : class NativeContext::BodyDescriptor final : public BodyDescriptorBase {
737 : public:
738 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
739 0 : return offset < NativeContext::kEndOfTaggedFieldsOffset;
740 : }
741 :
742 : template <typename ObjectVisitor>
743 94674 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
744 : ObjectVisitor* v) {
745 92686 : IteratePointers(obj, NativeContext::kStartOfStrongFieldsOffset,
746 : NativeContext::kEndOfStrongFieldsOffset, v);
747 : IterateCustomWeakPointers(obj, NativeContext::kStartOfWeakFieldsOffset,
748 : NativeContext::kEndOfWeakFieldsOffset, v);
749 94674 : }
750 :
751 61215 : static inline int SizeOf(Map map, HeapObject object) {
752 61215 : return NativeContext::kSize;
753 : }
754 : };
755 :
756 : class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase {
757 : public:
758 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
759 0 : return offset >= CodeDataContainer::kHeaderSize &&
760 0 : offset < CodeDataContainer::kSize;
761 : }
762 :
763 : template <typename ObjectVisitor>
764 128721155 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
765 : ObjectVisitor* v) {
766 125792777 : IteratePointers(obj, CodeDataContainer::kHeaderSize,
767 : CodeDataContainer::kPointerFieldsStrongEndOffset, v);
768 : IterateCustomWeakPointers(
769 : obj, CodeDataContainer::kPointerFieldsStrongEndOffset,
770 : CodeDataContainer::kPointerFieldsWeakEndOffset, v);
771 128843950 : }
772 :
773 102181038 : static inline int SizeOf(Map map, HeapObject object) {
774 102181038 : return CodeDataContainer::kSize;
775 : }
776 : };
777 :
778 : class EmbedderDataArray::BodyDescriptor final : public BodyDescriptorBase {
779 : public:
780 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
781 : #ifdef V8_COMPRESS_POINTERS
782 : STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kSystemPointerSize);
783 : STATIC_ASSERT(base::bits::IsPowerOfTwo(kEmbedderDataSlotSize));
784 : return (offset < EmbedderDataArray::kHeaderSize) ||
785 : (((offset - EmbedderDataArray::kHeaderSize) &
786 : (kEmbedderDataSlotSize - 1)) ==
787 : EmbedderDataSlot::kTaggedPayloadOffset);
788 : #else
789 : STATIC_ASSERT(kEmbedderDataSlotSize == kTaggedSize);
790 : // We store raw aligned pointers as Smis, so it's safe to iterate the whole
791 : // array.
792 : return true;
793 : #endif
794 : }
795 :
796 : template <typename ObjectVisitor>
797 111620 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
798 : ObjectVisitor* v) {
799 : #ifdef V8_COMPRESS_POINTERS
800 : STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kSystemPointerSize);
801 : // Iterate only tagged payload of the embedder slots and skip raw payload.
802 : for (int offset = EmbedderDataArray::OffsetOfElementAt(0) +
803 : EmbedderDataSlot::kTaggedPayloadOffset;
804 : offset < object_size; offset += kEmbedderDataSlotSize) {
805 : IteratePointer(obj, offset, v);
806 : }
807 : #else
808 : // We store raw aligned pointers as Smis, so it's safe to iterate the whole
809 : // array.
810 : STATIC_ASSERT(kEmbedderDataSlotSize == kTaggedSize);
811 126151 : IteratePointers(obj, EmbedderDataArray::kHeaderSize, object_size, v);
812 : #endif
813 111620 : }
814 :
815 111620 : static inline int SizeOf(Map map, HeapObject object) {
816 111620 : return object->SizeFromMap(map);
817 : }
818 : };
819 :
820 : template <typename Op, typename ReturnType, typename T1, typename T2,
821 : typename T3, typename T4>
822 137781982 : ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
823 137781982 : if (type < FIRST_NONSTRING_TYPE) {
824 74731887 : switch (type & kStringRepresentationMask) {
825 : case kSeqStringTag:
826 : return ReturnType();
827 : case kConsStringTag:
828 0 : return Op::template apply<ConsString::BodyDescriptor>(p1, p2, p3, p4);
829 : case kThinStringTag:
830 20 : return Op::template apply<ThinString::BodyDescriptor>(p1, p2, p3, p4);
831 : case kSlicedStringTag:
832 0 : return Op::template apply<SlicedString::BodyDescriptor>(p1, p2, p3, p4);
833 : case kExternalStringTag:
834 : if ((type & kStringEncodingMask) == kOneByteStringTag) {
835 : return Op::template apply<ExternalOneByteString::BodyDescriptor>(
836 : p1, p2, p3, p4);
837 : } else {
838 : return Op::template apply<ExternalTwoByteString::BodyDescriptor>(
839 : p1, p2, p3, p4);
840 : }
841 : }
842 0 : UNREACHABLE();
843 : }
844 :
845 63050095 : switch (type) {
846 : case EMBEDDER_DATA_ARRAY_TYPE:
847 : return Op::template apply<EmbedderDataArray::BodyDescriptor>(p1, p2, p3,
848 : p4);
849 : case FIXED_ARRAY_TYPE:
850 : case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
851 : case HASH_TABLE_TYPE:
852 : case ORDERED_HASH_MAP_TYPE:
853 : case ORDERED_HASH_SET_TYPE:
854 : case ORDERED_NAME_DICTIONARY_TYPE:
855 : case NAME_DICTIONARY_TYPE:
856 : case GLOBAL_DICTIONARY_TYPE:
857 : case NUMBER_DICTIONARY_TYPE:
858 : case SIMPLE_NUMBER_DICTIONARY_TYPE:
859 : case STRING_TABLE_TYPE:
860 : case EPHEMERON_HASH_TABLE_TYPE:
861 : case SCOPE_INFO_TYPE:
862 : case SCRIPT_CONTEXT_TABLE_TYPE:
863 49 : return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
864 : case AWAIT_CONTEXT_TYPE:
865 : case BLOCK_CONTEXT_TYPE:
866 : case CATCH_CONTEXT_TYPE:
867 : case DEBUG_EVALUATE_CONTEXT_TYPE:
868 : case EVAL_CONTEXT_TYPE:
869 : case FUNCTION_CONTEXT_TYPE:
870 : case MODULE_CONTEXT_TYPE:
871 : case SCRIPT_CONTEXT_TYPE:
872 : case WITH_CONTEXT_TYPE:
873 0 : return Op::template apply<Context::BodyDescriptor>(p1, p2, p3, p4);
874 : case NATIVE_CONTEXT_TYPE:
875 0 : return Op::template apply<NativeContext::BodyDescriptor>(p1, p2, p3, p4);
876 : case WEAK_FIXED_ARRAY_TYPE:
877 0 : return Op::template apply<WeakFixedArray::BodyDescriptor>(p1, p2, p3, p4);
878 : case WEAK_ARRAY_LIST_TYPE:
879 0 : return Op::template apply<WeakArrayList::BodyDescriptor>(p1, p2, p3, p4);
880 : case FIXED_DOUBLE_ARRAY_TYPE:
881 0 : return ReturnType();
882 : case FEEDBACK_METADATA_TYPE:
883 : return Op::template apply<FeedbackMetadata::BodyDescriptor>(p1, p2, p3,
884 0 : p4);
885 : case PROPERTY_ARRAY_TYPE:
886 0 : return Op::template apply<PropertyArray::BodyDescriptor>(p1, p2, p3, p4);
887 : case DESCRIPTOR_ARRAY_TYPE:
888 : return Op::template apply<DescriptorArray::BodyDescriptor>(p1, p2, p3,
889 0 : p4);
890 : case TRANSITION_ARRAY_TYPE:
891 : return Op::template apply<TransitionArray::BodyDescriptor>(p1, p2, p3,
892 0 : p4);
893 : case FEEDBACK_CELL_TYPE:
894 0 : return Op::template apply<FeedbackCell::BodyDescriptor>(p1, p2, p3, p4);
895 : case FEEDBACK_VECTOR_TYPE:
896 0 : return Op::template apply<FeedbackVector::BodyDescriptor>(p1, p2, p3, p4);
897 : case JS_OBJECT_TYPE:
898 : case JS_ERROR_TYPE:
899 : case JS_ARGUMENTS_TYPE:
900 : case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
901 : case JS_PROMISE_TYPE:
902 : case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
903 : case JS_GENERATOR_OBJECT_TYPE:
904 : case JS_ASYNC_FUNCTION_OBJECT_TYPE:
905 : case JS_ASYNC_GENERATOR_OBJECT_TYPE:
906 : case JS_VALUE_TYPE:
907 : case JS_DATE_TYPE:
908 : case JS_ARRAY_TYPE:
909 : case JS_ARRAY_ITERATOR_TYPE:
910 : case JS_MODULE_NAMESPACE_TYPE:
911 : case JS_SET_TYPE:
912 : case JS_MAP_TYPE:
913 : case JS_SET_KEY_VALUE_ITERATOR_TYPE:
914 : case JS_SET_VALUE_ITERATOR_TYPE:
915 : case JS_MAP_KEY_ITERATOR_TYPE:
916 : case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
917 : case JS_MAP_VALUE_ITERATOR_TYPE:
918 : case JS_STRING_ITERATOR_TYPE:
919 : case JS_REGEXP_STRING_ITERATOR_TYPE:
920 : case JS_REGEXP_TYPE:
921 : case JS_GLOBAL_PROXY_TYPE:
922 : case JS_GLOBAL_OBJECT_TYPE:
923 : case JS_API_OBJECT_TYPE:
924 : case JS_SPECIAL_API_OBJECT_TYPE:
925 : case JS_MESSAGE_OBJECT_TYPE:
926 : case JS_BOUND_FUNCTION_TYPE:
927 : case JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE:
928 : case JS_WEAK_FACTORY_TYPE:
929 : #ifdef V8_INTL_SUPPORT
930 : case JS_INTL_V8_BREAK_ITERATOR_TYPE:
931 : case JS_INTL_COLLATOR_TYPE:
932 : case JS_INTL_DATE_TIME_FORMAT_TYPE:
933 : case JS_INTL_LIST_FORMAT_TYPE:
934 : case JS_INTL_LOCALE_TYPE:
935 : case JS_INTL_NUMBER_FORMAT_TYPE:
936 : case JS_INTL_PLURAL_RULES_TYPE:
937 : case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
938 : case JS_INTL_SEGMENT_ITERATOR_TYPE:
939 : case JS_INTL_SEGMENTER_TYPE:
940 : #endif // V8_INTL_SUPPORT
941 : case WASM_EXCEPTION_TYPE:
942 : case WASM_GLOBAL_TYPE:
943 : case WASM_MEMORY_TYPE:
944 : case WASM_MODULE_TYPE:
945 : case WASM_TABLE_TYPE:
946 32 : return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4);
947 : case WASM_INSTANCE_TYPE:
948 : return Op::template apply<WasmInstanceObject::BodyDescriptor>(p1, p2, p3,
949 0 : p4);
950 : case JS_WEAK_MAP_TYPE:
951 : case JS_WEAK_SET_TYPE:
952 : return Op::template apply<JSWeakCollection::BodyDescriptor>(p1, p2, p3,
953 0 : p4);
954 : case JS_ARRAY_BUFFER_TYPE:
955 0 : return Op::template apply<JSArrayBuffer::BodyDescriptor>(p1, p2, p3, p4);
956 : case JS_DATA_VIEW_TYPE:
957 0 : return Op::template apply<JSDataView::BodyDescriptor>(p1, p2, p3, p4);
958 : case JS_TYPED_ARRAY_TYPE:
959 0 : return Op::template apply<JSTypedArray::BodyDescriptor>(p1, p2, p3, p4);
960 : case JS_FUNCTION_TYPE:
961 0 : return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3, p4);
962 : case JS_WEAK_CELL_TYPE:
963 0 : return Op::template apply<JSWeakCell::BodyDescriptor>(p1, p2, p3, p4);
964 : case JS_WEAK_REF_TYPE:
965 0 : return Op::template apply<JSWeakRef::BodyDescriptor>(p1, p2, p3, p4);
966 : case ODDBALL_TYPE:
967 0 : return Op::template apply<Oddball::BodyDescriptor>(p1, p2, p3, p4);
968 : case JS_PROXY_TYPE:
969 0 : return Op::template apply<JSProxy::BodyDescriptor>(p1, p2, p3, p4);
970 : case FOREIGN_TYPE:
971 0 : return Op::template apply<Foreign::BodyDescriptor>(p1, p2, p3, p4);
972 : case MAP_TYPE:
973 0 : return Op::template apply<Map::BodyDescriptor>(p1, p2, p3, p4);
974 : case CODE_TYPE:
975 : return Op::template apply<Code::BodyDescriptor>(p1, p2, p3, p4);
976 : case CELL_TYPE:
977 0 : return Op::template apply<Cell::BodyDescriptor>(p1, p2, p3, p4);
978 : case PROPERTY_CELL_TYPE:
979 0 : return Op::template apply<PropertyCell::BodyDescriptor>(p1, p2, p3, p4);
980 : case SYMBOL_TYPE:
981 0 : return Op::template apply<Symbol::BodyDescriptor>(p1, p2, p3, p4);
982 : case BYTECODE_ARRAY_TYPE:
983 0 : return Op::template apply<BytecodeArray::BodyDescriptor>(p1, p2, p3, p4);
984 : case SMALL_ORDERED_HASH_SET_TYPE:
985 : return Op::template apply<
986 : SmallOrderedHashTable<SmallOrderedHashSet>::BodyDescriptor>(p1, p2,
987 0 : p3, p4);
988 : case SMALL_ORDERED_HASH_MAP_TYPE:
989 : return Op::template apply<
990 : SmallOrderedHashTable<SmallOrderedHashMap>::BodyDescriptor>(p1, p2,
991 0 : p3, p4);
992 : case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
993 : return Op::template apply<
994 : SmallOrderedHashTable<SmallOrderedNameDictionary>::BodyDescriptor>(
995 0 : p1, p2, p3, p4);
996 : case CODE_DATA_CONTAINER_TYPE:
997 : return Op::template apply<CodeDataContainer::BodyDescriptor>(p1, p2, p3,
998 0 : p4);
999 : case PREPARSE_DATA_TYPE:
1000 0 : return Op::template apply<PreparseData::BodyDescriptor>(p1, p2, p3, p4);
1001 : case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
1002 : return Op::template apply<
1003 0 : UncompiledDataWithoutPreparseData::BodyDescriptor>(p1, p2, p3, p4);
1004 : case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
1005 : return Op::template apply<UncompiledDataWithPreparseData::BodyDescriptor>(
1006 0 : p1, p2, p3, p4);
1007 : case HEAP_NUMBER_TYPE:
1008 : case MUTABLE_HEAP_NUMBER_TYPE:
1009 : case FILLER_TYPE:
1010 : case BYTE_ARRAY_TYPE:
1011 : case FREE_SPACE_TYPE:
1012 : case BIGINT_TYPE:
1013 767105 : return ReturnType();
1014 :
1015 : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
1016 : case FIXED_##TYPE##_ARRAY_TYPE: \
1017 : return Op::template apply<FixedTypedArrayBase::BodyDescriptor>(p1, p2, p3, \
1018 : p4);
1019 0 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
1020 : #undef TYPED_ARRAY_CASE
1021 :
1022 : case SHARED_FUNCTION_INFO_TYPE: {
1023 : return Op::template apply<SharedFunctionInfo::BodyDescriptor>(p1, p2, p3,
1024 0 : p4);
1025 : }
1026 : case ALLOCATION_SITE_TYPE:
1027 0 : return Op::template apply<AllocationSite::BodyDescriptor>(p1, p2, p3, p4);
1028 :
1029 : #define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
1030 : STRUCT_LIST(MAKE_STRUCT_CASE)
1031 : #undef MAKE_STRUCT_CASE
1032 1199198 : if (type == PROTOTYPE_INFO_TYPE) {
1033 : return Op::template apply<PrototypeInfo::BodyDescriptor>(p1, p2, p3,
1034 0 : p4);
1035 : } else {
1036 0 : return Op::template apply<StructBodyDescriptor>(p1, p2, p3, p4);
1037 : }
1038 : case CALL_HANDLER_INFO_TYPE:
1039 0 : return Op::template apply<StructBodyDescriptor>(p1, p2, p3, p4);
1040 : case LOAD_HANDLER_TYPE:
1041 : case STORE_HANDLER_TYPE:
1042 0 : return Op::template apply<DataHandler::BodyDescriptor>(p1, p2, p3, p4);
1043 : default:
1044 0 : PrintF("Unknown type: %d\n", type);
1045 0 : UNREACHABLE();
1046 : }
1047 : }
1048 :
1049 :
1050 : template <typename ObjectVisitor>
1051 13391297 : void HeapObject::IterateFast(ObjectVisitor* v) {
1052 : BodyDescriptorBase::IteratePointer(*this, kMapOffset, v);
1053 13391297 : IterateBodyFast(v);
1054 13391297 : }
1055 :
1056 :
1057 : template <typename ObjectVisitor>
1058 20248804 : void HeapObject::IterateBodyFast(ObjectVisitor* v) {
1059 : Map m = map();
1060 20248804 : IterateBodyFast(m, SizeFromMap(m), v);
1061 20148966 : }
1062 :
1063 :
1064 : struct CallIterateBody {
1065 : template <typename BodyDescriptor, typename ObjectVisitor>
1066 : static void apply(Map map, HeapObject obj, int object_size,
1067 : ObjectVisitor* v) {
1068 7398747 : BodyDescriptor::IterateBody(map, obj, object_size, v);
1069 : }
1070 : };
1071 :
1072 : template <typename ObjectVisitor>
1073 : void HeapObject::IterateBodyFast(Map map, int object_size, ObjectVisitor* v) {
1074 136716997 : BodyDescriptorApply<CallIterateBody, void>(map->instance_type(), map, *this,
1075 136716997 : object_size, v);
1076 : }
1077 : } // namespace internal
1078 : } // namespace v8
1079 :
1080 : #endif // V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
|