LCOV - code coverage report
Current view: top level - src/compiler - js-heap-broker.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 933 1043 89.5 %
Date: 2019-01-20 Functions: 346 548 63.1 %

          Line data    Source code
       1             : // Copyright 2018 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             : #include "src/compiler/js-heap-broker.h"
       6             : 
       7             : #include "src/ast/modules.h"
       8             : #include "src/bootstrapper.h"
       9             : #include "src/boxed-float.h"
      10             : #include "src/code-factory.h"
      11             : #include "src/compiler/graph-reducer.h"
      12             : #include "src/compiler/per-isolate-compiler-cache.h"
      13             : #include "src/objects-inl.h"
      14             : #include "src/objects/cell-inl.h"
      15             : #include "src/objects/heap-number-inl.h"
      16             : #include "src/objects/instance-type-inl.h"
      17             : #include "src/objects/js-array-buffer-inl.h"
      18             : #include "src/objects/js-array-inl.h"
      19             : #include "src/objects/js-regexp-inl.h"
      20             : #include "src/objects/module-inl.h"
      21             : #include "src/utils.h"
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : namespace compiler {
      26             : 
      27             : #define TRACE(broker, x) TRACE_BROKER(broker, x)
      28             : 
      29             : #define FORWARD_DECL(Name) class Name##Data;
      30             : HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
      31             : #undef FORWARD_DECL
      32             : 
      33             : // There are three kinds of ObjectData values.
      34             : //
      35             : // kSmi: The underlying V8 object is a Smi and the data is an instance of the
      36             : //   base class (ObjectData), i.e. it's basically just the handle.  Because the
      37             : //   object is a Smi, it's safe to access the handle in order to extract the
      38             : //   number value, and AsSmi() does exactly that.
      39             : //
      40             : // kSerializedHeapObject: The underlying V8 object is a HeapObject and the
      41             : //   data is an instance of the corresponding (most-specific) subclass, e.g.
      42             : //   JSFunctionData, which provides serialized information about the object.
      43             : //
      44             : // kUnserializedHeapObject: The underlying V8 object is a HeapObject and the
      45             : //   data is an instance of the base class (ObjectData), i.e. it basically
      46             : //   carries no information other than the handle.
      47             : //
      48             : enum ObjectDataKind { kSmi, kSerializedHeapObject, kUnserializedHeapObject };
      49             : 
      50             : class ObjectData : public ZoneObject {
      51             :  public:
      52   185662770 :   ObjectData(JSHeapBroker* broker, ObjectData** storage, Handle<Object> object,
      53             :              ObjectDataKind kind)
      54    92831385 :       : object_(object), kind_(kind) {
      55             :     // This assignment ensures we don't end up inserting the same object
      56             :     // in an endless recursion.
      57    92831385 :     *storage = this;
      58             : 
      59    92831385 :     TRACE(broker, "Creating data " << this << " for handle " << object.address()
      60             :                                    << " (" << Brief(*object) << ")");
      61             : 
      62    92831385 :     CHECK_NOT_NULL(broker->isolate()->handle_scope_data()->canonical_scope);
      63    92831385 :   }
      64             : 
      65             : #define DECLARE_IS_AND_AS(Name) \
      66             :   bool Is##Name() const;        \
      67             :   Name##Data* As##Name();
      68             :   HEAP_BROKER_OBJECT_LIST(DECLARE_IS_AND_AS)
      69             : #undef DECLARE_IS_AND_AS
      70             : 
      71             :   Handle<Object> object() const { return object_; }
      72             :   ObjectDataKind kind() const { return kind_; }
      73    12117527 :   bool is_smi() const { return kind_ == kSmi; }
      74             : 
      75             :  private:
      76             :   Handle<Object> const object_;
      77             :   ObjectDataKind const kind_;
      78             : };
      79             : 
      80             : class HeapObjectData : public ObjectData {
      81             :  public:
      82             :   HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
      83             :                  Handle<HeapObject> object);
      84             : 
      85             :   bool boolean_value() const { return boolean_value_; }
      86             :   MapData* map() const { return map_; }
      87             : 
      88             :   static HeapObjectData* Serialize(JSHeapBroker* broker,
      89             :                                    Handle<HeapObject> object);
      90             : 
      91             :  private:
      92             :   bool const boolean_value_;
      93             :   MapData* const map_;
      94             : };
      95             : 
      96             : class PropertyCellData : public HeapObjectData {
      97             :  public:
      98             :   PropertyCellData(JSHeapBroker* broker, ObjectData** storage,
      99             :                    Handle<PropertyCell> object);
     100             : 
     101             :   PropertyDetails property_details() const { return property_details_; }
     102             : 
     103             :   void Serialize(JSHeapBroker* broker);
     104             :   ObjectData* value() { return value_; }
     105             : 
     106             :  private:
     107             :   PropertyDetails const property_details_;
     108             : 
     109             :   bool serialized_ = false;
     110             :   ObjectData* value_ = nullptr;
     111             : };
     112             : 
     113    29192053 : void JSHeapBroker::IncrementTracingIndentation() { ++trace_indentation_; }
     114             : 
     115    29192111 : void JSHeapBroker::DecrementTracingIndentation() { --trace_indentation_; }
     116             : 
     117             : class TraceScope {
     118             :  public:
     119             :   TraceScope(JSHeapBroker* broker, const char* label)
     120      471198 :       : TraceScope(broker, static_cast<void*>(broker), label) {}
     121             : 
     122             :   TraceScope(JSHeapBroker* broker, ObjectData* data, const char* label)
     123    28720860 :       : TraceScope(broker, static_cast<void*>(data), label) {}
     124             : 
     125    29192111 :   ~TraceScope() { broker_->DecrementTracingIndentation(); }
     126             : 
     127             :  private:
     128             :   JSHeapBroker* const broker_;
     129             : 
     130    29192053 :   TraceScope(JSHeapBroker* broker, void* self, const char* label)
     131    29192053 :       : broker_(broker) {
     132    29192053 :     TRACE(broker_, "Running " << label << " on " << self << ".");
     133    29192053 :     broker_->IncrementTracingIndentation();
     134    29192053 :   }
     135             : };
     136             : 
     137     3236086 : PropertyCellData::PropertyCellData(JSHeapBroker* broker, ObjectData** storage,
     138             :                                    Handle<PropertyCell> object)
     139             :     : HeapObjectData(broker, storage, object),
     140     6472172 :       property_details_(object->property_details()) {}
     141             : 
     142     3193078 : void PropertyCellData::Serialize(JSHeapBroker* broker) {
     143     3193078 :   if (serialized_) return;
     144     3193078 :   serialized_ = true;
     145             : 
     146     3193078 :   TraceScope tracer(broker, this, "PropertyCellData::Serialize");
     147     3193078 :   auto cell = Handle<PropertyCell>::cast(object());
     148             :   DCHECK_NULL(value_);
     149     3193078 :   value_ = broker->GetOrCreateData(cell->value());
     150             : }
     151             : 
     152             : class JSObjectField {
     153             :  public:
     154             :   bool IsDouble() const { return object_ == nullptr; }
     155         127 :   double AsDouble() const {
     156         127 :     CHECK(IsDouble());
     157         127 :     return number_;
     158             :   }
     159             : 
     160             :   bool IsObject() const { return object_ != nullptr; }
     161        3225 :   ObjectData* AsObject() const {
     162        3225 :     CHECK(IsObject());
     163        3225 :     return object_;
     164             :   }
     165             : 
     166         127 :   explicit JSObjectField(double value) : number_(value) {}
     167        2722 :   explicit JSObjectField(ObjectData* value) : object_(value) {}
     168             : 
     169             :  private:
     170             :   ObjectData* object_ = nullptr;
     171             :   double number_ = 0;
     172             : };
     173             : 
     174             : class JSObjectData : public HeapObjectData {
     175             :  public:
     176             :   JSObjectData(JSHeapBroker* broker, ObjectData** storage,
     177             :                Handle<JSObject> object);
     178             : 
     179             :   // Recursively serializes all reachable JSObjects.
     180             :   void SerializeAsBoilerplate(JSHeapBroker* broker);
     181             :   // Shallow serialization of {elements}.
     182             :   void SerializeElements(JSHeapBroker* broker);
     183             : 
     184             :   const JSObjectField& GetInobjectField(int property_index) const;
     185             :   FixedArrayBaseData* elements() const;
     186             : 
     187             :   // This method is only used to assert our invariants.
     188             :   bool cow_or_empty_elements_tenured() const;
     189             : 
     190             :   void SerializeObjectCreateMap(JSHeapBroker* broker);
     191             :   MapData* object_create_map() const {  // Can be nullptr.
     192          15 :     CHECK(serialized_object_create_map_);
     193          15 :     return object_create_map_;
     194             :   }
     195             : 
     196             :  private:
     197             :   void SerializeRecursive(JSHeapBroker* broker, int max_depths);
     198             : 
     199             :   FixedArrayBaseData* elements_ = nullptr;
     200             :   bool cow_or_empty_elements_tenured_ = false;
     201             :   // The {serialized_as_boilerplate} flag is set when all recursively
     202             :   // reachable JSObjects are serialized.
     203             :   bool serialized_as_boilerplate_ = false;
     204             :   bool serialized_elements_ = false;
     205             : 
     206             :   ZoneVector<JSObjectField> inobject_fields_;
     207             : 
     208             :   bool serialized_object_create_map_ = false;
     209             :   MapData* object_create_map_ = nullptr;
     210             : };
     211             : 
     212     1678354 : void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker) {
     213     2370907 :   if (serialized_object_create_map_) return;
     214      882279 :   serialized_object_create_map_ = true;
     215             : 
     216      882279 :   TraceScope tracer(broker, this, "JSObjectData::SerializeObjectCreateMap");
     217      882279 :   Handle<JSObject> jsobject = Handle<JSObject>::cast(object());
     218             : 
     219      882280 :   if (jsobject->map()->is_prototype_map()) {
     220             :     Handle<Object> maybe_proto_info(jsobject->map()->prototype_info(),
     221             :                                     broker->isolate());
     222      103522 :     if (maybe_proto_info->IsPrototypeInfo()) {
     223       29353 :       auto proto_info = Handle<PrototypeInfo>::cast(maybe_proto_info);
     224       29353 :       if (proto_info->HasObjectCreateMap()) {
     225             :         DCHECK_NULL(object_create_map_);
     226             :         object_create_map_ =
     227          31 :             broker->GetOrCreateData(proto_info->ObjectCreateMap())->AsMap();
     228             :       }
     229             :     }
     230             :   }
     231             : }
     232             : 
     233             : class JSTypedArrayData : public JSObjectData {
     234             :  public:
     235             :   JSTypedArrayData(JSHeapBroker* broker, ObjectData** storage,
     236             :                    Handle<JSTypedArray> object);
     237             : 
     238             :   bool is_on_heap() const { return is_on_heap_; }
     239             :   size_t length_value() const { return length_value_; }
     240             :   void* elements_external_pointer() const { return elements_external_pointer_; }
     241             : 
     242             :   void Serialize(JSHeapBroker* broker);
     243             : 
     244             :   HeapObjectData* buffer() const { return buffer_; }
     245             : 
     246             :  private:
     247             :   bool const is_on_heap_;
     248             :   size_t const length_value_;
     249             :   void* const elements_external_pointer_;
     250             : 
     251             :   bool serialized_ = false;
     252             :   HeapObjectData* buffer_ = nullptr;
     253             : };
     254             : 
     255        1722 : JSTypedArrayData::JSTypedArrayData(JSHeapBroker* broker, ObjectData** storage,
     256             :                                    Handle<JSTypedArray> object)
     257             :     : JSObjectData(broker, storage, object),
     258        3444 :       is_on_heap_(object->is_on_heap()),
     259             :       length_value_(object->length_value()),
     260             :       elements_external_pointer_(
     261        8610 :           FixedTypedArrayBase::cast(object->elements())->external_pointer()) {}
     262             : 
     263           0 : void JSTypedArrayData::Serialize(JSHeapBroker* broker) {
     264           0 :   if (serialized_) return;
     265           0 :   serialized_ = true;
     266             : 
     267           0 :   TraceScope tracer(broker, this, "JSTypedArrayData::Serialize");
     268           0 :   Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast(object());
     269             : 
     270           0 :   if (!is_on_heap()) {
     271             :     DCHECK_NULL(buffer_);
     272           0 :     buffer_ = broker->GetOrCreateData(typed_array->buffer())->AsHeapObject();
     273             :   }
     274             : }
     275             : 
     276             : class JSDataViewData : public JSObjectData {
     277             :  public:
     278             :   JSDataViewData(JSHeapBroker* broker, ObjectData** storage,
     279             :                  Handle<JSDataView> object);
     280             : 
     281             :   size_t byte_length() const { return byte_length_; }
     282             :   size_t byte_offset() const { return byte_offset_; }
     283             : 
     284             :  private:
     285             :   size_t const byte_length_;
     286             :   size_t const byte_offset_;
     287             : };
     288             : 
     289             : class JSBoundFunctionData : public JSObjectData {
     290             :  public:
     291             :   JSBoundFunctionData(JSHeapBroker* broker, ObjectData** storage,
     292             :                       Handle<JSBoundFunction> object);
     293             : 
     294             :   void Serialize(JSHeapBroker* broker);
     295             : 
     296             :   ObjectData* bound_target_function() const { return bound_target_function_; }
     297             :   ObjectData* bound_this() const { return bound_this_; }
     298             :   FixedArrayData* bound_arguments() const { return bound_arguments_; }
     299             : 
     300             :  private:
     301             :   bool serialized_ = false;
     302             : 
     303             :   ObjectData* bound_target_function_ = nullptr;
     304             :   ObjectData* bound_this_ = nullptr;
     305             :   FixedArrayData* bound_arguments_ = nullptr;
     306             : };
     307             : 
     308             : class JSFunctionData : public JSObjectData {
     309             :  public:
     310             :   JSFunctionData(JSHeapBroker* broker, ObjectData** storage,
     311             :                  Handle<JSFunction> object);
     312             : 
     313             :   bool has_initial_map() const { return has_initial_map_; }
     314             :   bool has_prototype() const { return has_prototype_; }
     315             :   bool PrototypeRequiresRuntimeLookup() const {
     316             :     return PrototypeRequiresRuntimeLookup_;
     317             :   }
     318             : 
     319             :   void Serialize(JSHeapBroker* broker);
     320             : 
     321           0 :   void SetSerializedForCompilation(JSHeapBroker* broker) {
     322           0 :     CHECK(!serialized_for_compilation_);
     323           0 :     serialized_for_compilation_ = true;
     324           0 :   }
     325             :   bool serialized_for_compilation() const {
     326             :     return serialized_for_compilation_;
     327             :   }
     328             : 
     329             :   ContextData* context() const { return context_; }
     330             :   NativeContextData* native_context() const { return native_context_; }
     331             :   MapData* initial_map() const { return initial_map_; }
     332             :   ObjectData* prototype() const { return prototype_; }
     333             :   SharedFunctionInfoData* shared() const { return shared_; }
     334             :   int initial_map_instance_size_with_min_slack() const {
     335        5403 :     CHECK(serialized_);
     336        5403 :     return initial_map_instance_size_with_min_slack_;
     337             :   }
     338             : 
     339             :  private:
     340             :   bool has_initial_map_;
     341             :   bool has_prototype_;
     342             :   bool PrototypeRequiresRuntimeLookup_;
     343             : 
     344             :   bool serialized_ = false;
     345             :   bool serialized_for_compilation_ = false;
     346             : 
     347             :   ContextData* context_ = nullptr;
     348             :   NativeContextData* native_context_ = nullptr;
     349             :   MapData* initial_map_ = nullptr;
     350             :   ObjectData* prototype_ = nullptr;
     351             :   SharedFunctionInfoData* shared_ = nullptr;
     352             :   int initial_map_instance_size_with_min_slack_;
     353             : };
     354             : 
     355             : class JSRegExpData : public JSObjectData {
     356             :  public:
     357        1427 :   JSRegExpData(JSHeapBroker* broker, ObjectData** storage,
     358             :                Handle<JSRegExp> object)
     359        1427 :       : JSObjectData(broker, storage, object) {}
     360             : 
     361             :   void SerializeAsRegExpBoilerplate(JSHeapBroker* broker);
     362             : 
     363             :   ObjectData* raw_properties_or_hash() const { return raw_properties_or_hash_; }
     364             :   ObjectData* data() const { return data_; }
     365             :   ObjectData* source() const { return source_; }
     366             :   ObjectData* flags() const { return flags_; }
     367             :   ObjectData* last_index() const { return last_index_; }
     368             : 
     369             :  private:
     370             :   bool serialized_as_reg_exp_boilerplate_ = false;
     371             : 
     372             :   ObjectData* raw_properties_or_hash_ = nullptr;
     373             :   ObjectData* data_ = nullptr;
     374             :   ObjectData* source_ = nullptr;
     375             :   ObjectData* flags_ = nullptr;
     376             :   ObjectData* last_index_ = nullptr;
     377             : };
     378             : 
     379             : class HeapNumberData : public HeapObjectData {
     380             :  public:
     381      456285 :   HeapNumberData(JSHeapBroker* broker, ObjectData** storage,
     382             :                  Handle<HeapNumber> object)
     383      912570 :       : HeapObjectData(broker, storage, object), value_(object->value()) {}
     384             : 
     385             :   double value() const { return value_; }
     386             : 
     387             :  private:
     388             :   double const value_;
     389             : };
     390             : 
     391             : class MutableHeapNumberData : public HeapObjectData {
     392             :  public:
     393           0 :   MutableHeapNumberData(JSHeapBroker* broker, ObjectData** storage,
     394             :                         Handle<MutableHeapNumber> object)
     395           0 :       : HeapObjectData(broker, storage, object), value_(object->value()) {}
     396             : 
     397             :   double value() const { return value_; }
     398             : 
     399             :  private:
     400             :   double const value_;
     401             : };
     402             : 
     403             : class ContextData : public HeapObjectData {
     404             :  public:
     405             :   ContextData(JSHeapBroker* broker, ObjectData** storage,
     406             :               Handle<Context> object);
     407             :   void Serialize(JSHeapBroker* broker);
     408             : 
     409             :   ContextData* previous() const {
     410           0 :     CHECK(serialized_);
     411           0 :     return previous_;
     412             :   }
     413             : 
     414             :  private:
     415             :   bool serialized_ = false;
     416             :   ContextData* previous_ = nullptr;
     417             : };
     418             : 
     419      201034 : ContextData::ContextData(JSHeapBroker* broker, ObjectData** storage,
     420             :                          Handle<Context> object)
     421      657232 :     : HeapObjectData(broker, storage, object) {}
     422             : 
     423     1165352 : void ContextData::Serialize(JSHeapBroker* broker) {
     424     1778591 :   if (serialized_) return;
     425      552113 :   serialized_ = true;
     426             : 
     427      552113 :   TraceScope tracer(broker, this, "ContextData::Serialize");
     428      552116 :   Handle<Context> context = Handle<Context>::cast(object());
     429             : 
     430             :   DCHECK_NULL(previous_);
     431             :   // Context::previous DCHECK-fails when called on the native context.
     432     1104237 :   if (!context->IsNativeContext()) {
     433       95966 :     previous_ = broker->GetOrCreateData(context->previous())->AsContext();
     434       95966 :     previous_->Serialize(broker);
     435             :   }
     436             : }
     437             : 
     438             : class NativeContextData : public ContextData {
     439             :  public:
     440             : #define DECL_ACCESSOR(type, name) \
     441             :   type##Data* name() const { return name##_; }
     442             :   BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR)
     443             : #undef DECL_ACCESSOR
     444             : 
     445       32335 :   const ZoneVector<MapData*>& function_maps() const {
     446       32335 :     CHECK(serialized_);
     447       32335 :     return function_maps_;
     448             :   }
     449             : 
     450             :   NativeContextData(JSHeapBroker* broker, ObjectData** storage,
     451             :                     Handle<NativeContext> object);
     452             :   void Serialize(JSHeapBroker* broker);
     453             : 
     454             :  private:
     455             :   bool serialized_ = false;
     456             : #define DECL_MEMBER(type, name) type##Data* name##_ = nullptr;
     457             :   BROKER_NATIVE_CONTEXT_FIELDS(DECL_MEMBER)
     458             : #undef DECL_MEMBER
     459             :   ZoneVector<MapData*> function_maps_;
     460             : };
     461             : 
     462             : class NameData : public HeapObjectData {
     463             :  public:
     464           0 :   NameData(JSHeapBroker* broker, ObjectData** storage, Handle<Name> object)
     465     7529820 :       : HeapObjectData(broker, storage, object) {}
     466             : };
     467             : 
     468             : class StringData : public NameData {
     469             :  public:
     470             :   StringData(JSHeapBroker* broker, ObjectData** storage, Handle<String> object);
     471             : 
     472             :   int length() const { return length_; }
     473             :   uint16_t first_char() const { return first_char_; }
     474             :   base::Optional<double> to_number() const { return to_number_; }
     475             :   bool is_external_string() const { return is_external_string_; }
     476             :   bool is_seq_string() const { return is_seq_string_; }
     477             : 
     478             :  private:
     479             :   int const length_;
     480             :   uint16_t const first_char_;
     481             :   base::Optional<double> to_number_;
     482             :   bool const is_external_string_;
     483             :   bool const is_seq_string_;
     484             : 
     485             :   static constexpr int kMaxLengthForDoubleConversion = 23;
     486             : };
     487             : 
     488             : class SymbolData : public NameData {
     489             :  public:
     490       36226 :   SymbolData(JSHeapBroker* broker, ObjectData** storage, Handle<Symbol> object)
     491       36226 :       : NameData(broker, storage, object) {}
     492             : };
     493             : 
     494    14942039 : StringData::StringData(JSHeapBroker* broker, ObjectData** storage,
     495             :                        Handle<String> object)
     496             :     : NameData(broker, storage, object),
     497             :       length_(object->length()),
     498    21568465 :       first_char_(length_ > 0 ? object->Get(0) : 0),
     499    14987160 :       is_external_string_(object->IsExternalString()),
     500    45417679 :       is_seq_string_(object->IsSeqString()) {
     501             :   int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
     502     7493589 :   if (length_ <= kMaxLengthForDoubleConversion) {
     503     7448445 :     to_number_ = StringToDouble(broker->isolate(), object, flags);
     504             :   }
     505     7493590 : }
     506             : 
     507             : class InternalizedStringData : public StringData {
     508             :  public:
     509             :   InternalizedStringData(JSHeapBroker* broker, ObjectData** storage,
     510             :                          Handle<InternalizedString> object);
     511             : 
     512             :   uint32_t array_index() const { return array_index_; }
     513             : 
     514             :  private:
     515             :   uint32_t array_index_;
     516             : };
     517             : 
     518     7492994 : InternalizedStringData::InternalizedStringData(
     519             :     JSHeapBroker* broker, ObjectData** storage,
     520             :     Handle<InternalizedString> object)
     521     7492994 :     : StringData(broker, storage, object) {
     522    14985979 :   if (!object->AsArrayIndex(&array_index_)) {
     523     7034145 :     array_index_ = InternalizedStringRef::kNotAnArrayIndex;
     524             :   }
     525     7492988 : }
     526             : 
     527             : namespace {
     528             : 
     529        6842 : bool IsFastLiteralHelper(Handle<JSObject> boilerplate, int max_depth,
     530             :                          int* max_properties) {
     531             :   DCHECK_GE(max_depth, 0);
     532             :   DCHECK_GE(*max_properties, 0);
     533             : 
     534             :   // Make sure the boilerplate map is not deprecated.
     535        6842 :   if (!JSObject::TryMigrateInstance(boilerplate)) return false;
     536             : 
     537             :   // Check for too deep nesting.
     538        6842 :   if (max_depth == 0) return false;
     539             : 
     540             :   // Check the elements.
     541             :   Isolate* const isolate = boilerplate->GetIsolate();
     542       13684 :   Handle<FixedArrayBase> elements(boilerplate->elements(), isolate);
     543       11264 :   if (elements->length() > 0 &&
     544             :       elements->map() != ReadOnlyRoots(isolate).fixed_cow_array_map()) {
     545        4508 :     if (boilerplate->HasSmiOrObjectElements()) {
     546        1678 :       Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
     547             :       int length = elements->length();
     548       12174 :       for (int i = 0; i < length; i++) {
     549       10510 :         if ((*max_properties)-- == 0) return false;
     550             :         Handle<Object> value(fast_elements->get(i), isolate);
     551       20992 :         if (value->IsJSObject()) {
     552         455 :           Handle<JSObject> value_object = Handle<JSObject>::cast(value);
     553         455 :           if (!IsFastLiteralHelper(value_object, max_depth - 1,
     554         455 :                                    max_properties)) {
     555           0 :             return false;
     556             :           }
     557             :         }
     558             :       }
     559        1152 :     } else if (boilerplate->HasDoubleElements()) {
     560         540 :       if (elements->Size() > kMaxRegularHeapObjectSize) return false;
     561             :     } else {
     562             :       return false;
     563             :     }
     564             :   }
     565             : 
     566             :   // TODO(turbofan): Do we want to support out-of-object properties?
     567       13570 :   if (!(boilerplate->HasFastProperties() &&
     568       20189 :         boilerplate->property_array()->length() == 0)) {
     569             :     return false;
     570             :   }
     571             : 
     572             :   // Check the in-object properties.
     573             :   Handle<DescriptorArray> descriptors(
     574       13404 :       boilerplate->map()->instance_descriptors(), isolate);
     575             :   int limit = boilerplate->map()->NumberOfOwnDescriptors();
     576       13931 :   for (int i = 0; i < limit; i++) {
     577        7236 :     PropertyDetails details = descriptors->GetDetails(i);
     578       11743 :     if (details.location() != kField) continue;
     579             :     DCHECK_EQ(kData, details.kind());
     580        2863 :     if ((*max_properties)-- == 0) return false;
     581        2856 :     FieldIndex field_index = FieldIndex::ForDescriptor(boilerplate->map(), i);
     582        2856 :     if (boilerplate->IsUnboxedDoubleField(field_index)) continue;
     583        5458 :     Handle<Object> value(boilerplate->RawFastPropertyAt(field_index), isolate);
     584        5458 :     if (value->IsJSObject()) {
     585         283 :       Handle<JSObject> value_object = Handle<JSObject>::cast(value);
     586         283 :       if (!IsFastLiteralHelper(value_object, max_depth - 1, max_properties)) {
     587           7 :         return false;
     588             :       }
     589             :     }
     590             :   }
     591             :   return true;
     592             : }
     593             : 
     594             : // Maximum depth and total number of elements and properties for literal
     595             : // graphs to be considered for fast deep-copying. The limit is chosen to
     596             : // match the maximum number of inobject properties, to ensure that the
     597             : // performance of using object literals is not worse than using constructor
     598             : // functions, see crbug.com/v8/6211 for details.
     599             : const int kMaxFastLiteralDepth = 3;
     600             : const int kMaxFastLiteralProperties = JSObject::kMaxInObjectProperties;
     601             : 
     602             : // Determines whether the given array or object literal boilerplate satisfies
     603             : // all limits to be considered for fast deep-copying and computes the total
     604             : // size of all objects that are part of the graph.
     605             : bool IsInlinableFastLiteral(Handle<JSObject> boilerplate) {
     606        6104 :   int max_properties = kMaxFastLiteralProperties;
     607             :   return IsFastLiteralHelper(boilerplate, kMaxFastLiteralDepth,
     608        6104 :                              &max_properties);
     609             : }
     610             : 
     611             : }  // namespace
     612             : 
     613             : class AllocationSiteData : public HeapObjectData {
     614             :  public:
     615             :   AllocationSiteData(JSHeapBroker* broker, ObjectData** storage,
     616             :                      Handle<AllocationSite> object);
     617             :   void SerializeBoilerplate(JSHeapBroker* broker);
     618             : 
     619             :   bool PointsToLiteral() const { return PointsToLiteral_; }
     620             :   PretenureFlag GetPretenureMode() const { return GetPretenureMode_; }
     621             :   ObjectData* nested_site() const { return nested_site_; }
     622             :   bool IsFastLiteral() const { return IsFastLiteral_; }
     623             :   JSObjectData* boilerplate() const { return boilerplate_; }
     624             : 
     625             :   // These are only valid if PointsToLiteral is false.
     626             :   ElementsKind GetElementsKind() const { return GetElementsKind_; }
     627             :   bool CanInlineCall() const { return CanInlineCall_; }
     628             : 
     629             :  private:
     630             :   bool const PointsToLiteral_;
     631             :   PretenureFlag const GetPretenureMode_;
     632             :   ObjectData* nested_site_ = nullptr;
     633             :   bool IsFastLiteral_ = false;
     634             :   JSObjectData* boilerplate_ = nullptr;
     635             :   ElementsKind GetElementsKind_ = NO_ELEMENTS;
     636             :   bool CanInlineCall_ = false;
     637             :   bool serialized_boilerplate_ = false;
     638             : };
     639             : 
     640             : // Only used in JSNativeContextSpecialization.
     641             : class ScriptContextTableData : public HeapObjectData {
     642             :  public:
     643      456153 :   ScriptContextTableData(JSHeapBroker* broker, ObjectData** storage,
     644             :                          Handle<ScriptContextTable> object)
     645      456153 :       : HeapObjectData(broker, storage, object) {}
     646             : };
     647             : 
     648        8416 : struct PropertyDescriptor {
     649             :   NameData* key = nullptr;
     650             :   PropertyDetails details = PropertyDetails::Empty();
     651             :   FieldIndex field_index;
     652             :   MapData* field_owner = nullptr;
     653             :   ObjectData* field_type = nullptr;
     654             :   bool is_unboxed_double_field = false;
     655             : };
     656             : 
     657             : class MapData : public HeapObjectData {
     658             :  public:
     659             :   MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object);
     660             : 
     661             :   InstanceType instance_type() const { return instance_type_; }
     662             :   int instance_size() const { return instance_size_; }
     663             :   byte bit_field() const { return bit_field_; }
     664             :   byte bit_field2() const { return bit_field2_; }
     665             :   uint32_t bit_field3() const { return bit_field3_; }
     666             :   bool can_be_deprecated() const { return can_be_deprecated_; }
     667             :   bool can_transition() const { return can_transition_; }
     668       39458 :   int in_object_properties_start_in_words() const {
     669       39458 :     CHECK(InstanceTypeChecker::IsJSObject(instance_type()));
     670       39458 :     return in_object_properties_start_in_words_;
     671             :   }
     672       75665 :   int in_object_properties() const {
     673       75665 :     CHECK(InstanceTypeChecker::IsJSObject(instance_type()));
     674       75665 :     return in_object_properties_;
     675             :   }
     676             :   int constructor_function_index() const { return constructor_function_index_; }
     677             :   int NextFreePropertyIndex() const { return next_free_property_index_; }
     678             :   int UnusedPropertyFields() const { return unused_property_fields_; }
     679             :   bool supports_fast_array_iteration() const {
     680             :     return supports_fast_array_iteration_;
     681             :   }
     682             :   bool supports_fast_array_resize() const {
     683             :     return supports_fast_array_resize_;
     684             :   }
     685             : 
     686             :   // Extra information.
     687             : 
     688             :   void SerializeElementsKindGeneralizations(JSHeapBroker* broker);
     689         909 :   const ZoneVector<MapData*>& elements_kind_generalizations() const {
     690         909 :     CHECK(serialized_elements_kind_generalizations_);
     691         909 :     return elements_kind_generalizations_;
     692             :   }
     693             : 
     694             :   // Serialize the own part of the descriptor array and, recursively, that of
     695             :   // any field owner.
     696             :   void SerializeOwnDescriptors(JSHeapBroker* broker);
     697             :   DescriptorArrayData* instance_descriptors() const {
     698       17564 :     CHECK(serialized_own_descriptors_);
     699       17564 :     return instance_descriptors_;
     700             :   }
     701             : 
     702             :   void SerializeConstructor(JSHeapBroker* broker);
     703             :   ObjectData* GetConstructor() const {
     704        4913 :     CHECK(serialized_constructor_);
     705        4913 :     return constructor_;
     706             :   }
     707             : 
     708             :   void SerializePrototype(JSHeapBroker* broker);
     709             :   ObjectData* prototype() const {
     710          37 :     CHECK(serialized_prototype_);
     711          37 :     return prototype_;
     712             :   }
     713             : 
     714             :  private:
     715             :   InstanceType const instance_type_;
     716             :   int const instance_size_;
     717             :   byte const bit_field_;
     718             :   byte const bit_field2_;
     719             :   uint32_t const bit_field3_;
     720             :   bool const can_be_deprecated_;
     721             :   bool const can_transition_;
     722             :   int const in_object_properties_start_in_words_;
     723             :   int const in_object_properties_;
     724             :   int const constructor_function_index_;
     725             :   int const next_free_property_index_;
     726             :   int const unused_property_fields_;
     727             :   bool const supports_fast_array_iteration_;
     728             :   bool const supports_fast_array_resize_;
     729             : 
     730             :   bool serialized_elements_kind_generalizations_ = false;
     731             :   ZoneVector<MapData*> elements_kind_generalizations_;
     732             : 
     733             :   bool serialized_own_descriptors_ = false;
     734             :   DescriptorArrayData* instance_descriptors_ = nullptr;
     735             : 
     736             :   bool serialized_constructor_ = false;
     737             :   ObjectData* constructor_ = nullptr;
     738             : 
     739             :   bool serialized_prototype_ = false;
     740             :   ObjectData* prototype_ = nullptr;
     741             : };
     742             : 
     743       13796 : AllocationSiteData::AllocationSiteData(JSHeapBroker* broker,
     744             :                                        ObjectData** storage,
     745             :                                        Handle<AllocationSite> object)
     746             :     : HeapObjectData(broker, storage, object),
     747       15384 :       PointsToLiteral_(object->PointsToLiteral()),
     748       23076 :       GetPretenureMode_(object->GetPretenureMode()) {
     749        7692 :   if (PointsToLiteral_) {
     750             :     IsFastLiteral_ = IsInlinableFastLiteral(
     751       12208 :         handle(object->boilerplate(), broker->isolate()));
     752             :   } else {
     753        3176 :     GetElementsKind_ = object->GetElementsKind();
     754        3176 :     CanInlineCall_ = object->CanInlineCall();
     755             :   }
     756        7692 : }
     757             : 
     758        5964 : void AllocationSiteData::SerializeBoilerplate(JSHeapBroker* broker) {
     759        5964 :   if (serialized_boilerplate_) return;
     760        5964 :   serialized_boilerplate_ = true;
     761             : 
     762        5964 :   TraceScope tracer(broker, this, "AllocationSiteData::SerializeBoilerplate");
     763        5964 :   Handle<AllocationSite> site = Handle<AllocationSite>::cast(object());
     764             : 
     765        5964 :   CHECK(IsFastLiteral_);
     766             :   DCHECK_NULL(boilerplate_);
     767        5964 :   boilerplate_ = broker->GetOrCreateData(site->boilerplate())->AsJSObject();
     768             :   boilerplate_->SerializeAsBoilerplate(broker);
     769             : 
     770             :   DCHECK_NULL(nested_site_);
     771        5964 :   nested_site_ = broker->GetOrCreateData(site->nested_site());
     772        5964 :   if (nested_site_->IsAllocationSite()) {
     773         239 :     nested_site_->AsAllocationSite()->SerializeBoilerplate(broker);
     774             :   }
     775             : }
     776             : 
     777   179068757 : HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage,
     778             :                                Handle<HeapObject> object)
     779             :     : ObjectData(broker, storage, object, kSerializedHeapObject),
     780   179068528 :       boolean_value_(object->BooleanValue(broker->isolate())),
     781             :       // We have to use a raw cast below instead of AsMap() because of
     782             :       // recursion. AsMap() would call IsMap(), which accesses the
     783             :       // instance_type_ member. In the case of constructing the MapData for the
     784             :       // meta map (whose map is itself), this member has not yet been
     785             :       // initialized.
     786   268603020 :       map_(static_cast<MapData*>(broker->GetOrCreateData(object->map()))) {
     787    89534080 :   CHECK(broker->SerializingAllowed());
     788    89534080 : }
     789             : 
     790             : namespace {
     791     2718636 : bool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle<Map> jsarray_map) {
     792             :   DCHECK(!jsarray_map->is_dictionary_map());
     793             :   Handle<Name> length_string = isolate->factory()->length_string();
     794     2718636 :   DescriptorArray descriptors = jsarray_map->instance_descriptors();
     795             :   int number = descriptors->Search(*length_string, *jsarray_map);
     796             :   DCHECK_NE(DescriptorArray::kNotFound, number);
     797     5437274 :   return descriptors->GetDetails(number).IsReadOnly();
     798             : }
     799             : 
     800    93211526 : bool SupportsFastArrayIteration(Isolate* isolate, Handle<Map> map) {
     801     6407178 :   return map->instance_type() == JS_ARRAY_TYPE &&
     802     6404918 :          IsFastElementsKind(map->elements_kind()) &&
     803   105100624 :          map->prototype()->IsJSArray() &&
     804             :          isolate->IsAnyInitialArrayPrototype(
     805   104179517 :              handle(JSArray::cast(map->prototype()), isolate)) &&
     806    98695350 :          isolate->IsNoElementsProtectorIntact();
     807             : }
     808             : 
     809    46606759 : bool SupportsFastArrayResize(Isolate* isolate, Handle<Map> map) {
     810    52044050 :   return SupportsFastArrayIteration(isolate, map) && map->is_extensible() &&
     811    52044093 :          !map->is_dictionary_map() && !IsReadOnlyLengthDescriptor(isolate, map);
     812             : }
     813             : }  // namespace
     814             : 
     815   186402657 : MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object)
     816             :     : HeapObjectData(broker, storage, object),
     817             :       instance_type_(object->instance_type()),
     818             :       instance_size_(object->instance_size()),
     819             :       bit_field_(object->bit_field()),
     820             :       bit_field2_(object->bit_field2()),
     821             :       bit_field3_(object->bit_field3()),
     822             :       can_be_deprecated_(object->NumberOfOwnDescriptors() > 0
     823    71419591 :                              ? object->CanBeDeprecated()
     824             :                              : false),
     825             :       can_transition_(object->CanTransition()),
     826             :       in_object_properties_start_in_words_(
     827             :           object->IsJSObjectMap() ? object->GetInObjectPropertiesStartInWords()
     828             :                                   : 0),
     829             :       in_object_properties_(
     830    78763948 :           object->IsJSObjectMap() ? object->GetInObjectProperties() : 0),
     831             :       constructor_function_index_(object->IsPrimitiveMap()
     832             :                                       ? object->GetConstructorFunctionIndex()
     833             :                                       : Map::kNoConstructorFunctionIndex),
     834    93201318 :       next_free_property_index_(object->NextFreePropertyIndex()),
     835    93201357 :       unused_property_fields_(object->UnusedPropertyFields()),
     836             :       supports_fast_array_iteration_(
     837    46600681 :           SupportsFastArrayIteration(broker->isolate(), object)),
     838             :       supports_fast_array_resize_(
     839    46600674 :           SupportsFastArrayResize(broker->isolate(), object)),
     840   895793329 :       elements_kind_generalizations_(broker->zone()) {}
     841             : 
     842     7534566 : JSFunctionData::JSFunctionData(JSHeapBroker* broker, ObjectData** storage,
     843             :                                Handle<JSFunction> object)
     844             :     : JSObjectData(broker, storage, object),
     845    21559792 :       has_initial_map_(object->has_prototype_slot() &&
     846    14025227 :                        object->has_initial_map()),
     847    21559812 :       has_prototype_(object->has_prototype_slot() && object->has_prototype()),
     848             :       PrototypeRequiresRuntimeLookup_(
     849    30138268 :           object->PrototypeRequiresRuntimeLookup()) {}
     850             : 
     851    18781965 : void JSFunctionData::Serialize(JSHeapBroker* broker) {
     852     6188925 :   if (serialized_) return;
     853     4799095 :   serialized_ = true;
     854             : 
     855     4799095 :   TraceScope tracer(broker, this, "JSFunctionData::Serialize");
     856     4799101 :   Handle<JSFunction> function = Handle<JSFunction>::cast(object());
     857             : 
     858             :   DCHECK_NULL(context_);
     859             :   DCHECK_NULL(native_context_);
     860             :   DCHECK_NULL(initial_map_);
     861             :   DCHECK_NULL(prototype_);
     862             :   DCHECK_NULL(shared_);
     863             : 
     864     4799106 :   context_ = broker->GetOrCreateData(function->context())->AsContext();
     865             :   native_context_ =
     866     4799105 :       broker->GetOrCreateData(function->native_context())->AsNativeContext();
     867     4799105 :   shared_ = broker->GetOrCreateData(function->shared())->AsSharedFunctionInfo();
     868             :   initial_map_ = has_initial_map()
     869    12178616 :                      ? broker->GetOrCreateData(function->initial_map())->AsMap()
     870     9598193 :                      : nullptr;
     871    12196324 :   prototype_ = has_prototype() ? broker->GetOrCreateData(function->prototype())
     872     9598206 :                                : nullptr;
     873             : 
     874     8488857 :   if (initial_map_ != nullptr) {
     875             :     initial_map_instance_size_with_min_slack_ =
     876     3689754 :         function->ComputeInstanceSizeWithMinSlack(broker->isolate());
     877     7379522 :     if (initial_map_->instance_type() == JS_ARRAY_TYPE) {
     878      456610 :       initial_map_->SerializeElementsKindGeneralizations(broker);
     879             :     }
     880     3689761 :     initial_map_->SerializeConstructor(broker);
     881             :     // TODO(neis): This is currently only needed for native_context's
     882             :     // object_function, as used by GetObjectCreateMap. If no further use sites
     883             :     // show up, we should move this into NativeContextData::Serialize.
     884     3689761 :     initial_map_->SerializePrototype(broker);
     885             :   }
     886             : }
     887             : 
     888     2739660 : void MapData::SerializeElementsKindGeneralizations(JSHeapBroker* broker) {
     889      456610 :   if (serialized_elements_kind_generalizations_) return;
     890      456610 :   serialized_elements_kind_generalizations_ = true;
     891             : 
     892             :   TraceScope tracer(broker, this,
     893      456610 :                     "MapData::SerializeElementsKindGeneralizations");
     894             :   DCHECK_EQ(instance_type(), JS_ARRAY_TYPE);
     895             :   MapRef self(broker, this);
     896      456610 :   ElementsKind from_kind = self.elements_kind();
     897             :   DCHECK(elements_kind_generalizations_.empty());
     898     3196271 :   for (int i = FIRST_FAST_ELEMENTS_KIND; i <= LAST_FAST_ELEMENTS_KIND; i++) {
     899             :     ElementsKind to_kind = static_cast<ElementsKind>(i);
     900     2739661 :     if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
     901             :       Handle<Map> target =
     902     2283050 :           Map::AsElementsKind(broker->isolate(), self.object(), to_kind);
     903             :       elements_kind_generalizations_.push_back(
     904     4566104 :           broker->GetOrCreateData(target)->AsMap());
     905             :     }
     906             :   }
     907             : }
     908             : 
     909             : class DescriptorArrayData : public HeapObjectData {
     910             :  public:
     911        7478 :   DescriptorArrayData(JSHeapBroker* broker, ObjectData** storage,
     912             :                       Handle<DescriptorArray> object)
     913        7478 :       : HeapObjectData(broker, storage, object), contents_(broker->zone()) {}
     914             : 
     915             :   ZoneVector<PropertyDescriptor>& contents() { return contents_; }
     916             : 
     917             :  private:
     918             :   ZoneVector<PropertyDescriptor> contents_;
     919             : };
     920             : 
     921             : class FeedbackVectorData : public HeapObjectData {
     922             :  public:
     923             :   const ZoneVector<ObjectData*>& feedback() { return feedback_; }
     924             : 
     925             :   FeedbackVectorData(JSHeapBroker* broker, ObjectData** storage,
     926             :                      Handle<FeedbackVector> object);
     927             : 
     928             :   void SerializeSlots(JSHeapBroker* broker);
     929             : 
     930             :  private:
     931             :   bool serialized_ = false;
     932             :   ZoneVector<ObjectData*> feedback_;
     933             : };
     934             : 
     935       67854 : FeedbackVectorData::FeedbackVectorData(JSHeapBroker* broker,
     936             :                                        ObjectData** storage,
     937             :                                        Handle<FeedbackVector> object)
     938       67854 :     : HeapObjectData(broker, storage, object), feedback_(broker->zone()) {}
     939             : 
     940       50964 : void FeedbackVectorData::SerializeSlots(JSHeapBroker* broker) {
     941       68018 :   if (serialized_) return;
     942       33910 :   serialized_ = true;
     943             : 
     944       33910 :   TraceScope tracer(broker, this, "FeedbackVectorData::SerializeSlots");
     945       33910 :   Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(object());
     946             :   DCHECK(feedback_.empty());
     947       33910 :   feedback_.reserve(vector->length());
     948     1393260 :   for (int i = 0; i < vector->length(); ++i) {
     949      662720 :     MaybeObject value = vector->get(i);
     950             :     ObjectData* slot_value =
     951      561927 :         value->IsObject() ? broker->GetOrCreateData(value->cast<Object>())
     952     1224647 :                           : nullptr;
     953      662720 :     feedback_.push_back(slot_value);
     954      763513 :     if (slot_value == nullptr) continue;
     955             : 
     956      568920 :     if (slot_value->IsAllocationSite() &&
     957        6993 :         slot_value->AsAllocationSite()->IsFastLiteral()) {
     958        5725 :       slot_value->AsAllocationSite()->SerializeBoilerplate(broker);
     959      556202 :     } else if (slot_value->IsJSRegExp()) {
     960         518 :       slot_value->AsJSRegExp()->SerializeAsRegExpBoilerplate(broker);
     961             :     }
     962             :   }
     963             :   DCHECK_EQ(vector->length(), feedback_.size());
     964       33910 :   TRACE(broker, "Copied " << feedback_.size() << " slots.");
     965             : }
     966             : 
     967             : class FixedArrayBaseData : public HeapObjectData {
     968             :  public:
     969     1189856 :   FixedArrayBaseData(JSHeapBroker* broker, ObjectData** storage,
     970             :                      Handle<FixedArrayBase> object)
     971     2379714 :       : HeapObjectData(broker, storage, object), length_(object->length()) {}
     972             : 
     973             :   int length() const { return length_; }
     974             : 
     975             :  private:
     976             :   int const length_;
     977             : };
     978             : 
     979             : class FixedArrayData : public FixedArrayBaseData {
     980             :  public:
     981             :   FixedArrayData(JSHeapBroker* broker, ObjectData** storage,
     982             :                  Handle<FixedArray> object);
     983             : 
     984             :   // Creates all elements of the fixed array.
     985             :   void SerializeContents(JSHeapBroker* broker);
     986             : 
     987             :   ObjectData* Get(int i) const;
     988             : 
     989             :  private:
     990             :   bool serialized_contents_ = false;
     991             :   ZoneVector<ObjectData*> contents_;
     992             : };
     993             : 
     994         190 : JSDataViewData::JSDataViewData(JSHeapBroker* broker, ObjectData** storage,
     995             :                                Handle<JSDataView> object)
     996             :     : JSObjectData(broker, storage, object),
     997             :       byte_length_(object->byte_length()),
     998         570 :       byte_offset_(object->byte_offset()) {}
     999             : 
    1000         231 : JSBoundFunctionData::JSBoundFunctionData(JSHeapBroker* broker,
    1001             :                                          ObjectData** storage,
    1002             :                                          Handle<JSBoundFunction> object)
    1003         231 :     : JSObjectData(broker, storage, object) {}
    1004             : 
    1005           0 : void JSBoundFunctionData::Serialize(JSHeapBroker* broker) {
    1006           0 :   if (serialized_) return;
    1007           0 :   serialized_ = true;
    1008             : 
    1009           0 :   TraceScope tracer(broker, this, "JSBoundFunctionData::Serialize");
    1010           0 :   Handle<JSBoundFunction> function = Handle<JSBoundFunction>::cast(object());
    1011             : 
    1012             :   DCHECK_NULL(bound_target_function_);
    1013             :   DCHECK_NULL(bound_this_);
    1014             :   DCHECK_NULL(bound_arguments_);
    1015             : 
    1016             :   bound_target_function_ =
    1017           0 :       broker->GetOrCreateData(function->bound_target_function());
    1018           0 :   bound_this_ = broker->GetOrCreateData(function->bound_this());
    1019             :   bound_arguments_ =
    1020           0 :       broker->GetOrCreateData(function->bound_arguments())->AsFixedArray();
    1021             : 
    1022           0 :   bound_arguments_->SerializeContents(broker);
    1023             : }
    1024             : 
    1025    23548338 : JSObjectData::JSObjectData(JSHeapBroker* broker, ObjectData** storage,
    1026             :                            Handle<JSObject> object)
    1027             :     : HeapObjectData(broker, storage, object),
    1028    23548338 :       inobject_fields_(broker->zone()) {}
    1029             : 
    1030     1008947 : FixedArrayData::FixedArrayData(JSHeapBroker* broker, ObjectData** storage,
    1031             :                                Handle<FixedArray> object)
    1032     1008947 :     : FixedArrayBaseData(broker, storage, object), contents_(broker->zone()) {}
    1033             : 
    1034        8266 : void FixedArrayData::SerializeContents(JSHeapBroker* broker) {
    1035        1627 :   if (serialized_contents_) return;
    1036        1627 :   serialized_contents_ = true;
    1037             : 
    1038        1627 :   TraceScope tracer(broker, this, "FixedArrayData::SerializeContents");
    1039        1627 :   Handle<FixedArray> array = Handle<FixedArray>::cast(object());
    1040       13147 :   CHECK_EQ(array->length(), length());
    1041        1627 :   CHECK(contents_.empty());
    1042        1627 :   contents_.reserve(static_cast<size_t>(length()));
    1043             : 
    1044       16532 :   for (int i = 0; i < length(); i++) {
    1045             :     Handle<Object> value(array->get(i), broker->isolate());
    1046       13278 :     contents_.push_back(broker->GetOrCreateData(value));
    1047             :   }
    1048        1627 :   TRACE(broker, "Copied " << contents_.size() << " elements.");
    1049             : }
    1050             : 
    1051             : class FixedDoubleArrayData : public FixedArrayBaseData {
    1052             :  public:
    1053             :   FixedDoubleArrayData(JSHeapBroker* broker, ObjectData** storage,
    1054             :                        Handle<FixedDoubleArray> object);
    1055             : 
    1056             :   // Serializes all elements of the fixed array.
    1057             :   void SerializeContents(JSHeapBroker* broker);
    1058             : 
    1059             :   Float64 Get(int i) const;
    1060             : 
    1061             :  private:
    1062             :   bool serialized_contents_ = false;
    1063             :   ZoneVector<Float64> contents_;
    1064             : };
    1065             : 
    1066        1022 : FixedDoubleArrayData::FixedDoubleArrayData(JSHeapBroker* broker,
    1067             :                                            ObjectData** storage,
    1068             :                                            Handle<FixedDoubleArray> object)
    1069        1022 :     : FixedArrayBaseData(broker, storage, object), contents_(broker->zone()) {}
    1070             : 
    1071         511 : void FixedDoubleArrayData::SerializeContents(JSHeapBroker* broker) {
    1072         511 :   if (serialized_contents_) return;
    1073         511 :   serialized_contents_ = true;
    1074             : 
    1075         511 :   TraceScope tracer(broker, this, "FixedDoubleArrayData::SerializeContents");
    1076         511 :   Handle<FixedDoubleArray> self = Handle<FixedDoubleArray>::cast(object());
    1077        8538 :   CHECK_EQ(self->length(), length());
    1078         511 :   CHECK(contents_.empty());
    1079         511 :   contents_.reserve(static_cast<size_t>(length()));
    1080             : 
    1081       14010 :   for (int i = 0; i < length(); i++) {
    1082       12988 :     contents_.push_back(Float64::FromBits(self->get_representation(i)));
    1083             :   }
    1084         511 :   TRACE(broker, "Copied " << contents_.size() << " elements.");
    1085             : }
    1086             : 
    1087             : class BytecodeArrayData : public FixedArrayBaseData {
    1088             :  public:
    1089             :   int register_count() const { return register_count_; }
    1090             : 
    1091      684873 :   BytecodeArrayData(JSHeapBroker* broker, ObjectData** storage,
    1092             :                     Handle<BytecodeArray> object)
    1093             :       : FixedArrayBaseData(broker, storage, object),
    1094     1369746 :         register_count_(object->register_count()) {}
    1095             : 
    1096             :  private:
    1097             :   int const register_count_;
    1098             : };
    1099             : 
    1100             : class JSArrayData : public JSObjectData {
    1101             :  public:
    1102             :   JSArrayData(JSHeapBroker* broker, ObjectData** storage,
    1103             :               Handle<JSArray> object);
    1104             :   void Serialize(JSHeapBroker* broker);
    1105             : 
    1106             :   ObjectData* length() const { return length_; }
    1107             : 
    1108             :  private:
    1109             :   bool serialized_ = false;
    1110             :   ObjectData* length_ = nullptr;
    1111             : };
    1112             : 
    1113      468544 : JSArrayData::JSArrayData(JSHeapBroker* broker, ObjectData** storage,
    1114             :                          Handle<JSArray> object)
    1115      468544 :     : JSObjectData(broker, storage, object) {}
    1116             : 
    1117        4098 : void JSArrayData::Serialize(JSHeapBroker* broker) {
    1118        4098 :   if (serialized_) return;
    1119        4098 :   serialized_ = true;
    1120             : 
    1121        4098 :   TraceScope tracer(broker, this, "JSArrayData::Serialize");
    1122        4098 :   Handle<JSArray> jsarray = Handle<JSArray>::cast(object());
    1123             :   DCHECK_NULL(length_);
    1124        4098 :   length_ = broker->GetOrCreateData(jsarray->length());
    1125             : }
    1126             : 
    1127             : class ScopeInfoData : public HeapObjectData {
    1128             :  public:
    1129             :   ScopeInfoData(JSHeapBroker* broker, ObjectData** storage,
    1130             :                 Handle<ScopeInfo> object);
    1131             : 
    1132             :   int context_length() const { return context_length_; }
    1133             : 
    1134             :  private:
    1135             :   int const context_length_;
    1136             : };
    1137             : 
    1138       55169 : ScopeInfoData::ScopeInfoData(JSHeapBroker* broker, ObjectData** storage,
    1139             :                              Handle<ScopeInfo> object)
    1140             :     : HeapObjectData(broker, storage, object),
    1141      110338 :       context_length_(object->ContextLength()) {}
    1142             : 
    1143             : class SharedFunctionInfoData : public HeapObjectData {
    1144             :  public:
    1145             :   int builtin_id() const { return builtin_id_; }
    1146             :   BytecodeArrayData* GetBytecodeArray() const { return GetBytecodeArray_; }
    1147             : #define DECL_ACCESSOR(type, name) \
    1148             :   type name() const { return name##_; }
    1149             :   BROKER_SFI_FIELDS(DECL_ACCESSOR)
    1150             : #undef DECL_ACCESSOR
    1151             : 
    1152     7044091 :   SharedFunctionInfoData(JSHeapBroker* broker, ObjectData** storage,
    1153             :                          Handle<SharedFunctionInfo> object)
    1154             :       : HeapObjectData(broker, storage, object),
    1155    20131163 :         builtin_id_(object->HasBuiltinId() ? object->builtin_id()
    1156             :                                            : Builtins::kNoBuiltinId),
    1157             :         GetBytecodeArray_(
    1158    14088177 :             object->HasBytecodeArray()
    1159     7728963 :                 ? broker->GetOrCreateData(object->GetBytecodeArray())
    1160     7728963 :                       ->AsBytecodeArray()
    1161             :                 : nullptr)
    1162             : #define INIT_MEMBER(type, name) , name##_(object->name())
    1163   112389254 :             BROKER_SFI_FIELDS(INIT_MEMBER)
    1164             : #undef INIT_MEMBER
    1165             :   {
    1166             :     DCHECK_EQ(HasBuiltinId_, builtin_id_ != Builtins::kNoBuiltinId);
    1167             :     DCHECK_EQ(HasBytecodeArray_, GetBytecodeArray_ != nullptr);
    1168     7044096 :   }
    1169             : 
    1170             :  private:
    1171             :   int const builtin_id_;
    1172             :   BytecodeArrayData* const GetBytecodeArray_;
    1173             : #define DECL_MEMBER(type, name) type const name##_;
    1174             :   BROKER_SFI_FIELDS(DECL_MEMBER)
    1175             : #undef DECL_MEMBER
    1176             : };
    1177             : 
    1178             : class ModuleData : public HeapObjectData {
    1179             :  public:
    1180             :   ModuleData(JSHeapBroker* broker, ObjectData** storage, Handle<Module> object);
    1181             :   void Serialize(JSHeapBroker* broker);
    1182             : 
    1183             :   CellData* GetCell(int cell_index) const;
    1184             : 
    1185             :  private:
    1186             :   bool serialized_ = false;
    1187             :   ZoneVector<CellData*> imports_;
    1188             :   ZoneVector<CellData*> exports_;
    1189             : };
    1190             : 
    1191         258 : ModuleData::ModuleData(JSHeapBroker* broker, ObjectData** storage,
    1192             :                        Handle<Module> object)
    1193             :     : HeapObjectData(broker, storage, object),
    1194             :       imports_(broker->zone()),
    1195         172 :       exports_(broker->zone()) {}
    1196             : 
    1197         141 : CellData* ModuleData::GetCell(int cell_index) const {
    1198         141 :   CHECK(serialized_);
    1199             :   CellData* cell;
    1200         141 :   switch (ModuleDescriptor::GetCellIndexKind(cell_index)) {
    1201             :     case ModuleDescriptor::kImport:
    1202          62 :       cell = imports_.at(Module::ImportIndex(cell_index));
    1203          31 :       break;
    1204             :     case ModuleDescriptor::kExport:
    1205         220 :       cell = exports_.at(Module::ExportIndex(cell_index));
    1206         110 :       break;
    1207             :     case ModuleDescriptor::kInvalid:
    1208           0 :       UNREACHABLE();
    1209             :       break;
    1210             :   }
    1211         141 :   CHECK_NOT_NULL(cell);
    1212         141 :   return cell;
    1213             : }
    1214             : 
    1215         344 : void ModuleData::Serialize(JSHeapBroker* broker) {
    1216         258 :   if (serialized_) return;
    1217          86 :   serialized_ = true;
    1218             : 
    1219          86 :   TraceScope tracer(broker, this, "ModuleData::Serialize");
    1220          86 :   Handle<Module> module = Handle<Module>::cast(object());
    1221             : 
    1222             :   // TODO(neis): We could be smarter and only serialize the cells we care about.
    1223             :   // TODO(neis): Define a helper for serializing a FixedArray into a ZoneVector.
    1224             : 
    1225             :   DCHECK(imports_.empty());
    1226         172 :   Handle<FixedArray> imports(module->regular_imports(), broker->isolate());
    1227             :   int const imports_length = imports->length();
    1228          86 :   imports_.reserve(imports_length);
    1229         180 :   for (int i = 0; i < imports_length; ++i) {
    1230         188 :     imports_.push_back(broker->GetOrCreateData(imports->get(i))->AsCell());
    1231             :   }
    1232          86 :   TRACE(broker, "Copied " << imports_.size() << " imports.");
    1233             : 
    1234             :   DCHECK(exports_.empty());
    1235         172 :   Handle<FixedArray> exports(module->regular_exports(), broker->isolate());
    1236             :   int const exports_length = exports->length();
    1237          86 :   exports_.reserve(exports_length);
    1238         259 :   for (int i = 0; i < exports_length; ++i) {
    1239         346 :     exports_.push_back(broker->GetOrCreateData(exports->get(i))->AsCell());
    1240             :   }
    1241          86 :   TRACE(broker, "Copied " << exports_.size() << " exports.");
    1242             : }
    1243             : 
    1244             : class CellData : public HeapObjectData {
    1245             :  public:
    1246             :   CellData(JSHeapBroker* broker, ObjectData** storage, Handle<Cell> object);
    1247             : 
    1248             :   void Serialize(JSHeapBroker* broker);
    1249             :   ObjectData* value() { return value_; }
    1250             : 
    1251             :  private:
    1252             :   bool serialized_ = false;
    1253             :   ObjectData* value_ = nullptr;
    1254             : };
    1255             : 
    1256      912566 : CellData::CellData(JSHeapBroker* broker, ObjectData** storage,
    1257             :                    Handle<Cell> object)
    1258      912566 :     : HeapObjectData(broker, storage, object) {}
    1259             : 
    1260      912308 : void CellData::Serialize(JSHeapBroker* broker) {
    1261      912308 :   if (serialized_) return;
    1262      912308 :   serialized_ = true;
    1263             : 
    1264      912308 :   TraceScope tracer(broker, this, "CellData::Serialize");
    1265      912308 :   auto cell = Handle<Cell>::cast(object());
    1266             :   DCHECK_NULL(value_);
    1267      912307 :   value_ = broker->GetOrCreateData(cell->value());
    1268             : }
    1269             : 
    1270             : class JSGlobalProxyData : public JSObjectData {
    1271             :  public:
    1272      456267 :   JSGlobalProxyData(JSHeapBroker* broker, ObjectData** storage,
    1273             :                     Handle<JSGlobalProxy> object)
    1274      456267 :       : JSObjectData(broker, storage, object) {}
    1275             : };
    1276             : 
    1277             : class CodeData : public HeapObjectData {
    1278             :  public:
    1279     5929866 :   CodeData(JSHeapBroker* broker, ObjectData** storage, Handle<Code> object)
    1280     5929866 :       : HeapObjectData(broker, storage, object) {}
    1281             : };
    1282             : 
    1283             : #define DEFINE_IS_AND_AS(Name)                                            \
    1284             :   bool ObjectData::Is##Name() const {                                     \
    1285             :     if (kind() == kUnserializedHeapObject) {                              \
    1286             :       AllowHandleDereference allow_handle_dereference;                    \
    1287             :       return object()->Is##Name();                                        \
    1288             :     }                                                                     \
    1289             :     if (is_smi()) return false;                                           \
    1290             :     InstanceType instance_type =                                          \
    1291             :         static_cast<const HeapObjectData*>(this)->map()->instance_type(); \
    1292             :     return InstanceTypeChecker::Is##Name(instance_type);                  \
    1293             :   }                                                                       \
    1294             :   Name##Data* ObjectData::As##Name() {                                    \
    1295             :     CHECK_EQ(kind(), kSerializedHeapObject);                              \
    1296             :     CHECK(Is##Name());                                                    \
    1297             :     return static_cast<Name##Data*>(this);                                \
    1298             :   }
    1299   748810390 : HEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS)
    1300             : #undef DEFINE_IS_AND_AS
    1301             : 
    1302        3352 : const JSObjectField& JSObjectData::GetInobjectField(int property_index) const {
    1303        6704 :   CHECK_LT(static_cast<size_t>(property_index), inobject_fields_.size());
    1304        3352 :   return inobject_fields_[property_index];
    1305             : }
    1306             : 
    1307           0 : bool JSObjectData::cow_or_empty_elements_tenured() const {
    1308          40 :   return cow_or_empty_elements_tenured_;
    1309             : }
    1310             : 
    1311        7305 : FixedArrayBaseData* JSObjectData::elements() const { return elements_; }
    1312             : 
    1313           0 : void JSObjectData::SerializeAsBoilerplate(JSHeapBroker* broker) {
    1314        5964 :   SerializeRecursive(broker, kMaxFastLiteralDepth);
    1315           0 : }
    1316             : 
    1317        1036 : void JSObjectData::SerializeElements(JSHeapBroker* broker) {
    1318         518 :   if (serialized_elements_) return;
    1319         518 :   serialized_elements_ = true;
    1320             : 
    1321         518 :   TraceScope tracer(broker, this, "JSObjectData::SerializeElements");
    1322         518 :   Handle<JSObject> boilerplate = Handle<JSObject>::cast(object());
    1323             :   Handle<FixedArrayBase> elements_object(boilerplate->elements(),
    1324        1036 :                                          broker->isolate());
    1325             :   DCHECK_NULL(elements_);
    1326         518 :   elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase();
    1327             : }
    1328             : 
    1329    13264953 : void MapData::SerializeConstructor(JSHeapBroker* broker) {
    1330    13721106 :   if (serialized_constructor_) return;
    1331    12808800 :   serialized_constructor_ = true;
    1332             : 
    1333    12808800 :   TraceScope tracer(broker, this, "MapData::SerializeConstructor");
    1334    12808806 :   Handle<Map> map = Handle<Map>::cast(object());
    1335             :   DCHECK_NULL(constructor_);
    1336    12808809 :   constructor_ = broker->GetOrCreateData(map->GetConstructor());
    1337             : }
    1338             : 
    1339     4602069 : void MapData::SerializePrototype(JSHeapBroker* broker) {
    1340     4602069 :   if (serialized_prototype_) return;
    1341     4602069 :   serialized_prototype_ = true;
    1342             : 
    1343     4602069 :   TraceScope tracer(broker, this, "MapData::SerializePrototype");
    1344     4602069 :   Handle<Map> map = Handle<Map>::cast(object());
    1345             :   DCHECK_NULL(prototype_);
    1346     4602068 :   prototype_ = broker->GetOrCreateData(map->prototype());
    1347             : }
    1348             : 
    1349       12096 : void MapData::SerializeOwnDescriptors(JSHeapBroker* broker) {
    1350       13650 :   if (serialized_own_descriptors_) return;
    1351        4754 :   serialized_own_descriptors_ = true;
    1352             : 
    1353        4754 :   TraceScope tracer(broker, this, "MapData::SerializeOwnDescriptors");
    1354        4754 :   Handle<Map> map = Handle<Map>::cast(object());
    1355             : 
    1356             :   DCHECK_NULL(instance_descriptors_);
    1357             :   instance_descriptors_ =
    1358        4754 :       broker->GetOrCreateData(map->instance_descriptors())->AsDescriptorArray();
    1359             : 
    1360             :   int const number_of_own = map->NumberOfOwnDescriptors();
    1361        4754 :   ZoneVector<PropertyDescriptor>& contents = instance_descriptors_->contents();
    1362       17230 :   int const current_size = static_cast<int>(contents.size());
    1363        4754 :   if (number_of_own <= current_size) return;
    1364             : 
    1365             :   Isolate* const isolate = broker->isolate();
    1366             :   auto descriptors =
    1367        3514 :       Handle<DescriptorArray>::cast(instance_descriptors_->object());
    1368       10542 :   CHECK_EQ(*descriptors, map->instance_descriptors());
    1369        3514 :   contents.reserve(number_of_own);
    1370             : 
    1371             :   // Copy the new descriptors.
    1372        7722 :   for (int i = current_size; i < number_of_own; ++i) {
    1373             :     PropertyDescriptor d;
    1374        4208 :     d.key = broker->GetOrCreateData(descriptors->GetKey(i))->AsName();
    1375        4208 :     d.details = descriptors->GetDetails(i);
    1376        4208 :     if (d.details.location() == kField) {
    1377        2189 :       d.field_index = FieldIndex::ForDescriptor(*map, i);
    1378             :       d.field_owner =
    1379        2189 :           broker->GetOrCreateData(map->FindFieldOwner(isolate, i))->AsMap();
    1380        2189 :       d.field_type = broker->GetOrCreateData(descriptors->GetFieldType(i));
    1381        2189 :       d.is_unboxed_double_field = map->IsUnboxedDoubleField(d.field_index);
    1382             :       // Recurse.
    1383             :     }
    1384        4208 :     contents.push_back(d);
    1385             :   }
    1386        3514 :   CHECK_EQ(number_of_own, contents.size());
    1387             : 
    1388             :   // Recurse on the new owner maps.
    1389        4208 :   for (int i = current_size; i < number_of_own; ++i) {
    1390        4208 :     const PropertyDescriptor& d = contents[i];
    1391        4208 :     if (d.details.location() == kField) {
    1392        4378 :       CHECK_LE(
    1393             :           Handle<Map>::cast(d.field_owner->object())->NumberOfOwnDescriptors(),
    1394             :           number_of_own);
    1395        2189 :       d.field_owner->SerializeOwnDescriptors(broker);
    1396             :     }
    1397             :   }
    1398             : 
    1399        3514 :   TRACE(broker, "Copied " << number_of_own - current_size
    1400             :                           << " descriptors into " << instance_descriptors_
    1401             :                           << " (" << number_of_own << " total).");
    1402             : }
    1403             : 
    1404       13025 : void JSObjectData::SerializeRecursive(JSHeapBroker* broker, int depth) {
    1405        6871 :   if (serialized_as_boilerplate_) return;
    1406        6393 :   serialized_as_boilerplate_ = true;
    1407             : 
    1408        6393 :   TraceScope tracer(broker, this, "JSObjectData::SerializeRecursive");
    1409        6393 :   Handle<JSObject> boilerplate = Handle<JSObject>::cast(object());
    1410             : 
    1411             :   // We only serialize boilerplates that pass the IsInlinableFastLiteral
    1412             :   // check, so we only do a sanity check on the depth here.
    1413        6393 :   CHECK_GT(depth, 0);
    1414        6393 :   CHECK(!boilerplate->map()->is_deprecated());
    1415             : 
    1416             :   // Serialize the elements.
    1417             :   Isolate* const isolate = broker->isolate();
    1418       12786 :   Handle<FixedArrayBase> elements_object(boilerplate->elements(), isolate);
    1419             : 
    1420             :   // Boilerplates need special serialization - we need to make sure COW arrays
    1421             :   // are tenured. Boilerplate objects should only be reachable from their
    1422             :   // allocation site, so it is safe to assume that the elements have not been
    1423             :   // serialized yet.
    1424             : 
    1425             :   bool const empty_or_cow =
    1426       10572 :       elements_object->length() == 0 ||
    1427             :       elements_object->map() == ReadOnlyRoots(isolate).fixed_cow_array_map();
    1428        6393 :   if (empty_or_cow) {
    1429             :     // We need to make sure copy-on-write elements are tenured.
    1430        4255 :     if (Heap::InNewSpace(*elements_object)) {
    1431             :       elements_object = isolate->factory()->CopyAndTenureFixedCOWArray(
    1432        1663 :           Handle<FixedArray>::cast(elements_object));
    1433        1663 :       boilerplate->set_elements(*elements_object);
    1434             :     }
    1435        4255 :     cow_or_empty_elements_tenured_ = true;
    1436             :   }
    1437             : 
    1438             :   DCHECK_NULL(elements_);
    1439        6393 :   elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase();
    1440             : 
    1441        6393 :   if (empty_or_cow) {
    1442             :     // No need to do anything here. Empty or copy-on-write elements
    1443             :     // do not need to be serialized because we only need to store the elements
    1444             :     // reference to the allocated object.
    1445        4276 :   } else if (boilerplate->HasSmiOrObjectElements()) {
    1446        1627 :     elements_->AsFixedArray()->SerializeContents(broker);
    1447             :     Handle<FixedArray> fast_elements =
    1448        1627 :         Handle<FixedArray>::cast(elements_object);
    1449             :     int length = elements_object->length();
    1450        8266 :     for (int i = 0; i < length; i++) {
    1451             :       Handle<Object> value(fast_elements->get(i), isolate);
    1452       13278 :       if (value->IsJSObject()) {
    1453         392 :         ObjectData* value_data = broker->GetOrCreateData(value);
    1454         392 :         value_data->AsJSObject()->SerializeRecursive(broker, depth - 1);
    1455             :       }
    1456             :     }
    1457             :   } else {
    1458        1022 :     CHECK(boilerplate->HasDoubleElements());
    1459         511 :     CHECK_LE(elements_object->Size(), kMaxRegularHeapObjectSize);
    1460         511 :     elements_->AsFixedDoubleArray()->SerializeContents(broker);
    1461             :   }
    1462             : 
    1463             :   // TODO(turbofan): Do we want to support out-of-object properties?
    1464       19179 :   CHECK(boilerplate->HasFastProperties() &&
    1465             :         boilerplate->property_array()->length() == 0);
    1466       12786 :   CHECK_EQ(inobject_fields_.size(), 0u);
    1467             : 
    1468             :   // Check the in-object properties.
    1469             :   Handle<DescriptorArray> descriptors(
    1470       12786 :       boilerplate->map()->instance_descriptors(), isolate);
    1471             :   int const limit = boilerplate->map()->NumberOfOwnDescriptors();
    1472       13340 :   for (int i = 0; i < limit; i++) {
    1473        6947 :     PropertyDetails details = descriptors->GetDetails(i);
    1474       11045 :     if (details.location() != kField) continue;
    1475             :     DCHECK_EQ(kData, details.kind());
    1476             : 
    1477        2849 :     FieldIndex field_index = FieldIndex::ForDescriptor(boilerplate->map(), i);
    1478             :     // Make sure {field_index} agrees with {inobject_properties} on the index of
    1479             :     // this field.
    1480             :     DCHECK_EQ(field_index.property_index(),
    1481             :               static_cast<int>(inobject_fields_.size()));
    1482        2849 :     if (boilerplate->IsUnboxedDoubleField(field_index)) {
    1483             :       double value = boilerplate->RawFastDoublePropertyAt(field_index);
    1484         254 :       inobject_fields_.push_back(JSObjectField{value});
    1485             :     } else {
    1486             :       Handle<Object> value(boilerplate->RawFastPropertyAt(field_index),
    1487        5444 :                            isolate);
    1488        2722 :       ObjectData* value_data = broker->GetOrCreateData(value);
    1489        5444 :       if (value->IsJSObject()) {
    1490         276 :         value_data->AsJSObject()->SerializeRecursive(broker, depth - 1);
    1491             :       }
    1492        5444 :       inobject_fields_.push_back(JSObjectField{value_data});
    1493             :     }
    1494             :   }
    1495        6393 :   TRACE(broker, "Copied " << inobject_fields_.size() << " in-object fields.");
    1496             : 
    1497        6393 :   map()->SerializeOwnDescriptors(broker);
    1498             : 
    1499        6393 :   if (IsJSArray()) AsJSArray()->Serialize(broker);
    1500             : }
    1501             : 
    1502         518 : void JSRegExpData::SerializeAsRegExpBoilerplate(JSHeapBroker* broker) {
    1503         518 :   if (serialized_as_reg_exp_boilerplate_) return;
    1504         518 :   serialized_as_reg_exp_boilerplate_ = true;
    1505             : 
    1506         518 :   TraceScope tracer(broker, this, "JSRegExpData::SerializeAsRegExpBoilerplate");
    1507         518 :   Handle<JSRegExp> boilerplate = Handle<JSRegExp>::cast(object());
    1508             : 
    1509         518 :   SerializeElements(broker);
    1510             : 
    1511             :   raw_properties_or_hash_ =
    1512         518 :       broker->GetOrCreateData(boilerplate->raw_properties_or_hash());
    1513         518 :   data_ = broker->GetOrCreateData(boilerplate->data());
    1514         518 :   source_ = broker->GetOrCreateData(boilerplate->source());
    1515         518 :   flags_ = broker->GetOrCreateData(boilerplate->flags());
    1516         518 :   last_index_ = broker->GetOrCreateData(boilerplate->last_index());
    1517             : }
    1518             : 
    1519     1425782 : bool ObjectRef::equals(const ObjectRef& other) const {
    1520    33246183 :   return data_ == other.data_;
    1521             : }
    1522             : 
    1523     4273526 : Isolate* ObjectRef::isolate() const { return broker()->isolate(); }
    1524             : 
    1525       12800 : ContextRef ContextRef::previous() const {
    1526       12800 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1527             :     AllowHandleAllocation handle_allocation;
    1528             :     AllowHandleDereference handle_dereference;
    1529             :     return ContextRef(broker(),
    1530       38400 :                       handle(object()->previous(), broker()->isolate()));
    1531             :   }
    1532           0 :   return ContextRef(broker(), data()->AsContext()->previous());
    1533             : }
    1534             : 
    1535             : // Not needed for TypedLowering.
    1536       45462 : ObjectRef ContextRef::get(int index) const {
    1537             :   AllowHandleAllocation handle_allocation;
    1538             :   AllowHandleDereference handle_dereference;
    1539      136387 :   Handle<Object> value(object()->get(index), broker()->isolate());
    1540       45463 :   return ObjectRef(broker(), value);
    1541             : }
    1542             : 
    1543      954876 : JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone)
    1544             :     : isolate_(isolate),
    1545             :       broker_zone_(broker_zone),
    1546             :       current_zone_(broker_zone),
    1547             :       refs_(new (zone())
    1548      477436 :                 RefsMap(kMinimalRefsBucketCount, AddressMatcher(), zone())),
    1549     1432319 :       array_and_object_prototypes_(zone()) {
    1550             :   // Note that this initialization of the refs_ pointer with the minimal
    1551             :   // initial capacity is redundant in the normal use case (concurrent
    1552             :   // compilation enabled, standard objects to be serialized), as the map
    1553             :   // is going to be replaced immediatelly with a larger capacity one.
    1554             :   // It doesn't seem to affect the performance in a noticeable way though.
    1555      477431 :   TRACE(this, "Constructing heap broker.");
    1556      477431 : }
    1557             : 
    1558           0 : std::ostream& JSHeapBroker::Trace() const {
    1559           0 :   std::cout << "[" << this << "] " << std::string(trace_indentation_ * 2, ' ');
    1560           0 :   return std::cout;
    1561             : }
    1562             : 
    1563      456144 : void JSHeapBroker::StartSerializing() {
    1564      456144 :   CHECK_EQ(mode_, kDisabled);
    1565      456144 :   TRACE(this, "Starting serialization.");
    1566      456153 :   mode_ = kSerializing;
    1567      456153 :   refs_->Clear();
    1568      456153 : }
    1569             : 
    1570      456152 : void JSHeapBroker::StopSerializing() {
    1571      456152 :   CHECK_EQ(mode_, kSerializing);
    1572      456152 :   TRACE(this, "Stopping serialization.");
    1573      456152 :   mode_ = kSerialized;
    1574      456152 : }
    1575             : 
    1576      455980 : void JSHeapBroker::Retire() {
    1577      455980 :   CHECK_EQ(mode_, kSerialized);
    1578      455980 :   TRACE(this, "Retiring.");
    1579      455980 :   mode_ = kRetired;
    1580      455980 : }
    1581             : 
    1582   294875644 : bool JSHeapBroker::SerializingAllowed() const { return mode() == kSerializing; }
    1583             : 
    1584      912872 : void JSHeapBroker::SetNativeContextRef() {
    1585     1825741 :   native_context_ = NativeContextRef(this, isolate()->native_context());
    1586      912869 : }
    1587             : 
    1588     5385752 : bool IsShareable(Handle<Object> object, Isolate* isolate) {
    1589     5385752 :   Builtins* const b = isolate->builtins();
    1590             : 
    1591             :   int index;
    1592             :   RootIndex root_index;
    1593    16157256 :   return (object->IsHeapObject() &&
    1594     5415840 :           b->IsBuiltinHandle(Handle<HeapObject>::cast(object), &index)) ||
    1595     5385752 :          isolate->roots_table().IsRootHandle(object, &root_index);
    1596             : }
    1597             : 
    1598     6784266 : void JSHeapBroker::SerializeShareableObjects() {
    1599      456129 :   PerIsolateCompilerCache::Setup(isolate());
    1600      456147 :   compiler_cache_ = isolate()->compiler_cache();
    1601             : 
    1602      471194 :   if (compiler_cache_->HasSnapshot()) {
    1603             :     RefsMap* snapshot = compiler_cache_->GetSnapshot();
    1604             : 
    1605      441109 :     refs_ = new (zone()) RefsMap(snapshot, zone());
    1606      897264 :     return;
    1607             :   }
    1608             : 
    1609             :   TraceScope tracer(
    1610             :       this, "JSHeapBroker::SerializeShareableObjects (building snapshot)");
    1611             : 
    1612             :   refs_ =
    1613       30088 :       new (zone()) RefsMap(kInitialRefsBucketCount, AddressMatcher(), zone());
    1614             : 
    1615       30094 :   current_zone_ = compiler_cache_->zone();
    1616             : 
    1617       15047 :   Builtins* const b = isolate()->builtins();
    1618             :   {
    1619             :     Builtins::Name builtins[] = {
    1620             :         Builtins::kAllocateInNewSpace,
    1621             :         Builtins::kAllocateInOldSpace,
    1622             :         Builtins::kArgumentsAdaptorTrampoline,
    1623             :         Builtins::kArrayConstructorImpl,
    1624             :         Builtins::kCallFunctionForwardVarargs,
    1625             :         Builtins::kCallFunction_ReceiverIsAny,
    1626             :         Builtins::kCallFunction_ReceiverIsNotNullOrUndefined,
    1627             :         Builtins::kCallFunction_ReceiverIsNullOrUndefined,
    1628             :         Builtins::kConstructFunctionForwardVarargs,
    1629             :         Builtins::kForInFilter,
    1630             :         Builtins::kJSBuiltinsConstructStub,
    1631             :         Builtins::kJSConstructStubGeneric,
    1632             :         Builtins::kStringAdd_CheckNone,
    1633             :         Builtins::kStringAdd_ConvertLeft,
    1634             :         Builtins::kStringAdd_ConvertRight,
    1635             :         Builtins::kToNumber,
    1636             :         Builtins::kToObject,
    1637       15047 :     };
    1638      270793 :     for (auto id : builtins) {
    1639      511492 :       GetOrCreateData(b->builtin_handle(id));
    1640             :     }
    1641             :   }
    1642    22746398 :   for (int32_t id = 0; id < Builtins::builtin_count; ++id) {
    1643    22731354 :     if (Builtins::KindOf(id) == Builtins::TFJ) {
    1644    10199693 :       GetOrCreateData(b->builtin_handle(id));
    1645             :     }
    1646             :   }
    1647             : 
    1648    10816636 :   for (RefsMap::Entry* p = refs_->Start(); p != nullptr; p = refs_->Next(p)) {
    1649     5385752 :     CHECK(IsShareable(p->value->object(), isolate()));
    1650             :   }
    1651             : 
    1652             :   // TODO(mslekova):
    1653             :   // Serialize root objects (from factory).
    1654       30088 :   compiler_cache()->SetSnapshot(refs_);
    1655       15044 :   current_zone_ = broker_zone_;
    1656             : }
    1657             : 
    1658     6249982 : void JSHeapBroker::CollectArrayAndObjectPrototypes() {
    1659             :   DisallowHeapAllocation no_gc;
    1660      456154 :   CHECK_EQ(mode(), kSerializing);
    1661      456154 :   CHECK(array_and_object_prototypes_.empty());
    1662             : 
    1663      456154 :   Object maybe_context = isolate()->heap()->native_contexts_list();
    1664     2539482 :   while (!maybe_context->IsUndefined(isolate())) {
    1665     1627174 :     Context context = Context::cast(maybe_context);
    1666             :     Object array_prot = context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
    1667             :     Object object_prot = context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
    1668     4881520 :     array_and_object_prototypes_.emplace(JSObject::cast(array_prot), isolate());
    1669             :     array_and_object_prototypes_.emplace(JSObject::cast(object_prot),
    1670     4881520 :                                          isolate());
    1671     1627174 :     maybe_context = context->next_context_link();
    1672             :   }
    1673             : 
    1674      456154 :   CHECK(!array_and_object_prototypes_.empty());
    1675      456154 : }
    1676             : 
    1677      216194 : bool JSHeapBroker::IsArrayOrObjectPrototype(const JSObjectRef& object) const {
    1678       73086 :   if (mode() == kDisabled) {
    1679             :     return isolate()->IsInAnyContext(*object.object(),
    1680      289280 :                                      Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ||
    1681             :            isolate()->IsInAnyContext(*object.object(),
    1682      213130 :                                      Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
    1683             :   }
    1684           0 :   CHECK(!array_and_object_prototypes_.empty());
    1685           0 :   return array_and_object_prototypes_.find(object.object()) !=
    1686             :          array_and_object_prototypes_.end();
    1687             : }
    1688             : 
    1689     1368462 : void JSHeapBroker::SerializeStandardObjects() {
    1690      456178 :   if (mode() == kDisabled) return;
    1691      456130 :   CHECK_EQ(mode(), kSerializing);
    1692             : 
    1693      456130 :   SerializeShareableObjects();
    1694             : 
    1695             :   TraceScope tracer(this, "JSHeapBroker::SerializeStandardObjects");
    1696             : 
    1697      456154 :   CollectArrayAndObjectPrototypes();
    1698             : 
    1699      456154 :   SetNativeContextRef();
    1700      456146 :   native_context().Serialize();
    1701             : 
    1702             :   Factory* const f = isolate()->factory();
    1703             : 
    1704             :   // Maps, strings, oddballs
    1705      456154 :   GetOrCreateData(f->arguments_marker_map());
    1706      456154 :   GetOrCreateData(f->bigint_string());
    1707      456153 :   GetOrCreateData(f->block_context_map());
    1708      456154 :   GetOrCreateData(f->boolean_map());
    1709      456154 :   GetOrCreateData(f->boolean_string());
    1710      456154 :   GetOrCreateData(f->catch_context_map());
    1711      456154 :   GetOrCreateData(f->empty_fixed_array());
    1712      456154 :   GetOrCreateData(f->empty_string());
    1713      456154 :   GetOrCreateData(f->eval_context_map());
    1714      456154 :   GetOrCreateData(f->false_string());
    1715      456154 :   GetOrCreateData(f->false_value());
    1716      456154 :   GetOrCreateData(f->fixed_array_map());
    1717      456154 :   GetOrCreateData(f->fixed_cow_array_map());
    1718      456154 :   GetOrCreateData(f->fixed_double_array_map());
    1719      456153 :   GetOrCreateData(f->function_context_map());
    1720      456152 :   GetOrCreateData(f->function_string());
    1721      456154 :   GetOrCreateData(f->heap_number_map());
    1722      456153 :   GetOrCreateData(f->length_string());
    1723      456154 :   GetOrCreateData(f->many_closures_cell_map());
    1724      456154 :   GetOrCreateData(f->minus_zero_value());
    1725      456154 :   GetOrCreateData(f->mutable_heap_number_map());
    1726      456153 :   GetOrCreateData(f->name_dictionary_map());
    1727      456154 :   GetOrCreateData(f->NaN_string());
    1728      456154 :   GetOrCreateData(f->null_map());
    1729      456154 :   GetOrCreateData(f->null_string());
    1730      456154 :   GetOrCreateData(f->null_value());
    1731      456154 :   GetOrCreateData(f->number_string());
    1732      456154 :   GetOrCreateData(f->object_string());
    1733      456154 :   GetOrCreateData(f->one_pointer_filler_map());
    1734      456152 :   GetOrCreateData(f->optimized_out());
    1735      456153 :   GetOrCreateData(f->optimized_out_map());
    1736      456154 :   GetOrCreateData(f->property_array_map());
    1737      456154 :   GetOrCreateData(f->sloppy_arguments_elements_map());
    1738      456153 :   GetOrCreateData(f->stale_register());
    1739      456154 :   GetOrCreateData(f->stale_register_map());
    1740      456154 :   GetOrCreateData(f->string_string());
    1741      456154 :   GetOrCreateData(f->symbol_string());
    1742      456154 :   GetOrCreateData(f->termination_exception_map());
    1743      456154 :   GetOrCreateData(f->the_hole_map());
    1744      456154 :   GetOrCreateData(f->the_hole_value());
    1745      456154 :   GetOrCreateData(f->true_string());
    1746      456154 :   GetOrCreateData(f->true_value());
    1747      456154 :   GetOrCreateData(f->undefined_map());
    1748      456154 :   GetOrCreateData(f->undefined_string());
    1749      456154 :   GetOrCreateData(f->undefined_value());
    1750      456154 :   GetOrCreateData(f->uninitialized_map());
    1751      456154 :   GetOrCreateData(f->with_context_map());
    1752      456154 :   GetOrCreateData(f->zero_string());
    1753             : 
    1754             :   // Protector cells
    1755             :   GetOrCreateData(f->array_buffer_detaching_protector())
    1756             :       ->AsPropertyCell()
    1757      456153 :       ->Serialize(this);
    1758      456154 :   GetOrCreateData(f->array_constructor_protector())->AsCell()->Serialize(this);
    1759             :   GetOrCreateData(f->array_iterator_protector())
    1760             :       ->AsPropertyCell()
    1761      456154 :       ->Serialize(this);
    1762             :   GetOrCreateData(f->array_species_protector())
    1763             :       ->AsPropertyCell()
    1764      456154 :       ->Serialize(this);
    1765             :   GetOrCreateData(f->no_elements_protector())
    1766             :       ->AsPropertyCell()
    1767      456154 :       ->Serialize(this);
    1768             :   GetOrCreateData(f->promise_hook_protector())
    1769             :       ->AsPropertyCell()
    1770      456154 :       ->Serialize(this);
    1771             :   GetOrCreateData(f->promise_species_protector())
    1772             :       ->AsPropertyCell()
    1773      456154 :       ->Serialize(this);
    1774             :   GetOrCreateData(f->promise_then_protector())
    1775             :       ->AsPropertyCell()
    1776      456154 :       ->Serialize(this);
    1777      456154 :   GetOrCreateData(f->string_length_protector())->AsCell()->Serialize(this);
    1778             : 
    1779             :   // CEntry stub
    1780             :   GetOrCreateData(
    1781      912308 :       CodeFactory::CEntry(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, true));
    1782             : 
    1783      456154 :   TRACE(this, "Finished serializing standard objects.");
    1784             : }
    1785             : 
    1786           0 : ObjectData* JSHeapBroker::GetData(Handle<Object> object) const {
    1787    51256758 :   RefsMap::Entry* entry = refs_->Lookup(object.address());
    1788    51257096 :   return entry ? entry->value : nullptr;
    1789             : }
    1790             : 
    1791             : // clang-format off
    1792   500741182 : ObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object) {
    1793   205341564 :   CHECK(SerializingAllowed());
    1794   205341564 :   RefsMap::Entry* entry = refs_->LookupOrInsert(object.address(), zone());
    1795   205341125 :   ObjectData** data_storage = &(entry->value);
    1796   205341125 :   if (*data_storage == nullptr) {
    1797             :     // TODO(neis): Remove these Allow* once we serialize everything upfront.
    1798             :     AllowHandleAllocation handle_allocation;
    1799             :     AllowHandleDereference handle_dereference;
    1800   180115903 :     if (object->IsSmi()) {
    1801     1046764 :       new (zone()) ObjectData(this, data_storage, object, kSmi);
    1802             : #define CREATE_DATA_IF_MATCH(name)                                             \
    1803             :     } else if (object->Is##name()) {                                           \
    1804             :       new (zone()) name##Data(this, data_storage, Handle<name>::cast(object));
    1805  4181831983 :     HEAP_BROKER_OBJECT_LIST(CREATE_DATA_IF_MATCH)
    1806             : #undef CREATE_DATA_IF_MATCH
    1807             :     } else {
    1808           0 :       UNREACHABLE();
    1809             :     }
    1810             :   }
    1811   205340926 :   CHECK_NOT_NULL(*data_storage);
    1812   205340926 :   return (*data_storage);
    1813             : }
    1814             : // clang-format on
    1815             : 
    1816   162031879 : ObjectData* JSHeapBroker::GetOrCreateData(Object object) {
    1817   162031961 :   return GetOrCreateData(handle(object, isolate()));
    1818             : }
    1819             : 
    1820             : #define DEFINE_IS_AND_AS(Name)                                    \
    1821             :   bool ObjectRef::Is##Name() const { return data()->Is##Name(); } \
    1822             :   Name##Ref ObjectRef::As##Name() const {                         \
    1823             :     DCHECK(Is##Name());                                           \
    1824             :     return Name##Ref(broker(), data());                           \
    1825             :   }
    1826    87632869 : HEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS)
    1827             : #undef DEFINE_IS_AND_AS
    1828             : 
    1829    24347436 : bool ObjectRef::IsSmi() const { return data()->is_smi(); }
    1830             : 
    1831      615424 : int ObjectRef::AsSmi() const {
    1832             :   DCHECK(IsSmi());
    1833             :   // Handle-dereference is always allowed for Handle<Smi>.
    1834     1230848 :   return Handle<Smi>::cast(object())->value();
    1835             : }
    1836             : 
    1837          15 : base::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const {
    1838          15 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1839             :     AllowHandleAllocation handle_allocation;
    1840             :     AllowHandleDereference allow_handle_dereference;
    1841             :     AllowHeapAllocation heap_allocation;
    1842             :     Handle<Map> instance_map;
    1843           0 :     if (Map::TryGetObjectCreateMap(broker()->isolate(), object())
    1844           0 :             .ToHandle(&instance_map)) {
    1845           0 :       return MapRef(broker(), instance_map);
    1846             :     } else {
    1847           0 :       return base::Optional<MapRef>();
    1848             :     }
    1849             :   }
    1850          15 :   MapData* map_data = data()->AsJSObject()->object_create_map();
    1851             :   return map_data != nullptr ? MapRef(broker(), map_data)
    1852          23 :                              : base::Optional<MapRef>();
    1853             : }
    1854             : 
    1855             : #define DEF_TESTER(Type, ...)                              \
    1856             :   bool MapRef::Is##Type##Map() const {                     \
    1857             :     return InstanceTypeChecker::Is##Type(instance_type()); \
    1858             :   }
    1859      338751 : INSTANCE_TYPE_CHECKERS(DEF_TESTER)
    1860             : #undef DEF_TESTER
    1861             : 
    1862        2395 : base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
    1863        2395 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1864             :     AllowHandleAllocation handle_allocation;
    1865             :     AllowHeapAllocation heap_allocation;
    1866             :     AllowHandleDereference allow_handle_dereference;
    1867             :     return MapRef(broker(),
    1868           0 :                   Map::AsElementsKind(broker()->isolate(), object(), kind));
    1869             :   }
    1870        2395 :   if (kind == elements_kind()) return *this;
    1871             :   const ZoneVector<MapData*>& elements_kind_generalizations =
    1872         909 :       data()->AsMap()->elements_kind_generalizations();
    1873        2451 :   for (auto data : elements_kind_generalizations) {
    1874             :     MapRef map(broker(), data);
    1875        2451 :     if (map.elements_kind() == kind) return map;
    1876             :   }
    1877           0 :   return base::Optional<MapRef>();
    1878             : }
    1879             : 
    1880        4191 : bool MapRef::supports_fast_array_iteration() const {
    1881        4191 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1882             :     AllowHandleDereference allow_handle_dereference;
    1883             :     AllowHandleAllocation handle_allocation;
    1884        4191 :     return SupportsFastArrayIteration(broker()->isolate(), object());
    1885             :   }
    1886           0 :   return data()->AsMap()->supports_fast_array_iteration();
    1887             : }
    1888             : 
    1889        6159 : bool MapRef::supports_fast_array_resize() const {
    1890        6159 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1891             :     AllowHandleDereference allow_handle_dereference;
    1892             :     AllowHandleAllocation handle_allocation;
    1893        6159 :     return SupportsFastArrayResize(broker()->isolate(), object());
    1894             :   }
    1895           0 :   return data()->AsMap()->supports_fast_array_resize();
    1896             : }
    1897             : 
    1898        5404 : int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const {
    1899        5404 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1900             :     AllowHandleDereference allow_handle_dereference;
    1901             :     AllowHandleAllocation handle_allocation;
    1902           2 :     return object()->ComputeInstanceSizeWithMinSlack(broker()->isolate());
    1903             :   }
    1904       10806 :   return data()->AsJSFunction()->initial_map_instance_size_with_min_slack();
    1905             : }
    1906             : 
    1907             : // Not needed for TypedLowering.
    1908             : base::Optional<ScriptContextTableRef::LookupResult>
    1909     1240294 : ScriptContextTableRef::lookup(const NameRef& name) const {
    1910             :   AllowHandleAllocation handle_allocation;
    1911             :   AllowHandleDereference handle_dereference;
    1912     2480588 :   if (!name.IsString()) return {};
    1913             :   ScriptContextTable::LookupResult lookup_result;
    1914     1240294 :   auto table = object();
    1915     1240294 :   if (!ScriptContextTable::Lookup(broker()->isolate(), table,
    1916     2480588 :                                   name.AsString().object(), &lookup_result)) {
    1917     1223032 :     return {};
    1918             :   }
    1919             :   Handle<Context> script_context = ScriptContextTable::GetContext(
    1920       34524 :       broker()->isolate(), table, lookup_result.context_index);
    1921             :   LookupResult result{ContextRef(broker(), script_context),
    1922       17262 :                       lookup_result.mode == VariableMode::kConst,
    1923       17262 :                       lookup_result.slot_index};
    1924             :   return result;
    1925             : }
    1926             : 
    1927    17380564 : OddballType MapRef::oddball_type() const {
    1928    17380564 :   if (instance_type() != ODDBALL_TYPE) {
    1929             :     return OddballType::kNone;
    1930             :   }
    1931    10095222 :   Factory* f = broker()->isolate()->factory();
    1932    10095229 :   if (equals(MapRef(broker(), f->undefined_map()))) {
    1933             :     return OddballType::kUndefined;
    1934             :   }
    1935     9179871 :   if (equals(MapRef(broker(), f->null_map()))) {
    1936             :     return OddballType::kNull;
    1937             :   }
    1938     9147027 :   if (equals(MapRef(broker(), f->boolean_map()))) {
    1939             :     return OddballType::kBoolean;
    1940             :   }
    1941     2478147 :   if (equals(MapRef(broker(), f->the_hole_map()))) {
    1942             :     return OddballType::kHole;
    1943             :   }
    1944      915315 :   if (equals(MapRef(broker(), f->uninitialized_map()))) {
    1945             :     return OddballType::kUninitialized;
    1946             :   }
    1947             :   DCHECK(equals(MapRef(broker(), f->termination_exception_map())) ||
    1948             :          equals(MapRef(broker(), f->arguments_marker_map())) ||
    1949             :          equals(MapRef(broker(), f->optimized_out_map())) ||
    1950             :          equals(MapRef(broker(), f->stale_register_map())));
    1951      913387 :   return OddballType::kOther;
    1952             : }
    1953             : 
    1954       50916 : ObjectRef FeedbackVectorRef::get(FeedbackSlot slot) const {
    1955       50916 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1956             :     AllowHandleAllocation handle_allocation;
    1957             :     AllowHandleDereference handle_dereference;
    1958           0 :     Handle<Object> value(object()->Get(slot)->cast<Object>(),
    1959           0 :                          broker()->isolate());
    1960           0 :     return ObjectRef(broker(), value);
    1961             :   }
    1962             :   int i = FeedbackVector::GetIndex(slot);
    1963      152750 :   return ObjectRef(broker(), data()->AsFeedbackVector()->feedback().at(i));
    1964             : }
    1965             : 
    1966         127 : double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const {
    1967         127 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1968             :     AllowHandleDereference handle_dereference;
    1969             :     return object()->RawFastDoublePropertyAt(index);
    1970             :   }
    1971         127 :   JSObjectData* object_data = data()->AsJSObject();
    1972         127 :   CHECK(index.is_inobject());
    1973         127 :   return object_data->GetInobjectField(index.property_index()).AsDouble();
    1974             : }
    1975             : 
    1976        3225 : ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const {
    1977        3225 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1978             :     AllowHandleAllocation handle_allocation;
    1979             :     AllowHandleDereference handle_dereference;
    1980             :     return ObjectRef(broker(), handle(object()->RawFastPropertyAt(index),
    1981           0 :                                       broker()->isolate()));
    1982             :   }
    1983        3225 :   JSObjectData* object_data = data()->AsJSObject();
    1984        3225 :   CHECK(index.is_inobject());
    1985             :   return ObjectRef(
    1986             :       broker(),
    1987        6450 :       object_data->GetInobjectField(index.property_index()).AsObject());
    1988             : }
    1989             : 
    1990        6190 : bool AllocationSiteRef::IsFastLiteral() const {
    1991        6190 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    1992             :     AllowHeapAllocation allow_heap_allocation;  // For TryMigrateInstance.
    1993             :     AllowHandleAllocation allow_handle_allocation;
    1994             :     AllowHandleDereference allow_handle_dereference;
    1995             :     return IsInlinableFastLiteral(
    1996           0 :         handle(object()->boilerplate(), broker()->isolate()));
    1997             :   }
    1998        6190 :   return data()->AsAllocationSite()->IsFastLiteral();
    1999             : }
    2000             : 
    2001          40 : void JSObjectRef::EnsureElementsTenured() {
    2002          40 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2003             :     AllowHandleAllocation allow_handle_allocation;
    2004             :     AllowHandleDereference allow_handle_dereference;
    2005             :     AllowHeapAllocation allow_heap_allocation;
    2006             : 
    2007           0 :     Handle<FixedArrayBase> object_elements = elements().object();
    2008           0 :     if (Heap::InNewSpace(*object_elements)) {
    2009             :       // If we would like to pretenure a fixed cow array, we must ensure that
    2010             :       // the array is already in old space, otherwise we'll create too many
    2011             :       // old-to-new-space pointers (overflowing the store buffer).
    2012             :       object_elements =
    2013             :           broker()->isolate()->factory()->CopyAndTenureFixedCOWArray(
    2014           0 :               Handle<FixedArray>::cast(object_elements));
    2015           0 :       object()->set_elements(*object_elements);
    2016             :     }
    2017          40 :     return;
    2018             :   }
    2019          80 :   CHECK(data()->AsJSObject()->cow_or_empty_elements_tenured());
    2020             : }
    2021             : 
    2022        3352 : FieldIndex MapRef::GetFieldIndexFor(int descriptor_index) const {
    2023        3352 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2024             :     AllowHandleDereference allow_handle_dereference;
    2025           0 :     return FieldIndex::ForDescriptor(*object(), descriptor_index);
    2026             :   }
    2027        3352 :   DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
    2028        6704 :   return descriptors->contents().at(descriptor_index).field_index;
    2029             : }
    2030             : 
    2031       32997 : int MapRef::GetInObjectPropertyOffset(int i) const {
    2032       32997 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2033             :     AllowHandleDereference allow_handle_dereference;
    2034             :     return object()->GetInObjectPropertyOffset(i);
    2035             :   }
    2036       32993 :   return (GetInObjectPropertiesStartInWords() + i) * kTaggedSize;
    2037             : }
    2038             : 
    2039        9372 : PropertyDetails MapRef::GetPropertyDetails(int descriptor_index) const {
    2040        9372 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2041             :     AllowHandleDereference allow_handle_dereference;
    2042        1864 :     return object()->instance_descriptors()->GetDetails(descriptor_index);
    2043             :   }
    2044        7508 :   DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
    2045       15016 :   return descriptors->contents().at(descriptor_index).details;
    2046             : }
    2047             : 
    2048        3352 : NameRef MapRef::GetPropertyKey(int descriptor_index) const {
    2049        3352 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2050             :     AllowHandleAllocation handle_allocation;
    2051             :     AllowHandleDereference allow_handle_dereference;
    2052             :     return NameRef(
    2053             :         broker(),
    2054           0 :         handle(object()->instance_descriptors()->GetKey(descriptor_index),
    2055           0 :                broker()->isolate()));
    2056             :   }
    2057        3352 :   DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
    2058       10056 :   return NameRef(broker(), descriptors->contents().at(descriptor_index).key);
    2059             : }
    2060             : 
    2061        4237 : bool MapRef::IsFixedCowArrayMap() const {
    2062             :   Handle<Map> fixed_cow_array_map =
    2063        4237 :       ReadOnlyRoots(broker()->isolate()).fixed_cow_array_map_handle();
    2064        4237 :   return equals(MapRef(broker(), fixed_cow_array_map));
    2065             : }
    2066             : 
    2067      111829 : bool MapRef::IsPrimitiveMap() const {
    2068      120375 :   return instance_type() <= LAST_PRIMITIVE_TYPE;
    2069             : }
    2070             : 
    2071        1864 : MapRef MapRef::FindFieldOwner(int descriptor_index) const {
    2072        1864 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2073             :     AllowHandleAllocation handle_allocation;
    2074             :     AllowHandleDereference allow_handle_dereference;
    2075             :     Handle<Map> owner(
    2076             :         object()->FindFieldOwner(broker()->isolate(), descriptor_index),
    2077        5592 :         broker()->isolate());
    2078        1864 :     return MapRef(broker(), owner);
    2079             :   }
    2080           0 :   DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
    2081             :   return MapRef(broker(),
    2082           0 :                 descriptors->contents().at(descriptor_index).field_owner);
    2083             : }
    2084             : 
    2085        1864 : ObjectRef MapRef::GetFieldType(int descriptor_index) const {
    2086        1864 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2087             :     AllowHandleAllocation handle_allocation;
    2088             :     AllowHandleDereference allow_handle_dereference;
    2089             :     Handle<FieldType> field_type(
    2090        3728 :         object()->instance_descriptors()->GetFieldType(descriptor_index),
    2091        5592 :         broker()->isolate());
    2092        1864 :     return ObjectRef(broker(), field_type);
    2093             :   }
    2094           0 :   DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
    2095             :   return ObjectRef(broker(),
    2096           0 :                    descriptors->contents().at(descriptor_index).field_type);
    2097             : }
    2098             : 
    2099        3352 : bool MapRef::IsUnboxedDoubleField(int descriptor_index) const {
    2100        3352 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2101             :     AllowHandleDereference allow_handle_dereference;
    2102             :     return object()->IsUnboxedDoubleField(
    2103           0 :         FieldIndex::ForDescriptor(*object(), descriptor_index));
    2104             :   }
    2105        3352 :   DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors();
    2106        6704 :   return descriptors->contents().at(descriptor_index).is_unboxed_double_field;
    2107             : }
    2108             : 
    2109          99 : uint16_t StringRef::GetFirstChar() {
    2110          99 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2111             :     AllowHandleDereference allow_handle_dereference;
    2112           0 :     return object()->Get(0);
    2113             :   }
    2114          99 :   return data()->AsString()->first_char();
    2115             : }
    2116             : 
    2117        1240 : base::Optional<double> StringRef::ToNumber() {
    2118        1240 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2119             :     AllowHandleDereference allow_handle_dereference;
    2120             :     AllowHandleAllocation allow_handle_allocation;
    2121             :     AllowHeapAllocation allow_heap_allocation;
    2122             :     int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
    2123           0 :     return StringToDouble(broker()->isolate(), object(), flags);
    2124             :   }
    2125        1240 :   return data()->AsString()->to_number();
    2126             : }
    2127             : 
    2128         281 : uint32_t InternalizedStringRef::array_index() const {
    2129         281 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2130             :     AllowHandleDereference allow_handle_dereference;
    2131             :     AllowHandleAllocation allow_handle_allocation;
    2132             :     uint32_t result;
    2133         281 :     if (!object()->AsArrayIndex(&result)) {
    2134         281 :       result = kNotAnArrayIndex;
    2135             :     }
    2136         281 :     return result;
    2137             :   }
    2138           0 :   return data()->AsInternalizedString()->array_index();
    2139             : }
    2140             : 
    2141        7002 : ObjectRef FixedArrayRef::get(int i) const {
    2142        7002 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2143             :     AllowHandleAllocation handle_allocation;
    2144             :     AllowHandleDereference allow_handle_dereference;
    2145         612 :     return ObjectRef(broker(), handle(object()->get(i), broker()->isolate()));
    2146             :   }
    2147       13392 :   return ObjectRef(broker(), data()->AsFixedArray()->Get(i));
    2148             : }
    2149             : 
    2150        6494 : bool FixedDoubleArrayRef::is_the_hole(int i) const {
    2151        6494 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2152             :     AllowHandleDereference allow_handle_dereference;
    2153             :     return object()->is_the_hole(i);
    2154             :   }
    2155       12988 :   return data()->AsFixedDoubleArray()->Get(i).is_hole_nan();
    2156             : }
    2157             : 
    2158        6395 : double FixedDoubleArrayRef::get_scalar(int i) const {
    2159        6395 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2160             :     AllowHandleDereference allow_handle_dereference;
    2161             :     return object()->get_scalar(i);
    2162             :   }
    2163       12790 :   CHECK(!data()->AsFixedDoubleArray()->Get(i).is_hole_nan());
    2164       12790 :   return data()->AsFixedDoubleArray()->Get(i).get_scalar();
    2165             : }
    2166             : 
    2167             : #define IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name) \
    2168             :   if (broker()->mode() == JSHeapBroker::kDisabled) {     \
    2169             :     AllowHandleAllocation handle_allocation;             \
    2170             :     AllowHandleDereference allow_handle_dereference;     \
    2171             :     return object()->name();                             \
    2172             :   }
    2173             : 
    2174             : #define IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name)         \
    2175             :   if (broker()->mode() == JSHeapBroker::kDisabled) {                   \
    2176             :     AllowHandleAllocation handle_allocation;                           \
    2177             :     AllowHandleDereference allow_handle_dereference;                   \
    2178             :     return result##Ref(broker(),                                       \
    2179             :                        handle(object()->name(), broker()->isolate())); \
    2180             :   }
    2181             : 
    2182             : // Macros for definining a const getter that, depending on the broker mode,
    2183             : // either looks into the handle or into the serialized data.
    2184             : #define BIMODAL_ACCESSOR(holder, result, name)                             \
    2185             :   result##Ref holder##Ref::name() const {                                  \
    2186             :     IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name);                \
    2187             :     return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \
    2188             :   }
    2189             : 
    2190             : // Like above except that the result type is not an XYZRef.
    2191             : #define BIMODAL_ACCESSOR_C(holder, result, name)      \
    2192             :   result holder##Ref::name() const {                  \
    2193             :     IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name); \
    2194             :     return ObjectRef::data()->As##holder()->name();   \
    2195             :   }
    2196             : 
    2197             : // Like above but for BitFields.
    2198             : #define BIMODAL_ACCESSOR_B(holder, field, name, BitField)              \
    2199             :   typename BitField::FieldType holder##Ref::name() const {             \
    2200             :     IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name);                  \
    2201             :     return BitField::decode(ObjectRef::data()->As##holder()->field()); \
    2202             :   }
    2203             : 
    2204       37254 : BIMODAL_ACCESSOR(AllocationSite, Object, nested_site)
    2205        1106 : BIMODAL_ACCESSOR_C(AllocationSite, bool, CanInlineCall)
    2206       15648 : BIMODAL_ACCESSOR_C(AllocationSite, bool, PointsToLiteral)
    2207        6460 : BIMODAL_ACCESSOR_C(AllocationSite, ElementsKind, GetElementsKind)
    2208       15170 : BIMODAL_ACCESSOR_C(AllocationSite, PretenureFlag, GetPretenureMode)
    2209             : 
    2210        1470 : BIMODAL_ACCESSOR_C(BytecodeArray, int, register_count)
    2211             : 
    2212       64102 : BIMODAL_ACCESSOR(Cell, Object, value)
    2213             : 
    2214   210648926 : BIMODAL_ACCESSOR(HeapObject, Map, map)
    2215             : 
    2216       12468 : BIMODAL_ACCESSOR(JSArray, Object, length)
    2217             : 
    2218        1316 : BIMODAL_ACCESSOR(JSBoundFunction, Object, bound_target_function)
    2219        1120 : BIMODAL_ACCESSOR(JSBoundFunction, Object, bound_this)
    2220        1316 : BIMODAL_ACCESSOR(JSBoundFunction, FixedArray, bound_arguments)
    2221             : 
    2222         868 : BIMODAL_ACCESSOR_C(JSDataView, size_t, byte_length)
    2223         434 : BIMODAL_ACCESSOR_C(JSDataView, size_t, byte_offset)
    2224             : 
    2225      171546 : BIMODAL_ACCESSOR_C(JSFunction, bool, has_prototype)
    2226       31092 : BIMODAL_ACCESSOR_C(JSFunction, bool, has_initial_map)
    2227      171102 : BIMODAL_ACCESSOR_C(JSFunction, bool, PrototypeRequiresRuntimeLookup)
    2228        6216 : BIMODAL_ACCESSOR(JSFunction, Context, context)
    2229     2226580 : BIMODAL_ACCESSOR(JSFunction, NativeContext, native_context)
    2230      131083 : BIMODAL_ACCESSOR(JSFunction, Map, initial_map)
    2231      227568 : BIMODAL_ACCESSOR(JSFunction, Object, prototype)
    2232     2748832 : BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared)
    2233             : 
    2234        6018 : BIMODAL_ACCESSOR_C(JSTypedArray, bool, is_on_heap)
    2235        2530 : BIMODAL_ACCESSOR_C(JSTypedArray, size_t, length_value)
    2236        5060 : BIMODAL_ACCESSOR(JSTypedArray, HeapObject, buffer)
    2237             : 
    2238     1934318 : BIMODAL_ACCESSOR_B(Map, bit_field2, elements_kind, Map::ElementsKindBits)
    2239           0 : BIMODAL_ACCESSOR_B(Map, bit_field2, is_extensible, Map::IsExtensibleBit)
    2240           0 : BIMODAL_ACCESSOR_B(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit)
    2241       15210 : BIMODAL_ACCESSOR_B(Map, bit_field3, is_dictionary_map, Map::IsDictionaryMapBit)
    2242       26652 : BIMODAL_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors,
    2243             :                    Map::NumberOfOwnDescriptorsBits)
    2244         489 : BIMODAL_ACCESSOR_B(Map, bit_field3, has_hidden_prototype,
    2245             :                    Map::HasHiddenPrototypeBit)
    2246      243788 : BIMODAL_ACCESSOR_B(Map, bit_field, has_prototype_slot, Map::HasPrototypeSlotBit)
    2247           0 : BIMODAL_ACCESSOR_B(Map, bit_field, is_access_check_needed,
    2248             :                    Map::IsAccessCheckNeededBit)
    2249    69336890 : BIMODAL_ACCESSOR_B(Map, bit_field, is_callable, Map::IsCallableBit)
    2250      155767 : BIMODAL_ACCESSOR_B(Map, bit_field, is_constructor, Map::IsConstructorBit)
    2251    69313798 : BIMODAL_ACCESSOR_B(Map, bit_field, is_undetectable, Map::IsUndetectableBit)
    2252      142783 : BIMODAL_ACCESSOR_C(Map, int, instance_size)
    2253        2817 : BIMODAL_ACCESSOR_C(Map, int, NextFreePropertyIndex)
    2254           0 : BIMODAL_ACCESSOR_C(Map, int, UnusedPropertyFields)
    2255      271285 : BIMODAL_ACCESSOR(Map, Object, prototype)
    2256   104700144 : BIMODAL_ACCESSOR_C(Map, InstanceType, instance_type)
    2257       27975 : BIMODAL_ACCESSOR(Map, Object, GetConstructor)
    2258             : 
    2259             : #define DEF_NATIVE_CONTEXT_ACCESSOR(type, name) \
    2260             :   BIMODAL_ACCESSOR(NativeContext, type, name)
    2261     5487242 : BROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR)
    2262             : #undef DEF_NATIVE_CONTEXT_ACCESSOR
    2263             : 
    2264           0 : BIMODAL_ACCESSOR(PropertyCell, Object, value)
    2265     3609437 : BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details)
    2266             : 
    2267      371859 : BIMODAL_ACCESSOR_C(SharedFunctionInfo, int, builtin_id)
    2268        1470 : BIMODAL_ACCESSOR(SharedFunctionInfo, BytecodeArray, GetBytecodeArray)
    2269             : #define DEF_SFI_ACCESSOR(type, name) \
    2270             :   BIMODAL_ACCESSOR_C(SharedFunctionInfo, type, name)
    2271     6442201 : BROKER_SFI_FIELDS(DEF_SFI_ACCESSOR)
    2272             : #undef DEF_SFI_ACCESSOR
    2273             : 
    2274      186182 : BIMODAL_ACCESSOR_C(String, int, length)
    2275             : 
    2276        1265 : void* JSTypedArrayRef::elements_external_pointer() const {
    2277        1265 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2278             :     AllowHandleDereference allow_handle_dereference;
    2279        2530 :     return FixedTypedArrayBase::cast(object()->elements())->external_pointer();
    2280             :   }
    2281           0 :   return data()->AsJSTypedArray()->elements_external_pointer();
    2282             : }
    2283             : 
    2284          29 : bool MapRef::IsInobjectSlackTrackingInProgress() const {
    2285          29 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, IsInobjectSlackTrackingInProgress);
    2286          29 :   return Map::ConstructionCounterBits::decode(data()->AsMap()->bit_field3()) !=
    2287          29 :          Map::kNoSlackTracking;
    2288             : }
    2289             : 
    2290        8546 : int MapRef::constructor_function_index() const {
    2291        8546 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetConstructorFunctionIndex);
    2292           0 :   CHECK(IsPrimitiveMap());
    2293           0 :   return data()->AsMap()->constructor_function_index();
    2294             : }
    2295             : 
    2296      176016 : bool MapRef::is_stable() const {
    2297      336943 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, is_stable);
    2298       30180 :   return !Map::IsUnstableBit::decode(data()->AsMap()->bit_field3());
    2299             : }
    2300             : 
    2301       17873 : bool MapRef::CanBeDeprecated() const {
    2302       35746 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanBeDeprecated);
    2303           0 :   CHECK_GT(NumberOfOwnDescriptors(), 0);
    2304           0 :   return data()->AsMap()->can_be_deprecated();
    2305             : }
    2306             : 
    2307      161346 : bool MapRef::CanTransition() const {
    2308      161346 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanTransition);
    2309          57 :   return data()->AsMap()->can_transition();
    2310             : }
    2311             : 
    2312       39459 : int MapRef::GetInObjectPropertiesStartInWords() const {
    2313       39459 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectPropertiesStartInWords);
    2314       39458 :   return data()->AsMap()->in_object_properties_start_in_words();
    2315             : }
    2316             : 
    2317       76768 : int MapRef::GetInObjectProperties() const {
    2318       77871 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectProperties);
    2319       75665 :   return data()->AsMap()->in_object_properties();
    2320             : }
    2321             : 
    2322        8845 : int ScopeInfoRef::ContextLength() const {
    2323        8845 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, ContextLength);
    2324        8845 :   return data()->AsScopeInfo()->context_length();
    2325             : }
    2326             : 
    2327           7 : bool StringRef::IsExternalString() const {
    2328           7 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsExternalString);
    2329           7 :   return data()->AsString()->is_external_string();
    2330             : }
    2331             : 
    2332         751 : bool StringRef::IsSeqString() const {
    2333         751 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsSeqString);
    2334         751 :   return data()->AsString()->is_seq_string();
    2335             : }
    2336             : 
    2337       32335 : MapRef NativeContextRef::GetFunctionMapFromIndex(int index) const {
    2338             :   DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX);
    2339             :   DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
    2340       32335 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2341           0 :     return get(index).AsMap();
    2342             :   }
    2343       32335 :   return MapRef(broker(), data()->AsNativeContext()->function_maps().at(
    2344       97005 :                               index - Context::FIRST_FUNCTION_MAP_INDEX));
    2345             : }
    2346             : 
    2347        2204 : MapRef NativeContextRef::GetInitialJSArrayMap(ElementsKind kind) const {
    2348        2204 :   switch (kind) {
    2349             :     case PACKED_SMI_ELEMENTS:
    2350        1019 :       return js_array_packed_smi_elements_map();
    2351             :     case HOLEY_SMI_ELEMENTS:
    2352          38 :       return js_array_holey_smi_elements_map();
    2353             :     case PACKED_DOUBLE_ELEMENTS:
    2354          49 :       return js_array_packed_double_elements_map();
    2355             :     case HOLEY_DOUBLE_ELEMENTS:
    2356         347 :       return js_array_holey_double_elements_map();
    2357             :     case PACKED_ELEMENTS:
    2358         423 :       return js_array_packed_elements_map();
    2359             :     case HOLEY_ELEMENTS:
    2360         328 :       return js_array_holey_elements_map();
    2361             :     default:
    2362           0 :       UNREACHABLE();
    2363             :   }
    2364             : }
    2365             : 
    2366        8546 : base::Optional<JSFunctionRef> NativeContextRef::GetConstructorFunction(
    2367             :     const MapRef& map) const {
    2368        8546 :   CHECK(map.IsPrimitiveMap());
    2369        8546 :   switch (map.constructor_function_index()) {
    2370             :     case Map::kNoConstructorFunctionIndex:
    2371             :       return base::nullopt;
    2372             :     case Context::BIGINT_FUNCTION_INDEX:
    2373           0 :       return bigint_function();
    2374             :     case Context::BOOLEAN_FUNCTION_INDEX:
    2375        1062 :       return boolean_function();
    2376             :     case Context::NUMBER_FUNCTION_INDEX:
    2377        3302 :       return number_function();
    2378             :     case Context::STRING_FUNCTION_INDEX:
    2379       12658 :       return string_function();
    2380             :     case Context::SYMBOL_FUNCTION_INDEX:
    2381          70 :       return symbol_function();
    2382             :     default:
    2383           0 :       UNREACHABLE();
    2384             :   }
    2385             : }
    2386             : 
    2387         280 : bool ObjectRef::IsNullOrUndefined() const {
    2388         280 :   if (IsSmi()) return false;
    2389         280 :   OddballType type = AsHeapObject().map().oddball_type();
    2390         280 :   return type == OddballType::kNull || type == OddballType::kUndefined;
    2391             : }
    2392             : 
    2393      121428 : bool ObjectRef::BooleanValue() const {
    2394      121428 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2395             :     AllowHandleDereference allow_handle_dereference;
    2396       18620 :     return object()->BooleanValue(broker()->isolate());
    2397             :   }
    2398      112119 :   return IsSmi() ? (AsSmi() != 0) : data()->AsHeapObject()->boolean_value();
    2399             : }
    2400             : 
    2401        1198 : double ObjectRef::OddballToNumber() const {
    2402        1198 :   OddballType type = AsHeapObject().map().oddball_type();
    2403             : 
    2404        1198 :   switch (type) {
    2405             :     case OddballType::kBoolean: {
    2406             :       ObjectRef true_ref(broker(),
    2407        1150 :                          broker()->isolate()->factory()->true_value());
    2408         575 :       return this->equals(true_ref) ? 1 : 0;
    2409             :       break;
    2410             :     }
    2411             :     case OddballType::kUndefined: {
    2412             :       return std::numeric_limits<double>::quiet_NaN();
    2413             :       break;
    2414             :     }
    2415             :     case OddballType::kNull: {
    2416         155 :       return 0;
    2417             :       break;
    2418             :     }
    2419             :     default: {
    2420           0 :       UNREACHABLE();
    2421             :       break;
    2422             :     }
    2423             :   }
    2424             : }
    2425             : 
    2426     2389631 : double HeapNumberRef::value() const {
    2427     2389631 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(HeapNumber, value);
    2428         154 :   return data()->AsHeapNumber()->value();
    2429             : }
    2430             : 
    2431           0 : double MutableHeapNumberRef::value() const {
    2432           0 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(MutableHeapNumber, value);
    2433           0 :   return data()->AsMutableHeapNumber()->value();
    2434             : }
    2435             : 
    2436         141 : CellRef ModuleRef::GetCell(int cell_index) const {
    2437         141 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2438             :     AllowHandleAllocation handle_allocation;
    2439             :     AllowHandleDereference allow_handle_dereference;
    2440             :     return CellRef(broker(),
    2441           0 :                    handle(object()->GetCell(cell_index), broker()->isolate()));
    2442             :   }
    2443         282 :   return CellRef(broker(), data()->AsModule()->GetCell(cell_index));
    2444             : }
    2445             : 
    2446   159576553 : ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object)
    2447    72419201 :     : broker_(broker) {
    2448    72419201 :   switch (broker->mode()) {
    2449             :     case JSHeapBroker::kSerialized:
    2450    51257096 :       data_ = broker->GetData(object);
    2451    51257096 :       break;
    2452             :     case JSHeapBroker::kSerializing:
    2453     9198184 :       data_ = broker->GetOrCreateData(object);
    2454     9198177 :       break;
    2455             :     case JSHeapBroker::kDisabled: {
    2456             :       RefsMap::Entry* entry =
    2457    11964353 :           broker->refs_->LookupOrInsert(object.address(), broker->zone());
    2458    11964368 :       ObjectData** storage = &(entry->value);
    2459    11964368 :       if (*storage == nullptr) {
    2460             :         AllowHandleDereference handle_dereference;
    2461             :         entry->value = new (broker->zone())
    2462             :             ObjectData(broker, storage, object,
    2463    11095188 :                        object->IsSmi() ? kSmi : kUnserializedHeapObject);
    2464             :       }
    2465    11964363 :       data_ = *storage;
    2466    11964363 :       break;
    2467             :     }
    2468             :     case JSHeapBroker::kRetired:
    2469           0 :       UNREACHABLE();
    2470             :   }
    2471    72419542 :   CHECK_NOT_NULL(data_);
    2472    72419542 : }
    2473             : 
    2474             : namespace {
    2475     2299923 : OddballType GetOddballType(Isolate* isolate, Map map) {
    2476     2299923 :   if (map->instance_type() != ODDBALL_TYPE) {
    2477             :     return OddballType::kNone;
    2478             :   }
    2479             :   ReadOnlyRoots roots(isolate);
    2480      520559 :   if (map == roots.undefined_map()) {
    2481             :     return OddballType::kUndefined;
    2482             :   }
    2483      483204 :   if (map == roots.null_map()) {
    2484             :     return OddballType::kNull;
    2485             :   }
    2486      482904 :   if (map == roots.boolean_map()) {
    2487             :     return OddballType::kBoolean;
    2488             :   }
    2489      469045 :   if (map == roots.the_hole_map()) {
    2490             :     return OddballType::kHole;
    2491             :   }
    2492      468366 :   if (map == roots.uninitialized_map()) {
    2493             :     return OddballType::kUninitialized;
    2494             :   }
    2495             :   DCHECK(map == roots.termination_exception_map() ||
    2496             :          map == roots.arguments_marker_map() ||
    2497             :          map == roots.optimized_out_map() || map == roots.stale_register_map());
    2498           0 :   return OddballType::kOther;
    2499             : }
    2500             : }  // namespace
    2501             : 
    2502    19625041 : HeapObjectType HeapObjectRef::GetHeapObjectType() const {
    2503    19625041 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2504             :     AllowHandleDereference handle_dereference;
    2505     4599844 :     Map map = Handle<HeapObject>::cast(object())->map();
    2506             :     HeapObjectType::Flags flags(0);
    2507     2299922 :     if (map->is_undetectable()) flags |= HeapObjectType::kUndetectable;
    2508     2299922 :     if (map->is_callable()) flags |= HeapObjectType::kCallable;
    2509             :     return HeapObjectType(map->instance_type(), flags,
    2510     4599845 :                           GetOddballType(broker()->isolate(), map));
    2511             :   }
    2512             :   HeapObjectType::Flags flags(0);
    2513    17325119 :   if (map().is_undetectable()) flags |= HeapObjectType::kUndetectable;
    2514    17325133 :   if (map().is_callable()) flags |= HeapObjectType::kCallable;
    2515    17325119 :   return HeapObjectType(map().instance_type(), flags, map().oddball_type());
    2516             : }
    2517       12179 : base::Optional<JSObjectRef> AllocationSiteRef::boilerplate() const {
    2518       12179 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2519             :     AllowHandleAllocation handle_allocation;
    2520             :     AllowHandleDereference allow_handle_dereference;
    2521             :     return JSObjectRef(broker(),
    2522           0 :                        handle(object()->boilerplate(), broker()->isolate()));
    2523             :   }
    2524       12179 :   JSObjectData* boilerplate = data()->AsAllocationSite()->boilerplate();
    2525       12179 :   if (boilerplate) {
    2526             :     return JSObjectRef(broker(), boilerplate);
    2527             :   } else {
    2528             :     return base::nullopt;
    2529             :   }
    2530             : }
    2531             : 
    2532       10365 : ElementsKind JSObjectRef::GetElementsKind() const {
    2533       10365 :   return map().elements_kind();
    2534             : }
    2535             : 
    2536        7305 : FixedArrayBaseRef JSObjectRef::elements() const {
    2537        7305 :   if (broker()->mode() == JSHeapBroker::kDisabled) {
    2538             :     AllowHandleAllocation handle_allocation;
    2539             :     AllowHandleDereference allow_handle_dereference;
    2540             :     return FixedArrayBaseRef(broker(),
    2541           0 :                              handle(object()->elements(), broker()->isolate()));
    2542             :   }
    2543       14610 :   return FixedArrayBaseRef(broker(), data()->AsJSObject()->elements());
    2544             : }
    2545             : 
    2546       13961 : int FixedArrayBaseRef::length() const {
    2547       13961 :   IF_BROKER_DISABLED_ACCESS_HANDLE_C(FixedArrayBase, length);
    2548       13326 :   return data()->AsFixedArrayBase()->length();
    2549             : }
    2550             : 
    2551        6696 : ObjectData* FixedArrayData::Get(int i) const {
    2552       13392 :   CHECK_LT(i, static_cast<int>(contents_.size()));
    2553       13392 :   CHECK_NOT_NULL(contents_[i]);
    2554        6696 :   return contents_[i];
    2555             : }
    2556             : 
    2557       19284 : Float64 FixedDoubleArrayData::Get(int i) const {
    2558       38568 :   CHECK_LT(i, static_cast<int>(contents_.size()));
    2559       38568 :   return contents_[i];
    2560             : }
    2561             : 
    2562       50964 : void FeedbackVectorRef::SerializeSlots() {
    2563       50964 :   data()->AsFeedbackVector()->SerializeSlots(broker());
    2564       50964 : }
    2565             : 
    2566         602 : ObjectRef JSRegExpRef::data() const {
    2567         602 :   IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, data);
    2568        1204 :   return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->data());
    2569             : }
    2570             : 
    2571         602 : ObjectRef JSRegExpRef::flags() const {
    2572         602 :   IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, flags);
    2573        1204 :   return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->flags());
    2574             : }
    2575             : 
    2576         602 : ObjectRef JSRegExpRef::last_index() const {
    2577         602 :   IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, last_index);
    2578        1204 :   return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->last_index());
    2579             : }
    2580             : 
    2581         602 : ObjectRef JSRegExpRef::raw_properties_or_hash() const {
    2582         602 :   IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, raw_properties_or_hash);
    2583             :   return ObjectRef(broker(),
    2584        1204 :                    ObjectRef::data()->AsJSRegExp()->raw_properties_or_hash());
    2585             : }
    2586             : 
    2587         602 : ObjectRef JSRegExpRef::source() const {
    2588         602 :   IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, source);
    2589        1204 :   return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->source());
    2590             : }
    2591             : 
    2592      911473 : Handle<Object> ObjectRef::object() const { return data_->object(); }
    2593             : 
    2594             : #define DEF_OBJECT_GETTER(T)                                                 \
    2595             :   Handle<T> T##Ref::object() const {                                         \
    2596             :     return Handle<T>(reinterpret_cast<Address*>(data_->object().address())); \
    2597             :   }
    2598    43192191 : HEAP_BROKER_OBJECT_LIST(DEF_OBJECT_GETTER)
    2599             : #undef DEF_OBJECT_GETTER
    2600             : 
    2601   533817950 : JSHeapBroker* ObjectRef::broker() const { return broker_; }
    2602             : 
    2603   227708673 : ObjectData* ObjectRef::data() const {
    2604   227708673 :   switch (broker()->mode()) {
    2605             :     case JSHeapBroker::kDisabled:
    2606   227708673 :       CHECK_NE(data_->kind(), kSerializedHeapObject);
    2607             :       return data_;
    2608             :     case JSHeapBroker::kSerializing:
    2609             :     case JSHeapBroker::kSerialized:
    2610   412529896 :       CHECK_NE(data_->kind(), kUnserializedHeapObject);
    2611             :       return data_;
    2612             :     case JSHeapBroker::kRetired:
    2613           0 :       UNREACHABLE();
    2614             :   }
    2615           0 : }
    2616             : 
    2617           0 : Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
    2618             :                                        const char* function, int line) {
    2619           0 :   if (FLAG_trace_heap_broker) {
    2620             :     PrintF("[%p] Skipping optimization in %s at line %d due to missing data\n",
    2621           0 :            broker, function, line);
    2622             :   }
    2623           0 :   return AdvancedReducer::NoChange();
    2624             : }
    2625             : 
    2626      912389 : NativeContextData::NativeContextData(JSHeapBroker* broker, ObjectData** storage,
    2627             :                                      Handle<NativeContext> object)
    2628      912382 :     : ContextData(broker, storage, object), function_maps_(broker->zone()) {}
    2629             : 
    2630      912283 : void NativeContextData::Serialize(JSHeapBroker* broker) {
    2631      456129 :   if (serialized_) return;
    2632      456129 :   serialized_ = true;
    2633             : 
    2634      456129 :   TraceScope tracer(broker, this, "NativeContextData::Serialize");
    2635      456141 :   Handle<NativeContext> context = Handle<NativeContext>::cast(object());
    2636             : 
    2637             : #define SERIALIZE_MEMBER(type, name)                                       \
    2638             :   DCHECK_NULL(name##_);                                                    \
    2639             :   name##_ = broker->GetOrCreateData(context->name())->As##type();          \
    2640             :   if (name##_->IsJSFunction()) name##_->AsJSFunction()->Serialize(broker); \
    2641             :   if (name##_->IsMap()) name##_->AsMap()->SerializeConstructor(broker);
    2642    14140769 :   BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(SERIALIZE_MEMBER)
    2643      456154 :   if (!broker->isolate()->bootstrapper()->IsActive()) {
    2644     2732898 :     BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(SERIALIZE_MEMBER)
    2645             :   }
    2646             : #undef SERIALIZE_MEMBER
    2647             : 
    2648      456154 :   bound_function_with_constructor_map_->SerializePrototype(broker);
    2649      456154 :   bound_function_without_constructor_map_->SerializePrototype(broker);
    2650             : 
    2651             :   DCHECK(function_maps_.empty());
    2652             :   int const first = Context::FIRST_FUNCTION_MAP_INDEX;
    2653             :   int const last = Context::LAST_FUNCTION_MAP_INDEX;
    2654      456154 :   function_maps_.reserve(last + 1 - first);
    2655    11403826 :   for (int i = first; i <= last; ++i) {
    2656    32843041 :     function_maps_.push_back(broker->GetOrCreateData(context->get(i))->AsMap());
    2657             :   }
    2658             : }
    2659             : 
    2660     1837025 : void JSFunctionRef::Serialize() {
    2661     3674053 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2662     1388632 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2663     1388632 :   data()->AsJSFunction()->Serialize(broker());
    2664             : }
    2665             : 
    2666           0 : void JSFunctionRef::SetSerializedForCompilation() {
    2667           0 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2668           0 :   data()->AsJSFunction()->SetSerializedForCompilation(broker());
    2669           0 : }
    2670             : 
    2671           0 : bool JSFunctionRef::serialized_for_compilation() const {
    2672           0 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2673           0 :   return data()->AsJSFunction()->serialized_for_compilation();
    2674             : }
    2675             : 
    2676     1626593 : void JSObjectRef::SerializeObjectCreateMap() {
    2677     3253185 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2678     1626594 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2679     1626594 :   data()->AsJSObject()->SerializeObjectCreateMap(broker());
    2680             : }
    2681             : 
    2682        1864 : void MapRef::SerializeOwnDescriptors() {
    2683        3728 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2684           0 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2685           0 :   data()->AsMap()->SerializeOwnDescriptors(broker());
    2686             : }
    2687             : 
    2688       90308 : void MapRef::SerializePrototype() {
    2689      180616 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2690           0 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2691           0 :   data()->AsMap()->SerializePrototype(broker());
    2692             : }
    2693             : 
    2694         172 : void ModuleRef::Serialize() {
    2695         344 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2696         172 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2697         172 :   data()->AsModule()->Serialize(broker());
    2698             : }
    2699             : 
    2700     1342021 : void ContextRef::Serialize() {
    2701     2684044 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2702     1069390 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2703     1069390 :   data()->AsContext()->Serialize(broker());
    2704             : }
    2705             : 
    2706      456128 : void NativeContextRef::Serialize() {
    2707      912264 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2708      456146 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2709      456146 :   data()->AsNativeContext()->Serialize(broker());
    2710             : }
    2711             : 
    2712        1265 : void JSTypedArrayRef::Serialize() {
    2713        2530 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2714           0 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2715           0 :   data()->AsJSTypedArray()->Serialize(broker());
    2716             : }
    2717             : 
    2718         329 : void JSBoundFunctionRef::Serialize() {
    2719         658 :   if (broker()->mode() == JSHeapBroker::kDisabled) return;
    2720           0 :   CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing);
    2721           0 :   data()->AsJSBoundFunction()->Serialize(broker());
    2722             : }
    2723             : 
    2724             : #undef BIMODAL_ACCESSOR
    2725             : #undef BIMODAL_ACCESSOR_B
    2726             : #undef BIMODAL_ACCESSOR_C
    2727             : #undef IF_BROKER_DISABLED_ACCESS_HANDLE
    2728             : #undef IF_BROKER_DISABLED_ACCESS_HANDLE_C
    2729             : #undef TRACE
    2730             : 
    2731             : }  // namespace compiler
    2732             : }  // namespace internal
    2733      183867 : }  // namespace v8

Generated by: LCOV version 1.10