Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index da2211b7b686abc9f28a586fcaba986f4b90eaec..2c3a488e707cb9880fbaeb7c781b37018a391da4 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -1355,7 +1355,8 @@ MaybeObject* KeyedLoadIC::Load(State state, |
stub = non_strict_arguments_stub(); |
} else if (receiver->HasIndexedInterceptor()) { |
stub = indexed_interceptor_stub(); |
- } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { |
+ } else if (!key->ToSmi()->IsFailure() && |
+ (target() != *non_strict_arguments_stub())) { |
stub = LoadElementStub(receiver); |
} |
} |
@@ -1649,7 +1650,8 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, |
return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); |
} |
- if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW || |
+ if (!FLAG_compiled_keyed_stores && |
+ (store_mode == STORE_NO_TRANSITION_HANDLE_COW || |
store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS)) { |
// TODO(danno): We'll soon handle MONOMORPHIC ICs that also support |
// copying COW arrays and silently ignoring some OOB stores into external |
@@ -1712,9 +1714,12 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, |
return isolate()->stub_cache()->ComputeKeyedStoreElement( |
transitioned_receiver_map, strict_mode, store_mode); |
} else if (*previous_receiver_map == receiver->map()) { |
- if (IsGrowStoreMode(store_mode)) { |
+ if (IsGrowStoreMode(store_mode) || |
+ store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
+ store_mode == STORE_NO_TRANSITION_HANDLE_COW) { |
// A "normal" IC that handles stores can switch to a version that can |
- // grow at the end of the array and still stay MONOMORPHIC. |
+ // grow at the end of the array, handle OOB accesses or copy COW arrays |
+ // and still stay MONOMORPHIC. |
return isolate()->stub_cache()->ComputeKeyedStoreElement( |
receiver_map, strict_mode, store_mode); |
} |
@@ -1813,8 +1818,10 @@ bool IsOutOfBoundsAccess(Handle<JSObject> receiver, |
KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver, |
Handle<Object> key, |
Handle<Object> value) { |
- ASSERT(key->IsSmi()); |
- int index = Smi::cast(*key)->value(); |
+ ASSERT(!key->ToSmi()->IsFailure()); |
+ Smi* smi_key = NULL; |
+ key->ToSmi()->To(&smi_key); |
+ int index = smi_key->value(); |
bool oob_access = IsOutOfBoundsAccess(receiver, index); |
bool allow_growth = receiver->IsJSArray() && oob_access; |
if (allow_growth) { |
@@ -1872,6 +1879,10 @@ KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver, |
if (!FLAG_trace_external_array_abuse && |
receiver->map()->has_external_array_elements() && oob_access) { |
return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS; |
+ } |
+ Heap* heap = receiver->GetHeap(); |
+ if (receiver->elements()->map() == heap->fixed_cow_array_map()) { |
+ return STORE_NO_TRANSITION_HANDLE_COW; |
} else { |
return STANDARD_STORE; |
} |
@@ -1910,13 +1921,20 @@ MaybeObject* KeyedStoreIC::Store(State state, |
if (miss_mode != MISS_FORCE_GENERIC) { |
if (object->IsJSObject()) { |
Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
+ bool key_is_smi_like = key->IsSmi() || |
+ (FLAG_compiled_keyed_stores && !key->ToSmi()->IsFailure()); |
if (receiver->elements()->map() == |
isolate()->heap()->non_strict_arguments_elements_map()) { |
stub = non_strict_arguments_stub(); |
- } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { |
+ } else if (key_is_smi_like && |
+ (target() != *non_strict_arguments_stub())) { |
KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); |
stub = StoreElementStub(receiver, store_mode, strict_mode); |
+ } else { |
+ TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "key not a number"); |
} |
+ } else { |
+ TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "not an object"); |
} |
} else { |
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); |
@@ -2074,7 +2092,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) { |
RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
- StoreIC ic(isolate); |
+ StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
return ic.Store(state, |
@@ -2150,7 +2168,22 @@ RUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { |
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
- KeyedStoreIC ic(isolate); |
+ KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
+ Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
+ return ic.Store(state, |
+ Code::GetStrictMode(extra_ic_state), |
+ args.at<Object>(0), |
+ args.at<Object>(1), |
+ args.at<Object>(2), |
+ MISS); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 3); |
+ KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); |
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
return ic.Store(state, |
@@ -2165,7 +2198,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { |
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { |
NoHandleAllocation na(isolate); |
ASSERT(args.length() == 3); |
- KeyedStoreIC ic(isolate); |
+ KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
Handle<Object> object = args.at<Object>(0); |
Handle<Object> key = args.at<Object>(1); |
@@ -2183,7 +2216,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { |
RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 3); |
- KeyedStoreIC ic(isolate); |
+ KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
return ic.Store(state, |