Commit 0fd9a0a3 authored by verwaest's avatar verwaest Committed by Commit bot

Minor cleanup IC keyed access handling.

BUG=

Review URL: https://codereview.chromium.org/1238463002

Cr-Commit-Position: refs/heads/master@{#29614}
parent 0337fedf
......@@ -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");
......
......@@ -659,9 +659,6 @@ class KeyedStoreIC : public StoreIC {
static void Clear(Isolate* isolate, Address address, Code* target,
Address constant_pool);
KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver,
Handle<Object> key, Handle<Object> value);
Handle<Map> ComputeTransitionedMap(Handle<Map> map,
KeyedAccessStoreMode store_mode);
......
......@@ -1132,19 +1132,6 @@ bool Object::IsMinusZero() const {
}
MaybeHandle<Smi> Object::ToSmi(Isolate* isolate, Handle<Object> object) {
if (object->IsSmi()) return Handle<Smi>::cast(object);
if (object->IsHeapNumber()) {
double value = Handle<HeapNumber>::cast(object)->value();
int int_value = FastD2I(value);
if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
return handle(Smi::FromInt(int_value), isolate);
}
}
return Handle<Smi>();
}
MaybeHandle<JSReceiver> Object::ToObject(Isolate* isolate,
Handle<Object> object) {
return ToObject(
......@@ -1838,12 +1825,6 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
}
bool JSObject::WouldConvertToSlowElements(Handle<Object> key) {
uint32_t index = 0;
return key->ToArrayIndex(&index) && WouldConvertToSlowElements(index);
}
void JSObject::SetMapAndElements(Handle<JSObject> object,
Handle<Map> new_map,
Handle<FixedArrayBase> value) {
......
......@@ -1154,10 +1154,6 @@ class Object {
Handle<Object> object,
Handle<Context> context);
// Converts this to a Smi if possible.
MUST_USE_RESULT static inline MaybeHandle<Smi> ToSmi(Isolate* isolate,
Handle<Object> object);
MUST_USE_RESULT static MaybeHandle<Object> GetProperty(
LookupIterator* it, LanguageMode language_mode = SLOPPY);
......@@ -2010,7 +2006,6 @@ class JSObject: public JSReceiver {
// Would we convert a fast elements array to dictionary mode given
// an access at key?
bool WouldConvertToSlowElements(uint32_t index);
inline bool WouldConvertToSlowElements(Handle<Object> key);
// Computes the new capacity when expanding the elements of a JSObject.
static uint32_t NewElementsCapacity(uint32_t old_capacity) {
......
......@@ -1085,8 +1085,9 @@ TEST(CachedHashOverflow) {
CHECK_EQ(results[i]->IsUndefined(), result->IsUndefined());
CHECK_EQ(results[i]->IsNumber(), result->IsNumber());
if (result->IsNumber()) {
CHECK_EQ(Object::ToSmi(isolate, results[i]).ToHandleChecked()->value(),
result->ToInt32(CcTest::isolate())->Value());
int32_t value = 0;
CHECK(results[i]->ToInt32(&value));
CHECK_EQ(value, result->ToInt32(CcTest::isolate())->Value());
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment