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