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