| 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");
|
|
|