Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index a6ffb13ad40a84b16073b7d6b8a4bbb43ab7e702..64c3e3832b7ea884be514a44f16c677007493530 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -1959,21 +1959,36 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object, |
Handle<Code> stub = generic_stub(); |
if (miss_mode != MISS_FORCE_GENERIC) { |
- if (object->IsJSObject()) { |
- Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
- bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure(); |
- if (receiver->elements()->map() == |
- isolate()->heap()->non_strict_arguments_elements_map()) { |
- stub = non_strict_arguments_stub(); |
- } else if (key_is_smi_like && |
- (!target().is_identical_to(non_strict_arguments_stub()))) { |
- KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); |
- stub = StoreElementStub(receiver, store_mode); |
+ bool indexed_callbacks = false; |
+ if (object->IsJSReceiver()) { |
+ Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object); |
+ if (receiver->map()->has_element_callbacks() || |
+ receiver->MayHaveIndexedCallbacksInPrototypeChain()) { |
danno
2013/10/23 12:22:11
I think you can and should combine this with the I
danno
2013/10/23 12:22:11
Why doesn't MayHaveIndexedCallbacksInPrototypeChai
mvstanton
2013/10/30 10:42:42
Done.
mvstanton
2013/10/30 10:42:42
Done.
|
+ indexed_callbacks = true; |
+ } |
+ } |
+ |
+ if (!indexed_callbacks) { |
+ if (object->IsJSObject()) { |
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
+ bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure(); |
+ if (receiver->elements()->map() == |
+ isolate()->heap()->non_strict_arguments_elements_map()) { |
+ stub = non_strict_arguments_stub(); |
+ } else if (key_is_smi_like && |
+ (!target().is_identical_to(non_strict_arguments_stub()))) { |
+ KeyedAccessStoreMode store_mode = GetStoreMode( |
+ receiver, key, value); |
+ stub = StoreElementStub(receiver, store_mode); |
+ } else { |
+ TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number"); |
+ } |
} else { |
- TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number"); |
+ TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object"); |
} |
} else { |
- TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object"); |
+ TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
+ "indexed callbacks in prototype chain"); |
} |
} else { |
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); |
@@ -2257,9 +2272,14 @@ RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) { |
ASSERT(args.length() == 4); |
KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
Handle<Object> value = args.at<Object>(0); |
+ Handle<Map> map = args.at<Map>(1); |
Handle<Object> key = args.at<Object>(2); |
Handle<Object> object = args.at<Object>(3); |
StrictModeFlag strict_mode = ic.strict_mode(); |
+ if (object->IsJSObject()) { |
+ JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), |
+ map->elements_kind()); |
+ } |
return Runtime::SetObjectProperty(isolate, |
object, |
key, |