LCOV - code coverage report
Current view: top level - src - objects-body-descriptors-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 191 281 68.0 %
Date: 2019-02-19 Functions: 212 346 61.3 %

          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_

Generated by: LCOV version 1.10