Index: src/ic.cc |
=================================================================== |
--- src/ic.cc (revision 2399) |
+++ src/ic.cc (working copy) |
@@ -273,28 +273,39 @@ |
static void LookupForRead(Object* object, |
String* name, |
LookupResult* lookup) { |
- object->Lookup(name, lookup); |
- if (lookup->IsNotFound() || lookup->type() != INTERCEPTOR) { |
- return; |
- } |
+ AssertNoAllocation no_gc; // pointers must stay valid |
- JSObject* holder = lookup->holder(); |
- if (HasInterceptorGetter(holder)) { |
- return; |
- } |
+ // Skip all the objects with named interceptors, but |
+ // without actual getter. |
+ while (true) { |
+ object->Lookup(name, lookup); |
+ // Besides normal conditions (property not found or it's not |
+ // an interceptor), bail out of lookup is not cacheable: we won't |
+ // be able to IC it anyway and regular lookup should work fine. |
+ if (lookup->IsNotFound() || lookup->type() != INTERCEPTOR || |
+ !lookup->IsCacheable()) { |
+ return; |
+ } |
- // There is no getter, just skip it and lookup down the proto chain |
- holder->LocalLookupRealNamedProperty(name, lookup); |
- if (lookup->IsValid()) { |
- return; |
- } |
+ JSObject* holder = lookup->holder(); |
+ if (HasInterceptorGetter(holder)) { |
+ return; |
+ } |
- Object* proto = holder->GetPrototype(); |
- if (proto == Heap::null_value()) { |
- return; |
+ holder->LocalLookupRealNamedProperty(name, lookup); |
+ if (lookup->IsValid()) { |
+ ASSERT(lookup->type() != INTERCEPTOR); |
+ return; |
+ } |
+ |
+ Object* proto = holder->GetPrototype(); |
+ if (proto->IsNull()) { |
+ lookup->NotFound(); |
+ return; |
+ } |
+ |
+ object = proto; |
} |
- |
- LookupForRead(proto, name, lookup); |
} |