LCOV - code coverage report
Current view: top level - src - objects-body-descriptors-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 156 259 60.2 %
Date: 2019-03-21 Functions: 132 238 55.5 %

          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_

Generated by: LCOV version 1.10