From 0a099371a3dcc5b1c538da77339a5465058d91c7 Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Tue, 29 Jul 2014 16:04:07 +0000 Subject: [PATCH] Remove all compilation related interface from the StubCache BUG= R=ishell@chromium.org Review URL: https://codereview.chromium.org/422853003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22678 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/stub-cache-arm.cc | 18 ++-- src/arm64/stub-cache-arm64.cc | 18 ++-- src/ia32/stub-cache-ia32.cc | 18 ++-- src/ic.cc | 58 +++++------ src/stub-cache.cc | 180 +++++++++++++++++----------------- src/stub-cache.h | 137 +++++++++++--------------- src/x64/stub-cache-x64.cc | 18 ++-- 7 files changed, 215 insertions(+), 232 deletions(-) diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index c5abfbb723..7945fb241a 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -619,11 +619,11 @@ static void PushInterceptorArguments(MacroAssembler* masm, Register holder, Register name, Handle holder_obj) { - STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); - STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); - STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); - STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); - STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); __ push(name); Handle interceptor(holder_obj->GetNamedInterceptor()); ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); @@ -643,9 +643,8 @@ static void CompileCallLoadPropertyWithInterceptor( Handle holder_obj, IC::UtilityId id) { PushInterceptorArguments(masm, receiver, holder, name, holder_obj); - __ CallExternalReference( - ExternalReference(IC_Utility(id), masm->isolate()), - StubCache::kInterceptorArgsLength); + __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), + NamedLoadHandlerCompiler::kInterceptorArgsLength); } @@ -1053,7 +1052,8 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); - __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); + __ TailCallExternalReference( + ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); } } diff --git a/src/arm64/stub-cache-arm64.cc b/src/arm64/stub-cache-arm64.cc index 5e394c5dfe..d5803c9925 100644 --- a/src/arm64/stub-cache-arm64.cc +++ b/src/arm64/stub-cache-arm64.cc @@ -567,11 +567,11 @@ static void PushInterceptorArguments(MacroAssembler* masm, Register holder, Register name, Handle holder_obj) { - STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); - STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); - STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); - STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); - STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); __ Push(name); Handle interceptor(holder_obj->GetNamedInterceptor()); @@ -591,9 +591,8 @@ static void CompileCallLoadPropertyWithInterceptor( IC::UtilityId id) { PushInterceptorArguments(masm, receiver, holder, name, holder_obj); - __ CallExternalReference( - ExternalReference(IC_Utility(id), masm->isolate()), - StubCache::kInterceptorArgsLength); + __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), + NamedLoadHandlerCompiler::kInterceptorArgsLength); } @@ -1015,7 +1014,8 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); - __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); + __ TailCallExternalReference( + ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); } } diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 7d09ce3e95..c66303ce50 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -264,11 +264,11 @@ static void PushInterceptorArguments(MacroAssembler* masm, Register holder, Register name, Handle holder_obj) { - STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); - STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); - STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); - STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); - STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); __ push(name); Handle interceptor(holder_obj->GetNamedInterceptor()); ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); @@ -288,9 +288,8 @@ static void CompileCallLoadPropertyWithInterceptor( Handle holder_obj, IC::UtilityId id) { PushInterceptorArguments(masm, receiver, holder, name, holder_obj); - __ CallExternalReference( - ExternalReference(IC_Utility(id), masm->isolate()), - StubCache::kInterceptorArgsLength); + __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), + NamedLoadHandlerCompiler::kInterceptorArgsLength); } @@ -1036,7 +1035,8 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor( ExternalReference ref = ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); - __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); + __ TailCallExternalReference( + ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); } } diff --git a/src/ic.cc b/src/ic.cc index 089b3fe710..74d402a539 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -482,8 +482,8 @@ void LoadIC::Clear(Isolate* isolate, Code* target, ConstantPoolArray* constant_pool) { if (IsCleared(target)) return; - Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( - Code::LOAD_IC, target->extra_ic_state()); + Code* code = PropertyICCompiler::FindPreMonomorphicIC( + isolate, Code::LOAD_IC, target->extra_ic_state()); SetTargetAtAddress(address, code, constant_pool); } @@ -493,8 +493,8 @@ void StoreIC::Clear(Isolate* isolate, Code* target, ConstantPoolArray* constant_pool) { if (IsCleared(target)) return; - Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( - Code::STORE_IC, target->extra_ic_state()); + Code* code = PropertyICCompiler::FindPreMonomorphicIC( + isolate, Code::STORE_IC, target->extra_ic_state()); SetTargetAtAddress(address, code, constant_pool); } @@ -660,8 +660,8 @@ bool IC::UpdatePolymorphicIC(Handle name, Handle code) { if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false; Handle ic; if (number_of_valid_types == 1) { - ic = isolate()->stub_cache()->ComputeMonomorphicIC(kind(), name, type, code, - extra_ic_state()); + ic = PropertyICCompiler::ComputeMonomorphicIC(kind(), name, type, code, + extra_ic_state()); } else { if (handler_to_overwrite >= 0) { handlers.Set(handler_to_overwrite, code); @@ -672,9 +672,9 @@ bool IC::UpdatePolymorphicIC(Handle name, Handle code) { types.Add(type); handlers.Add(code); } - ic = isolate()->stub_cache()->ComputePolymorphicIC( - kind(), &types, &handlers, number_of_valid_types, name, - extra_ic_state()); + ic = PropertyICCompiler::ComputePolymorphicIC(kind(), &types, &handlers, + number_of_valid_types, name, + extra_ic_state()); } set_target(*ic); return true; @@ -725,7 +725,7 @@ Handle IC::MapToType(Handle map, Isolate* region); void IC::UpdateMonomorphicIC(Handle handler, Handle name) { if (!handler->is_handler()) return set_target(*handler); - Handle ic = isolate()->stub_cache()->ComputeMonomorphicIC( + Handle ic = PropertyICCompiler::ComputeMonomorphicIC( kind(), name, receiver_type(), handler, extra_ic_state()); set_target(*ic); } @@ -786,13 +786,14 @@ void IC::PatchCache(Handle name, Handle code) { Handle LoadIC::initialize_stub(Isolate* isolate, ExtraICState extra_state) { - return isolate->stub_cache()->ComputeLoad(UNINITIALIZED, extra_state); + return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state); } Handle LoadIC::megamorphic_stub() { if (kind() == Code::LOAD_IC) { - return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, extra_ic_state()); + return PropertyICCompiler::ComputeLoad(isolate(), MEGAMORPHIC, + extra_ic_state()); } else { ASSERT_EQ(Code::KEYED_LOAD_IC, kind()); return KeyedLoadIC::generic_stub(isolate()); @@ -802,7 +803,7 @@ Handle LoadIC::megamorphic_stub() { Handle LoadIC::pre_monomorphic_stub(Isolate* isolate, ExtraICState extra_state) { - return isolate->stub_cache()->ComputeLoad(PREMONOMORPHIC, extra_state); + return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state); } @@ -845,8 +846,8 @@ void LoadIC::UpdateCaches(LookupResult* lookup, code = slow_stub(); } else if (!lookup->IsProperty()) { if (kind() == Code::LOAD_IC) { - code = isolate()->stub_cache()->ComputeLoadNonexistent(name, - receiver_type()); + code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(name, + receiver_type()); // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. if (code.is_null()) code = slow_stub(); } else { @@ -1072,7 +1073,7 @@ Handle KeyedLoadIC::LoadElementStub(Handle receiver) { TargetMaps(&target_receiver_maps); } if (target_receiver_maps.length() == 0) { - return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); + return PropertyICCompiler::ComputeKeyedLoadElement(receiver_map); } // The first time a receiver is seen that is a transitioned version of the @@ -1086,7 +1087,7 @@ Handle KeyedLoadIC::LoadElementStub(Handle receiver) { IsMoreGeneralElementsKindTransition( target_receiver_maps.at(0)->elements_kind(), receiver->GetElementsKind())) { - return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); + return PropertyICCompiler::ComputeKeyedLoadElement(receiver_map); } ASSERT(state() != GENERIC); @@ -1107,7 +1108,7 @@ Handle KeyedLoadIC::LoadElementStub(Handle receiver) { return generic_stub(); } - return isolate()->stub_cache()->ComputeLoadElementPolymorphic( + return PropertyICCompiler::ComputeLoadElementPolymorphic( &target_receiver_maps); } @@ -1341,26 +1342,27 @@ Handle CallIC::initialize_stub(Isolate* isolate, Handle StoreIC::initialize_stub(Isolate* isolate, StrictMode strict_mode) { ExtraICState extra_state = ComputeExtraICState(strict_mode); - Handle ic = isolate->stub_cache()->ComputeStore( - UNINITIALIZED, extra_state); + Handle ic = + PropertyICCompiler::ComputeStore(isolate, UNINITIALIZED, extra_state); return ic; } Handle StoreIC::megamorphic_stub() { - return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state()); + return PropertyICCompiler::ComputeStore(isolate(), MEGAMORPHIC, + extra_ic_state()); } Handle StoreIC::generic_stub() const { - return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state()); + return PropertyICCompiler::ComputeStore(isolate(), GENERIC, extra_ic_state()); } Handle StoreIC::pre_monomorphic_stub(Isolate* isolate, StrictMode strict_mode) { ExtraICState state = ComputeExtraICState(strict_mode); - return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state); + return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); } @@ -1492,7 +1494,7 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, Handle monomorphic_map = ComputeTransitionedMap(receiver_map, store_mode); store_mode = GetNonTransitioningStoreMode(store_mode); - return isolate()->stub_cache()->ComputeKeyedStoreElement( + return PropertyICCompiler::ComputeKeyedStoreElement( monomorphic_map, strict_mode(), store_mode); } @@ -1517,7 +1519,7 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, // if they at least come from the same origin for a transitioning store, // stay MONOMORPHIC and use the map for the most generic ElementsKind. store_mode = GetNonTransitioningStoreMode(store_mode); - return isolate()->stub_cache()->ComputeKeyedStoreElement( + return PropertyICCompiler::ComputeKeyedStoreElement( transitioned_receiver_map, strict_mode(), store_mode); } else if (*previous_receiver_map == receiver->map() && old_store_mode == STANDARD_STORE && @@ -1527,7 +1529,7 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, // A "normal" IC that handles stores can switch to a version that can // grow at the end of the array, handle OOB accesses or copy COW arrays // and still stay MONOMORPHIC. - return isolate()->stub_cache()->ComputeKeyedStoreElement( + return PropertyICCompiler::ComputeKeyedStoreElement( receiver_map, strict_mode(), store_mode); } } @@ -1589,7 +1591,7 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, } } - return isolate()->stub_cache()->ComputeStoreElementPolymorphic( + return PropertyICCompiler::ComputeStoreElementPolymorphic( &target_receiver_maps, store_mode, strict_mode()); } @@ -2955,7 +2957,7 @@ Handle CompareNilIC::CompareNil(Handle object) { Handle monomorphic_map(already_monomorphic && FirstTargetMap() != NULL ? FirstTargetMap() : HeapObject::cast(*object)->map()); - code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, &stub); + code = PropertyICCompiler::ComputeCompareNil(monomorphic_map, &stub); } else { code = stub.GetCode(); } diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 841f838ba5..cbd248a980 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -57,7 +57,8 @@ static Code::Flags CommonStubCacheChecks(Name* name, Map* map, Code* StubCache::Set(Name* name, Map* map, Code* code) { - Code::Flags flags = CommonStubCacheChecks(name, map, code->flags(), heap()); + Code::Flags flags = + CommonStubCacheChecks(name, map, code->flags(), isolate()->heap()); // Compute the primary entry. int primary_offset = PrimaryOffset(name, flags, map); @@ -86,7 +87,7 @@ Code* StubCache::Set(Name* name, Map* map, Code* code) { Code* StubCache::Get(Name* name, Map* map, Code::Flags flags) { - flags = CommonStubCacheChecks(name, map, flags, heap()); + flags = CommonStubCacheChecks(name, map, flags, isolate()->heap()); int primary_offset = PrimaryOffset(name, flags, map); Entry* primary = entry(primary_, primary_offset); if (primary->key == name && primary->map == map) { @@ -128,14 +129,12 @@ Handle PropertyHandlerCompiler::Find(Handle name, } -Handle StubCache::ComputeMonomorphicIC( - Code::Kind kind, - Handle name, - Handle type, - Handle handler, - ExtraICState extra_ic_state) { +Handle PropertyICCompiler::ComputeMonomorphicIC( + Code::Kind kind, Handle name, Handle type, + Handle handler, ExtraICState extra_ic_state) { CacheHolderFlag flag; - Handle stub_holder = IC::GetICCacheHolder(*type, isolate(), &flag); + Isolate* isolate = name->GetIsolate(); + Handle stub_holder = IC::GetICCacheHolder(*type, isolate, &flag); Handle ic; // There are multiple string maps that all use the same prototype. That @@ -143,8 +142,7 @@ Handle StubCache::ComputeMonomorphicIC( // for a single name. Hence, turn off caching of the IC. bool can_be_cached = !type->Is(HeapType::String()); if (can_be_cached) { - ic = - PropertyICCompiler::Find(name, stub_holder, kind, extra_ic_state, flag); + ic = Find(name, stub_holder, kind, extra_ic_state, flag); if (!ic.is_null()) return ic; } @@ -155,7 +153,7 @@ Handle StubCache::ComputeMonomorphicIC( } #endif - PropertyICCompiler ic_compiler(isolate(), kind, extra_ic_state, flag); + PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag); ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY); if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); @@ -163,9 +161,10 @@ Handle StubCache::ComputeMonomorphicIC( } -Handle StubCache::ComputeLoadNonexistent(Handle name, - Handle type) { - Handle receiver_map = IC::TypeToMap(*type, isolate()); +Handle NamedLoadHandlerCompiler::ComputeLoadNonexistent( + Handle name, Handle type) { + Isolate* isolate = name->GetIsolate(); + Handle receiver_map = IC::TypeToMap(*type, isolate); if (receiver_map->prototype()->IsNull()) { // TODO(jkummerow/verwaest): If there is no prototype and the property // is nonexistent, introduce a builtin to handle this (fast properties @@ -174,7 +173,7 @@ Handle StubCache::ComputeLoadNonexistent(Handle name, } CacheHolderFlag flag; Handle stub_holder_map = - IC::GetHandlerCacheHolder(*type, false, isolate(), &flag); + IC::GetHandlerCacheHolder(*type, false, isolate, &flag); // If no dictionary mode objects are present in the prototype chain, the load // nonexistent IC stub can be shared for all names for a given map and we use @@ -184,7 +183,7 @@ Handle StubCache::ComputeLoadNonexistent(Handle name, Handle cache_name = receiver_map->is_dictionary_map() ? name - : Handle::cast(isolate()->factory()->nonexistent_symbol()); + : Handle::cast(isolate->factory()->nonexistent_symbol()); Handle current_map = stub_holder_map; Handle last(JSObject::cast(receiver_map->prototype())); while (true) { @@ -199,19 +198,20 @@ Handle StubCache::ComputeLoadNonexistent(Handle name, cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); if (!handler.is_null()) return handler; - NamedLoadHandlerCompiler compiler(isolate_, flag); + NamedLoadHandlerCompiler compiler(isolate, flag); handler = compiler.CompileLoadNonexistent(type, last, cache_name); Map::UpdateCodeCache(stub_holder_map, cache_name, handler); return handler; } -Handle StubCache::ComputeKeyedLoadElement(Handle receiver_map) { +Handle PropertyICCompiler::ComputeKeyedLoadElement( + Handle receiver_map) { + Isolate* isolate = receiver_map->GetIsolate(); Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); - Handle name = - isolate()->factory()->KeyedLoadElementMonomorphic_string(); + Handle name = isolate->factory()->KeyedLoadElementMonomorphic_string(); - Handle probe(receiver_map->FindInCodeCache(*name, flags), isolate_); + Handle probe(receiver_map->FindInCodeCache(*name, flags), isolate); if (probe->IsCode()) return Handle::cast(probe); ElementsKind elements_kind = receiver_map->elements_kind(); @@ -220,27 +220,27 @@ Handle StubCache::ComputeKeyedLoadElement(Handle receiver_map) { receiver_map->has_external_array_elements() || receiver_map->has_fixed_typed_array_elements()) { stub = KeyedLoadFastElementStub( - isolate(), receiver_map->instance_type() == JS_ARRAY_TYPE, + isolate, receiver_map->instance_type() == JS_ARRAY_TYPE, elements_kind).GetCode(); } else { stub = FLAG_compiled_keyed_dictionary_loads - ? KeyedLoadDictionaryElementStub(isolate()).GetCode() - : KeyedLoadDictionaryElementPlatformStub(isolate()).GetCode(); + ? KeyedLoadDictionaryElementStub(isolate).GetCode() + : KeyedLoadDictionaryElementPlatformStub(isolate).GetCode(); } - PropertyICCompiler compiler(isolate(), Code::KEYED_LOAD_IC); + PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC); Handle code = - compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate()), - stub, factory()->empty_string(), ELEMENT); + compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub, + isolate->factory()->empty_string(), ELEMENT); Map::UpdateCodeCache(receiver_map, name, code); return code; } -Handle StubCache::ComputeKeyedStoreElement( - Handle receiver_map, - StrictMode strict_mode, +Handle PropertyICCompiler::ComputeKeyedStoreElement( + Handle receiver_map, StrictMode strict_mode, KeyedAccessStoreMode store_mode) { + Isolate* isolate = receiver_map->GetIsolate(); ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); Code::Flags flags = @@ -252,11 +252,11 @@ Handle StubCache::ComputeKeyedStoreElement( store_mode == STORE_NO_TRANSITION_HANDLE_COW); Handle name = - isolate()->factory()->KeyedStoreElementMonomorphic_string(); - Handle probe(receiver_map->FindInCodeCache(*name, flags), isolate_); + isolate->factory()->KeyedStoreElementMonomorphic_string(); + Handle probe(receiver_map->FindInCodeCache(*name, flags), isolate); if (probe->IsCode()) return Handle::cast(probe); - PropertyICCompiler compiler(isolate(), Code::KEYED_STORE_IC, extra_state); + PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); Handle code = compiler.CompileIndexedStoreMonomorphic(receiver_map, store_mode); @@ -278,11 +278,13 @@ static void FillCache(Isolate* isolate, Handle code) { } -Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) { +Code* PropertyICCompiler::FindPreMonomorphicIC(Isolate* isolate, + Code::Kind kind, + ExtraICState state) { Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); UnseededNumberDictionary* dictionary = - isolate()->heap()->non_monomorphic_cache(); - int entry = dictionary->FindEntry(isolate(), flags); + isolate->heap()->non_monomorphic_cache(); + int entry = dictionary->FindEntry(isolate, flags); ASSERT(entry != -1); Object* code = dictionary->ValueAt(entry); // This might be called during the marking phase of the collector @@ -291,15 +293,16 @@ Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) { } -Handle StubCache::ComputeLoad(InlineCacheState ic_state, - ExtraICState extra_state) { +Handle PropertyICCompiler::ComputeLoad(Isolate* isolate, + InlineCacheState ic_state, + ExtraICState extra_state) { Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state); Handle cache = - isolate_->factory()->non_monomorphic_cache(); - int entry = cache->FindEntry(isolate_, flags); + isolate->factory()->non_monomorphic_cache(); + int entry = cache->FindEntry(isolate, flags); if (entry != -1) return Handle(Code::cast(cache->ValueAt(entry))); - PropertyICCompiler compiler(isolate_, Code::LOAD_IC); + PropertyICCompiler compiler(isolate, Code::LOAD_IC); Handle code; if (ic_state == UNINITIALIZED) { code = compiler.CompileLoadInitialize(flags); @@ -310,20 +313,21 @@ Handle StubCache::ComputeLoad(InlineCacheState ic_state, } else { UNREACHABLE(); } - FillCache(isolate_, code); + FillCache(isolate, code); return code; } -Handle StubCache::ComputeStore(InlineCacheState ic_state, - ExtraICState extra_state) { +Handle PropertyICCompiler::ComputeStore(Isolate* isolate, + InlineCacheState ic_state, + ExtraICState extra_state) { Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, ic_state, extra_state); Handle cache = - isolate_->factory()->non_monomorphic_cache(); - int entry = cache->FindEntry(isolate_, flags); + isolate->factory()->non_monomorphic_cache(); + int entry = cache->FindEntry(isolate, flags); if (entry != -1) return Handle(Code::cast(cache->ValueAt(entry))); - PropertyICCompiler compiler(isolate_, Code::STORE_IC); + PropertyICCompiler compiler(isolate, Code::STORE_IC); Handle code; if (ic_state == UNINITIALIZED) { code = compiler.CompileStoreInitialize(flags); @@ -337,22 +341,23 @@ Handle StubCache::ComputeStore(InlineCacheState ic_state, UNREACHABLE(); } - FillCache(isolate_, code); + FillCache(isolate, code); return code; } -Handle StubCache::ComputeCompareNil(Handle receiver_map, - CompareNilICStub* stub) { - Handle name(isolate_->heap()->empty_string()); +Handle PropertyICCompiler::ComputeCompareNil(Handle receiver_map, + CompareNilICStub* stub) { + Isolate* isolate = receiver_map->GetIsolate(); + Handle name(isolate->heap()->empty_string()); if (!receiver_map->is_shared()) { - Handle cached_ic = PropertyICCompiler::Find( - name, receiver_map, Code::COMPARE_NIL_IC, stub->GetExtraICState()); + Handle cached_ic = + Find(name, receiver_map, Code::COMPARE_NIL_IC, stub->GetExtraICState()); if (!cached_ic.is_null()) return cached_ic; } Code::FindAndReplacePattern pattern; - pattern.Add(isolate_->factory()->meta_map(), receiver_map); + pattern.Add(isolate->factory()->meta_map(), receiver_map); Handle ic = stub->GetCodeCopy(pattern); if (!receiver_map->is_shared()) { @@ -364,58 +369,55 @@ Handle StubCache::ComputeCompareNil(Handle receiver_map, // TODO(verwaest): Change this method so it takes in a TypeHandleList. -Handle StubCache::ComputeLoadElementPolymorphic( +Handle PropertyICCompiler::ComputeLoadElementPolymorphic( MapHandleList* receiver_maps) { + Isolate* isolate = receiver_maps->at(0)->GetIsolate(); Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); Handle cache = - isolate_->factory()->polymorphic_code_cache(); + isolate->factory()->polymorphic_code_cache(); Handle probe = cache->Lookup(receiver_maps, flags); if (probe->IsCode()) return Handle::cast(probe); TypeHandleList types(receiver_maps->length()); for (int i = 0; i < receiver_maps->length(); i++) { - types.Add(HeapType::Class(receiver_maps->at(i), isolate())); + types.Add(HeapType::Class(receiver_maps->at(i), isolate)); } CodeHandleList handlers(receiver_maps->length()); - IndexedHandlerCompiler compiler(isolate_); + IndexedHandlerCompiler compiler(isolate); compiler.CompileElementHandlers(receiver_maps, &handlers); - PropertyICCompiler ic_compiler(isolate_, Code::KEYED_LOAD_IC); + PropertyICCompiler ic_compiler(isolate, Code::KEYED_LOAD_IC); Handle code = ic_compiler.CompilePolymorphic( - &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); + &types, &handlers, isolate->factory()->empty_string(), Code::NORMAL, + ELEMENT); - isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); + isolate->counters()->keyed_load_polymorphic_stubs()->Increment(); PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); return code; } -Handle StubCache::ComputePolymorphicIC( - Code::Kind kind, - TypeHandleList* types, - CodeHandleList* handlers, - int number_of_valid_types, - Handle name, - ExtraICState extra_ic_state) { +Handle PropertyICCompiler::ComputePolymorphicIC( + Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, + int valid_types, Handle name, ExtraICState extra_ic_state) { Handle handler = handlers->at(0); - Code::StubType type = number_of_valid_types == 1 ? handler->type() - : Code::NORMAL; + Code::StubType type = valid_types == 1 ? handler->type() : Code::NORMAL; ASSERT(kind == Code::LOAD_IC || kind == Code::STORE_IC); - PropertyICCompiler ic_compiler(isolate_, kind, extra_ic_state); + PropertyICCompiler ic_compiler(name->GetIsolate(), kind, extra_ic_state); return ic_compiler.CompilePolymorphic(types, handlers, name, type, PROPERTY); } -Handle StubCache::ComputeStoreElementPolymorphic( - MapHandleList* receiver_maps, - KeyedAccessStoreMode store_mode, +Handle PropertyICCompiler::ComputeStoreElementPolymorphic( + MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, StrictMode strict_mode) { + Isolate* isolate = receiver_maps->at(0)->GetIsolate(); ASSERT(store_mode == STANDARD_STORE || store_mode == STORE_AND_GROW_NO_TRANSITION || store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || store_mode == STORE_NO_TRANSITION_HANDLE_COW); Handle cache = - isolate_->factory()->polymorphic_code_cache(); + isolate->factory()->polymorphic_code_cache(); ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState( strict_mode, store_mode); Code::Flags flags = @@ -423,7 +425,7 @@ Handle StubCache::ComputeStoreElementPolymorphic( Handle probe = cache->Lookup(receiver_maps, flags); if (probe->IsCode()) return Handle::cast(probe); - PropertyICCompiler compiler(isolate_, Code::KEYED_STORE_IC, extra_state); + PropertyICCompiler compiler(isolate, Code::KEYED_STORE_IC, extra_state); Handle code = compiler.CompileIndexedStorePolymorphic(receiver_maps, store_mode); PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); @@ -434,12 +436,12 @@ Handle StubCache::ComputeStoreElementPolymorphic( void StubCache::Clear() { Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); for (int i = 0; i < kPrimaryTableSize; i++) { - primary_[i].key = heap()->empty_string(); + primary_[i].key = isolate()->heap()->empty_string(); primary_[i].map = NULL; primary_[i].value = empty; } for (int j = 0; j < kSecondaryTableSize; j++) { - secondary_[j].key = heap()->empty_string(); + secondary_[j].key = isolate()->heap()->empty_string(); secondary_[j].map = NULL; secondary_[j].value = empty; } @@ -525,11 +527,11 @@ RUNTIME_FUNCTION(StoreCallbackProperty) { * provide any value for the given name. */ RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) { - ASSERT(args.length() == StubCache::kInterceptorArgsLength); + ASSERT(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength); Handle name_handle = - args.at(StubCache::kInterceptorArgsNameIndex); - Handle interceptor_info = - args.at(StubCache::kInterceptorArgsInfoIndex); + args.at(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex); + Handle interceptor_info = args.at( + NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex); // TODO(rossberg): Support symbols in the API. if (name_handle->IsSymbol()) @@ -542,9 +544,9 @@ RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) { ASSERT(getter != NULL); Handle receiver = - args.at(StubCache::kInterceptorArgsThisIndex); + args.at(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex); Handle holder = - args.at(StubCache::kInterceptorArgsHolderIndex); + args.at(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); PropertyCallbackArguments callback_args( isolate, interceptor_info->data(), *receiver, *holder); { @@ -588,13 +590,13 @@ static Object* ThrowReferenceError(Isolate* isolate, Name* name) { */ RUNTIME_FUNCTION(LoadPropertyWithInterceptor) { HandleScope scope(isolate); - ASSERT(args.length() == StubCache::kInterceptorArgsLength); + ASSERT(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength); Handle name = - args.at(StubCache::kInterceptorArgsNameIndex); + args.at(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex); Handle receiver = - args.at(StubCache::kInterceptorArgsThisIndex); + args.at(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex); Handle holder = - args.at(StubCache::kInterceptorArgsHolderIndex); + args.at(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); Handle result; LookupIterator it(receiver, name, holder); diff --git a/src/stub-cache.h b/src/stub-cache.h index 7851a2bc5c..a3bfa42e6e 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -17,13 +17,10 @@ namespace v8 { namespace internal { -// The stub cache is used for megamorphic calls and property accesses. -// It maps (map, name, type)->Code* - -// The design of the table uses the inline cache stubs used for -// mono-morphic calls. The beauty of this, we do not have to -// invalidate the cache whenever a prototype map is changed. The stub -// validates the map chain as in the mono-morphic case. +// The stub cache is used for megamorphic property accesses. +// It maps (map, name, type) to property access handlers. The cache does not +// need explicit invalidation when a prototype chain is modified, since the +// handlers verify the chain. class CallOptimization; @@ -53,64 +50,17 @@ class StubCache { }; void Initialize(); - - Handle ComputeMonomorphicIC(Code::Kind kind, - Handle name, - Handle type, - Handle handler, - ExtraICState extra_ic_state); - - Handle ComputeLoadNonexistent(Handle name, Handle type); - - Handle ComputeKeyedLoadElement(Handle receiver_map); - - Handle ComputeKeyedStoreElement(Handle receiver_map, - StrictMode strict_mode, - KeyedAccessStoreMode store_mode); - - // --- - - Handle ComputeLoad(InlineCacheState ic_state, ExtraICState extra_state); - Handle ComputeStore(InlineCacheState ic_state, - ExtraICState extra_state); - - // --- - - Handle ComputeCompareNil(Handle receiver_map, - CompareNilICStub* stub); - - // --- - - Handle ComputeLoadElementPolymorphic(MapHandleList* receiver_maps); - Handle ComputeStoreElementPolymorphic(MapHandleList* receiver_maps, - KeyedAccessStoreMode store_mode, - StrictMode strict_mode); - - Handle ComputePolymorphicIC(Code::Kind kind, - TypeHandleList* types, - CodeHandleList* handlers, - int number_of_valid_maps, - Handle name, - ExtraICState extra_ic_state); - - // Finds the Code object stored in the Heap::non_monomorphic_cache(). - Code* FindPreMonomorphicIC(Code::Kind kind, ExtraICState extra_ic_state); - - // Update cache for entry hash(name, map). + // Access cache for entry hash(name, map). Code* Set(Name* name, Map* map, Code* code); - Code* Get(Name* name, Map* map, Code::Flags flags); - // Clear the lookup table (@ mark compact collection). void Clear(); - // Collect all maps that match the name and flags. void CollectMatchingMaps(SmallMapList* types, Handle name, Code::Flags flags, Handle native_context, Zone* zone); - // Generate code for probing the stub cache table. // Arguments extra, extra2 and extra3 may be used to pass additional scratch // registers. Set to no_reg if not needed. @@ -128,25 +78,21 @@ class StubCache { kSecondary }; - SCTableReference key_reference(StubCache::Table table) { return SCTableReference( reinterpret_cast
(&first_entry(table)->key)); } - SCTableReference map_reference(StubCache::Table table) { return SCTableReference( reinterpret_cast
(&first_entry(table)->map)); } - SCTableReference value_reference(StubCache::Table table) { return SCTableReference( reinterpret_cast
(&first_entry(table)->value)); } - StubCache::Entry* first_entry(StubCache::Table table) { switch (table) { case StubCache::kPrimary: return StubCache::primary_; @@ -157,18 +103,6 @@ class StubCache { } Isolate* isolate() { return isolate_; } - Heap* heap() { return isolate()->heap(); } - Factory* factory() { return isolate()->factory(); } - - // These constants describe the structure of the interceptor arguments on the - // stack. The arguments are pushed by the (platform-specific) - // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and - // LoadWithInterceptor. - static const int kInterceptorArgsNameIndex = 0; - static const int kInterceptorArgsInfoIndex = 1; - static const int kInterceptorArgsThisIndex = 2; - static const int kInterceptorArgsHolderIndex = 3; - static const int kInterceptorArgsLength = 4; // Setting the entry size such that the index is shifted by Name::kHashShift // is convenient; shifting down the length field (to extract the hash code) @@ -335,6 +269,42 @@ class PropertyAccessCompiler BASE_EMBEDDED { class PropertyICCompiler : public PropertyAccessCompiler { public: + // Finds the Code object stored in the Heap::non_monomorphic_cache(). + static Code* FindPreMonomorphicIC(Isolate* isolate, Code::Kind kind, + ExtraICState extra_ic_state); + + // Named + static Handle ComputeLoad(Isolate* isolate, InlineCacheState ic_state, + ExtraICState extra_state); + static Handle ComputeStore(Isolate* isolate, InlineCacheState ic_state, + ExtraICState extra_state); + + static Handle ComputeMonomorphicIC(Code::Kind kind, Handle name, + Handle type, + Handle handler, + ExtraICState extra_ic_state); + static Handle ComputePolymorphicIC( + Code::Kind kind, TypeHandleList* types, CodeHandleList* handlers, + int number_of_valid_maps, Handle name, ExtraICState extra_ic_state); + + // Keyed + static Handle ComputeKeyedLoadElement(Handle receiver_map); + + static Handle ComputeKeyedStoreElement(Handle receiver_map, + StrictMode strict_mode, + KeyedAccessStoreMode store_mode); + static Handle ComputeLoadElementPolymorphic( + MapHandleList* receiver_maps); + static Handle ComputeStoreElementPolymorphic( + MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode, + StrictMode strict_mode); + + // Compare nil + static Handle ComputeCompareNil(Handle receiver_map, + CompareNilICStub* stub); + + + private: PropertyICCompiler(Isolate* isolate, Code::Kind kind, ExtraICState extra_ic_state = kNoExtraICState, CacheHolderFlag cache_holder = kCacheOnReceiver) @@ -356,7 +326,6 @@ class PropertyICCompiler : public PropertyAccessCompiler { Handle CompileMonomorphic(Handle type, Handle handler, Handle name, IcCheckType check); - Handle CompilePolymorphic(TypeHandleList* types, CodeHandleList* handlers, Handle name, Code::StubType type, IcCheckType check); @@ -365,8 +334,10 @@ class PropertyICCompiler : public PropertyAccessCompiler { KeyedAccessStoreMode store_mode); Handle CompileIndexedStorePolymorphic(MapHandleList* receiver_maps, KeyedAccessStoreMode store_mode); + Handle CompileIndexedStorePolymorphic(MapHandleList* receiver_maps, + CodeHandleList* handler_stubs, + MapHandleList* transitioned_maps); - private: bool IncludesNumberType(TypeHandleList* types); Handle GetCode(Code::Kind kind, Code::StubType type, Handle name, @@ -391,9 +362,6 @@ class PropertyICCompiler : public PropertyAccessCompiler { } } - Handle CompileIndexedStorePolymorphic(MapHandleList* receiver_maps, - CodeHandleList* handler_stubs, - MapHandleList* transitioned_maps); const ExtraICState extra_ic_state_; }; @@ -514,9 +482,8 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { Handle name, Handle getter); - Handle CompileLoadNonexistent(Handle type, - Handle last, - Handle name); + static Handle ComputeLoadNonexistent(Handle name, + Handle type); Handle CompileLoadGlobal(Handle type, Handle holder, @@ -539,6 +506,16 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { Register scratch2, Label* miss_label); + // These constants describe the structure of the interceptor arguments on the + // stack. The arguments are pushed by the (platform-specific) + // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and + // LoadWithInterceptor. + static const int kInterceptorArgsNameIndex = 0; + static const int kInterceptorArgsInfoIndex = 1; + static const int kInterceptorArgsThisIndex = 2; + static const int kInterceptorArgsHolderIndex = 3; + static const int kInterceptorArgsLength = 4; + protected: virtual Register FrontendHeader(Handle type, Register object_reg, Handle holder, Handle name, @@ -550,6 +527,8 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler { Register CallbackFrontend(Handle type, Register object_reg, Handle holder, Handle name, Handle callback); + Handle CompileLoadNonexistent(Handle type, + Handle last, Handle name); void NonexistentFrontend(Handle type, Handle last, Handle name); diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index ae4c16e086..abcd7d036c 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -232,11 +232,11 @@ static void PushInterceptorArguments(MacroAssembler* masm, Register holder, Register name, Handle holder_obj) { - STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); - STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); - STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); - STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); - STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3); + STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4); __ Push(name); Handle interceptor(holder_obj->GetNamedInterceptor()); ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); @@ -255,9 +255,8 @@ static void CompileCallLoadPropertyWithInterceptor( Handle holder_obj, IC::UtilityId id) { PushInterceptorArguments(masm, receiver, holder, name, holder_obj); - __ CallExternalReference( - ExternalReference(IC_Utility(id), masm->isolate()), - StubCache::kInterceptorArgsLength); + __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()), + NamedLoadHandlerCompiler::kInterceptorArgsLength); } @@ -959,7 +958,8 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor( ExternalReference ref = ExternalReference( IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); - __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); + __ TailCallExternalReference( + ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); } }