| Index: src/ic/ic.cc
|
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc
|
| index e6ee50108bb33699349a0bd32c49454b3c7de5a6..50fc1adb2569afea23e28bc7ea376433ff80a980 100644
|
| --- a/src/ic/ic.cc
|
| +++ b/src/ic/ic.cc
|
| @@ -1851,7 +1851,7 @@ Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
|
| }
|
|
|
|
|
| -Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
| +Handle<Code> KeyedStoreIC::StoreElementStub(Handle<Map> receiver_map,
|
| KeyedAccessStoreMode store_mode) {
|
| // Don't handle megamorphic property accesses for INTERCEPTORS or
|
| // ACCESSOR_CONSTANT
|
| @@ -1862,7 +1862,6 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
| return megamorphic_stub();
|
| }
|
|
|
| - Handle<Map> receiver_map(receiver->map(), isolate());
|
| MapHandleList target_receiver_maps;
|
| TargetMaps(&target_receiver_maps);
|
| if (target_receiver_maps.length() == 0) {
|
| @@ -1896,7 +1895,7 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> 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<Object> KeyedStoreIC::Store(Handle<Object> object,
|
| }
|
| }
|
|
|
| + Handle<Map> 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<JSObject> receiver = Handle<JSObject>::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<uint32_t>(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<JSObject> receiver = Handle<JSObject>::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<uint32_t>(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<Object> KeyedStoreIC::Store(Handle<Object> 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();
|
|
|