diff --git a/src/ic/access-compiler.cc b/src/ic/access-compiler.cc index 0dc9ab6e8d..951966e7de 100644 --- a/src/ic/access-compiler.cc +++ b/src/ic/access-compiler.cc @@ -49,5 +49,25 @@ Register* PropertyAccessCompiler::GetCallingConvention(Code::Kind kind) { DCHECK(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC); return store_calling_convention(); } + + +Register PropertyAccessCompiler::slot() const { + if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) { + return LoadDescriptor::SlotRegister(); + } + DCHECK(FLAG_vector_stores && + (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC)); + return VectorStoreICDescriptor::SlotRegister(); +} + + +Register PropertyAccessCompiler::vector() const { + if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) { + return LoadWithVectorDescriptor::VectorRegister(); + } + DCHECK(FLAG_vector_stores && + (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC)); + return VectorStoreICDescriptor::VectorRegister(); +} } // namespace internal } // namespace v8 diff --git a/src/ic/access-compiler.h b/src/ic/access-compiler.h index 61567a2224..4eb70eff77 100644 --- a/src/ic/access-compiler.h +++ b/src/ic/access-compiler.h @@ -54,8 +54,8 @@ class PropertyAccessCompiler BASE_EMBEDDED { Register receiver() const { return registers_[0]; } Register name() const { return registers_[1]; } - Register slot() const { return LoadDescriptor::SlotRegister(); } - Register vector() const { return LoadWithVectorDescriptor::VectorRegister(); } + Register slot() const; + Register vector() const; Register scratch1() const { return registers_[2]; } Register scratch2() const { return registers_[3]; } Register scratch3() const { return registers_[4]; } diff --git a/src/ic/handler-compiler.cc b/src/ic/handler-compiler.cc index 7e242d3bc9..a42fc690f8 100644 --- a/src/ic/handler-compiler.cc +++ b/src/ic/handler-compiler.cc @@ -424,6 +424,8 @@ Handle NamedStoreHandlerCompiler::CompileStoreTransition( Handle transition, Handle name) { Label miss; + if (FLAG_vector_stores) PushVectorAndSlot(); + // Check that we are allowed to write this. bool is_nonexistent = holder()->map() == transition->GetBackPointer(); if (is_nonexistent) { @@ -454,16 +456,19 @@ Handle NamedStoreHandlerCompiler::CompileStoreTransition( DCHECK(!transition->is_access_check_needed()); // Call to respective StoreTransitionStub. - Register transition_map_reg = StoreTransitionDescriptor::MapRegister(); - bool push_map_on_stack = transition_map_reg.is(no_reg); - Register map_reg = push_map_on_stack ? scratch1() : transition_map_reg; + Register transition_map_reg = StoreTransitionHelper::MapRegister(); + bool stack_args = StoreTransitionHelper::UsesStackArgs(); + Register map_reg = stack_args ? scratch1() : transition_map_reg; if (details.type() == DATA_CONSTANT) { DCHECK(descriptors->GetValue(descriptor)->IsJSFunction()); GenerateRestoreMap(transition, map_reg, scratch2(), &miss); GenerateConstantCheck(map_reg, descriptor, value(), scratch2(), &miss); - if (push_map_on_stack) { + if (stack_args) { + // Also pushes vector and slot. GeneratePushMap(map_reg, scratch2()); + } else if (FLAG_vector_stores) { + PopVectorAndSlot(); } GenerateRestoreName(name); StoreTransitionStub stub(isolate()); @@ -480,8 +485,11 @@ Handle NamedStoreHandlerCompiler::CompileStoreTransition( : StoreTransitionStub::StoreMapAndValue; GenerateRestoreMap(transition, map_reg, scratch2(), &miss); - if (push_map_on_stack) { + if (stack_args) { + // Also pushes vector and slot. GeneratePushMap(map_reg, scratch2()); + } else if (FLAG_vector_stores) { + PopVectorAndSlot(); } GenerateRestoreName(name); StoreTransitionStub stub(isolate(), @@ -491,21 +499,37 @@ Handle NamedStoreHandlerCompiler::CompileStoreTransition( } GenerateRestoreName(&miss, name); + if (FLAG_vector_stores) PopVectorAndSlot(); TailCallBuiltin(masm(), MissBuiltin(kind())); return GetCode(kind(), Code::FAST, name); } +bool NamedStoreHandlerCompiler::RequiresFieldTypeChecks( + HeapType* field_type) const { + return !field_type->Classes().Done(); +} + + Handle NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { Label miss; DCHECK(it->representation().IsHeapObject()); - GenerateFieldTypeChecks(*it->GetFieldType(), value(), &miss); + HeapType* field_type = *it->GetFieldType(); + bool need_save_restore = false; + if (RequiresFieldTypeChecks(field_type)) { + need_save_restore = IC::ICUseVector(kind()); + if (need_save_restore) PushVectorAndSlot(); + GenerateFieldTypeChecks(field_type, value(), &miss); + if (need_save_restore) PopVectorAndSlot(); + } + StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation()); GenerateTailCall(masm(), stub.GetCode()); __ bind(&miss); + if (need_save_restore) PopVectorAndSlot(); TailCallBuiltin(masm(), MissBuiltin(kind())); return GetCode(kind(), Code::FAST, it->name()); } diff --git a/src/ic/handler-compiler.h b/src/ic/handler-compiler.h index 05c973a625..f5dafe9038 100644 --- a/src/ic/handler-compiler.h +++ b/src/ic/handler-compiler.h @@ -262,6 +262,7 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler { Register value_reg, Register scratch, Label* miss_label); + bool RequiresFieldTypeChecks(HeapType* field_type) const; void GenerateFieldTypeChecks(HeapType* field_type, Register value_reg, Label* miss_label); diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc index d42bfa7793..875d98729f 100644 --- a/src/ic/ic-compiler.cc +++ b/src/ic/ic-compiler.cc @@ -119,6 +119,25 @@ Handle PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler( } +Handle PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( + Handle receiver_map, LanguageMode language_mode, + KeyedAccessStoreMode store_mode) { + Isolate* isolate = receiver_map->GetIsolate(); + ExtraICState extra_state = + KeyedStoreIC::ComputeExtraICState(language_mode, store_mode); + + DCHECK(store_mode == STANDARD_STORE || + store_mode == STORE_AND_GROW_NO_TRANSITION || + store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || + store_mode == STORE_NO_TRANSITION_HANDLE_COW); + + PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); + Handle code = + compiler.CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode); + return code; +} + + Handle PropertyICCompiler::ComputeKeyedStoreMonomorphic( Handle receiver_map, LanguageMode language_mode, KeyedAccessStoreMode store_mode) { @@ -220,31 +239,6 @@ Handle PropertyICCompiler::ComputeCompareNil(Handle receiver_map, } -Handle PropertyICCompiler::ComputeKeyedLoadPolymorphic( - MapHandleList* receiver_maps, LanguageMode language_mode) { - Isolate* isolate = receiver_maps->at(0)->GetIsolate(); - DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT); - Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); - Handle cache = - isolate->factory()->polymorphic_code_cache(); - Handle probe = cache->Lookup(receiver_maps, flags); - if (probe->IsCode()) return Handle::cast(probe); - - CodeHandleList handlers(receiver_maps->length()); - ElementHandlerCompiler compiler(isolate); - compiler.CompileElementHandlers(receiver_maps, &handlers, language_mode); - PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC); - Handle code = ic_compiler.CompilePolymorphic( - receiver_maps, &handlers, isolate->factory()->empty_string(), - Code::NORMAL, ELEMENT); - - isolate->counters()->keyed_load_polymorphic_stubs()->Increment(); - - PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); - return code; -} - - Handle PropertyICCompiler::ComputePolymorphic( Code::Kind kind, MapHandleList* maps, CodeHandleList* handlers, int valid_maps, Handle name, ExtraICState extra_ic_state) { @@ -256,6 +250,23 @@ Handle PropertyICCompiler::ComputePolymorphic( } +void PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( + MapHandleList* receiver_maps, MapHandleList* transitioned_maps, + CodeHandleList* handlers, KeyedAccessStoreMode store_mode, + LanguageMode language_mode) { + Isolate* isolate = receiver_maps->at(0)->GetIsolate(); + DCHECK(store_mode == STANDARD_STORE || + store_mode == STORE_AND_GROW_NO_TRANSITION || + store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || + store_mode == STORE_NO_TRANSITION_HANDLE_COW); + ExtraICState extra_state = + KeyedStoreIC::ComputeExtraICState(language_mode, store_mode); + PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); + compiler.CompileKeyedStorePolymorphicHandlers( + receiver_maps, transitioned_maps, handlers, store_mode); +} + + Handle PropertyICCompiler::ComputeKeyedStorePolymorphic( MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, LanguageMode language_mode) { @@ -338,11 +349,9 @@ Handle PropertyICCompiler::GetCode(Code::Kind kind, Code::StubType type, } -Handle PropertyICCompiler::CompileKeyedStorePolymorphic( - MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) { - // Collect MONOMORPHIC stubs for all |receiver_maps|. - CodeHandleList handlers(receiver_maps->length()); - MapHandleList transitioned_maps(receiver_maps->length()); +void PropertyICCompiler::CompileKeyedStorePolymorphicHandlers( + MapHandleList* receiver_maps, MapHandleList* transitioned_maps, + CodeHandleList* handlers, KeyedAccessStoreMode store_mode) { for (int i = 0; i < receiver_maps->length(); ++i) { Handle receiver_map(receiver_maps->at(i)); Handle cached_stub; @@ -379,9 +388,19 @@ Handle PropertyICCompiler::CompileKeyedStorePolymorphic( } } DCHECK(!cached_stub.is_null()); - handlers.Add(cached_stub); - transitioned_maps.Add(transitioned_map); + handlers->Add(cached_stub); + transitioned_maps->Add(transitioned_map); } +} + + +Handle PropertyICCompiler::CompileKeyedStorePolymorphic( + MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode) { + // Collect MONOMORPHIC stubs for all |receiver_maps|. + CodeHandleList handlers(receiver_maps->length()); + MapHandleList transitioned_maps(receiver_maps->length()); + CompileKeyedStorePolymorphicHandlers(receiver_maps, &transitioned_maps, + &handlers, store_mode); Handle code = CompileKeyedStorePolymorphic(receiver_maps, &handlers, &transitioned_maps); @@ -394,7 +413,7 @@ Handle PropertyICCompiler::CompileKeyedStorePolymorphic( #define __ ACCESS_MASM(masm()) -Handle PropertyICCompiler::CompileKeyedStoreMonomorphic( +Handle PropertyICCompiler::CompileKeyedStoreMonomorphicHandler( Handle receiver_map, KeyedAccessStoreMode store_mode) { ElementsKind elements_kind = receiver_map->elements_kind(); bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; @@ -408,6 +427,14 @@ Handle PropertyICCompiler::CompileKeyedStoreMonomorphic( } else { stub = StoreElementStub(isolate(), elements_kind, store_mode).GetCode(); } + return stub; +} + + +Handle PropertyICCompiler::CompileKeyedStoreMonomorphic( + Handle receiver_map, KeyedAccessStoreMode store_mode) { + Handle stub = + CompileKeyedStoreMonomorphicHandler(receiver_map, store_mode); Handle cell = Map::WeakCellForMap(receiver_map); diff --git a/src/ic/ic-compiler.h b/src/ic/ic-compiler.h index b5226e9a6e..ee6597d59d 100644 --- a/src/ic/ic-compiler.h +++ b/src/ic/ic-compiler.h @@ -34,11 +34,16 @@ class PropertyICCompiler : public PropertyAccessCompiler { static Handle ComputeKeyedLoadMonomorphicHandler( Handle receiver_map, ExtraICState extra_ic_state); + static Handle ComputeKeyedStoreMonomorphicHandler( + Handle receiver_map, LanguageMode language_mode, + KeyedAccessStoreMode store_mode); static Handle ComputeKeyedStoreMonomorphic( Handle receiver_map, LanguageMode language_mode, KeyedAccessStoreMode store_mode); - static Handle ComputeKeyedLoadPolymorphic(MapHandleList* receiver_maps, - LanguageMode language_mode); + static void ComputeKeyedStorePolymorphicHandlers( + MapHandleList* receiver_maps, MapHandleList* transitioned_maps, + CodeHandleList* handlers, KeyedAccessStoreMode store_mode, + LanguageMode language_mode); static Handle ComputeKeyedStorePolymorphic( MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, LanguageMode language_mode); @@ -78,10 +83,16 @@ class PropertyICCompiler : public PropertyAccessCompiler { Handle name, Code::StubType type, IcCheckType check); + Handle CompileKeyedStoreMonomorphicHandler( + Handle receiver_map, KeyedAccessStoreMode store_mode); Handle CompileKeyedStoreMonomorphic(Handle receiver_map, KeyedAccessStoreMode store_mode); Handle CompileKeyedStorePolymorphic(MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode); + void CompileKeyedStorePolymorphicHandlers(MapHandleList* receiver_maps, + MapHandleList* transitioned_maps, + CodeHandleList* handlers, + KeyedAccessStoreMode store_mode); Handle CompileKeyedStorePolymorphic(MapHandleList* receiver_maps, CodeHandleList* handler_stubs, MapHandleList* transitioned_maps); diff --git a/src/ic/ic.cc b/src/ic/ic.cc index 644df525d2..85e3f3c889 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -123,8 +123,11 @@ void IC::TraceIC(const char* type, Handle name, State old_state, ExtraICState extra_state = new_target->extra_ic_state(); const char* modifier = ""; if (new_target->kind() == Code::KEYED_STORE_IC) { - modifier = GetTransitionMarkModifier( - KeyedStoreIC::GetKeyedAccessStoreMode(extra_state)); + KeyedAccessStoreMode mode = + FLAG_vector_stores + ? casted_nexus()->GetKeyedAccessStoreMode() + : KeyedStoreIC::GetKeyedAccessStoreMode(extra_state); + modifier = GetTransitionMarkModifier(mode); } PrintF(" (%c->%c%s) ", TransitionMarkFromState(old_state), TransitionMarkFromState(new_state), modifier); @@ -666,6 +669,20 @@ void IC::ConfigureVectorState(Handle name, MapHandleList* maps, } +void IC::ConfigureVectorState(MapHandleList* maps, + MapHandleList* transitioned_maps, + CodeHandleList* handlers) { + DCHECK(UseVector()); + DCHECK(kind() == Code::KEYED_STORE_IC); + KeyedStoreICNexus* nexus = casted_nexus(); + nexus->ConfigurePolymorphic(maps, transitioned_maps, handlers); + + vector_set_ = true; + OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), + POLYMORPHIC); +} + + MaybeHandle LoadIC::Load(Handle object, Handle name) { // If the object is undefined or null it's illegal to try to get any // of its properties; throw a TypeError in that case. @@ -967,7 +984,7 @@ static Handle KeyedStoreICInitializeStubHelper( Handle KeyedStoreIC::initialize_stub(Isolate* isolate, LanguageMode language_mode, State initialization_state) { - if (FLAG_vector_stores) { + if (FLAG_vector_stores && initialization_state != MEGAMORPHIC) { VectorKeyedStoreICTrampolineStub stub(isolate, StoreICState(language_mode)); return stub.GetCode(); } @@ -989,6 +1006,13 @@ Handle KeyedStoreIC::initialize_stub_in_optimized_code( } +Handle KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate, + ExtraICState extra_state) { + LanguageMode mode = StoreICState::GetLanguageMode(extra_state); + return KeyedStoreICInitializeStubHelper(isolate, mode, MEGAMORPHIC); +} + + Handle LoadIC::megamorphic_stub() { DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state()); @@ -1854,6 +1878,7 @@ Handle StoreIC::CompileHandler(LookupIterator* lookup, Handle KeyedStoreIC::StoreElementStub(Handle receiver_map, KeyedAccessStoreMode store_mode) { + Handle null_handle; // Don't handle megamorphic property accesses for INTERCEPTORS or // ACCESSOR_CONSTANT // via megamorphic stubs, since they don't have a map in their relocation info @@ -1869,6 +1894,13 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver_map, Handle monomorphic_map = ComputeTransitionedMap(receiver_map, store_mode); store_mode = GetNonTransitioningStoreMode(store_mode); + if (FLAG_vector_stores) { + Handle handler = + PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( + monomorphic_map, language_mode(), store_mode); + ConfigureVectorState(Handle::null(), monomorphic_map, handler); + return null_handle; + } return PropertyICCompiler::ComputeKeyedStoreMonomorphic( monomorphic_map, language_mode(), store_mode); } @@ -1878,7 +1910,9 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver_map, // superset of the original IC. Handle those here if the receiver map hasn't // changed or it has transitioned to a more general kind. KeyedAccessStoreMode old_store_mode = - KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); + FLAG_vector_stores + ? GetKeyedAccessStoreMode() + : KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); Handle previous_receiver_map = target_receiver_maps.at(0); if (state() == MONOMORPHIC) { Handle transitioned_receiver_map = receiver_map; @@ -1894,6 +1928,14 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver_map, // if they at least come from the same origin for a transitioning store, // stay MONOMORPHIC and use the map for the most generic ElementsKind. store_mode = GetNonTransitioningStoreMode(store_mode); + if (FLAG_vector_stores) { + Handle handler = + PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( + transitioned_receiver_map, language_mode(), store_mode); + ConfigureVectorState(Handle::null(), transitioned_receiver_map, + handler); + return null_handle; + } return PropertyICCompiler::ComputeKeyedStoreMonomorphic( transitioned_receiver_map, language_mode(), store_mode); } else if (receiver_map.is_identical_to(previous_receiver_map) && @@ -1904,6 +1946,13 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver_map, // A "normal" IC that handles stores can switch to a version that can // grow at the end of the array, handle OOB accesses or copy COW arrays // and still stay MONOMORPHIC. + if (FLAG_vector_stores) { + Handle handler = + PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( + receiver_map, language_mode(), store_mode); + ConfigureVectorState(Handle::null(), receiver_map, handler); + return null_handle; + } return PropertyICCompiler::ComputeKeyedStoreMonomorphic( receiver_map, language_mode(), store_mode); } @@ -1964,6 +2013,16 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver_map, } } + if (FLAG_vector_stores) { + MapHandleList transitioned_maps(target_receiver_maps.length()); + CodeHandleList handlers(target_receiver_maps.length()); + PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( + &target_receiver_maps, &transitioned_maps, &handlers, store_mode, + language_mode()); + ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers); + return null_handle; + } + return PropertyICCompiler::ComputeKeyedStorePolymorphic( &target_receiver_maps, store_mode, language_mode()); } @@ -2200,7 +2259,7 @@ MaybeHandle KeyedStoreIC::Store(Handle object, // Validate that the store_mode in the stub can also be derived // from peeking in the code bits of the handlers. - ValidateStoreMode(stub); + if (!FLAG_vector_stores) ValidateStoreMode(stub); } else { TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); } @@ -2467,7 +2526,7 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { Handle result; if (FLAG_vector_stores) { - DCHECK(args.length() == 5); + DCHECK(args.length() == 5 || args.length() == 6); Handle slot = args.at(3); Handle vector = args.at(4); FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); @@ -2595,12 +2654,19 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_MissFromStubFailure) { RUNTIME_FUNCTION(Runtime_StoreIC_Slow) { HandleScope scope(isolate); - DCHECK(args.length() == 3); - StoreIC ic(IC::NO_EXTRA_FRAME, isolate); + DCHECK(args.length() == (FLAG_vector_stores ? 5 : 3)); Handle object = args.at(0); Handle key = args.at(1); Handle value = args.at(2); - LanguageMode language_mode = ic.language_mode(); + LanguageMode language_mode; + if (FLAG_vector_stores) { + StoreICNexus nexus(isolate); + StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); + language_mode = ic.language_mode(); + } else { + StoreIC ic(IC::NO_EXTRA_FRAME, isolate); + language_mode = ic.language_mode(); + } Handle result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, @@ -2611,12 +2677,19 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Slow) { RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { HandleScope scope(isolate); - DCHECK(args.length() == 3); - KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); + DCHECK(args.length() == (FLAG_vector_stores ? 5 : 3)); Handle object = args.at(0); Handle key = args.at(1); Handle value = args.at(2); - LanguageMode language_mode = ic.language_mode(); + LanguageMode language_mode; + if (FLAG_vector_stores) { + KeyedStoreICNexus nexus(isolate); + KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); + language_mode = ic.language_mode(); + } else { + KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); + language_mode = ic.language_mode(); + } Handle result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, @@ -2628,14 +2701,20 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { TimerEventScope timer(isolate); HandleScope scope(isolate); - DCHECK(args.length() == 4); - KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); + DCHECK(args.length() == (FLAG_vector_stores ? 6 : 4)); Handle object = args.at(0); Handle key = args.at(1); Handle value = args.at(2); - Handle map = args.at(3); - - LanguageMode language_mode = ic.language_mode(); + Handle map = args.at(FLAG_vector_stores ? 5 : 3); + LanguageMode language_mode; + if (FLAG_vector_stores) { + KeyedStoreICNexus nexus(isolate); + KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); + language_mode = ic.language_mode(); + } else { + KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); + language_mode = ic.language_mode(); + } if (object->IsJSObject()) { JSObject::TransitionElementsKind(Handle::cast(object), map->elements_kind()); diff --git a/src/ic/ic.h b/src/ic/ic.h index 9223e7dce8..6002d92913 100644 --- a/src/ic/ic.h +++ b/src/ic/ic.h @@ -122,6 +122,11 @@ class IC { // Configure the vector for POLYMORPHIC. void ConfigureVectorState(Handle name, MapHandleList* maps, CodeHandleList* handlers); + // Configure the vector for POLYMORPHIC with transitions (only for element + // keyed stores). + void ConfigureVectorState(MapHandleList* maps, + MapHandleList* transitioned_maps, + CodeHandleList* handlers); char TransitionMarkFromState(IC::State state); void TraceIC(const char* type, Handle name); @@ -538,10 +543,17 @@ class KeyedStoreIC : public StoreIC { static KeyedAccessStoreMode GetKeyedAccessStoreMode( ExtraICState extra_state) { + DCHECK(!FLAG_vector_stores); return ExtraICStateKeyedAccessStoreMode::decode(extra_state); } + KeyedAccessStoreMode GetKeyedAccessStoreMode() { + DCHECK(FLAG_vector_stores); + return casted_nexus()->GetKeyedAccessStoreMode(); + } + static IcCheckType GetKeyType(ExtraICState extra_state) { + DCHECK(!FLAG_vector_stores); return IcCheckTypeField::decode(extra_state); } @@ -571,6 +583,8 @@ class KeyedStoreIC : public StoreIC { static Handle initialize_stub_in_optimized_code( Isolate* isolate, LanguageMode language_mode, State initialization_state); + static Handle ChooseMegamorphicStub(Isolate* isolate, + ExtraICState extra_state); static void Clear(Isolate* isolate, Code* host, KeyedStoreICNexus* nexus); diff --git a/src/type-feedback-vector.h b/src/type-feedback-vector.h index cbba89339a..2118a088f4 100644 --- a/src/type-feedback-vector.h +++ b/src/type-feedback-vector.h @@ -407,6 +407,10 @@ class KeyedStoreICNexus : public FeedbackNexus { : FeedbackNexus(vector, slot) { DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC); } + explicit KeyedStoreICNexus(Isolate* isolate) + : FeedbackNexus(TypeFeedbackVector::DummyVector(isolate), + TypeFeedbackVector::DummySlot( + TypeFeedbackVector::kDummyKeyedStoreICSlot)) {} KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) : FeedbackNexus(vector, slot) { DCHECK(vector->GetKind(slot) == Code::KEYED_STORE_IC);