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/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 2188138 : int FlexibleBodyDescriptor<start_offset>::SizeOf(Map map, HeapObject object) {
26 23063189 : return object->SizeFromMap(map);
27 : }
28 :
29 : template <int start_offset>
30 911213 : int FlexibleWeakBodyDescriptor<start_offset>::SizeOf(Map map,
31 : HeapObject object) {
32 10501723 : return object->SizeFromMap(map);
33 : }
34 :
35 25 : 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 25 : 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 0 : return ((offset - embedder_fields_offset) & (kEmbedderDataSlotSize - 1)) ==
49 0 : 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 : 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 : LayoutDescriptorHelper helper(map);
63 : DCHECK(!helper.all_fields_tagged());
64 : return helper.IsTagged(offset);
65 : }
66 : }
67 :
68 : template <typename ObjectVisitor>
69 83774776 : 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 83774776 : 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 and inobject properties.
80 83797844 : if (header_size < inobject_fields_offset) {
81 : // There are embedder fields.
82 295416 : IteratePointers(obj, start_offset, header_size, v);
83 : // Iterate only tagged payload of the embedder slots and skip raw payload.
84 : DCHECK_EQ(header_size, JSObject::GetEmbedderFieldsStartOffset(map));
85 3360306 : for (int offset = header_size + EmbedderDataSlot::kTaggedPayloadOffset;
86 : offset < inobject_fields_offset; offset += kEmbedderDataSlotSize) {
87 429476 : IteratePointer(obj, offset, v);
88 : }
89 : // Proceed processing inobject properties.
90 : start_offset = inobject_fields_offset;
91 : }
92 : #else
93 : // We store raw aligned pointers as Smis, so it's safe to iterate the whole
94 : // embedder field area as tagged slots.
95 : STATIC_ASSERT(kEmbedderDataSlotSize == kTaggedSize);
96 : #endif
97 : if (!FLAG_unbox_double_fields || map->HasFastPointerLayout()) {
98 35927118 : IteratePointers(obj, start_offset, end_offset, v);
99 : } else {
100 : DCHECK(FLAG_unbox_double_fields);
101 : DCHECK(IsAligned(start_offset, kSystemPointerSize) &&
102 : IsAligned(end_offset, kSystemPointerSize));
103 :
104 : LayoutDescriptorHelper helper(map);
105 : DCHECK(!helper.all_fields_tagged());
106 : for (int offset = start_offset; offset < end_offset;) {
107 : int end_of_region_offset;
108 : if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
109 : IteratePointers(obj, offset, end_of_region_offset, v);
110 : }
111 : offset = end_of_region_offset;
112 : }
113 : }
114 83689992 : }
115 :
116 : template <typename ObjectVisitor>
117 258499583 : DISABLE_CFI_PERF void BodyDescriptorBase::IteratePointers(HeapObject obj,
118 : int start_offset,
119 : int end_offset,
120 : ObjectVisitor* v) {
121 428692167 : v->VisitPointers(obj, obj.RawField(start_offset), obj.RawField(end_offset));
122 257943033 : }
123 :
124 : template <typename ObjectVisitor>
125 5284150 : void BodyDescriptorBase::IteratePointer(HeapObject obj, int offset,
126 : ObjectVisitor* v) {
127 45962650 : v->VisitPointer(obj, obj.RawField(offset));
128 5284186 : }
129 :
130 : template <typename ObjectVisitor>
131 6970663 : DISABLE_CFI_PERF void BodyDescriptorBase::IterateMaybeWeakPointers(
132 : HeapObject obj, int start_offset, int end_offset, ObjectVisitor* v) {
133 7517025 : v->VisitPointers(obj, obj.RawMaybeWeakField(start_offset),
134 : obj.RawMaybeWeakField(end_offset));
135 7109696 : }
136 :
137 : template <typename ObjectVisitor>
138 15600508 : void BodyDescriptorBase::IterateMaybeWeakPointer(HeapObject obj, int offset,
139 : ObjectVisitor* v) {
140 37034742 : v->VisitPointer(obj, obj.RawMaybeWeakField(offset));
141 15600335 : }
142 :
143 : template <typename ObjectVisitor>
144 : DISABLE_CFI_PERF void BodyDescriptorBase::IterateCustomWeakPointers(
145 : HeapObject obj, int start_offset, int end_offset, ObjectVisitor* v) {
146 6350602 : v->VisitCustomWeakPointers(obj, obj.RawField(start_offset),
147 : obj.RawField(end_offset));
148 : }
149 :
150 : template <typename ObjectVisitor>
151 : DISABLE_CFI_PERF void BodyDescriptorBase::IterateEphemeron(HeapObject obj,
152 : int index,
153 : int key_offset,
154 : int value_offset,
155 : ObjectVisitor* v) {
156 93244 : v->VisitEphemeron(obj, index, obj.RawField(key_offset),
157 : obj.RawField(value_offset));
158 : }
159 :
160 : template <typename ObjectVisitor>
161 : void BodyDescriptorBase::IterateCustomWeakPointer(HeapObject obj, int offset,
162 : ObjectVisitor* v) {
163 128730216 : v->VisitCustomWeakPointer(obj, obj.RawField(offset));
164 : }
165 :
166 : class JSObject::BodyDescriptor final : public BodyDescriptorBase {
167 : public:
168 : static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
169 :
170 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
171 25 : if (offset < kStartOffset) return false;
172 25 : return IsValidJSObjectSlotImpl(map, obj, offset);
173 : }
174 :
175 : template <typename ObjectVisitor>
176 13376 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
177 : ObjectVisitor* v) {
178 82870245 : IterateJSObjectBodyImpl(map, obj, kStartOffset, object_size, v);
179 13376 : }
180 :
181 13376 : static inline int SizeOf(Map map, HeapObject object) {
182 13376 : return map->instance_size();
183 : }
184 : };
185 :
186 : class JSObject::FastBodyDescriptor final : public BodyDescriptorBase {
187 : public:
188 : static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
189 :
190 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
191 : return offset >= kStartOffset;
192 : }
193 :
194 : template <typename ObjectVisitor>
195 3429306 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
196 : ObjectVisitor* v) {
197 20914526 : IteratePointers(obj, kStartOffset, object_size, v);
198 3429272 : }
199 :
200 3429306 : static inline int SizeOf(Map map, HeapObject object) {
201 3429306 : return map->instance_size();
202 : }
203 : };
204 :
205 : class WeakCell::BodyDescriptor final : public BodyDescriptorBase {
206 : public:
207 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
208 0 : return offset >= HeapObject::kHeaderSize;
209 : }
210 :
211 : template <typename ObjectVisitor>
212 364 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
213 : ObjectVisitor* v) {
214 346 : IteratePointers(obj, HeapObject::kHeaderSize, kTargetOffset, v);
215 : IterateCustomWeakPointer(obj, kTargetOffset, v);
216 346 : IteratePointers(obj, kTargetOffset + kTaggedSize, object_size, v);
217 364 : }
218 :
219 : static inline int SizeOf(Map map, HeapObject object) {
220 : return map->instance_size();
221 : }
222 : };
223 :
224 : class JSWeakRef::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 352 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
232 : ObjectVisitor* v) {
233 156 : IteratePointers(obj, JSReceiver::kPropertiesOrHashOffset, kTargetOffset, v);
234 : IterateCustomWeakPointer(obj, kTargetOffset, v);
235 352 : IterateJSObjectBodyImpl(map, obj, kTargetOffset + kTaggedSize, object_size,
236 : v);
237 352 : }
238 :
239 : static inline int SizeOf(Map map, HeapObject object) {
240 : return map->instance_size();
241 : }
242 : };
243 :
244 : class SharedFunctionInfo::BodyDescriptor final : public BodyDescriptorBase {
245 : public:
246 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
247 : return FixedBodyDescriptor<kStartOfPointerFieldsOffset,
248 : kEndOfTaggedFieldsOffset,
249 : kAlignedSize>::IsValidSlot(map, obj, offset);
250 : }
251 :
252 : template <typename ObjectVisitor>
253 64364499 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
254 : ObjectVisitor* v) {
255 : IterateCustomWeakPointer(obj, kFunctionDataOffset, v);
256 20673913 : IteratePointers(obj, SharedFunctionInfo::kStartOfStrongFieldsOffset,
257 : SharedFunctionInfo::kEndOfTaggedFieldsOffset, v);
258 63756597 : }
259 :
260 3584961 : static inline int SizeOf(Map map, HeapObject object) {
261 3584961 : return map->instance_size();
262 : }
263 : };
264 :
265 : class AllocationSite::BodyDescriptor final : public BodyDescriptorBase {
266 : public:
267 : STATIC_ASSERT(AllocationSite::kCommonPointerFieldEndOffset ==
268 : AllocationSite::kPretenureDataOffset);
269 : STATIC_ASSERT(AllocationSite::kPretenureDataOffset + kInt32Size ==
270 : AllocationSite::kPretenureCreateCountOffset);
271 : STATIC_ASSERT(AllocationSite::kPretenureCreateCountOffset + kInt32Size ==
272 : AllocationSite::kWeakNextOffset);
273 :
274 0 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
275 0 : if (offset >= AllocationSite::kStartOffset &&
276 : offset < AllocationSite::kCommonPointerFieldEndOffset) {
277 : return true;
278 : }
279 : // check for weak_next offset
280 0 : if (map->instance_size() == AllocationSite::kSizeWithWeakNext &&
281 : offset == AllocationSite::kWeakNextOffset) {
282 : return true;
283 : }
284 : return false;
285 : }
286 :
287 : template <typename ObjectVisitor>
288 2525295 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
289 : ObjectVisitor* v) {
290 : // Iterate over all the common pointer fields
291 1116002 : IteratePointers(obj, AllocationSite::kStartOffset,
292 : AllocationSite::kCommonPointerFieldEndOffset, v);
293 : // Skip PretenureDataOffset and PretenureCreateCount which are Int32 fields.
294 : // Visit weak_next only if it has weak_next field.
295 209117 : if (object_size == AllocationSite::kSizeWithWeakNext) {
296 : IterateCustomWeakPointers(obj, AllocationSite::kWeakNextOffset,
297 : AllocationSite::kSizeWithWeakNext, v);
298 : }
299 2498244 : }
300 :
301 : static inline int SizeOf(Map map, HeapObject object) {
302 : return map->instance_size();
303 : }
304 : };
305 :
306 : class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase {
307 : public:
308 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
309 0 : if (offset < kEndOfTaggedFieldsOffset) return true;
310 0 : if (offset < kHeaderSize) return false;
311 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
312 : }
313 :
314 : template <typename ObjectVisitor>
315 426553 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
316 : ObjectVisitor* v) {
317 : // JSArrayBuffer instances contain raw data that the GC does not know about.
318 148774 : IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
319 426560 : IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v);
320 426554 : }
321 :
322 : static inline int SizeOf(Map map, HeapObject object) {
323 : return map->instance_size();
324 : }
325 : };
326 :
327 : class JSArrayBufferView::BodyDescriptor final : public BodyDescriptorBase {
328 : public:
329 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
330 0 : if (offset < kEndOfTaggedFieldsOffset) return true;
331 0 : if (offset < kHeaderSize) return false;
332 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
333 : }
334 :
335 : template <typename ObjectVisitor>
336 224606 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
337 : ObjectVisitor* v) {
338 : // JSArrayBufferView contains raw data that the GC does not know about.
339 140657 : IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
340 225326 : IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v);
341 224026 : }
342 :
343 : static inline int SizeOf(Map map, HeapObject object) {
344 : return map->instance_size();
345 : }
346 : };
347 :
348 : template <typename Derived>
349 : class SmallOrderedHashTable<Derived>::BodyDescriptor final
350 : : public BodyDescriptorBase {
351 : public:
352 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
353 : Derived table = Derived::cast(obj);
354 : // Only data table part contains tagged values.
355 : return (offset >= DataTableStartOffset()) &&
356 0 : (offset < table->GetBucketsStartOffset());
357 : }
358 :
359 : template <typename ObjectVisitor>
360 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
361 : ObjectVisitor* v) {
362 : Derived table = Derived::cast(obj);
363 : int start_offset = DataTableStartOffset();
364 : int end_offset = table->GetBucketsStartOffset();
365 0 : IteratePointers(obj, start_offset, end_offset, v);
366 0 : }
367 :
368 0 : static inline int SizeOf(Map map, HeapObject obj) {
369 : Derived table = Derived::cast(obj);
370 0 : return table->SizeFor(table->Capacity());
371 : }
372 : };
373 :
374 : class ByteArray::BodyDescriptor final : public BodyDescriptorBase {
375 : public:
376 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
377 :
378 : template <typename ObjectVisitor>
379 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
380 0 : ObjectVisitor* v) {}
381 :
382 : static inline int SizeOf(Map map, HeapObject obj) {
383 : return ByteArray::SizeFor(ByteArray::cast(obj)->synchronized_length());
384 : }
385 : };
386 :
387 : class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase {
388 : public:
389 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
390 0 : return offset >= kConstantPoolOffset &&
391 0 : offset <= kSourcePositionTableOffset;
392 : }
393 :
394 : template <typename ObjectVisitor>
395 1943442 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
396 : ObjectVisitor* v) {
397 560959 : IteratePointer(obj, kConstantPoolOffset, v);
398 560959 : IteratePointer(obj, kHandlerTableOffset, v);
399 560955 : IteratePointer(obj, kSourcePositionTableOffset, v);
400 1948634 : }
401 :
402 : static inline int SizeOf(Map map, HeapObject obj) {
403 : return BytecodeArray::SizeFor(
404 : BytecodeArray::cast(obj)->synchronized_length());
405 : }
406 : };
407 :
408 : class BigInt::BodyDescriptor final : public BodyDescriptorBase {
409 : public:
410 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
411 :
412 : template <typename ObjectVisitor>
413 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
414 0 : ObjectVisitor* v) {}
415 :
416 : static inline int SizeOf(Map map, HeapObject obj) {
417 : return BigInt::SizeFor(BigInt::cast(obj)->synchronized_length());
418 : }
419 : };
420 :
421 : class FixedDoubleArray::BodyDescriptor final : public BodyDescriptorBase {
422 : public:
423 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
424 :
425 : template <typename ObjectVisitor>
426 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
427 0 : ObjectVisitor* v) {}
428 :
429 : static inline int SizeOf(Map map, HeapObject obj) {
430 : return FixedDoubleArray::SizeFor(
431 : FixedDoubleArray::cast(obj)->synchronized_length());
432 : }
433 : };
434 :
435 : class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase {
436 : public:
437 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
438 0 : return offset == kBasePointerOffset;
439 : }
440 :
441 : template <typename ObjectVisitor>
442 8537 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
443 : ObjectVisitor* v) {
444 80840 : IteratePointer(obj, kBasePointerOffset, v);
445 8537 : }
446 :
447 8537 : static inline int SizeOf(Map map, HeapObject object) {
448 354940 : return FixedTypedArrayBase::cast(object)->size();
449 : }
450 : };
451 :
452 : class FeedbackMetadata::BodyDescriptor final : public BodyDescriptorBase {
453 : public:
454 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
455 :
456 : template <typename ObjectVisitor>
457 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
458 : ObjectVisitor* v) {}
459 :
460 : static inline int SizeOf(Map map, HeapObject obj) {
461 : return FeedbackMetadata::SizeFor(
462 : FeedbackMetadata::cast(obj)->synchronized_slot_count());
463 : }
464 : };
465 :
466 : class FeedbackVector::BodyDescriptor final : public BodyDescriptorBase {
467 : public:
468 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
469 0 : return offset == kSharedFunctionInfoOffset ||
470 0 : offset == kOptimizedCodeOffset ||
471 0 : offset == kClosureFeedbackCellArrayOffset ||
472 0 : offset >= kFeedbackSlotsOffset;
473 : }
474 :
475 : template <typename ObjectVisitor>
476 4315045 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
477 : ObjectVisitor* v) {
478 1503987 : IteratePointer(obj, kSharedFunctionInfoOffset, v);
479 1503952 : IterateMaybeWeakPointer(obj, kOptimizedCodeOffset, v);
480 1503778 : IteratePointer(obj, kClosureFeedbackCellArrayOffset, v);
481 1288486 : IterateMaybeWeakPointers(obj, kFeedbackSlotsOffset, object_size, v);
482 4319032 : }
483 :
484 : static inline int SizeOf(Map map, HeapObject obj) {
485 : return FeedbackVector::SizeFor(FeedbackVector::cast(obj)->length());
486 : }
487 : };
488 :
489 : class PreparseData::BodyDescriptor final : public BodyDescriptorBase {
490 : public:
491 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
492 0 : return offset >= PreparseData::cast(obj)->inner_start_offset();
493 : }
494 :
495 : template <typename ObjectVisitor>
496 60560 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
497 : ObjectVisitor* v) {
498 : PreparseData data = PreparseData::cast(obj);
499 : int start_offset = data->inner_start_offset();
500 60560 : int end_offset = start_offset + data->children_length() * kTaggedSize;
501 12072 : IteratePointers(obj, start_offset, end_offset, v);
502 60546 : }
503 :
504 1411 : static inline int SizeOf(Map map, HeapObject obj) {
505 : PreparseData data = PreparseData::cast(obj);
506 1411 : return PreparseData::SizeFor(data->data_length(), data->children_length());
507 : }
508 : };
509 :
510 : class PrototypeInfo::BodyDescriptor final : public BodyDescriptorBase {
511 : public:
512 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
513 0 : return offset >= HeapObject::kHeaderSize;
514 : }
515 :
516 : template <typename ObjectVisitor>
517 5321492 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
518 : ObjectVisitor* v) {
519 1891138 : IteratePointers(obj, HeapObject::kHeaderSize, kObjectCreateMapOffset, v);
520 1972815 : IterateMaybeWeakPointer(obj, kObjectCreateMapOffset, v);
521 1891138 : IteratePointers(obj, kObjectCreateMapOffset + kTaggedSize, object_size, v);
522 5319788 : }
523 :
524 86343 : static inline int SizeOf(Map map, HeapObject obj) {
525 5121860 : return obj->SizeFromMap(map);
526 : }
527 : };
528 :
529 : class JSWeakCollection::BodyDescriptorImpl final : public BodyDescriptorBase {
530 : public:
531 : STATIC_ASSERT(kTableOffset + kTaggedSize == kSize);
532 :
533 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
534 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
535 : }
536 :
537 : template <typename ObjectVisitor>
538 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
539 : ObjectVisitor* v) {
540 46461 : IterateJSObjectBodyImpl(map, obj, kPropertiesOrHashOffset, object_size, v);
541 0 : }
542 :
543 : static inline int SizeOf(Map map, HeapObject object) {
544 : return map->instance_size();
545 : }
546 : };
547 :
548 : class Foreign::BodyDescriptor final : public BodyDescriptorBase {
549 : public:
550 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
551 :
552 : template <typename ObjectVisitor>
553 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
554 : ObjectVisitor* v) {
555 5841452 : v->VisitExternalReference(
556 : Foreign::cast(obj), reinterpret_cast<Address*>(
557 : obj.RawField(kForeignAddressOffset).address()));
558 : }
559 :
560 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
561 : };
562 :
563 : class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase {
564 : public:
565 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
566 :
567 : template <typename ObjectVisitor>
568 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
569 : ObjectVisitor* v) {}
570 :
571 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
572 : };
573 :
574 : class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
575 : public:
576 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
577 :
578 : template <typename ObjectVisitor>
579 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
580 : ObjectVisitor* v) {}
581 :
582 : static inline int SizeOf(Map map, HeapObject object) { return kSize; }
583 : };
584 :
585 : class Code::BodyDescriptor final : public BodyDescriptorBase {
586 : public:
587 : STATIC_ASSERT(kRelocationInfoOffset + kTaggedSize ==
588 : kDeoptimizationDataOffset);
589 : STATIC_ASSERT(kDeoptimizationDataOffset + kTaggedSize ==
590 : kSourcePositionTableOffset);
591 : STATIC_ASSERT(kSourcePositionTableOffset + kTaggedSize ==
592 : kCodeDataContainerOffset);
593 : STATIC_ASSERT(kCodeDataContainerOffset + kTaggedSize == kDataStart);
594 :
595 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
596 : // Slots in code can't be invalid because we never trim code objects.
597 : return true;
598 : }
599 :
600 : static constexpr int kRelocModeMask =
601 : RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
602 : RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
603 : RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
604 : RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
605 : RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
606 : RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
607 : RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
608 : RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
609 :
610 : template <typename ObjectVisitor>
611 114423149 : static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
612 : // GC does not visit data/code in the header and in the body directly.
613 31020865 : IteratePointers(obj, kRelocationInfoOffset, kDataStart, v);
614 :
615 117374569 : RelocIterator it(Code::cast(obj), kRelocModeMask);
616 117020229 : v->VisitRelocInfo(&it);
617 115975952 : }
618 :
619 : template <typename ObjectVisitor>
620 80402425 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
621 : ObjectVisitor* v) {
622 114378946 : IterateBody(map, obj, v);
623 82041462 : }
624 :
625 : static inline int SizeOf(Map map, HeapObject object) {
626 197652873 : return Code::unchecked_cast(object)->CodeSize();
627 : }
628 : };
629 :
630 : class SeqOneByteString::BodyDescriptor final : public BodyDescriptorBase {
631 : public:
632 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
633 :
634 : template <typename ObjectVisitor>
635 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
636 0 : ObjectVisitor* v) {}
637 :
638 5159478 : static inline int SizeOf(Map map, HeapObject obj) {
639 : SeqOneByteString string = SeqOneByteString::cast(obj);
640 5159478 : return string->SizeFor(string->synchronized_length());
641 : }
642 : };
643 :
644 : class SeqTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
645 : public:
646 : static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
647 :
648 : template <typename ObjectVisitor>
649 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
650 0 : ObjectVisitor* v) {}
651 :
652 328972 : static inline int SizeOf(Map map, HeapObject obj) {
653 : SeqTwoByteString string = SeqTwoByteString::cast(obj);
654 328972 : return string->SizeFor(string->synchronized_length());
655 : }
656 : };
657 :
658 : class WasmInstanceObject::BodyDescriptor final : public BodyDescriptorBase {
659 : public:
660 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
661 0 : if (offset < kMemoryStartOffset) return true;
662 0 : if (offset < kModuleObjectOffset) return false;
663 0 : return IsValidJSObjectSlotImpl(map, obj, offset);
664 : }
665 :
666 : template <typename ObjectVisitor>
667 33856 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
668 : ObjectVisitor* v) {
669 8387 : IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
670 33862 : IterateJSObjectBodyImpl(map, obj, kSize, object_size, v);
671 33850 : }
672 :
673 394 : static inline int SizeOf(Map map, HeapObject object) {
674 394 : return map->instance_size();
675 : }
676 : };
677 :
678 : class Map::BodyDescriptor final : public BodyDescriptorBase {
679 : public:
680 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
681 0 : return offset >= Map::kPointerFieldsBeginOffset &&
682 0 : offset < Map::kPointerFieldsEndOffset;
683 : }
684 :
685 : template <typename ObjectVisitor>
686 39858375 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
687 : ObjectVisitor* v) {
688 12123849 : IteratePointers(obj, Map::kPointerFieldsBeginOffset,
689 : Map::kTransitionsOrPrototypeInfoOffset, v);
690 12123849 : IterateMaybeWeakPointer(obj, kTransitionsOrPrototypeInfoOffset, v);
691 12123849 : IteratePointers(obj, Map::kTransitionsOrPrototypeInfoOffset + kTaggedSize,
692 : Map::kPointerFieldsEndOffset, v);
693 39277638 : }
694 :
695 : static inline int SizeOf(Map map, HeapObject obj) { return Map::kSize; }
696 : };
697 :
698 : class DataHandler::BodyDescriptor final : public BodyDescriptorBase {
699 : public:
700 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
701 0 : return offset >= HeapObject::kHeaderSize;
702 : }
703 :
704 : template <typename ObjectVisitor>
705 846878 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
706 : ObjectVisitor* v) {
707 : static_assert(kSmiHandlerOffset < kData1Offset,
708 : "Field order must be in sync with this iteration code");
709 : static_assert(kData1Offset < kSizeWithData1,
710 : "Field order must be in sync with this iteration code");
711 253074 : IteratePointers(obj, kSmiHandlerOffset, kData1Offset, v);
712 253074 : IterateMaybeWeakPointers(obj, kData1Offset, object_size, v);
713 845738 : }
714 :
715 : static inline int SizeOf(Map map, HeapObject object) {
716 815946 : return object->SizeFromMap(map);
717 : }
718 : };
719 :
720 : class NativeContext::BodyDescriptor final : public BodyDescriptorBase {
721 : public:
722 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
723 0 : return offset < NativeContext::kEndOfTaggedFieldsOffset;
724 : }
725 :
726 : template <typename ObjectVisitor>
727 54450 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
728 : ObjectVisitor* v) {
729 33879 : IteratePointers(obj, NativeContext::kStartOfStrongFieldsOffset,
730 : NativeContext::kEndOfStrongFieldsOffset, v);
731 : IterateCustomWeakPointers(obj, NativeContext::kStartOfWeakFieldsOffset,
732 : NativeContext::kEndOfWeakFieldsOffset, v);
733 54450 : }
734 :
735 : static inline int SizeOf(Map map, HeapObject object) {
736 : return NativeContext::kSize;
737 : }
738 : };
739 :
740 : class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase {
741 : public:
742 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
743 0 : return offset >= CodeDataContainer::kHeaderSize &&
744 0 : offset < CodeDataContainer::kSize;
745 : }
746 :
747 : template <typename ObjectVisitor>
748 85023490 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
749 : ObjectVisitor* v) {
750 30877183 : IteratePointers(obj, CodeDataContainer::kHeaderSize,
751 : CodeDataContainer::kPointerFieldsStrongEndOffset, v);
752 : IterateCustomWeakPointers(
753 : obj, CodeDataContainer::kPointerFieldsStrongEndOffset,
754 : CodeDataContainer::kPointerFieldsWeakEndOffset, v);
755 84476154 : }
756 :
757 : static inline int SizeOf(Map map, HeapObject object) {
758 : return CodeDataContainer::kSize;
759 : }
760 : };
761 :
762 : class EmbedderDataArray::BodyDescriptor final : public BodyDescriptorBase {
763 : public:
764 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
765 : #ifdef V8_COMPRESS_POINTERS
766 : STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kTaggedSize);
767 : STATIC_ASSERT(base::bits::IsPowerOfTwo(kEmbedderDataSlotSize));
768 0 : return (offset < EmbedderDataArray::kHeaderSize) ||
769 0 : (((offset - EmbedderDataArray::kHeaderSize) &
770 : (kEmbedderDataSlotSize - 1)) ==
771 : EmbedderDataSlot::kTaggedPayloadOffset);
772 : #else
773 : STATIC_ASSERT(kEmbedderDataSlotSize == kTaggedSize);
774 : // We store raw aligned pointers as Smis, so it's safe to iterate the whole
775 : // array.
776 : return true;
777 : #endif
778 : }
779 :
780 : template <typename ObjectVisitor>
781 0 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
782 : ObjectVisitor* v) {
783 : #ifdef V8_COMPRESS_POINTERS
784 : STATIC_ASSERT(kEmbedderDataSlotSize == 2 * kTaggedSize);
785 : // Iterate only tagged payload of the embedder slots and skip raw payload.
786 520654 : for (int offset = EmbedderDataArray::OffsetOfElementAt(0) +
787 : EmbedderDataSlot::kTaggedPayloadOffset;
788 : offset < object_size; offset += kEmbedderDataSlotSize) {
789 82396 : IteratePointer(obj, offset, v);
790 : }
791 : #else
792 : // We store raw aligned pointers as Smis, so it's safe to iterate the whole
793 : // array.
794 : STATIC_ASSERT(kEmbedderDataSlotSize == kTaggedSize);
795 : IteratePointers(obj, EmbedderDataArray::kHeaderSize, object_size, v);
796 : #endif
797 0 : }
798 :
799 : static inline int SizeOf(Map map, HeapObject object) {
800 105178 : return object->SizeFromMap(map);
801 : }
802 : };
803 :
804 : template <typename Op, typename ReturnType, typename T1, typename T2,
805 : typename T3, typename T4>
806 111712211 : ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
807 111712211 : if (type < FIRST_NONSTRING_TYPE) {
808 54555655 : switch (type & kStringRepresentationMask) {
809 : case kSeqStringTag:
810 : return ReturnType();
811 : case kConsStringTag:
812 0 : return Op::template apply<ConsString::BodyDescriptor>(p1, p2, p3, p4);
813 : case kThinStringTag:
814 15 : return Op::template apply<ThinString::BodyDescriptor>(p1, p2, p3, p4);
815 : case kSlicedStringTag:
816 0 : return Op::template apply<SlicedString::BodyDescriptor>(p1, p2, p3, p4);
817 : case kExternalStringTag:
818 : if ((type & kStringEncodingMask) == kOneByteStringTag) {
819 : return Op::template apply<ExternalOneByteString::BodyDescriptor>(
820 : p1, p2, p3, p4);
821 : } else {
822 : return Op::template apply<ExternalTwoByteString::BodyDescriptor>(
823 : p1, p2, p3, p4);
824 : }
825 : }
826 0 : UNREACHABLE();
827 : }
828 :
829 57156556 : switch (type) {
830 : case EMBEDDER_DATA_ARRAY_TYPE:
831 : return Op::template apply<EmbedderDataArray::BodyDescriptor>(p1, p2, p3,
832 0 : p4);
833 : case FIXED_ARRAY_TYPE:
834 : case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
835 : case HASH_TABLE_TYPE:
836 : case ORDERED_HASH_MAP_TYPE:
837 : case ORDERED_HASH_SET_TYPE:
838 : case ORDERED_NAME_DICTIONARY_TYPE:
839 : case NAME_DICTIONARY_TYPE:
840 : case GLOBAL_DICTIONARY_TYPE:
841 : case NUMBER_DICTIONARY_TYPE:
842 : case SIMPLE_NUMBER_DICTIONARY_TYPE:
843 : case STRING_TABLE_TYPE:
844 : case SCOPE_INFO_TYPE:
845 : case SCRIPT_CONTEXT_TABLE_TYPE:
846 25 : return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
847 : case EPHEMERON_HASH_TABLE_TYPE:
848 : return Op::template apply<EphemeronHashTable::BodyDescriptor>(p1, p2, p3,
849 0 : p4);
850 : case AWAIT_CONTEXT_TYPE:
851 : case BLOCK_CONTEXT_TYPE:
852 : case CATCH_CONTEXT_TYPE:
853 : case DEBUG_EVALUATE_CONTEXT_TYPE:
854 : case EVAL_CONTEXT_TYPE:
855 : case FUNCTION_CONTEXT_TYPE:
856 : case MODULE_CONTEXT_TYPE:
857 : case SCRIPT_CONTEXT_TYPE:
858 : case WITH_CONTEXT_TYPE:
859 0 : return Op::template apply<Context::BodyDescriptor>(p1, p2, p3, p4);
860 : case NATIVE_CONTEXT_TYPE:
861 0 : return Op::template apply<NativeContext::BodyDescriptor>(p1, p2, p3, p4);
862 : case WEAK_FIXED_ARRAY_TYPE:
863 0 : return Op::template apply<WeakFixedArray::BodyDescriptor>(p1, p2, p3, p4);
864 : case WEAK_ARRAY_LIST_TYPE:
865 0 : return Op::template apply<WeakArrayList::BodyDescriptor>(p1, p2, p3, p4);
866 : case FIXED_DOUBLE_ARRAY_TYPE:
867 : return ReturnType();
868 : case FEEDBACK_METADATA_TYPE:
869 : return Op::template apply<FeedbackMetadata::BodyDescriptor>(p1, p2, p3,
870 : p4);
871 : case PROPERTY_ARRAY_TYPE:
872 0 : return Op::template apply<PropertyArray::BodyDescriptor>(p1, p2, p3, p4);
873 : case DESCRIPTOR_ARRAY_TYPE:
874 : return Op::template apply<DescriptorArray::BodyDescriptor>(p1, p2, p3,
875 0 : p4);
876 : case TRANSITION_ARRAY_TYPE:
877 : return Op::template apply<TransitionArray::BodyDescriptor>(p1, p2, p3,
878 0 : p4);
879 : case FEEDBACK_CELL_TYPE:
880 0 : return Op::template apply<FeedbackCell::BodyDescriptor>(p1, p2, p3, p4);
881 : case FEEDBACK_VECTOR_TYPE:
882 0 : return Op::template apply<FeedbackVector::BodyDescriptor>(p1, p2, p3, p4);
883 : case JS_OBJECT_TYPE:
884 : case JS_ERROR_TYPE:
885 : case JS_ARGUMENTS_TYPE:
886 : case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
887 : case JS_PROMISE_TYPE:
888 : case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
889 : case JS_GENERATOR_OBJECT_TYPE:
890 : case JS_ASYNC_FUNCTION_OBJECT_TYPE:
891 : case JS_ASYNC_GENERATOR_OBJECT_TYPE:
892 : case JS_VALUE_TYPE:
893 : case JS_DATE_TYPE:
894 : case JS_ARRAY_TYPE:
895 : case JS_ARRAY_ITERATOR_TYPE:
896 : case JS_MODULE_NAMESPACE_TYPE:
897 : case JS_SET_TYPE:
898 : case JS_MAP_TYPE:
899 : case JS_SET_KEY_VALUE_ITERATOR_TYPE:
900 : case JS_SET_VALUE_ITERATOR_TYPE:
901 : case JS_MAP_KEY_ITERATOR_TYPE:
902 : case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
903 : case JS_MAP_VALUE_ITERATOR_TYPE:
904 : case JS_STRING_ITERATOR_TYPE:
905 : case JS_REGEXP_STRING_ITERATOR_TYPE:
906 : case JS_REGEXP_TYPE:
907 : case JS_GLOBAL_PROXY_TYPE:
908 : case JS_GLOBAL_OBJECT_TYPE:
909 : case JS_API_OBJECT_TYPE:
910 : case JS_SPECIAL_API_OBJECT_TYPE:
911 : case JS_MESSAGE_OBJECT_TYPE:
912 : case JS_BOUND_FUNCTION_TYPE:
913 : case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE:
914 : case JS_FINALIZATION_GROUP_TYPE:
915 : #ifdef V8_INTL_SUPPORT
916 : case JS_INTL_V8_BREAK_ITERATOR_TYPE:
917 : case JS_INTL_COLLATOR_TYPE:
918 : case JS_INTL_DATE_TIME_FORMAT_TYPE:
919 : case JS_INTL_LIST_FORMAT_TYPE:
920 : case JS_INTL_LOCALE_TYPE:
921 : case JS_INTL_NUMBER_FORMAT_TYPE:
922 : case JS_INTL_PLURAL_RULES_TYPE:
923 : case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
924 : case JS_INTL_SEGMENT_ITERATOR_TYPE:
925 : case JS_INTL_SEGMENTER_TYPE:
926 : #endif // V8_INTL_SUPPORT
927 : case WASM_EXCEPTION_TYPE:
928 : case WASM_GLOBAL_TYPE:
929 : case WASM_MEMORY_TYPE:
930 : case WASM_MODULE_TYPE:
931 : case WASM_TABLE_TYPE:
932 21 : return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4);
933 : case WASM_INSTANCE_TYPE:
934 : return Op::template apply<WasmInstanceObject::BodyDescriptor>(p1, p2, p3,
935 0 : p4);
936 : case JS_WEAK_MAP_TYPE:
937 : case JS_WEAK_SET_TYPE:
938 : return Op::template apply<JSWeakCollection::BodyDescriptor>(p1, p2, p3,
939 0 : p4);
940 : case JS_ARRAY_BUFFER_TYPE:
941 0 : return Op::template apply<JSArrayBuffer::BodyDescriptor>(p1, p2, p3, p4);
942 : case JS_DATA_VIEW_TYPE:
943 0 : return Op::template apply<JSDataView::BodyDescriptor>(p1, p2, p3, p4);
944 : case JS_TYPED_ARRAY_TYPE:
945 0 : return Op::template apply<JSTypedArray::BodyDescriptor>(p1, p2, p3, p4);
946 : case JS_FUNCTION_TYPE:
947 4 : return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3, p4);
948 : case WEAK_CELL_TYPE:
949 0 : return Op::template apply<WeakCell::BodyDescriptor>(p1, p2, p3, p4);
950 : case JS_WEAK_REF_TYPE:
951 0 : return Op::template apply<JSWeakRef::BodyDescriptor>(p1, p2, p3, p4);
952 : case ODDBALL_TYPE:
953 0 : return Op::template apply<Oddball::BodyDescriptor>(p1, p2, p3, p4);
954 : case JS_PROXY_TYPE:
955 0 : return Op::template apply<JSProxy::BodyDescriptor>(p1, p2, p3, p4);
956 : case FOREIGN_TYPE:
957 : return Op::template apply<Foreign::BodyDescriptor>(p1, p2, p3, p4);
958 : case MAP_TYPE:
959 0 : return Op::template apply<Map::BodyDescriptor>(p1, p2, p3, p4);
960 : case CODE_TYPE:
961 0 : return Op::template apply<Code::BodyDescriptor>(p1, p2, p3, p4);
962 : case CELL_TYPE:
963 0 : return Op::template apply<Cell::BodyDescriptor>(p1, p2, p3, p4);
964 : case PROPERTY_CELL_TYPE:
965 0 : return Op::template apply<PropertyCell::BodyDescriptor>(p1, p2, p3, p4);
966 : case SYMBOL_TYPE:
967 0 : return Op::template apply<Symbol::BodyDescriptor>(p1, p2, p3, p4);
968 : case BYTECODE_ARRAY_TYPE:
969 0 : return Op::template apply<BytecodeArray::BodyDescriptor>(p1, p2, p3, p4);
970 : case SMALL_ORDERED_HASH_SET_TYPE:
971 : return Op::template apply<
972 : SmallOrderedHashTable<SmallOrderedHashSet>::BodyDescriptor>(p1, p2,
973 0 : p3, p4);
974 : case SMALL_ORDERED_HASH_MAP_TYPE:
975 : return Op::template apply<
976 : SmallOrderedHashTable<SmallOrderedHashMap>::BodyDescriptor>(p1, p2,
977 0 : p3, p4);
978 : case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
979 : return Op::template apply<
980 : SmallOrderedHashTable<SmallOrderedNameDictionary>::BodyDescriptor>(
981 0 : p1, p2, p3, p4);
982 : case CODE_DATA_CONTAINER_TYPE:
983 : return Op::template apply<CodeDataContainer::BodyDescriptor>(p1, p2, p3,
984 0 : p4);
985 : case PREPARSE_DATA_TYPE:
986 0 : return Op::template apply<PreparseData::BodyDescriptor>(p1, p2, p3, p4);
987 : case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
988 : return Op::template apply<
989 0 : UncompiledDataWithoutPreparseData::BodyDescriptor>(p1, p2, p3, p4);
990 : case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
991 : return Op::template apply<UncompiledDataWithPreparseData::BodyDescriptor>(
992 0 : p1, p2, p3, p4);
993 : case HEAP_NUMBER_TYPE:
994 : case MUTABLE_HEAP_NUMBER_TYPE:
995 : case FILLER_TYPE:
996 : case BYTE_ARRAY_TYPE:
997 : case FREE_SPACE_TYPE:
998 : case BIGINT_TYPE:
999 : return ReturnType();
1000 :
1001 : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
1002 : case FIXED_##TYPE##_ARRAY_TYPE: \
1003 : return Op::template apply<FixedTypedArrayBase::BodyDescriptor>(p1, p2, p3, \
1004 : p4);
1005 0 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
1006 : #undef TYPED_ARRAY_CASE
1007 :
1008 : case SHARED_FUNCTION_INFO_TYPE: {
1009 : return Op::template apply<SharedFunctionInfo::BodyDescriptor>(p1, p2, p3,
1010 0 : p4);
1011 : }
1012 : case ALLOCATION_SITE_TYPE:
1013 0 : return Op::template apply<AllocationSite::BodyDescriptor>(p1, p2, p3, p4);
1014 :
1015 : #define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
1016 : STRUCT_LIST(MAKE_STRUCT_CASE)
1017 : #undef MAKE_STRUCT_CASE
1018 908500 : if (type == PROTOTYPE_INFO_TYPE) {
1019 : return Op::template apply<PrototypeInfo::BodyDescriptor>(p1, p2, p3,
1020 0 : p4);
1021 : } else {
1022 0 : return Op::template apply<StructBodyDescriptor>(p1, p2, p3, p4);
1023 : }
1024 : case CALL_HANDLER_INFO_TYPE:
1025 0 : return Op::template apply<StructBodyDescriptor>(p1, p2, p3, p4);
1026 : case LOAD_HANDLER_TYPE:
1027 : case STORE_HANDLER_TYPE:
1028 0 : return Op::template apply<DataHandler::BodyDescriptor>(p1, p2, p3, p4);
1029 : default:
1030 0 : PrintF("Unknown type: %d\n", type);
1031 0 : UNREACHABLE();
1032 : }
1033 : }
1034 :
1035 :
1036 : template <typename ObjectVisitor>
1037 13466481 : void HeapObject::IterateFast(ObjectVisitor* v) {
1038 : BodyDescriptorBase::IteratePointer(*this, kMapOffset, v);
1039 13466481 : IterateBodyFast(v);
1040 13466481 : }
1041 :
1042 :
1043 : template <typename ObjectVisitor>
1044 22306260 : void HeapObject::IterateBodyFast(ObjectVisitor* v) {
1045 : Map m = map();
1046 22306260 : IterateBodyFast(m, SizeFromMap(m), v);
1047 22327694 : }
1048 :
1049 :
1050 : struct CallIterateBody {
1051 : template <typename BodyDescriptor, typename ObjectVisitor>
1052 0 : static void apply(Map map, HeapObject obj, int object_size,
1053 : ObjectVisitor* v) {
1054 3524736 : BodyDescriptor::IterateBody(map, obj, object_size, v);
1055 0 : }
1056 : };
1057 :
1058 : template <typename ObjectVisitor>
1059 : void HeapObject::IterateBodyFast(Map map, int object_size, ObjectVisitor* v) {
1060 111689964 : BodyDescriptorApply<CallIterateBody, void>(map->instance_type(), map, *this,
1061 : object_size, v);
1062 : }
1063 :
1064 : class EphemeronHashTable::BodyDescriptor final : public BodyDescriptorBase {
1065 : public:
1066 : static bool IsValidSlot(Map map, HeapObject obj, int offset) {
1067 0 : return (offset >= EphemeronHashTable::kHeaderSize);
1068 : }
1069 :
1070 : template <typename ObjectVisitor>
1071 8574 : static inline void IterateBody(Map map, HeapObject obj, int object_size,
1072 : ObjectVisitor* v) {
1073 : int entries_start = EphemeronHashTable::kHeaderSize +
1074 : EphemeronHashTable::kElementsStartIndex * kTaggedSize;
1075 1500 : IteratePointers(obj, EphemeronHashTable::kHeaderSize, entries_start, v);
1076 : EphemeronHashTable table = EphemeronHashTable::unchecked_cast(obj);
1077 : int entries = table.Capacity();
1078 101814 : for (int i = 0; i < entries; ++i) {
1079 : const int key_index = EphemeronHashTable::EntryToIndex(i);
1080 : const int value_index = EphemeronHashTable::EntryToValueIndex(i);
1081 : IterateEphemeron(obj, i, OffsetOfElementAt(key_index),
1082 : OffsetOfElementAt(value_index), v);
1083 : }
1084 8574 : }
1085 :
1086 : static inline int SizeOf(Map map, HeapObject object) {
1087 0 : return object->SizeFromMap(map);
1088 : }
1089 : };
1090 :
1091 : } // namespace internal
1092 : } // namespace v8
1093 :
1094 : #endif // V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
|