From 03c9de73480184574fe103a13201174068809e3a Mon Sep 17 00:00:00 2001 From: Nico Hartmann Date: Wed, 18 Dec 2019 10:40:36 +0000 Subject: [PATCH] Revert "[TurboFan] Don't serialize read-only heap objects" This reverts commit 9f18e55ff0836339acd138284b104619b38fa1d9. Reason for revert: https://ci.chromium.org/p/v8/builders/ci/V8%20Linux64%20TSAN/29660 Original change's description: > [TurboFan] Don't serialize read-only heap objects > > Read-only heap objects are immutable and immovable. It is safe to access > these objects directly from the heap. Not having to serialize them > reduces the time we spend on main thread especially for TurboProp. > > Bug: v8:9684 > Change-Id: Ibabb7076af50c9007d2a8ed57fe257406958fb6a > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1955596 > Reviewed-by: Michael Stanton > Reviewed-by: Maya Lekova > Commit-Queue: Mythri Alle > Cr-Commit-Position: refs/heads/master@{#65490} TBR=mvstanton@chromium.org,neis@chromium.org,mythria@chromium.org,mslekova@chromium.org Change-Id: If2d8649cdc083f7d064684352501320a96a1ba2c No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: v8:9684 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1973732 Reviewed-by: Nico Hartmann Commit-Queue: Nico Hartmann Cr-Commit-Position: refs/heads/master@{#65492} --- src/compiler/js-heap-broker.cc | 948 ++++++++++++++------------------- src/compiler/js-heap-broker.h | 15 +- 2 files changed, 410 insertions(+), 553 deletions(-) diff --git a/src/compiler/js-heap-broker.cc b/src/compiler/js-heap-broker.cc index 361f336fbd..ca214d2a16 100644 --- a/src/compiler/js-heap-broker.cc +++ b/src/compiler/js-heap-broker.cc @@ -60,63 +60,7 @@ HEAP_BROKER_OBJECT_LIST(FORWARD_DECL) // data is an instance of the base class (ObjectData), i.e. it basically // carries no information other than the handle. // -// kUnserializedReadOnlyHeapObject: The underlying V8 object is a read-only -// HeapObject and the data is an instance of ObjectData. For -// ReadOnlyHeapObjects, it is OK to access heap even from off-thread, so -// these objects need not be serialized. -enum ObjectDataKind { - kSmi, - kSerializedHeapObject, - kUnserializedHeapObject, - kUnserializedReadOnlyHeapObject -}; - -class AllowHandleAllocationIf { - public: - explicit AllowHandleAllocationIf(ObjectDataKind kind, - JSHeapBroker::BrokerMode mode) { - DCHECK_IMPLIES(mode == JSHeapBroker::BrokerMode::kSerialized, - kind == kUnserializedReadOnlyHeapObject); - if (kind == kUnserializedHeapObject) maybe_allow_handle_.emplace(); - } - - private: - base::Optional maybe_allow_handle_; -}; - -class AllowHandleDereferenceIf { - public: - explicit AllowHandleDereferenceIf(ObjectDataKind kind, - JSHeapBroker::BrokerMode mode) { - DCHECK_IMPLIES(mode == JSHeapBroker::BrokerMode::kSerialized, - kind == kUnserializedReadOnlyHeapObject); - if (kind == kUnserializedHeapObject || - kind == kUnserializedReadOnlyHeapObject) - maybe_allow_handle_.emplace(); - } - - explicit AllowHandleDereferenceIf(ObjectDataKind kind) { - if (kind == kUnserializedHeapObject || - kind == kUnserializedReadOnlyHeapObject) - maybe_allow_handle_.emplace(); - } - - private: - base::Optional maybe_allow_handle_; -}; - -class AllowHeapAllocationIf { - public: - explicit AllowHeapAllocationIf(ObjectDataKind kind, - JSHeapBroker::BrokerMode mode) { - DCHECK_IMPLIES(mode == JSHeapBroker::BrokerMode::kSerialized, - kind == kUnserializedReadOnlyHeapObject); - if (kind == kUnserializedHeapObject) maybe_allow_handle_.emplace(); - } - - private: - base::Optional maybe_allow_handle_; -}; +enum ObjectDataKind { kSmi, kSerializedHeapObject, kUnserializedHeapObject }; class ObjectData : public ZoneObject { public: @@ -130,16 +74,7 @@ class ObjectData : public ZoneObject { TRACE(broker, "Creating data " << this << " for handle " << object.address() << " (" << Brief(*object) << ")"); - // It is safe to access read only heap objects and builtins from a - // background thread. When we read fileds of these objects, we may create - // ObjectData on the background thread even without a canonical handle - // scope. This is safe too since we don't create handles but just get - // handles from read only root table or builtins table which is what - // canonical scope uses as well. For all other objects we should have - // created ObjectData in canonical handle scope on the main thread. - CHECK(broker->isolate()->handle_scope_data()->canonical_scope != nullptr || - ReadOnlyHeap::Contains(HeapObject::cast(*object)) || - (Code::cast(*object).is_builtin())); + CHECK_NOT_NULL(broker->isolate()->handle_scope_data()->canonical_scope); } #define DECLARE_IS_AND_AS(Name) \ @@ -151,10 +86,6 @@ class ObjectData : public ZoneObject { Handle object() const { return object_; } ObjectDataKind kind() const { return kind_; } bool is_smi() const { return kind_ == kSmi; } - bool should_access_heap() const { - return kind_ == kUnserializedHeapObject || - kind_ == kUnserializedReadOnlyHeapObject; - } #ifdef DEBUG enum class Usage{kUnused, kOnlyIdentityUsed, kDataUsed}; @@ -172,15 +103,14 @@ class HeapObjectData : public ObjectData { Handle object); bool boolean_value() const { return boolean_value_; } - ObjectData* map() const { return map_; } - InstanceType GetMapInstanceType() const; + MapData* map() const { return map_; } static HeapObjectData* Serialize(JSHeapBroker* broker, Handle object); private: bool const boolean_value_; - ObjectData* const map_; + MapData* const map_; }; class PropertyCellData : public HeapObjectData { @@ -342,12 +272,11 @@ class JSObjectData : public JSReceiverData { // Shallow serialization of {elements}. void SerializeElements(JSHeapBroker* broker); bool serialized_elements() const { return serialized_elements_; } - ObjectData* elements() const; + FixedArrayBaseData* elements() const; void SerializeObjectCreateMap(JSHeapBroker* broker); - ObjectData* object_create_map( - JSHeapBroker* broker) const { // Can be nullptr. + MapData* object_create_map(JSHeapBroker* broker) const { // Can be nullptr. if (!serialized_object_create_map_) { DCHECK_NULL(object_create_map_); TRACE_MISSING(broker, "object_create_map on " << this); @@ -369,7 +298,7 @@ class JSObjectData : public JSReceiverData { private: void SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, int max_depths); - ObjectData* elements_ = nullptr; + FixedArrayBaseData* elements_ = nullptr; bool cow_or_empty_elements_tenured_ = false; // The {serialized_as_boilerplate} flag is set when all recursively // reachable JSObjects are serialized. @@ -379,7 +308,7 @@ class JSObjectData : public JSReceiverData { ZoneVector inobject_fields_; bool serialized_object_create_map_ = false; - ObjectData* object_create_map_ = nullptr; + MapData* object_create_map_ = nullptr; // Elements (indexed properties) that either // (1) are known to exist directly on the object as non-writable and @@ -411,7 +340,7 @@ void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker) { if (proto_info->HasObjectCreateMap()) { DCHECK_NULL(object_create_map_); object_create_map_ = - broker->GetOrCreateData(proto_info->ObjectCreateMap()); + broker->GetOrCreateData(proto_info->ObjectCreateMap())->AsMap(); } } } @@ -572,14 +501,14 @@ class JSBoundFunctionData : public JSObjectData { ObjectData* bound_target_function() const { return bound_target_function_; } ObjectData* bound_this() const { return bound_this_; } - ObjectData* bound_arguments() const { return bound_arguments_; } + FixedArrayData* bound_arguments() const { return bound_arguments_; } private: bool serialized_ = false; ObjectData* bound_target_function_ = nullptr; ObjectData* bound_this_ = nullptr; - ObjectData* bound_arguments_ = nullptr; + FixedArrayData* bound_arguments_ = nullptr; }; class JSFunctionData : public JSObjectData { @@ -599,7 +528,7 @@ class JSFunctionData : public JSObjectData { ContextData* context() const { return context_; } NativeContextData* native_context() const { return native_context_; } - ObjectData* initial_map() const { return initial_map_; } + MapData* initial_map() const { return initial_map_; } ObjectData* prototype() const { return prototype_; } SharedFunctionInfoData* shared() const { return shared_; } FeedbackVectorData* feedback_vector() const { return feedback_vector_; } @@ -618,7 +547,7 @@ class JSFunctionData : public JSObjectData { ContextData* context_ = nullptr; NativeContextData* native_context_ = nullptr; - ObjectData* initial_map_ = nullptr; + MapData* initial_map_ = nullptr; ObjectData* prototype_ = nullptr; SharedFunctionInfoData* shared_ = nullptr; FeedbackVectorData* feedback_vector_ = nullptr; @@ -1164,19 +1093,10 @@ HeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage, // instance_type_ member. In the case of constructing the MapData for the // meta map (whose map is itself), this member has not yet been // initialized. - map_(broker->GetOrCreateData(object->map())) { + map_(static_cast(broker->GetOrCreateData(object->map()))) { CHECK(broker->SerializingAllowed()); } -InstanceType HeapObjectData::GetMapInstanceType() const { - ObjectData* map_data = map(); - if (map_data->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(kind()); - return Handle::cast(map_data->object())->instance_type(); - } - return map_data->AsMap()->instance_type(); -} - namespace { bool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle jsarray_map) { DCHECK(!jsarray_map->is_dictionary_map()); @@ -1272,16 +1192,14 @@ void JSFunctionData::Serialize(JSHeapBroker* broker) { if (initial_map_ != nullptr) { initial_map_instance_size_with_min_slack_ = function->ComputeInstanceSizeWithMinSlack(broker->isolate()); - } - if (initial_map_ != nullptr && !initial_map_->should_access_heap()) { - if (initial_map_->AsMap()->instance_type() == JS_ARRAY_TYPE) { - initial_map_->AsMap()->SerializeElementsKindGeneralizations(broker); + if (initial_map_->instance_type() == JS_ARRAY_TYPE) { + initial_map_->SerializeElementsKindGeneralizations(broker); } - initial_map_->AsMap()->SerializeConstructor(broker); + initial_map_->SerializeConstructor(broker); // TODO(neis): This is currently only needed for native_context's // object_function, as used by GetObjectCreateMap. If no further use sites // show up, we should move this into NativeContextData::Serialize. - initial_map_->AsMap()->SerializePrototype(broker); + initial_map_->SerializePrototype(broker); } } @@ -1446,10 +1364,9 @@ void JSBoundFunctionData::Serialize(JSHeapBroker* broker) { } DCHECK_NULL(bound_arguments_); - bound_arguments_ = broker->GetOrCreateData(function->bound_arguments()); - if (!bound_arguments_->should_access_heap()) { - bound_arguments_->AsFixedArray()->SerializeContents(broker); - } + bound_arguments_ = + broker->GetOrCreateData(function->bound_arguments())->AsFixedArray(); + bound_arguments_->SerializeContents(broker); DCHECK_NULL(bound_this_); bound_this_ = broker->GetOrCreateData(function->bound_this()); @@ -1994,20 +1911,21 @@ class CodeData : public HeapObjectData { : HeapObjectData(broker, storage, object) {} }; -#define DEFINE_IS_AND_AS(Name) \ - bool ObjectData::Is##Name() const { \ - if (should_access_heap()) { \ - AllowHandleDereferenceIf allow_handle_dereference(kind()); \ - return object()->Is##Name(); \ - } \ - if (is_smi()) return false; \ - InstanceType instance_type = \ - static_cast(this)->GetMapInstanceType(); \ - return InstanceTypeChecker::Is##Name(instance_type); \ - } \ - Name##Data* ObjectData::As##Name() { \ - CHECK(Is##Name()); \ - return static_cast(this); \ +#define DEFINE_IS_AND_AS(Name) \ + bool ObjectData::Is##Name() const { \ + if (kind() == kUnserializedHeapObject) { \ + AllowHandleDereference allow_handle_dereference; \ + return object()->Is##Name(); \ + } \ + if (is_smi()) return false; \ + InstanceType instance_type = \ + static_cast(this)->map()->instance_type(); \ + return InstanceTypeChecker::Is##Name(instance_type); \ + } \ + Name##Data* ObjectData::As##Name() { \ + CHECK_EQ(kind(), kSerializedHeapObject); \ + CHECK(Is##Name()); \ + return static_cast(this); \ } HEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS) #undef DEFINE_IS_AND_AS @@ -2021,7 +1939,7 @@ bool JSObjectData::cow_or_empty_elements_tenured() const { return cow_or_empty_elements_tenured_; } -ObjectData* JSObjectData::elements() const { return elements_; } +FixedArrayBaseData* JSObjectData::elements() const { return elements_; } void JSObjectData::SerializeAsBoilerplate(JSHeapBroker* broker) { SerializeRecursiveAsBoilerplate(broker, kMaxFastLiteralDepth); @@ -2036,8 +1954,7 @@ void JSObjectData::SerializeElements(JSHeapBroker* broker) { Handle elements_object(boilerplate->elements(), broker->isolate()); DCHECK_NULL(elements_); - elements_ = broker->GetOrCreateData(elements_object); - DCHECK(elements_->IsFixedArrayBase()); + elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase(); } void MapData::SerializeConstructor(JSHeapBroker* broker) { @@ -2191,10 +2108,9 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, } DCHECK_NULL(elements_); - elements_ = broker->GetOrCreateData(elements_object); - DCHECK(elements_->IsFixedArrayBase()); + elements_ = broker->GetOrCreateData(elements_object)->AsFixedArrayBase(); - if (empty_or_cow || elements_->should_access_heap()) { + if (empty_or_cow) { // No need to do anything here. Empty or copy-on-write elements // do not need to be serialized because we only need to store the elements // reference to the allocated object. @@ -2265,9 +2181,7 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, } TRACE(broker, "Copied " << inobject_fields_.size() << " in-object fields"); - if (!map()->should_access_heap()) { - map()->AsMap()->SerializeOwnDescriptors(broker); - } + map()->SerializeOwnDescriptors(broker); if (IsJSArray()) AsJSArray()->Serialize(broker); } @@ -2304,11 +2218,9 @@ Isolate* ObjectRef::isolate() const { return broker()->isolate(); } ContextRef ContextRef::previous(size_t* depth, SerializationPolicy policy) const { DCHECK_NOT_NULL(depth); - if (data_->should_access_heap()) { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; Context current = *object(); while (*depth != 0 && current.unchecked_previous().IsContext()) { current = Context::cast(current.unchecked_previous()); @@ -2322,11 +2234,9 @@ ContextRef ContextRef::previous(size_t* depth, base::Optional ContextRef::get(int index, SerializationPolicy policy) const { - if (data_->should_access_heap()) { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; Handle value(object()->get(index), broker()->isolate()); return ObjectRef(broker(), value); } @@ -2341,10 +2251,10 @@ base::Optional ContextRef::get(int index, JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone, bool tracing_enabled) : isolate_(isolate), - zone_(broker_zone), + broker_zone_(broker_zone), + current_zone_(broker_zone), refs_(new (zone()) RefsMap(kMinimalRefsBucketCount, AddressMatcher(), zone())), - root_index_map_(isolate), array_and_object_prototypes_(zone()), tracing_enabled_(tracing_enabled), feedback_(zone()), @@ -2414,14 +2324,10 @@ void JSHeapBroker::PrintRefsAnalysis() const { break; } } else { - InstanceType instance_type; - if (ref->value->should_access_heap()) { - instance_type = Handle::cast(ref->value->object()) - ->map() - .instance_type(); - } else { - instance_type = ref->value->AsHeapObject()->GetMapInstanceType(); - } + InstanceType instance_type = + static_cast(ref->value) + ->map() + ->instance_type(); CHECK_LE(FIRST_TYPE, instance_type); CHECK_LE(instance_type, LAST_TYPE); switch (ref->value->used_status) { @@ -2488,6 +2394,85 @@ bool IsShareable(Handle object, Isolate* isolate) { isolate->roots_table().IsRootHandle(object, &root_index); } +void JSHeapBroker::InitializeRefsMap() { + TraceScope tracer(this, "JSHeapBroker::InitializeRefsMap"); + + DCHECK_NULL(compiler_cache_); + PerIsolateCompilerCache::Setup(isolate()); + compiler_cache_ = isolate()->compiler_cache(); + + if (compiler_cache_->HasSnapshot()) { + TRACE(this, "Importing existing RefsMap snapshot"); + DCHECK_NULL(refs_); + refs_ = new (zone()) RefsMap(compiler_cache_->GetSnapshot(), zone()); + return; + } + + TRACE(this, "Building RefsMap snapshot"); + DCHECK_NULL(refs_); + refs_ = + new (zone()) RefsMap(kInitialRefsBucketCount, AddressMatcher(), zone()); + + // Temporarily use the "compiler zone" for serialization, such that the + // serialized data survives this compilation. + DCHECK_EQ(current_zone_, broker_zone_); + current_zone_ = compiler_cache_->zone(); + + // Serialize various builtins. + Builtins* const b = isolate()->builtins(); + { + Builtins::Name builtins[] = { + Builtins::kAllocateInYoungGeneration, + Builtins::kAllocateRegularInYoungGeneration, + Builtins::kAllocateInOldGeneration, + Builtins::kAllocateRegularInOldGeneration, + Builtins::kArgumentsAdaptorTrampoline, + Builtins::kArrayConstructorImpl, + Builtins::kArrayIncludesHoleyDoubles, + Builtins::kArrayIncludesPackedDoubles, + Builtins::kArrayIncludesSmiOrObject, + Builtins::kArrayIndexOfHoleyDoubles, + Builtins::kArrayIndexOfPackedDoubles, + Builtins::kArrayIndexOfSmiOrObject, + Builtins::kCallApiCallback, + Builtins::kCallFunctionForwardVarargs, + Builtins::kCallFunction_ReceiverIsAny, + Builtins::kCallFunction_ReceiverIsNotNullOrUndefined, + Builtins::kCallFunction_ReceiverIsNullOrUndefined, + Builtins::kCloneFastJSArray, + Builtins::kConstructFunctionForwardVarargs, + Builtins::kForInFilter, + Builtins::kGetProperty, + Builtins::kIncBlockCounter, + Builtins::kJSBuiltinsConstructStub, + Builtins::kJSConstructStubGeneric, + Builtins::kStringAdd_CheckNone, + Builtins::kStringAddConvertLeft, + Builtins::kStringAddConvertRight, + Builtins::kToNumber, + Builtins::kToObject, + }; + for (auto id : builtins) { + GetOrCreateData(b->builtin_handle(id)); + } + } + for (int32_t id = 0; id < Builtins::kFirstBytecodeHandler; ++id) { + if (Builtins::HasJSLinkage(id)) { + GetOrCreateData(b->builtin_handle(id)); + } + } + + // TODO(mslekova): Serialize root objects (from factory). + + // Verify. + for (RefsMap::Entry* p = refs_->Start(); p != nullptr; p = refs_->Next(p)) { + CHECK(IsShareable(p->value->object(), isolate())); + } + + compiler_cache()->SetSnapshot(refs_); + current_zone_ = broker_zone_; +} + void JSHeapBroker::CollectArrayAndObjectPrototypes() { DisallowHeapAllocation no_gc; CHECK_EQ(mode(), kSerializing); @@ -2578,8 +2563,7 @@ void JSHeapBroker::InitializeAndStartSerializing( refs_->Clear(); refs_ = nullptr; - refs_ = - new (zone()) RefsMap(kInitialRefsBucketCount, AddressMatcher(), zone()); + InitializeRefsMap(); SetTargetNativeContextRef(native_context); target_native_context().Serialize(); @@ -2587,8 +2571,60 @@ void JSHeapBroker::InitializeAndStartSerializing( CollectArrayAndObjectPrototypes(); SerializeTypedArrayStringTags(); - // Serialize Cells + // Serialize standard objects. + // + // - Maps, strings, oddballs Factory* const f = isolate()->factory(); + GetOrCreateData(f->arguments_marker_map()); + GetOrCreateData(f->bigint_string()); + GetOrCreateData(f->boolean_map()); + GetOrCreateData(f->boolean_string()); + GetOrCreateData(f->empty_fixed_array()); + GetOrCreateData(f->empty_string()); + GetOrCreateData(f->exec_string()); + GetOrCreateData(f->false_string()); + GetOrCreateData(f->false_value()); + GetOrCreateData(f->fixed_array_map()); + GetOrCreateData(f->fixed_cow_array_map()); + GetOrCreateData(f->fixed_double_array_map()); + GetOrCreateData(f->function_string()); + GetOrCreateData(f->has_instance_symbol()); + GetOrCreateData(f->heap_number_map()); + GetOrCreateData(f->length_string()); + GetOrCreateData(f->many_closures_cell_map()); + GetOrCreateData(f->minus_zero_value()); + GetOrCreateData(f->name_dictionary_map()); + GetOrCreateData(f->name_string()); + GetOrCreateData(f->NaN_string()); + GetOrCreateData(f->null_map()); + GetOrCreateData(f->null_string()); + GetOrCreateData(f->null_value()); + GetOrCreateData(f->number_string()); + GetOrCreateData(f->object_string()); + GetOrCreateData(f->one_pointer_filler_map()); + GetOrCreateData(f->optimized_out()); + GetOrCreateData(f->optimized_out_map()); + GetOrCreateData(f->property_array_map()); + GetOrCreateData(f->prototype_string()); + GetOrCreateData(f->ReflectHas_string()); + GetOrCreateData(f->ReflectGet_string()); + GetOrCreateData(f->sloppy_arguments_elements_map()); + GetOrCreateData(f->stale_register()); + GetOrCreateData(f->stale_register_map()); + GetOrCreateData(f->string_string()); + GetOrCreateData(f->symbol_string()); + GetOrCreateData(f->termination_exception_map()); + GetOrCreateData(f->the_hole_map()); + GetOrCreateData(f->the_hole_value()); + GetOrCreateData(f->then_string()); + GetOrCreateData(f->true_string()); + GetOrCreateData(f->true_value()); + GetOrCreateData(f->undefined_map()); + GetOrCreateData(f->undefined_string()); + GetOrCreateData(f->undefined_value()); + GetOrCreateData(f->uninitialized_map()); + GetOrCreateData(f->zero_string()); + // - Cells GetOrCreateData(f->array_buffer_detaching_protector()) ->AsPropertyCell() ->Serialize(this); @@ -2624,25 +2660,24 @@ void JSHeapBroker::InitializeAndStartSerializing( TRACE(this, "Finished serializing standard objects"); } +ObjectData* JSHeapBroker::GetData(Handle object) const { + RefsMap::Entry* entry = refs_->Lookup(object.address()); + return entry ? entry->value : nullptr; +} + // clang-format off ObjectData* JSHeapBroker::GetOrCreateData(Handle object) { + CHECK(SerializingAllowed()); RefsMap::Entry* entry = refs_->LookupOrInsert(object.address(), zone()); ObjectData** data_storage = &(entry->value); if (*data_storage == nullptr) { // TODO(neis): Remove these Allow* once we serialize everything upfront. + AllowHandleAllocation handle_allocation; AllowHandleDereference handle_dereference; if (object->IsSmi()) { new (zone()) ObjectData(this, data_storage, object, kSmi); - } else if (ReadOnlyHeap::Contains(HeapObject::cast(*object))) { - new (zone()) ObjectData(this, data_storage, object, - kUnserializedReadOnlyHeapObject); - } else if (object->IsCode() && Code::cast(*object).builtin_index() != -1) { - new (zone()) ObjectData(this, data_storage, object, - kUnserializedReadOnlyHeapObject); #define CREATE_DATA_IF_MATCH(name) \ } else if (object->Is##name()) { \ - CHECK(SerializingAllowed()); \ - AllowHandleAllocation handle_allocation; \ new (zone()) name##Data(this, data_storage, Handle::cast(object)); HEAP_BROKER_OBJECT_LIST(CREATE_DATA_IF_MATCH) #undef CREATE_DATA_IF_MATCH @@ -2677,14 +2712,10 @@ int ObjectRef::AsSmi() const { } base::Optional JSObjectRef::GetObjectCreateMap() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHeapAllocationIf allow_heap_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; + AllowHeapAllocation heap_allocation; Handle instance_map; if (Map::TryGetObjectCreateMap(broker()->isolate(), object()) .ToHandle(&instance_map)) { @@ -2693,12 +2724,9 @@ base::Optional JSObjectRef::GetObjectCreateMap() const { return base::Optional(); } } - ObjectData* map_data = data()->AsJSObject()->object_create_map(broker()); - if (map_data == nullptr) return base::Optional(); - if (map_data->should_access_heap()) { - return MapRef(broker(), map_data->object()); - } - return MapRef(broker(), map_data->AsMap()); + MapData* map_data = data()->AsJSObject()->object_create_map(broker()); + return map_data != nullptr ? MapRef(broker(), map_data) + : base::Optional(); } #define DEF_TESTER(Type, ...) \ @@ -2709,13 +2737,10 @@ INSTANCE_TYPE_CHECKERS(DEF_TESTER) #undef DEF_TESTER base::Optional MapRef::AsElementsKind(ElementsKind kind) const { - if (data_->should_access_heap()) { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHeapAllocationIf allow_heap_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHeapAllocation heap_allocation; + AllowHandleDereference allow_handle_dereference; return MapRef(broker(), Map::AsElementsKind(broker()->isolate(), object(), kind)); } @@ -2731,13 +2756,11 @@ base::Optional MapRef::AsElementsKind(ElementsKind kind) const { void MapRef::SerializeForElementLoad() { CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); - if (data()->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) return; data()->AsMap()->SerializeForElementLoad(broker()); } void MapRef::SerializeForElementStore() { CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); - if (data()->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) return; data()->AsMap()->SerializeForElementStore(broker()); } @@ -2794,34 +2817,27 @@ bool MapRef::HasOnlyStablePrototypesWithFastElements( } bool MapRef::supports_fast_array_iteration() const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; + AllowHandleAllocation handle_allocation; return SupportsFastArrayIteration(broker()->isolate(), object()); } return data()->AsMap()->supports_fast_array_iteration(); } bool MapRef::supports_fast_array_resize() const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; + AllowHandleAllocation handle_allocation; return SupportsFastArrayResize(broker()->isolate(), object()); } return data()->AsMap()->supports_fast_array_resize(); } int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; + AllowHandleAllocation handle_allocation; return object()->ComputeInstanceSizeWithMinSlack(broker()->isolate()); } return data()->AsJSFunction()->initial_map_instance_size_with_min_slack(); @@ -2830,10 +2846,8 @@ int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const { // Not needed for TypedLowering. base::Optional ScriptContextTableRef::lookup(const NameRef& name) const { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; if (!name.IsString()) return {}; ScriptContextTable::LookupResult lookup_result; auto table = object(); @@ -2877,12 +2891,9 @@ OddballType MapRef::oddball_type() const { } FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; return FeedbackCellRef(broker(), object()->GetClosureFeedbackCell(index)); } @@ -2892,10 +2903,8 @@ FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const { } double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference handle_dereference; return object()->RawFastDoublePropertyAt(index); } JSObjectData* object_data = data()->AsJSObject(); @@ -2904,10 +2913,8 @@ double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const { } uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference handle_dereference; return object()->RawFastDoublePropertyAsBitsAt(index); } JSObjectData* object_data = data()->AsJSObject(); @@ -2916,12 +2923,9 @@ uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const { } ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; return ObjectRef(broker(), handle(object()->RawFastPropertyAt(index), broker()->isolate())); } @@ -2933,14 +2937,10 @@ ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const { } bool AllocationSiteRef::IsFastLiteral() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHeapAllocationIf allow_heap_allocation( - data()->kind(), broker()->mode()); // For TryMigrateInstance. - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHeapAllocation allow_heap_allocation; // For TryMigrateInstance. + AllowHandleAllocation allow_handle_allocation; + AllowHandleDereference allow_handle_dereference; return IsInlinableFastLiteral( handle(object()->boilerplate(), broker()->isolate())); } @@ -2958,14 +2958,10 @@ void JSObjectRef::SerializeElements() { } void JSObjectRef::EnsureElementsTenured() { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHeapAllocationIf allow_heap_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation allow_handle_allocation; + AllowHandleDereference allow_handle_dereference; + AllowHeapAllocation allow_heap_allocation; Handle object_elements = elements().object(); if (ObjectInYoungGeneration(*object_elements)) { @@ -2983,9 +2979,8 @@ void JSObjectRef::EnsureElementsTenured() { } FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return FieldIndex::ForDescriptor(*object(), descriptor_index); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); @@ -2993,9 +2988,8 @@ FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { } int MapRef::GetInObjectPropertyOffset(int i) const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->GetInObjectPropertyOffset(i); } return (GetInObjectPropertiesStartInWords() + i) * kTaggedSize; @@ -3003,9 +2997,8 @@ int MapRef::GetInObjectPropertyOffset(int i) const { PropertyDetails MapRef::GetPropertyDetails( InternalIndex descriptor_index) const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->instance_descriptors().GetDetails(descriptor_index); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); @@ -3013,11 +3006,9 @@ PropertyDetails MapRef::GetPropertyDetails( } NameRef MapRef::GetPropertyKey(InternalIndex descriptor_index) const { - if (data_->should_access_heap()) { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return NameRef( broker(), handle(object()->instance_descriptors().GetKey(descriptor_index), @@ -3039,11 +3030,9 @@ bool MapRef::IsPrimitiveMap() const { } MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const { - if (data_->should_access_heap()) { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; Handle owner( object()->FindFieldOwner(broker()->isolate(), descriptor_index), broker()->isolate()); @@ -3056,11 +3045,9 @@ MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const { } ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const { - if (data_->should_access_heap()) { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; Handle field_type( object()->instance_descriptors().GetFieldType(descriptor_index), broker()->isolate()); @@ -3073,9 +3060,8 @@ ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const { } bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->IsUnboxedDoubleField( FieldIndex::ForDescriptor(*object(), descriptor_index)); } @@ -3086,22 +3072,18 @@ bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const { } uint16_t StringRef::GetFirstChar() { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->Get(0); } return data()->AsString()->first_char(); } base::Optional StringRef::ToNumber() { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHeapAllocationIf allow_heap_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; + AllowHandleAllocation allow_handle_allocation; + AllowHeapAllocation allow_heap_allocation; int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY; return StringToDouble(broker()->isolate(), object(), flags); } @@ -3109,47 +3091,41 @@ base::Optional StringRef::ToNumber() { } int ArrayBoilerplateDescriptionRef::constants_elements_length() const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->constant_elements().length(); } return data()->AsArrayBoilerplateDescription()->constants_elements_length(); } int ObjectBoilerplateDescriptionRef::size() const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->size(); } return data()->AsObjectBoilerplateDescription()->size(); } ObjectRef FixedArrayRef::get(int i) const { - if (data_->should_access_heap()) { - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return ObjectRef(broker(), handle(object()->get(i), broker()->isolate())); } return ObjectRef(broker(), data()->AsFixedArray()->Get(i)); } bool FixedDoubleArrayRef::is_the_hole(int i) const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->is_the_hole(i); } return data()->AsFixedDoubleArray()->Get(i).is_hole_nan(); } double FixedDoubleArrayRef::get_scalar(int i) const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->get_scalar(i); } CHECK(!data()->AsFixedDoubleArray()->Get(i).is_hole_nan()); @@ -3157,36 +3133,27 @@ double FixedDoubleArrayRef::get_scalar(int i) const { } uint8_t BytecodeArrayRef::get(int index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return object()->get(index); } return data()->AsBytecodeArray()->get(index); } Address BytecodeArrayRef::GetFirstBytecodeAddress() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return object()->GetFirstBytecodeAddress(); } return data()->AsBytecodeArray()->GetFirstBytecodeAddress(); } Handle BytecodeArrayRef::GetConstantAtIndex(int index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return handle(object()->constant_pool().get(index), broker()->isolate()); } return data()->AsBytecodeArray()->GetConstantAtIndex(index, @@ -3194,60 +3161,47 @@ Handle BytecodeArrayRef::GetConstantAtIndex(int index) const { } bool BytecodeArrayRef::IsConstantAtIndexSmi(int index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return object()->constant_pool().get(index).IsSmi(); } return data()->AsBytecodeArray()->IsConstantAtIndexSmi(index); } Smi BytecodeArrayRef::GetConstantAtIndexAsSmi(int index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return Smi::cast(object()->constant_pool().get(index)); } return data()->AsBytecodeArray()->GetConstantAtIndexAsSmi(index); } void BytecodeArrayRef::SerializeForCompilation() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; data()->AsBytecodeArray()->SerializeForCompilation(broker()); } const byte* BytecodeArrayRef::source_positions_address() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->SourcePositionTableIfCollected().GetDataStartAddress(); } return data()->AsBytecodeArray()->source_positions_address(); } int BytecodeArrayRef::source_positions_size() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->SourcePositionTableIfCollected().length(); } return static_cast(data()->AsBytecodeArray()->source_positions_size()); } Address BytecodeArrayRef::handler_table_address() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return reinterpret_cast
( object()->handler_table().GetDataStartAddress()); } @@ -3255,71 +3209,47 @@ Address BytecodeArrayRef::handler_table_address() const { } int BytecodeArrayRef::handler_table_size() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->handler_table().length(); } return data()->AsBytecodeArray()->handler_table_size(); } -Handle JSHeapBroker::GetRootHandle(Object object) { - RootIndex root_index; - CHECK(root_index_map().Lookup(object.ptr(), &root_index)); - return Handle(isolate()->root_handle(root_index).location()); -} - -#define IF_ACCESS_FROM_HEAP_C(holder, name) \ - if (data_->should_access_heap()) { \ - CHECK(broker()->mode() == JSHeapBroker::kDisabled || \ - ReadOnlyHeap::Contains(HeapObject::cast(*object()))); \ - AllowHandleAllocationIf handle_allocation(data_->kind(), \ - broker()->mode()); \ - AllowHandleDereferenceIf allow_handle_dereference(data_->kind(), \ - broker()->mode()); \ - return object()->name(); \ +#define IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name) \ + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { \ + AllowHandleAllocation handle_allocation; \ + AllowHandleDereference allow_handle_dereference; \ + return object()->name(); \ } -#define IF_ACCESS_FROM_HEAP(holder, result, name) \ - if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { \ - AllowHandleAllocationIf handle_allocation(data_->kind(), \ - broker()->mode()); \ - AllowHandleDereferenceIf handle_dereference(data_->kind(), \ - broker()->mode()); \ - return result##Ref(broker(), \ - handle(object()->name(), broker()->isolate())); \ - } else if (data_->kind() == \ - ObjectDataKind::kUnserializedReadOnlyHeapObject) { \ - AllowHandleDereferenceIf handle_dereference(data_->kind(), \ - broker()->mode()); \ - return result##Ref(broker(), broker()->GetRootHandle(object()->name())); \ +#define IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name) \ + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { \ + AllowHandleAllocation handle_allocation; \ + AllowHandleDereference allow_handle_dereference; \ + return result##Ref(broker(), \ + handle(object()->name(), broker()->isolate())); \ } // Macros for definining a const getter that, depending on the broker mode, // either looks into the handle or into the serialized data. -#define BIMODAL_ACCESSOR(holder, result, name) \ - result##Ref holder##Ref::name() const { \ - IF_ACCESS_FROM_HEAP(holder, result, name); \ - ObjectData* data = ObjectRef::data()->As##holder()->name(); \ - if (data->kind() == ObjectDataKind::kUnserializedHeapObject) { \ - return result##Ref(broker(), data->object()); \ - } else { \ - return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \ - } \ +#define BIMODAL_ACCESSOR(holder, result, name) \ + result##Ref holder##Ref::name() const { \ + IF_BROKER_DISABLED_ACCESS_HANDLE(holder, result, name); \ + return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \ } // Like above except that the result type is not an XYZRef. -#define BIMODAL_ACCESSOR_C(holder, result, name) \ - result holder##Ref::name() const { \ - IF_ACCESS_FROM_HEAP_C(holder, name); \ - return ObjectRef::data()->As##holder()->name(); \ +#define BIMODAL_ACCESSOR_C(holder, result, name) \ + result holder##Ref::name() const { \ + IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name); \ + return ObjectRef::data()->As##holder()->name(); \ } // Like above but for BitFields. #define BIMODAL_ACCESSOR_B(holder, field, name, BitField) \ typename BitField::FieldType holder##Ref::name() const { \ - IF_ACCESS_FROM_HEAP_C(holder, name); \ + IF_BROKER_DISABLED_ACCESS_HANDLE_C(holder, name); \ return BitField::decode(ObjectRef::data()->As##holder()->field()); \ } @@ -3400,8 +3330,7 @@ BIMODAL_ACCESSOR(PropertyCell, Object, value) BIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details) base::Optional FunctionTemplateInfoRef::call_code() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { return CallHandlerInfoRef( broker(), handle(object()->call_code(), broker()->isolate())); } @@ -3412,12 +3341,9 @@ base::Optional FunctionTemplateInfoRef::call_code() const { } bool FunctionTemplateInfoRef::is_signature_undefined() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; + AllowHandleAllocation allow_handle_allocation; return object()->signature().IsUndefined(broker()->isolate()); } @@ -3425,12 +3351,9 @@ bool FunctionTemplateInfoRef::is_signature_undefined() const { } bool FunctionTemplateInfoRef::has_call_code() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; + AllowHandleAllocation allow_handle_allocation; CallOptimization call_optimization(broker()->isolate(), object()); return call_optimization.is_simple_api_call(); @@ -3444,12 +3367,9 @@ HolderLookupResult FunctionTemplateInfoRef::LookupHolderOfExpectedType( MapRef receiver_map, SerializationPolicy policy) { const HolderLookupResult not_found; - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; + AllowHandleAllocation allow_handle_allocation; CallOptimization call_optimization(broker()->isolate(), object()); Handle receiver_map_ref(receiver_map.object()); @@ -3528,9 +3448,8 @@ BIMODAL_ACCESSOR(FeedbackCell, HeapObject, value) base::Optional MapRef::GetStrongValue( InternalIndex descriptor_index) const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return ObjectRef(broker(), handle(object()->instance_descriptors().GetStrongValue( descriptor_index), @@ -3544,22 +3463,16 @@ base::Optional MapRef::GetStrongValue( } void MapRef::SerializeRootMap() { - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsMap()->SerializeRootMap(broker()); } base::Optional MapRef::FindRootMap() const { if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + AllowHandleDereference allow_handle_dereference; return MapRef(broker(), handle(object()->FindRootMap(broker()->isolate()), broker()->isolate())); - } else if (data_->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); - return MapRef(broker(), broker()->GetRootHandle( - object()->FindRootMap(broker()->isolate()))); } MapData* map_data = data()->AsMap()->FindRootMap(); if (map_data) { @@ -3570,59 +3483,58 @@ base::Optional MapRef::FindRootMap() const { } void* JSTypedArrayRef::data_ptr() const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->DataPtr(); } return data()->AsJSTypedArray()->data_ptr(); } bool MapRef::IsInobjectSlackTrackingInProgress() const { - IF_ACCESS_FROM_HEAP_C(Map, IsInobjectSlackTrackingInProgress); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, IsInobjectSlackTrackingInProgress); return Map::ConstructionCounterBits::decode(data()->AsMap()->bit_field3()) != Map::kNoSlackTracking; } int MapRef::constructor_function_index() const { - IF_ACCESS_FROM_HEAP_C(Map, GetConstructorFunctionIndex); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetConstructorFunctionIndex); CHECK(IsPrimitiveMap()); return data()->AsMap()->constructor_function_index(); } bool MapRef::is_stable() const { - IF_ACCESS_FROM_HEAP_C(Map, is_stable); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, is_stable); return !Map::IsUnstableBit::decode(data()->AsMap()->bit_field3()); } bool MapRef::CanBeDeprecated() const { - IF_ACCESS_FROM_HEAP_C(Map, CanBeDeprecated); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanBeDeprecated); CHECK_GT(NumberOfOwnDescriptors(), 0); return data()->AsMap()->can_be_deprecated(); } bool MapRef::CanTransition() const { - IF_ACCESS_FROM_HEAP_C(Map, CanTransition); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, CanTransition); return data()->AsMap()->can_transition(); } int MapRef::GetInObjectPropertiesStartInWords() const { - IF_ACCESS_FROM_HEAP_C(Map, GetInObjectPropertiesStartInWords); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectPropertiesStartInWords); return data()->AsMap()->in_object_properties_start_in_words(); } int MapRef::GetInObjectProperties() const { - IF_ACCESS_FROM_HEAP_C(Map, GetInObjectProperties); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(Map, GetInObjectProperties); return data()->AsMap()->in_object_properties(); } int ScopeInfoRef::ContextLength() const { - IF_ACCESS_FROM_HEAP_C(ScopeInfo, ContextLength); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, ContextLength); return data()->AsScopeInfo()->context_length(); } int ScopeInfoRef::Flags() const { - IF_ACCESS_FROM_HEAP_C(ScopeInfo, Flags); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, Flags); return data()->AsScopeInfo()->flags(); } @@ -3631,17 +3543,14 @@ bool ScopeInfoRef::HasContextExtension() const { } bool ScopeInfoRef::HasOuterScopeInfo() const { - IF_ACCESS_FROM_HEAP_C(ScopeInfo, HasOuterScopeInfo); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(ScopeInfo, HasOuterScopeInfo); return data()->AsScopeInfo()->has_outer_scope_info(); } ScopeInfoRef ScopeInfoRef::OuterScopeInfo() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; return ScopeInfoRef( broker(), handle(object()->OuterScopeInfo(), broker()->isolate())); } @@ -3654,29 +3563,26 @@ void ScopeInfoRef::SerializeScopeInfoChain() { } bool StringRef::IsExternalString() const { - IF_ACCESS_FROM_HEAP_C(String, IsExternalString); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsExternalString); return data()->AsString()->is_external_string(); } Address CallHandlerInfoRef::callback() const { - if (data_->should_access_heap()) { + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { return v8::ToCData
(object()->callback()); } return HeapObjectRef::data()->AsCallHandlerInfo()->callback(); } bool StringRef::IsSeqString() const { - IF_ACCESS_FROM_HEAP_C(String, IsSeqString); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(String, IsSeqString); return data()->AsString()->is_seq_string(); } ScopeInfoRef NativeContextRef::scope_info() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; return ScopeInfoRef(broker(), handle(object()->scope_info(), broker()->isolate())); } @@ -3686,7 +3592,7 @@ ScopeInfoRef NativeContextRef::scope_info() const { MapRef NativeContextRef::GetFunctionMapFromIndex(int index) const { DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX); DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX); - if (data_->should_access_heap()) { + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { return get(index).value().AsMap(); } return MapRef(broker(), data()->AsNativeContext()->function_maps().at( @@ -3740,9 +3646,8 @@ bool ObjectRef::IsNullOrUndefined() const { } bool ObjectRef::BooleanValue() const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference allow_handle_dereference; return object()->BooleanValue(broker()->isolate()); } return IsSmi() ? (AsSmi() != 0) : data()->AsHeapObject()->boolean_value(); @@ -3779,14 +3684,6 @@ base::Optional ObjectRef::GetOwnConstantElement( return (IsJSObject() || IsString()) ? GetOwnElementFromHeap(broker(), object(), index, true) : base::nullopt; - } else if (data_->kind() == ObjectDataKind::kUnserializedReadOnlyHeapObject) { - DCHECK(!IsJSObject()); - // TODO(mythria): For ReadOnly strings, currently we cannot access data from - // heap without creating handles since we use LookupIterator. We should have - // a custom implementation for read only strings that doesn't create - // handles. Till then it is OK to disable this optimization since this only - // impacts keyed accesses on read only strings. - return base::nullopt; } ObjectData* element = nullptr; if (IsJSObject()) { @@ -3802,8 +3699,7 @@ base::Optional ObjectRef::GetOwnConstantElement( base::Optional JSObjectRef::GetOwnDataProperty( Representation field_representation, FieldIndex index, SerializationPolicy policy) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { return GetOwnDataPropertyFromHeap(broker(), Handle::cast(object()), field_representation, index); @@ -3816,7 +3712,7 @@ base::Optional JSObjectRef::GetOwnDataProperty( base::Optional JSArrayRef::GetOwnCowElement( uint32_t index, SerializationPolicy policy) const { - if (data_->should_access_heap()) { + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (!object()->elements().IsCowArray()) return base::nullopt; return GetOwnElementFromHeap(broker(), object(), index, false); } @@ -3836,22 +3732,19 @@ base::Optional JSArrayRef::GetOwnCowElement( } double HeapNumberRef::value() const { - IF_ACCESS_FROM_HEAP_C(HeapNumber, value); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(HeapNumber, value); return data()->AsHeapNumber()->value(); } uint64_t BigIntRef::AsUint64() const { - IF_ACCESS_FROM_HEAP_C(BigInt, AsUint64); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(BigInt, AsUint64); return data()->AsBigInt()->AsUint64(); } base::Optional SourceTextModuleRef::GetCell(int cell_index) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return CellRef(broker(), handle(object()->GetCell(cell_index), broker()->isolate())); } @@ -3864,10 +3757,9 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle object, bool check_type) : broker_(broker) { switch (broker->mode()) { - // We may have to create data in JSHeapBroker::kSerialized as well since we - // read the data from read only heap objects directly instead of serializing - // them. case JSHeapBroker::kSerialized: + data_ = broker->GetData(object); + break; case JSHeapBroker::kSerializing: data_ = broker->GetOrCreateData(object); break; @@ -3876,8 +3768,7 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle object, broker->refs_->LookupOrInsert(object.address(), broker->zone()); ObjectData** storage = &(entry->value); if (*storage == nullptr) { - AllowHandleDereferenceIf allow_handle_dereference( - kUnserializedHeapObject, broker->mode()); + AllowHandleDereference handle_dereference; entry->value = new (broker->zone()) ObjectData(broker, storage, object, object->IsSmi() ? kSmi : kUnserializedHeapObject); @@ -3889,8 +3780,7 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle object, UNREACHABLE(); } if (!data_) { // TODO(mslekova): Remove once we're on the background thread. - AllowHandleDereferenceIf allow_handle_dereference(data_->kind(), - broker->mode()); + AllowHandleDereference handle_dereference; object->Print(); } CHECK_WITH_MSG(data_ != nullptr, "Object is not known to the heap broker"); @@ -3925,9 +3815,8 @@ OddballType GetOddballType(Isolate* isolate, Map map) { } // namespace HeapObjectType HeapObjectRef::GetHeapObjectType() const { - if (data_->should_access_heap()) { - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleDereference handle_dereference; Map map = Handle::cast(object())->map(); HeapObjectType::Flags flags(0); if (map.is_undetectable()) flags |= HeapObjectType::kUndetectable; @@ -3941,12 +3830,9 @@ HeapObjectType HeapObjectRef::GetHeapObjectType() const { return HeapObjectType(map().instance_type(), flags, map().oddball_type()); } base::Optional AllocationSiteRef::boilerplate() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return JSObjectRef(broker(), handle(object()->boilerplate(), broker()->isolate())); } @@ -3963,25 +3849,17 @@ ElementsKind JSObjectRef::GetElementsKind() const { } FixedArrayBaseRef JSObjectRef::elements() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; return FixedArrayBaseRef(broker(), handle(object()->elements(), broker()->isolate())); } - ObjectData* elements_data = data()->AsJSObject()->elements(); - if (elements_data->kind() == - ObjectDataKind::kUnserializedReadOnlyHeapObject) { - return FixedArrayBaseRef(broker(), elements_data->object()); - } - return FixedArrayBaseRef(broker(), elements_data->AsFixedArrayBase()); + return FixedArrayBaseRef(broker(), data()->AsJSObject()->elements()); } int FixedArrayBaseRef::length() const { - IF_ACCESS_FROM_HEAP_C(FixedArrayBase, length); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(FixedArrayBase, length); return data()->AsFixedArrayBase()->length(); } @@ -4006,28 +3884,28 @@ bool NameRef::IsUniqueName() const { } ObjectRef JSRegExpRef::data() const { - IF_ACCESS_FROM_HEAP(JSRegExp, Object, data); + IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, data); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->data()); } ObjectRef JSRegExpRef::flags() const { - IF_ACCESS_FROM_HEAP(JSRegExp, Object, flags); + IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, flags); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->flags()); } ObjectRef JSRegExpRef::last_index() const { - IF_ACCESS_FROM_HEAP(JSRegExp, Object, last_index); + IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, last_index); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->last_index()); } ObjectRef JSRegExpRef::raw_properties_or_hash() const { - IF_ACCESS_FROM_HEAP(JSRegExp, Object, raw_properties_or_hash); + IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, raw_properties_or_hash); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->raw_properties_or_hash()); } ObjectRef JSRegExpRef::source() const { - IF_ACCESS_FROM_HEAP(JSRegExp, Object, source); + IF_BROKER_DISABLED_ACCESS_HANDLE(JSRegExp, Object, source); return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->source()); } @@ -4132,21 +4010,18 @@ void NativeContextData::Serialize(JSHeapBroker* broker) { } void JSFunctionRef::Serialize() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsJSFunction()->Serialize(broker()); } bool JSBoundFunctionRef::serialized() const { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return true; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return true; return data()->AsJSBoundFunction()->serialized(); } bool JSFunctionRef::serialized() const { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return true; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return true; return data()->AsJSFunction()->serialized(); } @@ -4164,12 +4039,9 @@ JSArrayRef SharedFunctionInfoRef::GetTemplateObject( return feedback.AsTemplateObject().value(); } - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference allow_handle_dereference; Handle template_object = TemplateObjectDescription::GetTemplateObject( isolate(), broker()->target_native_context().object(), @@ -4205,8 +4077,7 @@ void SharedFunctionInfoRef::SerializeScopeInfoChain() { base::Optional SharedFunctionInfoRef::function_template_info() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { if (object()->IsApiFunction()) { return FunctionTemplateInfoRef( broker(), handle(object()->function_data(), broker()->isolate())); @@ -4220,17 +4091,15 @@ SharedFunctionInfoRef::function_template_info() const { } int SharedFunctionInfoRef::context_header_size() const { - IF_ACCESS_FROM_HEAP_C(SharedFunctionInfo, scope_info().ContextHeaderLength); + IF_BROKER_DISABLED_ACCESS_HANDLE_C(SharedFunctionInfo, + scope_info().ContextHeaderLength); return data()->AsSharedFunctionInfo()->context_header_size(); } ScopeInfoRef SharedFunctionInfoRef::scope_info() const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - AllowHandleAllocationIf allow_handle_allocation(data()->kind(), - broker()->mode()); - AllowHandleDereferenceIf allow_handle_dereference(data()->kind(), - broker()->mode()); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { + AllowHandleAllocation handle_allocation; + AllowHandleDereference handle_dereference; return ScopeInfoRef(broker(), handle(object()->scope_info(), broker()->isolate())); } @@ -4238,27 +4107,26 @@ ScopeInfoRef SharedFunctionInfoRef::scope_info() const { } void JSObjectRef::SerializeObjectCreateMap() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsJSObject()->SerializeObjectCreateMap(broker()); } void MapRef::SerializeOwnDescriptors() { - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsMap()->SerializeOwnDescriptors(broker()); } void MapRef::SerializeOwnDescriptor(InternalIndex descriptor_index) { - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsMap()->SerializeOwnDescriptor(broker(), descriptor_index); } bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const { CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); - if (data_->should_access_heap()) return true; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return true; DescriptorArrayData* desc_array_data = data()->AsMap()->instance_descriptors(); if (!desc_array_data) return false; @@ -4267,39 +4135,36 @@ bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const { } void MapRef::SerializeBackPointer() { - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsMap()->SerializeBackPointer(broker()); } void MapRef::SerializePrototype() { - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsMap()->SerializePrototype(broker()); } bool MapRef::serialized_prototype() const { CHECK_NE(broker()->mode(), JSHeapBroker::kDisabled); - if (data_->should_access_heap()) return true; return data()->AsMap()->serialized_prototype(); } void SourceTextModuleRef::Serialize() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsSourceTextModule()->Serialize(broker()); } void NativeContextRef::Serialize() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsNativeContext()->Serialize(broker()); } void JSTypedArrayRef::Serialize() { - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsJSTypedArray()->Serialize(broker()); } @@ -4310,30 +4175,26 @@ bool JSTypedArrayRef::serialized() const { } void JSBoundFunctionRef::Serialize() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsJSBoundFunction()->Serialize(broker()); } void PropertyCellRef::Serialize() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsPropertyCell()->Serialize(broker()); } void FunctionTemplateInfoRef::SerializeCallCode() { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); - if (data_->should_access_heap()) return; + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsFunctionTemplateInfo()->SerializeCallCode(broker()); } base::Optional JSGlobalObjectRef::GetPropertyCell( NameRef const& name, SerializationPolicy policy) const { - if (data_->should_access_heap()) { - DCHECK(data_->kind() != ObjectDataKind::kUnserializedReadOnlyHeapObject); + if (data_->kind() == ObjectDataKind::kUnserializedHeapObject) { return GetPropertyCellFromHeap(broker(), name.object()); } PropertyCellData* property_cell_data = @@ -5041,8 +4902,7 @@ std::ostream& operator<<(std::ostream& os, const ObjectRef& ref) { if (ref.data_->kind() == ObjectDataKind::kUnserializedHeapObject || !FLAG_concurrent_recompilation) { // We cannot be in a background thread so it's safe to read the heap. - AllowHandleDereferenceIf allow_handle_dereference(ref.data()->kind(), - ref.broker()->mode()); + AllowHandleDereference allow_handle_dereference; return os << ref.data() << " {" << ref.object() << "}"; } else { return os << ref.data(); @@ -5142,7 +5002,7 @@ TemplateObjectFeedback const& ProcessedFeedback::AsTemplateObject() const { BytecodeAnalysis const& JSHeapBroker::GetBytecodeAnalysis( Handle bytecode_array, BailoutId osr_bailout_id, bool analyze_liveness, SerializationPolicy policy) { - ObjectData* bytecode_array_data = GetOrCreateData(bytecode_array); + ObjectData* bytecode_array_data = GetData(bytecode_array); CHECK_NOT_NULL(bytecode_array_data); auto it = bytecode_analyses_.find(bytecode_array_data); @@ -5202,8 +5062,8 @@ Smi OffHeapBytecodeArray::GetConstantAtIndexAsSmi(int index) const { #undef BIMODAL_ACCESSOR #undef BIMODAL_ACCESSOR_B #undef BIMODAL_ACCESSOR_C -#undef IF_ACCESS_FROM_HEAP -#undef IF_ACCESS_FROM_HEAP_C +#undef IF_BROKER_DISABLED_ACCESS_HANDLE +#undef IF_BROKER_DISABLED_ACCESS_HANDLE_C #undef TRACE #undef TRACE_MISSING diff --git a/src/compiler/js-heap-broker.h b/src/compiler/js-heap-broker.h index 4a48a3a58c..28dabb1c4a 100644 --- a/src/compiler/js-heap-broker.h +++ b/src/compiler/js-heap-broker.h @@ -18,7 +18,6 @@ #include "src/objects/feedback-vector.h" #include "src/objects/function-kind.h" #include "src/objects/objects.h" -#include "src/utils/address-map.h" #include "src/utils/ostreams.h" #include "src/zone/zone-containers.h" @@ -85,7 +84,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { void InitializeAndStartSerializing(Handle native_context); Isolate* isolate() const { return isolate_; } - Zone* zone() const { return zone_; } + Zone* zone() const { return current_zone_; } bool tracing_enabled() const { return tracing_enabled_; } enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired }; @@ -98,9 +97,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker { void PrintRefsAnalysis() const; #endif // DEBUG - // Retruns the handle from root index table for read only heap objects. - Handle GetRootHandle(Object object); - + // Returns nullptr iff handle unknown. + ObjectData* GetData(Handle) const; // Never returns nullptr. ObjectData* GetOrCreateData(Handle); // Like the previous but wraps argument in handle first (for convenience). @@ -195,8 +193,6 @@ class V8_EXPORT_PRIVATE JSHeapBroker { void IncrementTracingIndentation(); void DecrementTracingIndentation(); - RootIndexMap const& root_index_map() { return root_index_map_; } - private: friend class HeapObjectRef; friend class ObjectRef; @@ -225,16 +221,17 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ProcessedFeedback const& ReadFeedbackForTemplateObject( FeedbackSource const& source); + void InitializeRefsMap(); void CollectArrayAndObjectPrototypes(); void SerializeTypedArrayStringTags(); PerIsolateCompilerCache* compiler_cache() const { return compiler_cache_; } Isolate* const isolate_; - Zone* const zone_ = nullptr; + Zone* const broker_zone_; + Zone* current_zone_ = nullptr; base::Optional target_native_context_; RefsMap* refs_; - RootIndexMap root_index_map_; ZoneUnorderedSet, Handle::hash, Handle::equal_to> array_and_object_prototypes_;