From f24a5d32009dfb170724734b8e6bce9c7fab3675 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Tue, 16 Jul 2013 14:01:46 +0000 Subject: [PATCH] Try to remove invalidated stubs before falling back to checking the constant state. BUG=chromium:260585 R=hpayer@chromium.org Review URL: https://chromiumcodereview.appspot.com/19267019 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15693 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ic.cc | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/ic.cc b/src/ic.cc index 2f63fee..e09d83e 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -191,17 +191,6 @@ static bool TryRemoveInvalidPrototypeDependentStub(Code* target, if (Name::cast(name) != stub_name) return false; } - if (receiver->IsGlobalObject()) { - if (!name->IsName()) return false; - Isolate* isolate = target->GetIsolate(); - LookupResult lookup(isolate); - GlobalObject* global = GlobalObject::cast(receiver); - global->LocalLookupRealNamedProperty(Name::cast(name), &lookup); - if (!lookup.IsFound()) return false; - PropertyCell* cell = global->GetPropertyCell(&lookup); - return cell->type()->IsConstant(); - } - InlineCacheHolderFlag cache_holder = Code::ExtractCacheHolderFromFlags(target->flags()); @@ -242,18 +231,32 @@ static bool TryRemoveInvalidPrototypeDependentStub(Code* target, return true; } + // The stub is not in the cache. We've ruled out all other kinds of failure + // except for proptotype chain changes, a deprecated map, a map that's + // different from the one that the stub expects, or a constant global property + // that will become mutable. Threat all those situations as prototype failures + // (stay monomorphic if possible). + // If the IC is shared between multiple receivers (slow dictionary mode), then // the map cannot be deprecated and the stub invalidated. - if (cache_holder != OWN_MAP) return false; + if (cache_holder == OWN_MAP) { + Map* old_map = target->FindFirstMap(); + if (old_map == map) return true; + if (old_map != NULL && old_map->is_deprecated()) return true; + } - // The stub is not in the cache. We've ruled out all other kinds of failure - // except for proptotype chain changes, a deprecated map, or a map that's - // different from the one that the stub expects. If the map hasn't changed, - // assume it's a prototype failure. Treat deprecated maps in the same way as - // prototype failures (stay monomorphic if possible). - Map* old_map = target->FindFirstMap(); - if (old_map == NULL) return false; - return old_map == map || old_map->is_deprecated(); + if (receiver->IsGlobalObject()) { + if (!name->IsName()) return false; + Isolate* isolate = target->GetIsolate(); + LookupResult lookup(isolate); + GlobalObject* global = GlobalObject::cast(receiver); + global->LocalLookupRealNamedProperty(Name::cast(name), &lookup); + if (!lookup.IsFound()) return false; + PropertyCell* cell = global->GetPropertyCell(&lookup); + return cell->type()->IsConstant(); + } + + return false; } -- 2.7.4