diff options
Diffstat (limited to 'deps/v8/src/compiler/js-heap-broker.cc')
-rw-r--r-- | deps/v8/src/compiler/js-heap-broker.cc | 311 |
1 files changed, 182 insertions, 129 deletions
diff --git a/deps/v8/src/compiler/js-heap-broker.cc b/deps/v8/src/compiler/js-heap-broker.cc index 77fbe92eab..86250e9d1f 100644 --- a/deps/v8/src/compiler/js-heap-broker.cc +++ b/deps/v8/src/compiler/js-heap-broker.cc @@ -8,14 +8,14 @@ #include <algorithm> #endif -#include "src/api-inl.h" +#include "src/api/api-inl.h" #include "src/ast/modules.h" -#include "src/bootstrapper.h" -#include "src/boxed-float.h" -#include "src/code-factory.h" +#include "src/codegen/code-factory.h" +#include "src/compiler/access-info.h" #include "src/compiler/graph-reducer.h" #include "src/compiler/per-isolate-compiler-cache.h" -#include "src/objects-inl.h" +#include "src/compiler/vector-slot-pair.h" +#include "src/init/bootstrapper.h" #include "src/objects/allocation-site-inl.h" #include "src/objects/api-callbacks.h" #include "src/objects/cell-inl.h" @@ -25,9 +25,10 @@ #include "src/objects/js-array-inl.h" #include "src/objects/js-regexp-inl.h" #include "src/objects/module-inl.h" +#include "src/objects/objects-inl.h" #include "src/objects/templates.h" -#include "src/utils.h" -#include "src/vector-slot-pair.h" +#include "src/utils/boxed-float.h" +#include "src/utils/utils.h" namespace v8 { namespace internal { @@ -165,26 +166,6 @@ void JSHeapBroker::IncrementTracingIndentation() { ++trace_indentation_; } void JSHeapBroker::DecrementTracingIndentation() { --trace_indentation_; } -class TraceScope { - public: - TraceScope(JSHeapBroker* broker, const char* label) - : TraceScope(broker, static_cast<void*>(broker), label) {} - - TraceScope(JSHeapBroker* broker, ObjectData* data, const char* label) - : TraceScope(broker, static_cast<void*>(data), label) {} - - ~TraceScope() { broker_->DecrementTracingIndentation(); } - - private: - JSHeapBroker* const broker_; - - TraceScope(JSHeapBroker* broker, void* self, const char* label) - : broker_(broker) { - TRACE(broker_, "Running " << label << " on " << self); - broker_->IncrementTracingIndentation(); - } -}; - PropertyCellData::PropertyCellData(JSHeapBroker* broker, ObjectData** storage, Handle<PropertyCell> object) : HeapObjectData(broker, storage, object), @@ -227,9 +208,13 @@ void CallHandlerInfoData::Serialize(JSHeapBroker* broker) { class JSObjectField { public: bool IsDouble() const { return object_ == nullptr; } + uint64_t AsBitsOfDouble() const { + CHECK(IsDouble()); + return number_bits_; + } double AsDouble() const { CHECK(IsDouble()); - return number_; + return bit_cast<double>(number_bits_); } bool IsObject() const { return object_ != nullptr; } @@ -238,12 +223,12 @@ class JSObjectField { return object_; } - explicit JSObjectField(double value) : number_(value) {} + explicit JSObjectField(uint64_t value_bits) : number_bits_(value_bits) {} explicit JSObjectField(ObjectData* value) : object_(value) {} private: ObjectData* object_ = nullptr; - double number_ = 0; + uint64_t number_bits_ = 0; }; class JSObjectData : public HeapObjectData { @@ -301,8 +286,8 @@ void JSObjectData::SerializeObjectCreateMap(JSHeapBroker* broker) { TraceScope tracer(broker, this, "JSObjectData::SerializeObjectCreateMap"); Handle<JSObject> jsobject = Handle<JSObject>::cast(object()); - if (jsobject->map()->is_prototype_map()) { - Handle<Object> maybe_proto_info(jsobject->map()->prototype_info(), + if (jsobject->map().is_prototype_map()) { + Handle<Object> maybe_proto_info(jsobject->map().prototype_info(), broker->isolate()); if (maybe_proto_info->IsPrototypeInfo()) { auto proto_info = Handle<PrototypeInfo>::cast(maybe_proto_info); @@ -354,8 +339,8 @@ class JSTypedArrayData : public JSObjectData { Handle<JSTypedArray> object); bool is_on_heap() const { return is_on_heap_; } - size_t length_value() const { return length_value_; } - void* elements_external_pointer() const { return elements_external_pointer_; } + size_t length() const { return length_; } + void* external_pointer() const { return external_pointer_; } void Serialize(JSHeapBroker* broker); bool serialized() const { return serialized_; } @@ -364,8 +349,8 @@ class JSTypedArrayData : public JSObjectData { private: bool const is_on_heap_; - size_t const length_value_; - void* const elements_external_pointer_; + size_t const length_; + void* const external_pointer_; bool serialized_ = false; HeapObjectData* buffer_ = nullptr; @@ -375,9 +360,8 @@ JSTypedArrayData::JSTypedArrayData(JSHeapBroker* broker, ObjectData** storage, Handle<JSTypedArray> object) : JSObjectData(broker, storage, object), is_on_heap_(object->is_on_heap()), - length_value_(object->length_value()), - elements_external_pointer_( - FixedTypedArrayBase::cast(object->elements())->external_pointer()) {} + length_(object->length()), + external_pointer_(object->external_pointer()) {} void JSTypedArrayData::Serialize(JSHeapBroker* broker) { if (serialized_) return; @@ -724,14 +708,14 @@ bool IsFastLiteralHelper(Handle<JSObject> boilerplate, int max_depth, // TODO(turbofan): Do we want to support out-of-object properties? if (!(boilerplate->HasFastProperties() && - boilerplate->property_array()->length() == 0)) { + boilerplate->property_array().length() == 0)) { return false; } // Check the in-object properties. - Handle<DescriptorArray> descriptors( - boilerplate->map()->instance_descriptors(), isolate); - int limit = boilerplate->map()->NumberOfOwnDescriptors(); + Handle<DescriptorArray> descriptors(boilerplate->map().instance_descriptors(), + isolate); + int limit = boilerplate->map().NumberOfOwnDescriptors(); for (int i = 0; i < limit; i++) { PropertyDetails details = descriptors->GetDetails(i); if (details.location() != kField) continue; @@ -853,11 +837,11 @@ class MapData : public HeapObjectData { return elements_kind_generalizations_; } - // Serialize the own part of the descriptor array and, recursively, that of - // any field owner. + // Serialize a single (or all) own slot(s) of the descriptor array and recurse + // on field owner(s). + void SerializeOwnDescriptor(JSHeapBroker* broker, int descriptor_index); void SerializeOwnDescriptors(JSHeapBroker* broker); DescriptorArrayData* instance_descriptors() const { - CHECK(serialized_own_descriptors_); return instance_descriptors_; } @@ -973,15 +957,15 @@ bool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle<Map> jsarray_map) { DCHECK(!jsarray_map->is_dictionary_map()); Handle<Name> length_string = isolate->factory()->length_string(); DescriptorArray descriptors = jsarray_map->instance_descriptors(); - int number = descriptors->Search(*length_string, *jsarray_map); + int number = descriptors.Search(*length_string, *jsarray_map); DCHECK_NE(DescriptorArray::kNotFound, number); - return descriptors->GetDetails(number).IsReadOnly(); + return descriptors.GetDetails(number).IsReadOnly(); } bool SupportsFastArrayIteration(Isolate* isolate, Handle<Map> map) { return map->instance_type() == JS_ARRAY_TYPE && IsFastElementsKind(map->elements_kind()) && - map->prototype()->IsJSArray() && + map->prototype().IsJSArray() && isolate->IsAnyInitialArrayPrototype( handle(JSArray::cast(map->prototype()), isolate)) && isolate->IsNoElementsProtectorIntact(); @@ -1101,12 +1085,28 @@ class DescriptorArrayData : public HeapObjectData { Handle<DescriptorArray> object) : HeapObjectData(broker, storage, object), contents_(broker->zone()) {} - ZoneVector<PropertyDescriptor>& contents() { return contents_; } + ZoneMap<int, PropertyDescriptor>& contents() { return contents_; } private: - ZoneVector<PropertyDescriptor> contents_; + ZoneMap<int, PropertyDescriptor> contents_; }; +class FeedbackCellData : public HeapObjectData { + public: + FeedbackCellData(JSHeapBroker* broker, ObjectData** storage, + Handle<FeedbackCell> object); + + HeapObjectData* value() const { return value_; } + + private: + HeapObjectData* const value_; +}; + +FeedbackCellData::FeedbackCellData(JSHeapBroker* broker, ObjectData** storage, + Handle<FeedbackCell> object) + : HeapObjectData(broker, storage, object), + value_(broker->GetOrCreateData(object->value())->AsHeapObject()) {} + class FeedbackVectorData : public HeapObjectData { public: const ZoneVector<ObjectData*>& feedback() { return feedback_; } @@ -1277,14 +1277,23 @@ void FixedDoubleArrayData::SerializeContents(JSHeapBroker* broker) { class BytecodeArrayData : public FixedArrayBaseData { public: int register_count() const { return register_count_; } + int parameter_count() const { return parameter_count_; } + interpreter::Register incoming_new_target_or_generator_register() const { + return incoming_new_target_or_generator_register_; + } BytecodeArrayData(JSHeapBroker* broker, ObjectData** storage, Handle<BytecodeArray> object) : FixedArrayBaseData(broker, storage, object), - register_count_(object->register_count()) {} + register_count_(object->register_count()), + parameter_count_(object->parameter_count()), + incoming_new_target_or_generator_register_( + object->incoming_new_target_or_generator_register()) {} private: int const register_count_; + int const parameter_count_; + interpreter::Register const incoming_new_target_or_generator_register_; }; class JSArrayData : public JSObjectData { @@ -1407,7 +1416,7 @@ SharedFunctionInfoData::SharedFunctionInfoData( void SharedFunctionInfoData::SetSerializedForCompilation( JSHeapBroker* broker, FeedbackVectorRef feedback) { CHECK(serialized_for_compilation_.insert(feedback.object()).second); - TRACE(broker, "Set function " << object() << " with " << feedback.object() + TRACE(broker, "Set function " << this << " with " << feedback << " as serialized for compilation"); } @@ -1448,7 +1457,6 @@ CellData* ModuleData::GetCell(int cell_index) const { break; case ModuleDescriptor::kInvalid: UNREACHABLE(); - break; } CHECK_NOT_NULL(cell); return cell; @@ -1658,52 +1666,55 @@ void MapData::SerializeOwnDescriptors(JSHeapBroker* broker) { TraceScope tracer(broker, this, "MapData::SerializeOwnDescriptors"); Handle<Map> map = Handle<Map>::cast(object()); - DCHECK_NULL(instance_descriptors_); - instance_descriptors_ = - broker->GetOrCreateData(map->instance_descriptors())->AsDescriptorArray(); - int const number_of_own = map->NumberOfOwnDescriptors(); - ZoneVector<PropertyDescriptor>& contents = instance_descriptors_->contents(); - int const current_size = static_cast<int>(contents.size()); - if (number_of_own <= current_size) return; + for (int i = 0; i < number_of_own; ++i) { + SerializeOwnDescriptor(broker, i); + } +} + +void MapData::SerializeOwnDescriptor(JSHeapBroker* broker, + int descriptor_index) { + TraceScope tracer(broker, this, "MapData::SerializeOwnDescriptor"); + Handle<Map> map = Handle<Map>::cast(object()); + + if (instance_descriptors_ == nullptr) { + instance_descriptors_ = broker->GetOrCreateData(map->instance_descriptors()) + ->AsDescriptorArray(); + } + + ZoneMap<int, PropertyDescriptor>& contents = + instance_descriptors_->contents(); + CHECK_LT(descriptor_index, map->NumberOfOwnDescriptors()); + if (contents.find(descriptor_index) != contents.end()) return; Isolate* const isolate = broker->isolate(); auto descriptors = Handle<DescriptorArray>::cast(instance_descriptors_->object()); CHECK_EQ(*descriptors, map->instance_descriptors()); - contents.reserve(number_of_own); - - // Copy the new descriptors. - for (int i = current_size; i < number_of_own; ++i) { - PropertyDescriptor d; - d.key = broker->GetOrCreateData(descriptors->GetKey(i))->AsName(); - d.details = descriptors->GetDetails(i); - if (d.details.location() == kField) { - d.field_index = FieldIndex::ForDescriptor(*map, i); - d.field_owner = - broker->GetOrCreateData(map->FindFieldOwner(isolate, i))->AsMap(); - d.field_type = broker->GetOrCreateData(descriptors->GetFieldType(i)); - d.is_unboxed_double_field = map->IsUnboxedDoubleField(d.field_index); - // Recurse. - } - contents.push_back(d); - } - CHECK_EQ(number_of_own, contents.size()); - - // Recurse on the new owner maps. - for (int i = current_size; i < number_of_own; ++i) { - const PropertyDescriptor& d = contents[i]; - if (d.details.location() == kField) { - CHECK_LE( - Handle<Map>::cast(d.field_owner->object())->NumberOfOwnDescriptors(), - number_of_own); - d.field_owner->SerializeOwnDescriptors(broker); - } + + PropertyDescriptor d; + d.key = + broker->GetOrCreateData(descriptors->GetKey(descriptor_index))->AsName(); + d.details = descriptors->GetDetails(descriptor_index); + if (d.details.location() == kField) { + d.field_index = FieldIndex::ForDescriptor(*map, descriptor_index); + d.field_owner = + broker->GetOrCreateData(map->FindFieldOwner(isolate, descriptor_index)) + ->AsMap(); + d.field_type = + broker->GetOrCreateData(descriptors->GetFieldType(descriptor_index)); + d.is_unboxed_double_field = map->IsUnboxedDoubleField(d.field_index); } + contents[descriptor_index] = d; - TRACE(broker, "Copied " << number_of_own - current_size - << " descriptors into " << instance_descriptors_ - << " (" << number_of_own << " total)"); + if (d.details.location() == kField) { + // Recurse on the owner map. + d.field_owner->SerializeOwnDescriptor(broker, descriptor_index); + } + + TRACE(broker, "Copied descriptor " << descriptor_index << " into " + << instance_descriptors_ << " (" + << contents.size() << " total)"); } void JSObjectData::SerializeRecursive(JSHeapBroker* broker, int depth) { @@ -1716,7 +1727,7 @@ void JSObjectData::SerializeRecursive(JSHeapBroker* broker, int depth) { // We only serialize boilerplates that pass the IsInlinableFastLiteral // check, so we only do a sanity check on the depth here. CHECK_GT(depth, 0); - CHECK(!boilerplate->map()->is_deprecated()); + CHECK(!boilerplate->map().is_deprecated()); // Serialize the elements. Isolate* const isolate = broker->isolate(); @@ -1767,13 +1778,13 @@ void JSObjectData::SerializeRecursive(JSHeapBroker* broker, int depth) { // TODO(turbofan): Do we want to support out-of-object properties? CHECK(boilerplate->HasFastProperties() && - boilerplate->property_array()->length() == 0); + boilerplate->property_array().length() == 0); CHECK_EQ(inobject_fields_.size(), 0u); // Check the in-object properties. - Handle<DescriptorArray> descriptors( - boilerplate->map()->instance_descriptors(), isolate); - int const limit = boilerplate->map()->NumberOfOwnDescriptors(); + Handle<DescriptorArray> descriptors(boilerplate->map().instance_descriptors(), + isolate); + int const limit = boilerplate->map().NumberOfOwnDescriptors(); for (int i = 0; i < limit; i++) { PropertyDetails details = descriptors->GetDetails(i); if (details.location() != kField) continue; @@ -1785,8 +1796,9 @@ void JSObjectData::SerializeRecursive(JSHeapBroker* broker, int depth) { DCHECK_EQ(field_index.property_index(), static_cast<int>(inobject_fields_.size())); if (boilerplate->IsUnboxedDoubleField(field_index)) { - double value = boilerplate->RawFastDoublePropertyAt(field_index); - inobject_fields_.push_back(JSObjectField{value}); + uint64_t value_bits = + boilerplate->RawFastDoublePropertyAsBitsAt(field_index); + inobject_fields_.push_back(JSObjectField{value_bits}); } else { Handle<Object> value(boilerplate->RawFastPropertyAt(field_index), isolate); @@ -1970,14 +1982,14 @@ void JSHeapBroker::CollectArrayAndObjectPrototypes() { CHECK(array_and_object_prototypes_.empty()); Object maybe_context = isolate()->heap()->native_contexts_list(); - while (!maybe_context->IsUndefined(isolate())) { + while (!maybe_context.IsUndefined(isolate())) { Context context = Context::cast(maybe_context); - Object array_prot = context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX); - Object object_prot = context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX); + Object array_prot = context.get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX); + Object object_prot = context.get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX); array_and_object_prototypes_.emplace(JSObject::cast(array_prot), isolate()); array_and_object_prototypes_.emplace(JSObject::cast(object_prot), isolate()); - maybe_context = context->next_context_link(); + maybe_context = context.next_context_link(); } CHECK(!array_and_object_prototypes_.empty()); @@ -2353,6 +2365,16 @@ double JSObjectRef::RawFastDoublePropertyAt(FieldIndex index) const { return object_data->GetInobjectField(index.property_index()).AsDouble(); } +uint64_t JSObjectRef::RawFastDoublePropertyAsBitsAt(FieldIndex index) const { + if (broker()->mode() == JSHeapBroker::kDisabled) { + AllowHandleDereference handle_dereference; + return object()->RawFastDoublePropertyAsBitsAt(index); + } + JSObjectData* object_data = data()->AsJSObject(); + CHECK(index.is_inobject()); + return object_data->GetInobjectField(index.property_index()).AsBitsOfDouble(); +} + ObjectRef JSObjectRef::RawFastPropertyAt(FieldIndex index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleAllocation handle_allocation; @@ -2419,7 +2441,7 @@ int MapRef::GetInObjectPropertyOffset(int i) const { PropertyDetails MapRef::GetPropertyDetails(int descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; - return object()->instance_descriptors()->GetDetails(descriptor_index); + return object()->instance_descriptors().GetDetails(descriptor_index); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); return descriptors->contents().at(descriptor_index).details; @@ -2431,7 +2453,7 @@ NameRef MapRef::GetPropertyKey(int descriptor_index) const { AllowHandleDereference allow_handle_dereference; return NameRef( broker(), - handle(object()->instance_descriptors()->GetKey(descriptor_index), + handle(object()->instance_descriptors().GetKey(descriptor_index), broker()->isolate())); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); @@ -2467,7 +2489,7 @@ ObjectRef MapRef::GetFieldType(int descriptor_index) const { AllowHandleAllocation handle_allocation; AllowHandleDereference allow_handle_dereference; Handle<FieldType> field_type( - object()->instance_descriptors()->GetFieldType(descriptor_index), + object()->instance_descriptors().GetFieldType(descriptor_index), broker()->isolate()); return ObjectRef(broker(), field_type); } @@ -2575,6 +2597,9 @@ BIMODAL_ACCESSOR_C(AllocationSite, ElementsKind, GetElementsKind) BIMODAL_ACCESSOR_C(AllocationSite, AllocationType, GetAllocationType) BIMODAL_ACCESSOR_C(BytecodeArray, int, register_count) +BIMODAL_ACCESSOR_C(BytecodeArray, int, parameter_count) +BIMODAL_ACCESSOR_C(BytecodeArray, interpreter::Register, + incoming_new_target_or_generator_register) BIMODAL_ACCESSOR(Cell, Object, value) @@ -2601,17 +2626,17 @@ BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared) BIMODAL_ACCESSOR(JSFunction, FeedbackVector, feedback_vector) BIMODAL_ACCESSOR_C(JSTypedArray, bool, is_on_heap) -BIMODAL_ACCESSOR_C(JSTypedArray, size_t, length_value) +BIMODAL_ACCESSOR_C(JSTypedArray, size_t, length) BIMODAL_ACCESSOR(JSTypedArray, HeapObject, buffer) BIMODAL_ACCESSOR_B(Map, bit_field2, elements_kind, Map::ElementsKindBits) BIMODAL_ACCESSOR_B(Map, bit_field2, is_extensible, Map::IsExtensibleBit) +BIMODAL_ACCESSOR_B(Map, bit_field2, has_hidden_prototype, + Map::HasHiddenPrototypeBit) BIMODAL_ACCESSOR_B(Map, bit_field3, is_deprecated, Map::IsDeprecatedBit) BIMODAL_ACCESSOR_B(Map, bit_field3, is_dictionary_map, Map::IsDictionaryMapBit) BIMODAL_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors, Map::NumberOfOwnDescriptorsBits) -BIMODAL_ACCESSOR_B(Map, bit_field3, has_hidden_prototype, - Map::HasHiddenPrototypeBit) BIMODAL_ACCESSOR_B(Map, bit_field3, is_migration_target, Map::IsMigrationTargetBit) BIMODAL_ACCESSOR_B(Map, bit_field, has_prototype_slot, Map::HasPrototypeSlotBit) @@ -2651,12 +2676,14 @@ BROKER_SFI_FIELDS(DEF_SFI_ACCESSOR) BIMODAL_ACCESSOR_C(String, int, length) -void* JSTypedArrayRef::elements_external_pointer() const { +BIMODAL_ACCESSOR(FeedbackCell, HeapObject, value) + +void* JSTypedArrayRef::external_pointer() const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; - return FixedTypedArrayBase::cast(object()->elements())->external_pointer(); + return object()->external_pointer(); } - return data()->AsJSTypedArray()->elements_external_pointer(); + return data()->AsJSTypedArray()->external_pointer(); } bool MapRef::IsInobjectSlackTrackingInProgress() const { @@ -2829,14 +2856,14 @@ base::Optional<ObjectRef> ObjectRef::GetOwnConstantElement( base::Optional<ObjectRef> JSArrayRef::GetOwnCowElement(uint32_t index, bool serialize) const { if (broker()->mode() == JSHeapBroker::kDisabled) { - if (!object()->elements()->IsCowArray()) return base::nullopt; + if (!object()->elements().IsCowArray()) return base::nullopt; return GetOwnElementFromHeap(broker(), object(), index, false); } if (serialize) { data()->AsJSObject()->SerializeElements(broker()); } else if (!data()->AsJSObject()->serialized_elements()) { - TRACE(broker(), "'elements' on data " << this); + TRACE(broker(), "'elements' on " << this); return base::nullopt; } if (!elements().map().IsFixedCowArrayMap()) return base::nullopt; @@ -2897,7 +2924,7 @@ ObjectRef::ObjectRef(JSHeapBroker* broker, Handle<Object> object) namespace { OddballType GetOddballType(Isolate* isolate, Map map) { - if (map->instance_type() != ODDBALL_TYPE) { + if (map.instance_type() != ODDBALL_TYPE) { return OddballType::kNone; } ReadOnlyRoots roots(isolate); @@ -2928,9 +2955,9 @@ HeapObjectType HeapObjectRef::GetHeapObjectType() const { AllowHandleDereference handle_dereference; Map map = Handle<HeapObject>::cast(object())->map(); HeapObjectType::Flags flags(0); - if (map->is_undetectable()) flags |= HeapObjectType::kUndetectable; - if (map->is_callable()) flags |= HeapObjectType::kCallable; - return HeapObjectType(map->instance_type(), flags, + if (map.is_undetectable()) flags |= HeapObjectType::kUndetectable; + if (map.is_callable()) flags |= HeapObjectType::kCallable; + return HeapObjectType(map.instance_type(), flags, GetOddballType(broker()->isolate(), map)); } HeapObjectType::Flags flags(0); @@ -3131,6 +3158,12 @@ void MapRef::SerializeOwnDescriptors() { data()->AsMap()->SerializeOwnDescriptors(broker()); } +void MapRef::SerializeOwnDescriptor(int descriptor_index) { + if (broker()->mode() == JSHeapBroker::kDisabled) return; + CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); + data()->AsMap()->SerializeOwnDescriptor(broker(), descriptor_index); +} + void MapRef::SerializeBackPointer() { if (broker()->mode() == JSHeapBroker::kDisabled) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); @@ -3219,7 +3252,7 @@ bool CanInlineElementAccess(MapRef const& map) { if (map.has_indexed_interceptor()) return false; ElementsKind const elements_kind = map.elements_kind(); if (IsFastElementsKind(elements_kind)) return true; - if (IsFixedTypedArrayElementsKind(elements_kind) && + if (IsTypedArrayElementsKind(elements_kind) && elements_kind != BIGUINT64_ELEMENTS && elements_kind != BIGINT64_ELEMENTS) { return true; @@ -3227,6 +3260,9 @@ bool CanInlineElementAccess(MapRef const& map) { return false; } +InsufficientFeedback::InsufficientFeedback() + : ProcessedFeedback(kInsufficient) {} + GlobalAccessFeedback::GlobalAccessFeedback(PropertyCellRef cell) : ProcessedFeedback(kGlobalAccess), cell_or_context_(cell), @@ -3307,6 +3343,14 @@ ElementAccessFeedback::MapIterator ElementAccessFeedback::all_maps( return MapIterator(*this, broker); } +NamedAccessFeedback::NamedAccessFeedback( + NameRef const& name, ZoneVector<PropertyAccessInfo> const& access_infos) + : ProcessedFeedback(kNamedAccess), + name_(name), + access_infos_(access_infos) { + CHECK(!access_infos.empty()); +} + FeedbackSource::FeedbackSource(FeedbackNexus const& nexus) : vector(nexus.vector_handle()), slot(nexus.slot()) {} @@ -3330,14 +3374,6 @@ ProcessedFeedback const* JSHeapBroker::GetFeedback( return it->second; } -ElementAccessFeedback const* JSHeapBroker::GetElementAccessFeedback( - FeedbackSource const& source) const { - ProcessedFeedback const* feedback = GetFeedback(source); - if (feedback == nullptr) return nullptr; - CHECK_EQ(feedback->kind(), ProcessedFeedback::kElementAccess); - return static_cast<ElementAccessFeedback const*>(feedback); -} - GlobalAccessFeedback const* JSHeapBroker::GetGlobalAccessFeedback( FeedbackSource const& source) const { ProcessedFeedback const* feedback = GetFeedback(source); @@ -3348,6 +3384,8 @@ GlobalAccessFeedback const* JSHeapBroker::GetGlobalAccessFeedback( ElementAccessFeedback const* JSHeapBroker::ProcessFeedbackMapsForElementAccess( MapHandles const& maps) { + DCHECK(!maps.empty()); + // Collect possible transition targets. MapHandles possible_transition_targets; possible_transition_targets.reserve(maps.size()); @@ -3359,8 +3397,6 @@ ElementAccessFeedback const* JSHeapBroker::ProcessFeedbackMapsForElementAccess( } } - if (maps.empty()) return nullptr; - ElementAccessFeedback* result = new (zone()) ElementAccessFeedback(zone()); // Separate the actual receiver maps and the possible transition sources. @@ -3446,6 +3482,23 @@ std::ostream& operator<<(std::ostream& os, const ObjectRef& ref) { return os << ref.data(); } +base::Optional<NameRef> JSHeapBroker::GetNameFeedback( + FeedbackNexus const& nexus) { + Name raw_name = nexus.GetName(); + if (raw_name.is_null()) return base::nullopt; + return NameRef(this, handle(raw_name, isolate())); +} + +ElementAccessFeedback const* ProcessedFeedback::AsElementAccess() const { + CHECK_EQ(kElementAccess, kind()); + return static_cast<ElementAccessFeedback const*>(this); +} + +NamedAccessFeedback const* ProcessedFeedback::AsNamedAccess() const { + CHECK_EQ(kNamedAccess, kind()); + return static_cast<NamedAccessFeedback const*>(this); +} + #undef BIMODAL_ACCESSOR #undef BIMODAL_ACCESSOR_B #undef BIMODAL_ACCESSOR_C |