LCOV - code coverage report
Current view: top level - src - objects-body-descriptors-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 203 288 70.5 %
Date: 2019-01-20 Functions: 224 349 64.2 %

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

Generated by: LCOV version 1.10