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