| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index fbe77b09d23fa7daccabb0a842ae49221adf9b77..b6b061470382ee856c2deed0757334f741278a50 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -1330,10 +1330,12 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
| Handle<JSObject> receiver,
|
| Handle<String> name,
|
| Handle<Object> value) {
|
| - // Skip JSGlobalProxy.
|
| ASSERT(!receiver->IsJSGlobalProxy());
|
| -
|
| ASSERT(StoreICableLookup(lookup));
|
| + // These are not cacheable, so we never see such LookupResults here.
|
| + ASSERT(lookup->type() != HANDLER);
|
| + // We get only called for properties or transitions, see StoreICableLookup.
|
| + ASSERT(lookup->type() != NULL_DESCRIPTOR);
|
|
|
| // If the property has a non-field type allowing map transitions
|
| // where there is extra room in the object, we leave the IC in its
|
| @@ -1354,7 +1356,6 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
| break;
|
| case MAP_TRANSITION: {
|
| if (lookup->GetAttributes() != NONE) return;
|
| - ASSERT(type == MAP_TRANSITION);
|
| Handle<Map> transition(lookup->GetTransitionMap());
|
| int index = transition->PropertyIndexFor(*name);
|
| code = isolate()->stub_cache()->ComputeStoreField(
|
| @@ -1390,7 +1391,13 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
| code = isolate()->stub_cache()->ComputeStoreInterceptor(
|
| name, receiver, strict_mode);
|
| break;
|
| - default:
|
| + case CONSTANT_FUNCTION:
|
| + case CONSTANT_TRANSITION:
|
| + case ELEMENTS_TRANSITION:
|
| + return;
|
| + case HANDLER:
|
| + case NULL_DESCRIPTOR:
|
| + UNREACHABLE();
|
| return;
|
| }
|
|
|
| @@ -1636,13 +1643,12 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
| return *value;
|
| }
|
|
|
| - // Lookup the property locally in the receiver.
|
| - LookupResult lookup(isolate());
|
| - receiver->LocalLookup(*name, &lookup);
|
| -
|
| // Update inline cache and stub cache.
|
| - if (FLAG_use_ic) {
|
| - UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
|
| + if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
|
| + LookupResult lookup(isolate());
|
| + if (LookupForWrite(receiver, name, &lookup)) {
|
| + UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
|
| + }
|
| }
|
|
|
| // Set the property.
|
| @@ -1698,15 +1704,12 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
|
| Handle<JSObject> receiver,
|
| Handle<String> name,
|
| Handle<Object> value) {
|
| - // Skip JSGlobalProxy.
|
| - if (receiver->IsJSGlobalProxy()) return;
|
| -
|
| - // Bail out if we didn't find a result.
|
| - if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;
|
| -
|
| - // If the property is read-only, we leave the IC in its current
|
| - // state.
|
| - if (lookup->IsReadOnly()) return;
|
| + ASSERT(!receiver->IsJSGlobalProxy());
|
| + ASSERT(StoreICableLookup(lookup));
|
| + // These are not cacheable, so we never see such LookupResults here.
|
| + ASSERT(lookup->type() != HANDLER);
|
| + // We get only called for properties or transitions, see StoreICableLookup.
|
| + ASSERT(lookup->type() != NULL_DESCRIPTOR);
|
|
|
| // If the property has a non-field type allowing map transitions
|
| // where there is extra room in the object, we leave the IC in its
|
| @@ -1726,7 +1729,6 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
|
| break;
|
| case MAP_TRANSITION:
|
| if (lookup->GetAttributes() == NONE) {
|
| - ASSERT(type == MAP_TRANSITION);
|
| Handle<Map> transition(lookup->GetTransitionMap());
|
| int index = transition->PropertyIndexFor(*name);
|
| code = isolate()->stub_cache()->ComputeKeyedStoreField(
|
| @@ -1734,13 +1736,22 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
|
| break;
|
| }
|
| // fall through.
|
| - default:
|
| + case NORMAL:
|
| + case CONSTANT_FUNCTION:
|
| + case CALLBACKS:
|
| + case INTERCEPTOR:
|
| + case CONSTANT_TRANSITION:
|
| + case ELEMENTS_TRANSITION:
|
| // Always rewrite to the generic case so that we do not
|
| // repeatedly try to rewrite.
|
| code = (strict_mode == kStrictMode)
|
| ? generic_stub_strict()
|
| : generic_stub();
|
| break;
|
| + case HANDLER:
|
| + case NULL_DESCRIPTOR:
|
| + UNREACHABLE();
|
| + return;
|
| }
|
|
|
| ASSERT(!code.is_null());
|
|
|