From 04e1462f9e3b686f83ec46c8427e9e98d57f3b36 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Fri, 11 Oct 2013 13:48:14 +0000 Subject: [PATCH] Centralize handler caching and probing in ic.cc. Also purge invalid POLYMORPHIC stubs. In a next step the compilers should probably be merged and the "Compute*" on the stub-cache removed. BUG= R=ulan@chromium.org Review URL: https://chromiumcodereview.appspot.com/25548009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17161 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ic.cc | 88 +++++++++++++++++++------ src/ic.h | 17 +++-- src/objects.h | 2 +- src/stub-cache.cc | 189 ++++++++++-------------------------------------------- src/stub-cache.h | 12 ++-- 5 files changed, 120 insertions(+), 188 deletions(-) diff --git a/src/ic.cc b/src/ic.cc index c223028..52578c5 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -300,7 +300,8 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, break; } - Map* map = IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map(); + Handle map( + IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map()); // Decide whether the inline cache failed because of changes to the // receiver itself or changes to one of its prototypes. @@ -314,13 +315,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, if (index >= 0) { map->RemoveFromCodeCache(*name, *target(), index); // Handlers are stored in addition to the ICs on the map. Remove those, too. - Code* handler = target()->FindFirstHandler(); - if (handler != NULL) { - index = map->IndexInCodeCache(*name, handler); - if (index >= 0) { - map->RemoveFromCodeCache(*name, handler, index); - } - } + TryRemoveInvalidHandlers(map, name); return true; } @@ -334,7 +329,7 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, // the map cannot be deprecated and the stub invalidated. if (cache_holder == OWN_MAP) { Map* old_map = target()->FindFirstMap(); - if (old_map == map) return true; + if (old_map == *map) return true; if (old_map != NULL) { if (old_map->is_deprecated()) return true; if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), @@ -357,8 +352,30 @@ bool IC::TryRemoveInvalidPrototypeDependentStub(Handle receiver, } +void IC::TryRemoveInvalidHandlers(Handle map, Handle name) { + CodeHandleList handlers; + target()->FindHandlers(&handlers); + for (int i = 0; i < handlers.length(); i++) { + Handle handler = handlers.at(i); + int index = map->IndexInCodeCache(*name, *handler); + if (index >= 0) { + map->RemoveFromCodeCache(*name, *handler, index); + return; + } + } +} + + void IC::UpdateState(Handle receiver, Handle name) { - if (state() != MONOMORPHIC || !name->IsString()) return; + if (!name->IsString()) return; + if (state() != MONOMORPHIC) { + if (state() == POLYMORPHIC && receiver->IsHeapObject()) { + TryRemoveInvalidHandlers( + handle(Handle::cast(receiver)->map()), + Handle::cast(name)); + } + return; + } if (receiver->IsUndefined() || receiver->IsNull()) return; // Remove the target from the code cache if it became invalid @@ -1122,7 +1139,6 @@ void LoadIC::UpdateCaches(LookupResult* lookup, code = slow_stub(); } else { code = ComputeLoadHandler(lookup, Handle::cast(receiver), name); - if (code.is_null()) code = slow_stub(); } PatchCache(receiver, name, code); @@ -1141,11 +1157,29 @@ Handle LoadIC::ComputeLoadHandler(LookupResult* lookup, Handle receiver, Handle name) { if (!lookup->IsProperty()) { - // Nonexistent property. The result is undefined. - return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver); + return kind() == Code::LOAD_IC + ? isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver) + : generic_stub(); } - // Compute monomorphic stub. + Handle code = isolate()->stub_cache()->FindHandler( + name, receiver, kind()); + if (!code.is_null()) return code; + + code = CompileLoadHandler(lookup, receiver, name); + if (code.is_null()) return slow_stub(); + + if (code->is_handler() && code->type() != Code::NORMAL) { + HeapObject::UpdateMapCodeCache(receiver, name, code); + } + + return code; +} + + +Handle LoadIC::CompileLoadHandler(LookupResult* lookup, + Handle receiver, + Handle name) { Handle holder(lookup->holder()); switch (lookup->type()) { case FIELD: @@ -1356,12 +1390,9 @@ MaybeObject* KeyedLoadIC::Load(Handle object, } -Handle KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, +Handle KeyedLoadIC::CompileLoadHandler(LookupResult* lookup, Handle receiver, Handle name) { - // Bail out if we didn't find a result. - if (!lookup->IsProperty()) return Handle::null(); - // Compute a monomorphic stub. Handle holder(lookup->holder(), isolate()); switch (lookup->type()) { @@ -1614,6 +1645,25 @@ Handle StoreIC::ComputeStoreHandler(LookupResult* lookup, Handle receiver, Handle name, Handle value) { + Handle code = isolate()->stub_cache()->FindHandler( + name, receiver, kind(), strict_mode()); + if (!code.is_null()) return code; + + code = CompileStoreHandler(lookup, receiver, name, value); + if (code.is_null()) return generic_stub(); + + if (code->is_handler() && code->type() != Code::NORMAL) { + HeapObject::UpdateMapCodeCache(receiver, name, code); + } + + return code; +} + + +Handle StoreIC::CompileStoreHandler(LookupResult* lookup, + Handle receiver, + Handle name, + Handle value) { Handle holder(lookup->holder()); switch (lookup->type()) { case FIELD: @@ -2002,7 +2052,7 @@ MaybeObject* KeyedStoreIC::Store(Handle object, } -Handle KeyedStoreIC::ComputeStoreHandler(LookupResult* lookup, +Handle KeyedStoreIC::CompileStoreHandler(LookupResult* lookup, Handle receiver, Handle name, Handle value) { diff --git a/src/ic.h b/src/ic.h index c909872..7e40131 100644 --- a/src/ic.h +++ b/src/ic.h @@ -198,6 +198,7 @@ class IC { virtual StrictModeFlag strict_mode() const { return kNonStrictMode; } bool TryRemoveInvalidPrototypeDependentStub(Handle receiver, Handle name); + void TryRemoveInvalidHandlers(Handle map, Handle name); private: // Frame pointer for the frame that uses (calls) the IC. @@ -394,7 +395,10 @@ class LoadIC: public IC { Handle object, Handle name); - virtual Handle ComputeLoadHandler(LookupResult* lookup, + Handle ComputeLoadHandler(LookupResult* lookup, + Handle receiver, + Handle name); + virtual Handle CompileLoadHandler(LookupResult* lookup, Handle receiver, Handle name); @@ -471,8 +475,7 @@ class KeyedLoadIC: public LoadIC { return isolate()->builtins()->KeyedLoadIC_Slow(); } - // Update the inline cache. - virtual Handle ComputeLoadHandler(LookupResult* lookup, + virtual Handle CompileLoadHandler(LookupResult* lookup, Handle receiver, Handle name); virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } @@ -590,7 +593,11 @@ class StoreIC: public IC { // Compute the code stub for this store; used for rewriting to // monomorphic state and making sure that the code stub is in the // stub cache. - virtual Handle ComputeStoreHandler(LookupResult* lookup, + Handle ComputeStoreHandler(LookupResult* lookup, + Handle receiver, + Handle name, + Handle value); + virtual Handle CompileStoreHandler(LookupResult* lookup, Handle receiver, Handle name, Handle value); @@ -661,7 +668,7 @@ class KeyedStoreIC: public StoreIC { protected: virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } - virtual Handle ComputeStoreHandler(LookupResult* lookup, + virtual Handle CompileStoreHandler(LookupResult* lookup, Handle receiver, Handle name, Handle value); diff --git a/src/objects.h b/src/objects.h index 4eb4539..0d1b251 100644 --- a/src/objects.h +++ b/src/objects.h @@ -5073,7 +5073,7 @@ class Code: public HeapObject { // Find |length| handlers and put them into |code_list|. Returns false if not // enough handlers can be found. - MUST_USE_RESULT bool FindHandlers(CodeHandleList* code_list, int length); + bool FindHandlers(CodeHandleList* code_list, int length = -1); // Find the first name in an IC stub. Name* FindFirstName(); diff --git a/src/stub-cache.cc b/src/stub-cache.cc index f8e09c4..0080390 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -119,24 +119,15 @@ Handle StubCache::FindIC(Handle name, } -Handle StubCache::FindLoadHandler(Handle name, - Handle receiver, - Code::Kind kind) { - Code::Flags flags = Code::ComputeMonomorphicFlags( - Code::HANDLER, Code::kNoExtraICState, Code::NORMAL, kind); - Handle probe(receiver->map()->FindInCodeCache(*name, flags), - isolate_); - if (probe->IsCode()) return Handle::cast(probe); - return Handle::null(); -} - - -Handle StubCache::FindStoreHandler(Handle name, - Handle receiver, - Code::Kind kind, - StrictModeFlag strict_mode) { - Code::ExtraICState extra_ic_state = Code::ComputeExtraICState( - STANDARD_STORE, strict_mode); +Handle StubCache::FindHandler(Handle name, + Handle receiver, + Code::Kind kind, + StrictModeFlag strict_mode) { + Code::ExtraICState extra_ic_state = Code::kNoExtraICState; + if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { + extra_ic_state = Code::ComputeExtraICState( + STANDARD_STORE, strict_mode); + } Code::Flags flags = Code::ComputeMonomorphicFlags( Code::HANDLER, extra_ic_state, Code::NORMAL, kind); Handle probe(receiver->map()->FindInCodeCache(*name, flags), @@ -200,7 +191,7 @@ Handle StubCache::ComputeLoadNonexistent(Handle name, // Compile the stub that is either shared for all names or // name specific if there are global objects involved. - Handle handler = FindLoadHandler(cache_name, receiver, Code::LOAD_IC); + Handle handler = FindHandler(cache_name, receiver, Code::LOAD_IC); if (!handler.is_null()) return handler; LoadStubCompiler compiler(isolate_); @@ -223,14 +214,9 @@ Handle StubCache::ComputeLoadField(Handle name, return stub.GetCode(isolate()); } - Handle stub = FindLoadHandler(name, receiver, Code::LOAD_IC); - if (!stub.is_null()) return stub; - LoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadField(receiver, holder, name, field, representation); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadField( + receiver, holder, name, field, representation); } @@ -240,14 +226,8 @@ Handle StubCache::ComputeLoadCallback( Handle holder, Handle callback) { ASSERT(v8::ToCData
(callback->getter()) != 0); - Handle stub = FindLoadHandler(name, receiver, Code::LOAD_IC); - if (!stub.is_null()) return stub; - LoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadCallback(receiver, holder, name, callback); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadCallback(receiver, holder, name, callback); } @@ -256,14 +236,9 @@ Handle StubCache::ComputeLoadCallback( Handle receiver, Handle holder, const CallOptimization& call_optimization) { - Handle stub = FindLoadHandler(name, receiver, Code::LOAD_IC); - if (!stub.is_null()) return stub; - LoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadCallback(receiver, holder, name, call_optimization); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadCallback( + receiver, holder, name, call_optimization); } @@ -271,14 +246,8 @@ Handle StubCache::ComputeLoadViaGetter(Handle name, Handle receiver, Handle holder, Handle getter) { - Handle stub = FindLoadHandler(name, receiver, Code::LOAD_IC); - if (!stub.is_null()) return stub; - LoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadViaGetter(receiver, holder, name, getter); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadViaGetter(receiver, holder, name, getter); } @@ -286,28 +255,16 @@ Handle StubCache::ComputeLoadConstant(Handle name, Handle receiver, Handle holder, Handle value) { - Handle handler = FindLoadHandler(name, receiver, Code::LOAD_IC); - if (!handler.is_null()) return handler; - LoadStubCompiler compiler(isolate_); - handler = compiler.CompileLoadConstant(receiver, holder, name, value); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - - return handler; + return compiler.CompileLoadConstant(receiver, holder, name, value); } Handle StubCache::ComputeLoadInterceptor(Handle name, Handle receiver, Handle holder) { - Handle stub = FindLoadHandler(name, receiver, Code::LOAD_IC); - if (!stub.is_null()) return stub; - LoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadInterceptor(receiver, holder, name); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadInterceptor(receiver, holder, name); } @@ -346,14 +303,9 @@ Handle StubCache::ComputeKeyedLoadField(Handle name, return stub.GetCode(isolate()); } - Handle stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); - if (!stub.is_null()) return stub; - KeyedLoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadField(receiver, holder, name, field, representation); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadField( + receiver, holder, name, field, representation); } @@ -361,27 +313,17 @@ Handle StubCache::ComputeKeyedLoadConstant(Handle name, Handle receiver, Handle holder, Handle value) { - Handle handler = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); - if (!handler.is_null()) return handler; - KeyedLoadStubCompiler compiler(isolate_); - handler = compiler.CompileLoadConstant(receiver, holder, name, value); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadConstant( + receiver, holder, name, value); } Handle StubCache::ComputeKeyedLoadInterceptor(Handle name, Handle receiver, Handle holder) { - Handle stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); - if (!stub.is_null()) return stub; - KeyedLoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadInterceptor(receiver, holder, name); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadInterceptor(receiver, holder, name); } @@ -390,14 +332,8 @@ Handle StubCache::ComputeKeyedLoadCallback( Handle receiver, Handle holder, Handle callback) { - Handle stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); - if (!stub.is_null()) return stub; - KeyedLoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadCallback(receiver, holder, name, callback); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadCallback(receiver, holder, name, callback); } @@ -406,14 +342,9 @@ Handle StubCache::ComputeKeyedLoadCallback( Handle receiver, Handle holder, const CallOptimization& call_optimization) { - Handle stub = FindLoadHandler(name, receiver, Code::KEYED_LOAD_IC); - if (!stub.is_null()) return stub; - KeyedLoadStubCompiler compiler(isolate_); - Handle handler = - compiler.CompileLoadCallback(receiver, holder, name, call_optimization); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileLoadCallback( + receiver, holder, name, call_optimization); } @@ -421,14 +352,8 @@ Handle StubCache::ComputeStoreField(Handle name, Handle receiver, LookupResult* lookup, StrictModeFlag strict_mode) { - Handle stub = FindStoreHandler( - name, receiver, Code::STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - StoreStubCompiler compiler(isolate_, strict_mode); - Handle handler = compiler.CompileStoreField(receiver, lookup, name); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileStoreField(receiver, lookup, name); } @@ -437,15 +362,8 @@ Handle StubCache::ComputeStoreTransition(Handle name, LookupResult* lookup, Handle transition, StrictModeFlag strict_mode) { - Handle stub = FindStoreHandler( - name, receiver, Code::STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - StoreStubCompiler compiler(isolate_, strict_mode); - Handle handler = - compiler.CompileStoreTransition(receiver, lookup, transition, name); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileStoreTransition(receiver, lookup, transition, name); } @@ -537,15 +455,8 @@ Handle StubCache::ComputeStoreCallback( Handle callback, StrictModeFlag strict_mode) { ASSERT(v8::ToCData
(callback->setter()) != 0); - Handle stub = FindStoreHandler( - name, receiver, Code::STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - StoreStubCompiler compiler(isolate_, strict_mode); - Handle handler = compiler.CompileStoreCallback( - receiver, holder, name, callback); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileStoreCallback(receiver, holder, name, callback); } @@ -555,15 +466,9 @@ Handle StubCache::ComputeStoreCallback( Handle holder, const CallOptimization& call_optimization, StrictModeFlag strict_mode) { - Handle stub = FindStoreHandler( - name, receiver, Code::STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - StoreStubCompiler compiler(isolate_, strict_mode); - Handle handler = compiler.CompileStoreCallback( + return compiler.CompileStoreCallback( receiver, holder, name, call_optimization); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; } @@ -572,29 +477,16 @@ Handle StubCache::ComputeStoreViaSetter(Handle name, Handle holder, Handle setter, StrictModeFlag strict_mode) { - Handle stub = FindStoreHandler( - name, receiver, Code::STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - StoreStubCompiler compiler(isolate_, strict_mode); - Handle handler = compiler.CompileStoreViaSetter( - receiver, holder, name, setter); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileStoreViaSetter(receiver, holder, name, setter); } Handle StubCache::ComputeStoreInterceptor(Handle name, Handle receiver, StrictModeFlag strict_mode) { - Handle stub = FindStoreHandler( - name, receiver, Code::STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - StoreStubCompiler compiler(isolate_, strict_mode); - Handle handler = compiler.CompileStoreInterceptor(receiver, name); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileStoreInterceptor(receiver, name); } @@ -602,14 +494,8 @@ Handle StubCache::ComputeKeyedStoreField(Handle name, Handle receiver, LookupResult* lookup, StrictModeFlag strict_mode) { - Handle stub = FindStoreHandler( - name, receiver, Code::KEYED_STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); - Handle handler = compiler.CompileStoreField(receiver, lookup, name); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileStoreField(receiver, lookup, name); } @@ -619,15 +505,8 @@ Handle StubCache::ComputeKeyedStoreTransition( LookupResult* lookup, Handle transition, StrictModeFlag strict_mode) { - Handle stub = FindStoreHandler( - name, receiver, Code::KEYED_STORE_IC, strict_mode); - if (!stub.is_null()) return stub; - KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); - Handle handler = - compiler.CompileStoreTransition(receiver, lookup, transition, name); - HeapObject::UpdateMapCodeCache(receiver, name, handler); - return handler; + return compiler.CompileStoreTransition(receiver, lookup, transition, name); } diff --git a/src/stub-cache.h b/src/stub-cache.h index 6d2099d..ae0c65d 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -90,14 +90,10 @@ class StubCache { Code::Kind kind, Code::ExtraICState extra_state = Code::kNoExtraICState); - Handle FindLoadHandler(Handle name, - Handle receiver, - Code::Kind kind); - - Handle FindStoreHandler(Handle name, - Handle receiver, - Code::Kind kind, - StrictModeFlag strict_mode); + Handle FindHandler(Handle name, + Handle receiver, + Code::Kind kind, + StrictModeFlag strict_mode = kNonStrictMode); Handle ComputeMonomorphicIC(Handle receiver, Handle handler, -- 2.7.4