Chromium Code Reviews| Index: src/ic.cc |
| diff --git a/src/ic.cc b/src/ic.cc |
| index c1d11bbb90678b646f8904673d61e3874f0bb872..8a2930f66cde0a00ce4fed7938f4bd863e0aeb04 100644 |
| --- a/src/ic.cc |
| +++ b/src/ic.cc |
| @@ -1418,41 +1418,37 @@ Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, |
| } |
| -static bool StoreICableLookup(LookupResult* lookup) { |
| - // Bail out if we didn't find a result. |
| - if (!lookup->IsFound()) return false; |
| - |
| - // Bail out if inline caching is not allowed. |
| - if (!lookup->IsCacheable()) return false; |
| - |
| - // If the property is read-only, we leave the IC in its current state. |
| - if (lookup->IsTransition()) { |
| - return !lookup->GetTransitionDetails().IsReadOnly(); |
| - } |
| - return !lookup->IsReadOnly(); |
| -} |
| - |
| - |
| static bool LookupForWrite(Handle<JSObject> receiver, |
| Handle<String> name, |
| LookupResult* lookup) { |
| - receiver->LocalLookup(*name, lookup); |
| - if (!lookup->IsFound()) { |
| - receiver->map()->LookupTransition(*receiver, *name, lookup); |
| - } |
| - if (!StoreICableLookup(lookup)) { |
| - // 2nd chance: There can be accessors somewhere in the prototype chain. |
| - receiver->Lookup(*name, lookup); |
| - return lookup->IsPropertyCallbacks() && StoreICableLookup(lookup); |
| - } |
| + Handle<JSObject> holder = receiver; |
| + receiver->Lookup(*name, lookup); |
| + if (lookup->IsFound()) { |
| + if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false; |
| + |
| + if (lookup->holder() == *receiver) { |
| + if (lookup->IsInterceptor() && |
| + receiver->GetNamedInterceptor()->setter()->IsUndefined()) { |
| + receiver->LocalLookupRealNamedProperty(*name, lookup); |
| + return lookup->IsFound() && |
| + !lookup->IsReadOnly() && |
| + lookup->IsCacheable(); |
| + } |
| + return true; |
| + } |
| - if (lookup->IsInterceptor() && |
| - receiver->GetNamedInterceptor()->setter()->IsUndefined()) { |
| - receiver->LocalLookupRealNamedProperty(*name, lookup); |
| - return StoreICableLookup(lookup); |
| + if (lookup->IsPropertyCallbacks()) return true; |
|
rossberg
2013/03/22 14:07:44
Test case... :)
Toon Verwaest
2013/03/25 11:44:44
Done.
|
| + |
| + // Currently normal holders in the prototype chain are not supported. They |
| + // would require a runtime positive lookup and verification that the details |
| + // have not changed. |
| + if (lookup->IsInterceptor() || lookup->IsNormal()) return false; |
| + holder = Handle<JSObject>(lookup->holder(), lookup->isolate()); |
| } |
| - return true; |
| + receiver->map()->LookupTransition(*holder, *name, lookup); |
|
rossberg
2013/03/22 14:07:44
Maybe add a comment explaining why you use the hol
Toon Verwaest
2013/03/25 11:44:44
Done.
|
| + return lookup->IsTransition() && |
| + !lookup->GetTransitionDetails(receiver->map()).IsReadOnly(); |
| } |
| @@ -1552,7 +1548,6 @@ void StoreIC::UpdateCaches(LookupResult* lookup, |
| Handle<String> name, |
| Handle<Object> value) { |
| ASSERT(!receiver->IsJSGlobalProxy()); |
| - ASSERT(StoreICableLookup(lookup)); |
| ASSERT(lookup->IsFound()); |
| // These are not cacheable, so we never see such LookupResults here. |
| @@ -1575,8 +1570,7 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| switch (lookup->type()) { |
| case FIELD: |
| return isolate()->stub_cache()->ComputeStoreField( |
| - name, receiver, lookup->GetFieldIndex().field_index(), |
| - Handle<Map>::null(), strict_mode); |
| + name, receiver, lookup, Handle<Map>::null(), strict_mode); |
| case NORMAL: |
| if (receiver->IsGlobalObject()) { |
| // The stub generated for the global object picks the value directly |
| @@ -1588,7 +1582,6 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| return isolate()->stub_cache()->ComputeStoreGlobal( |
| name, global, cell, strict_mode); |
| } |
| - if (!holder.is_identical_to(receiver)) break; |
|
rossberg
2013/03/22 14:07:44
If that's an impossible case, maybe turn it into a
Toon Verwaest
2013/03/25 11:44:44
Done.
|
| return isolate()->stub_cache()->ComputeStoreNormal(strict_mode); |
| case CALLBACKS: { |
| Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
| @@ -1623,7 +1616,8 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| case CONSTANT_FUNCTION: |
| break; |
| case TRANSITION: { |
| - Handle<Map> transition(lookup->GetTransitionTarget(), isolate()); |
| + Handle<Map> transition( |
| + lookup->GetTransitionTarget(receiver->map()), isolate()); |
| int descriptor = transition->LastAdded(); |
| DescriptorArray* target_descriptors = transition->instance_descriptors(); |
| @@ -1631,9 +1625,8 @@ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| if (details.type() != FIELD || details.attributes() != NONE) break; |
| - int field_index = target_descriptors->GetFieldIndex(descriptor); |
| return isolate()->stub_cache()->ComputeStoreField( |
| - name, receiver, field_index, transition, strict_mode); |
| + name, receiver, lookup, transition, strict_mode); |
| } |
| case NONEXISTENT: |
| case HANDLER: |
| @@ -1964,19 +1957,18 @@ Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup, |
| switch (lookup->type()) { |
| case FIELD: |
| return isolate()->stub_cache()->ComputeKeyedStoreField( |
| - name, receiver, lookup->GetFieldIndex().field_index(), |
| - Handle<Map>::null(), strict_mode); |
| + name, receiver, lookup, Handle<Map>::null(), strict_mode); |
| case TRANSITION: { |
| - Handle<Map> transition(lookup->GetTransitionTarget(), isolate()); |
| + Handle<Map> transition( |
| + lookup->GetTransitionTarget(receiver->map()), isolate()); |
| int descriptor = transition->LastAdded(); |
| DescriptorArray* target_descriptors = transition->instance_descriptors(); |
| PropertyDetails details = target_descriptors->GetDetails(descriptor); |
| if (details.type() == FIELD && details.attributes() == NONE) { |
| - int field_index = target_descriptors->GetFieldIndex(descriptor); |
| return isolate()->stub_cache()->ComputeKeyedStoreField( |
| - name, receiver, field_index, transition, strict_mode); |
| + name, receiver, lookup, transition, strict_mode); |
| } |
| // fall through. |
| } |