| Index: src/ic/ic.cc
|
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
| index 644df525d24492562c9a5cd017040df55a812806..85e3f3c889e0e0a617760eb3d3e1e49b05f2a8f4 100644
|
| --- a/src/ic/ic.cc
|
| +++ b/src/ic/ic.cc
|
| @@ -123,8 +123,11 @@ void IC::TraceIC(const char* type, Handle<Object> 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<KeyedStoreICNexus>()->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> 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<KeyedStoreICNexus>();
|
| + nexus->ConfigurePolymorphic(maps, transitioned_maps, handlers);
|
| +
|
| + vector_set_ = true;
|
| + OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
|
| + POLYMORPHIC);
|
| +}
|
| +
|
| +
|
| MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> 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<Code> KeyedStoreICInitializeStubHelper(
|
| Handle<Code> 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<Code> KeyedStoreIC::initialize_stub_in_optimized_code(
|
| }
|
|
|
|
|
| +Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
|
| + ExtraICState extra_state) {
|
| + LanguageMode mode = StoreICState::GetLanguageMode(extra_state);
|
| + return KeyedStoreICInitializeStubHelper(isolate, mode, MEGAMORPHIC);
|
| +}
|
| +
|
| +
|
| Handle<Code> LoadIC::megamorphic_stub() {
|
| DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
|
| return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state());
|
| @@ -1854,6 +1878,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
|
|
|
| Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
|
| KeyedAccessStoreMode store_mode) {
|
| + Handle<Code> 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<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
|
| Handle<Map> monomorphic_map =
|
| ComputeTransitionedMap(receiver_map, store_mode);
|
| store_mode = GetNonTransitioningStoreMode(store_mode);
|
| + if (FLAG_vector_stores) {
|
| + Handle<Code> handler =
|
| + PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
|
| + monomorphic_map, language_mode(), store_mode);
|
| + ConfigureVectorState(Handle<Name>::null(), monomorphic_map, handler);
|
| + return null_handle;
|
| + }
|
| return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
|
| monomorphic_map, language_mode(), store_mode);
|
| }
|
| @@ -1878,7 +1910,9 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> 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<Map> previous_receiver_map = target_receiver_maps.at(0);
|
| if (state() == MONOMORPHIC) {
|
| Handle<Map> transitioned_receiver_map = receiver_map;
|
| @@ -1894,6 +1928,14 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> 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<Code> handler =
|
| + PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
|
| + transitioned_receiver_map, language_mode(), store_mode);
|
| + ConfigureVectorState(Handle<Name>::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<Code> KeyedStoreIC::StoreElementStub(Handle<Map> 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<Code> handler =
|
| + PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
|
| + receiver_map, language_mode(), store_mode);
|
| + ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
|
| + return null_handle;
|
| + }
|
| return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
|
| receiver_map, language_mode(), store_mode);
|
| }
|
| @@ -1964,6 +2013,16 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> 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<Object> KeyedStoreIC::Store(Handle<Object> 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<Object> result;
|
|
|
| if (FLAG_vector_stores) {
|
| - DCHECK(args.length() == 5);
|
| + DCHECK(args.length() == 5 || args.length() == 6);
|
| Handle<Smi> slot = args.at<Smi>(3);
|
| Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(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> object = args.at<Object>(0);
|
| Handle<Object> key = args.at<Object>(1);
|
| Handle<Object> value = args.at<Object>(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<Object> 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> object = args.at<Object>(0);
|
| Handle<Object> key = args.at<Object>(1);
|
| Handle<Object> value = args.at<Object>(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<Object> result;
|
| ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| isolate, result,
|
| @@ -2628,14 +2701,20 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
|
| RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
|
| TimerEventScope<TimerEventIcMiss> 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> object = args.at<Object>(0);
|
| Handle<Object> key = args.at<Object>(1);
|
| Handle<Object> value = args.at<Object>(2);
|
| - Handle<Map> map = args.at<Map>(3);
|
| -
|
| - LanguageMode language_mode = ic.language_mode();
|
| + Handle<Map> map = args.at<Map>(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<JSObject>::cast(object),
|
| map->elements_kind());
|
|
|