Index: src/ic/ic.cc |
diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
index 7d572ee4819263c6368c0e83c458aa6d072c7e46..a6b45e9912f8eef13d114a78ac9719d3b50c9c1e 100644 |
--- a/src/ic/ic.cc |
+++ b/src/ic/ic.cc |
@@ -1402,9 +1402,7 @@ MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, |
} else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { |
if (object->IsJSObject() || (object->IsString() && key->IsNumber())) { |
Handle<HeapObject> receiver = Handle<HeapObject>::cast(object); |
- if (object->IsString() || !Object::ToSmi(isolate(), key).is_null()) { |
- stub = LoadElementStub(receiver); |
- } |
+ if (object->IsString() || key->IsSmi()) stub = LoadElementStub(receiver); |
} |
} |
@@ -1994,25 +1992,24 @@ Handle<Map> KeyedStoreIC::ComputeTransitionedMap( |
} |
-bool IsOutOfBoundsAccess(Handle<JSObject> receiver, int index) { |
+bool IsOutOfBoundsAccess(Handle<JSObject> receiver, uint32_t index) { |
+ uint32_t length = 0; |
if (receiver->IsJSArray()) { |
- return JSArray::cast(*receiver)->length()->IsSmi() && |
- index >= Smi::cast(JSArray::cast(*receiver)->length())->value(); |
+ JSArray::cast(*receiver)->length()->ToArrayLength(&length); |
+ } else { |
+ length = static_cast<uint32_t>(receiver->elements()->length()); |
} |
- return index >= receiver->elements()->length(); |
+ return index >= length; |
} |
-KeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver, |
- Handle<Object> key, |
- Handle<Object> value) { |
- Handle<Smi> smi_key = Object::ToSmi(isolate(), key).ToHandleChecked(); |
- int index = smi_key->value(); |
+static KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver, |
+ uint32_t index, Handle<Object> value) { |
bool oob_access = IsOutOfBoundsAccess(receiver, index); |
// Don't consider this a growing store if the store would send the receiver to |
// dictionary mode. |
bool allow_growth = receiver->IsJSArray() && oob_access && |
- !receiver->WouldConvertToSlowElements(key); |
+ !receiver->WouldConvertToSlowElements(index); |
if (allow_growth) { |
// Handle growing array in stub if necessary. |
if (receiver->HasFastSmiElements()) { |
@@ -2145,18 +2142,19 @@ MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, |
if (use_ic) { |
if (object->IsJSObject()) { |
Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
- bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); |
if (receiver->elements()->map() == |
isolate()->heap()->sloppy_arguments_elements_map() && |
!is_sloppy(language_mode())) { |
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); |
- } else if (key_is_smi_like) { |
+ } else if (key->IsSmi() && Smi::cast(*key)->value() >= 0) { |
+ uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value()); |
// 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); |
+ if (!receiver->map()->DictionaryElementsInPrototypeChainOnly()) { |
+ KeyedAccessStoreMode store_mode = |
+ GetStoreMode(receiver, index, value); |
stub = StoreElementStub(receiver, store_mode); |
} else { |
TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); |