Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 19d0abbc0c4db63ba8c352b4e7c1f098514f2122..9ae968521fd3f1784513b4a801206a0aef48a626 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -1338,9 +1338,14 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { |
} |
-MaybeObject* KeyedLoadIC::Load(Handle<Object> object, |
- Handle<Object> key, |
- ICMissMode miss_mode) { |
+MaybeObject* KeyedLoadIC::LoadForceGeneric(Handle<Object> object, |
+ Handle<Object> key) { |
+ set_target(*generic_stub()); |
+ return Runtime::GetObjectPropertyOrFail(isolate(), object, key); |
+} |
+ |
+ |
+MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) { |
if (MigrateDeprecated(object)) { |
return Runtime::GetObjectPropertyOrFail(isolate(), object, key); |
} |
@@ -1357,20 +1362,18 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, |
if (maybe_object->IsFailure()) return maybe_object; |
} else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { |
ASSERT(!object->IsJSGlobalProxy()); |
- if (miss_mode != MISS_FORCE_GENERIC) { |
- if (object->IsString() && key->IsNumber()) { |
- if (state() == UNINITIALIZED) stub = string_stub(); |
- } else if (object->IsJSObject()) { |
- Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
- if (receiver->elements()->map() == |
- isolate()->heap()->non_strict_arguments_elements_map()) { |
- stub = non_strict_arguments_stub(); |
- } else if (receiver->HasIndexedInterceptor()) { |
- stub = indexed_interceptor_stub(); |
- } else if (!key->ToSmi()->IsFailure() && |
- (!target().is_identical_to(non_strict_arguments_stub()))) { |
- stub = LoadElementStub(receiver); |
- } |
+ if (object->IsString() && key->IsNumber()) { |
+ if (state() == UNINITIALIZED) stub = string_stub(); |
+ } else if (object->IsJSObject()) { |
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
+ if (receiver->elements()->map() == |
+ isolate()->heap()->non_strict_arguments_elements_map()) { |
+ stub = non_strict_arguments_stub(); |
+ } else if (receiver->HasIndexedInterceptor()) { |
+ stub = indexed_interceptor_stub(); |
+ } else if (!key->ToSmi()->IsFailure() && |
+ (!target().is_identical_to(non_strict_arguments_stub()))) { |
+ stub = LoadElementStub(receiver); |
} |
} |
} |
@@ -1915,10 +1918,23 @@ KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver, |
} |
+MaybeObject* KeyedStoreIC::StoreForceGeneric(Handle<Object> object, |
+ Handle<Object> key, |
+ Handle<Object> value) { |
+ set_target(*generic_stub()); |
+ Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, |
+ key, |
+ value, |
+ NONE, |
+ strict_mode()); |
+ RETURN_IF_EMPTY_HANDLE(isolate(), result); |
+ return *result; |
+} |
+ |
+ |
MaybeObject* KeyedStoreIC::Store(Handle<Object> object, |
Handle<Object> key, |
- Handle<Object> value, |
- ICMissMode miss_mode) { |
+ Handle<Object> value) { |
if (MigrateDeprecated(object)) { |
Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, |
key, |
@@ -1957,24 +1973,22 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object, |
if (use_ic) { |
ASSERT(!object->IsJSGlobalProxy()); |
- 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()))) { |
- // 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, key, value); |
- stub = StoreElementStub(receiver, store_mode); |
- } |
+ 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()))) { |
+ // 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, key, value); |
+ stub = StoreElementStub(receiver, store_mode); |
} |
} |
} |
@@ -2073,7 +2087,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { |
Handle<Object> receiver = args.at<Object>(0); |
Handle<Object> key = args.at<Object>(1); |
ic.UpdateState(receiver, key); |
- return ic.Load(receiver, key, MISS); |
+ return ic.Load(receiver, key); |
} |
@@ -2084,7 +2098,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { |
Handle<Object> receiver = args.at<Object>(0); |
Handle<Object> key = args.at<Object>(1); |
ic.UpdateState(receiver, key); |
- return ic.Load(receiver, key, MISS); |
+ return ic.Load(receiver, key); |
} |
@@ -2095,7 +2109,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) { |
Handle<Object> receiver = args.at<Object>(0); |
Handle<Object> key = args.at<Object>(1); |
ic.UpdateState(receiver, key); |
- return ic.Load(receiver, key, MISS_FORCE_GENERIC); |
+ return ic.LoadForceGeneric(receiver, key); |
} |
@@ -2204,7 +2218,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { |
Handle<Object> receiver = args.at<Object>(0); |
Handle<Object> key = args.at<Object>(1); |
ic.UpdateState(receiver, key); |
- return ic.Store(receiver, key, args.at<Object>(2), MISS); |
+ return ic.Store(receiver, key, args.at<Object>(2)); |
} |
@@ -2215,7 +2229,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { |
Handle<Object> receiver = args.at<Object>(0); |
Handle<Object> key = args.at<Object>(1); |
ic.UpdateState(receiver, key); |
- return ic.Store(receiver, key, args.at<Object>(2), MISS); |
+ return ic.Store(receiver, key, args.at<Object>(2)); |
} |
@@ -2260,7 +2274,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { |
Handle<Object> receiver = args.at<Object>(0); |
Handle<Object> key = args.at<Object>(1); |
ic.UpdateState(receiver, key); |
- return ic.Store(receiver, key, args.at<Object>(2), MISS_FORCE_GENERIC); |
+ return ic.StoreForceGeneric(receiver, key, args.at<Object>(2)); |
} |