From dd0cde0e4872655a376f7aba7d0ba6251a343a88 Mon Sep 17 00:00:00 2001 From: mvstanton Date: Fri, 28 Aug 2015 06:13:11 -0700 Subject: [PATCH] Reorder KeyedStoreIC MISS code to avoid unnecessary compilation. We can set the property in the MISS handler before organizing our handlers for element-based keyed stores. Since the property set may fail with an exception, this saves work. BUG= Review URL: https://codereview.chromium.org/1308073010 Cr-Commit-Position: refs/heads/master@{#30444} --- src/ic/ic.cc | 55 +++++++++++++++++++++++++++++++++---------------------- src/ic/ic.h | 2 +- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/ic/ic.cc b/src/ic/ic.cc index e6ee501..50fc1ad 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -1851,7 +1851,7 @@ Handle StoreIC::CompileHandler(LookupIterator* lookup, } -Handle KeyedStoreIC::StoreElementStub(Handle receiver, +Handle KeyedStoreIC::StoreElementStub(Handle receiver_map, KeyedAccessStoreMode store_mode) { // Don't handle megamorphic property accesses for INTERCEPTORS or // ACCESSOR_CONSTANT @@ -1862,7 +1862,6 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, return megamorphic_stub(); } - Handle receiver_map(receiver->map(), isolate()); MapHandleList target_receiver_maps; TargetMaps(&target_receiver_maps); if (target_receiver_maps.length() == 0) { @@ -1896,7 +1895,7 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, store_mode = GetNonTransitioningStoreMode(store_mode); return PropertyICCompiler::ComputeKeyedStoreMonomorphic( transitioned_receiver_map, language_mode(), store_mode); - } else if (*previous_receiver_map == receiver->map() && + } else if (receiver_map.is_identical_to(previous_receiver_map) && old_store_mode == STANDARD_STORE && (store_mode == STORE_AND_GROW_NO_TRANSITION || store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || @@ -2160,23 +2159,43 @@ MaybeHandle KeyedStoreIC::Store(Handle object, } } + Handle old_receiver_map; + bool sloppy_arguments_elements = false; + bool key_is_valid_index = false; + KeyedAccessStoreMode store_mode = STANDARD_STORE; + if (use_ic && object->IsJSObject()) { + Handle receiver = Handle::cast(object); + old_receiver_map = handle(receiver->map(), isolate()); + sloppy_arguments_elements = + !is_sloppy(language_mode()) && + receiver->elements()->map() == + isolate()->heap()->sloppy_arguments_elements_map(); + if (!sloppy_arguments_elements) { + key_is_valid_index = key->IsSmi() && Smi::cast(*key)->value() >= 0; + if (key_is_valid_index) { + uint32_t index = static_cast(Smi::cast(*key)->value()); + store_mode = GetStoreMode(receiver, index, value); + } + } + } + + DCHECK(store_handle.is_null()); + ASSIGN_RETURN_ON_EXCEPTION(isolate(), store_handle, + Runtime::SetObjectProperty(isolate(), object, key, + value, language_mode()), + Object); + if (use_ic) { - if (object->IsJSObject()) { - Handle receiver = Handle::cast(object); - if (receiver->elements()->map() == - isolate()->heap()->sloppy_arguments_elements_map() && - !is_sloppy(language_mode())) { + if (!old_receiver_map.is_null()) { + if (sloppy_arguments_elements) { TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); - } else if (key->IsSmi() && Smi::cast(*key)->value() >= 0) { - uint32_t index = static_cast(Smi::cast(*key)->value()); + } else if (key_is_valid_index) { // We should go generic if receiver isn't a dictionary, but our // prototype chain does have dictionary elements. This ensures that // other non-dictionary receivers in the polymorphic case benefit // from fast path keyed stores. - if (!receiver->map()->DictionaryElementsInPrototypeChainOnly()) { - KeyedAccessStoreMode store_mode = - GetStoreMode(receiver, index, value); - stub = StoreElementStub(receiver, store_mode); + if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly()) { + stub = StoreElementStub(old_receiver_map, store_mode); // Validate that the store_mode in the stub can also be derived // from peeking in the code bits of the handlers. @@ -2192,14 +2211,6 @@ MaybeHandle KeyedStoreIC::Store(Handle object, } } - if (store_handle.is_null()) { - ASSIGN_RETURN_ON_EXCEPTION( - isolate(), store_handle, - Runtime::SetObjectProperty(isolate(), object, key, value, - language_mode()), - Object); - } - if (FLAG_vector_stores) { if (!is_vector_set() || stub.is_null()) { Code* megamorphic = *megamorphic_stub(); diff --git a/src/ic/ic.h b/src/ic/ic.h index 9f4ccd1..9223e7d 100644 --- a/src/ic/ic.h +++ b/src/ic/ic.h @@ -587,7 +587,7 @@ class KeyedStoreIC : public StoreIC { } } - Handle StoreElementStub(Handle receiver, + Handle StoreElementStub(Handle receiver_map, KeyedAccessStoreMode store_mode); private: -- 2.7.4