diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 9f3e0790ea..2e3a0f8a3e 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -3051,7 +3051,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( Handle BaseLoadStoreStubCompiler::CompilePolymorphicIC( - MapHandleList* receiver_maps, + TypeHandleList* types, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -3063,22 +3063,22 @@ Handle BaseLoadStoreStubCompiler::CompilePolymorphicIC( } Label number_case; - Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss; + Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; __ JumpIfSmi(receiver(), smi_target); Register map_reg = scratch1(); - int receiver_count = receiver_maps->length(); + int receiver_count = types->length(); int number_of_handled_maps = 0; __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); - Handle heap_number_map = isolate()->factory()->heap_number_map(); for (int current = 0; current < receiver_count; ++current) { - Handle map = receiver_maps->at(current); + Handle type = types->at(current); + Handle map = IC::TypeToMap(*type, isolate()); if (!map->is_deprecated()) { number_of_handled_maps++; - __ mov(ip, Operand(receiver_maps->at(current))); + __ mov(ip, Operand(map)); __ cmp(map_reg, ip); - if (map.is_identical_to(heap_number_map)) { + if (type->Is(Type::Number())) { ASSERT(!number_case.is_unused()); __ bind(&number_case); } diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 40144208f6..a3be0a7777 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -3156,7 +3156,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( Handle BaseLoadStoreStubCompiler::CompilePolymorphicIC( - MapHandleList* receiver_maps, + TypeHandleList* types, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -3168,20 +3168,20 @@ Handle BaseLoadStoreStubCompiler::CompilePolymorphicIC( } Label number_case; - Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss; + Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; __ JumpIfSmi(receiver(), smi_target); Register map_reg = scratch1(); __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); - int receiver_count = receiver_maps->length(); + int receiver_count = types->length(); int number_of_handled_maps = 0; - Handle heap_number_map = isolate()->factory()->heap_number_map(); for (int current = 0; current < receiver_count; ++current) { - Handle map = receiver_maps->at(current); + Handle type = types->at(current); + Handle map = IC::TypeToMap(*type, isolate()); if (!map->is_deprecated()) { number_of_handled_maps++; __ cmp(map_reg, map); - if (map.is_identical_to(heap_number_map)) { + if (type->Is(Type::Number())) { ASSERT(!number_case.is_unused()); __ bind(&number_case); } diff --git a/src/ic-inl.h b/src/ic-inl.h index d1c31c0c8f..bd45c3e99d 100644 --- a/src/ic-inl.h +++ b/src/ic-inl.h @@ -120,6 +120,39 @@ HeapObject* IC::GetCodeCacheHolder(Isolate* isolate, } +InlineCacheHolderFlag IC::GetCodeCacheFlag(Type* type) { + if (type->Is(Type::Boolean()) || + type->Is(Type::Number()) || + type->Is(Type::String()) || + type->Is(Type::Symbol())) { + return PROTOTYPE_MAP; + } + return OWN_MAP; +} + + +Handle IC::GetCodeCacheHolder(InlineCacheHolderFlag flag, + Type* type, + Isolate* isolate) { + if (flag == PROTOTYPE_MAP) { + Context* context = isolate->context()->native_context(); + JSFunction* constructor; + if (type->Is(Type::Boolean())) { + constructor = context->boolean_function(); + } else if (type->Is(Type::Number())) { + constructor = context->number_function(); + } else if (type->Is(Type::String())) { + constructor = context->string_function(); + } else { + ASSERT(type->Is(Type::Symbol())); + constructor = context->symbol_function(); + } + return handle(JSObject::cast(constructor->instance_prototype())->map()); + } + return type->AsClass(); +} + + } } // namespace v8::internal #endif // V8_IC_INL_H_ diff --git a/src/ic.cc b/src/ic.cc index 2f22532340..9b304057ad 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -783,7 +783,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup, : Handle(JSObject::cast(object->GetPrototype(isolate())), isolate()); - PatchCache(cache_object, name, code); + PatchCache(handle(Type::CurrentOf(cache_object), isolate()), name, code); TRACE_IC("CallIC", name); } @@ -967,79 +967,94 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, } -bool IC::UpdatePolymorphicIC(Handle receiver, +bool IC::UpdatePolymorphicIC(Handle type, Handle name, Handle code) { if (!code->is_handler()) return false; - MapHandleList receiver_maps; + TypeHandleList types; CodeHandleList handlers; - int number_of_valid_maps; + int number_of_valid_types; int handler_to_overwrite = -1; - Handle new_receiver_map(receiver->GetMarkerMap(isolate())); - target()->FindAllMaps(&receiver_maps); - int number_of_maps = receiver_maps.length(); - number_of_valid_maps = number_of_maps; + target()->FindAllTypes(&types); + int number_of_types = types.length(); + number_of_valid_types = number_of_types; - for (int i = 0; i < number_of_maps; i++) { - Handle map = receiver_maps.at(i); - // Filter out deprecated maps to ensure its instances get migrated. - if (map->is_deprecated()) { - number_of_valid_maps--; - // If the receiver map is already in the polymorphic IC, this indicates + for (int i = 0; i < number_of_types; i++) { + Handle current_type = types.at(i); + // Filter out deprecated maps to ensure their instances get migrated. + if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { + number_of_valid_types--; + // If the receiver type is already in the polymorphic IC, this indicates // there was a prototoype chain failure. In that case, just overwrite the // handler. - } else if (map.is_identical_to(new_receiver_map)) { - number_of_valid_maps--; + } else if (type->Is(current_type)) { + ASSERT(handler_to_overwrite == -1); + number_of_valid_types--; handler_to_overwrite = i; } } - if (number_of_valid_maps >= 4) return false; - if (number_of_maps == 0) return false; + if (number_of_valid_types >= 4) return false; + if (number_of_types == 0) return false; + if (!target()->FindHandlers(&handlers, types.length())) return false; - if (!target()->FindHandlers(&handlers, receiver_maps.length())) { - return false; - } - - number_of_valid_maps++; + number_of_valid_types++; if (handler_to_overwrite >= 0) { handlers.Set(handler_to_overwrite, code); } else { - receiver_maps.Add(new_receiver_map); + types.Add(type); handlers.Add(code); } Handle ic = isolate()->stub_cache()->ComputePolymorphicIC( - &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode()); + &types, &handlers, number_of_valid_types, name, strict_mode()); set_target(*ic); return true; } -void IC::UpdateMonomorphicIC(Handle receiver, +Handle IC::TypeToMap(Type* type, Isolate* isolate) { + if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); + if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); + ASSERT(type->IsClass()); + return type->AsClass(); +} + + +Type* IC::MapToType(Handle map) { + if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); + // The only oddballs that can be recorded in ICs are booleans. + if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); + return Type::Class(map); +} + + +void IC::UpdateMonomorphicIC(Handle type, Handle handler, Handle name) { if (!handler->is_handler()) return set_target(*handler); Handle ic = isolate()->stub_cache()->ComputeMonomorphicIC( - name, receiver, handler, strict_mode()); + name, type, handler, strict_mode()); set_target(*ic); } void IC::CopyICToMegamorphicCache(Handle name) { - MapHandleList receiver_maps; + TypeHandleList types; CodeHandleList handlers; - target()->FindAllMaps(&receiver_maps); - if (!target()->FindHandlers(&handlers, receiver_maps.length())) return; - for (int i = 0; i < receiver_maps.length(); i++) { - UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); + target()->FindAllTypes(&types); + if (!target()->FindHandlers(&handlers, types.length())) return; + for (int i = 0; i < types.length(); i++) { + UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); } } -bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { +bool IC::IsTransitionOfMonomorphicTarget(Type* type) { + if (!type->IsClass()) return false; + Map* receiver_map = *type->AsClass(); Map* current_map = target()->FindFirstMap(); ElementsKind receiver_elements_kind = receiver_map->elements_kind(); bool more_general_transition = @@ -1053,14 +1068,14 @@ bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { } -void IC::PatchCache(Handle object, +void IC::PatchCache(Handle type, Handle name, Handle code) { switch (state()) { case UNINITIALIZED: case PREMONOMORPHIC: case MONOMORPHIC_PROTOTYPE_FAILURE: - UpdateMonomorphicIC(object, code, name); + UpdateMonomorphicIC(type, code, name); break; case MONOMORPHIC: { // For now, call stubs are allowed to rewrite to the same stub. This @@ -1069,23 +1084,21 @@ void IC::PatchCache(Handle object, target()->is_keyed_call_stub() || !target().is_identical_to(code)); Code* old_handler = target()->FindFirstHandler(); - if (old_handler == *code && - IsTransitionedMapOfMonomorphicTarget( - object->GetMarkerMap(isolate()))) { - UpdateMonomorphicIC(object, code, name); + if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) { + UpdateMonomorphicIC(type, code, name); break; } // Fall through. } case POLYMORPHIC: if (!target()->is_keyed_stub()) { - if (UpdatePolymorphicIC(object, name, code)) break; + if (UpdatePolymorphicIC(type, name, code)) break; CopyICToMegamorphicCache(name); } set_target(*megamorphic_stub()); // Fall through. case MEGAMORPHIC: - UpdateMegamorphicCache(object->GetMarkerMap(isolate()), *name, *code); + UpdateMegamorphicCache(*type, *name, *code); break; case DEBUG_STUB: break; @@ -1135,14 +1148,15 @@ void LoadIC::UpdateCaches(LookupResult* lookup, code = ComputeHandler(lookup, object, name); } - PatchCache(object, name, code); + PatchCache(handle(Type::CurrentOf(object), isolate()), name, code); TRACE_IC("LoadIC", name); } -void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { +void IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) { // Cache code holding map should be consistent with // GenerateMonomorphicCacheProbe. + Map* map = *TypeToMap(type, isolate()); isolate()->stub_cache()->Set(name, map, code); } @@ -1598,7 +1612,7 @@ void StoreIC::UpdateCaches(LookupResult* lookup, Handle code = ComputeHandler(lookup, receiver, name, value); - PatchCache(receiver, name, code); + PatchCache(handle(Type::CurrentOf(receiver), isolate()), name, code); TRACE_IC("StoreIC", name); } @@ -1744,7 +1758,7 @@ Handle KeyedStoreIC::StoreElementStub(Handle receiver, transitioned_receiver_map = ComputeTransitionedMap(receiver, store_mode); } - if (IsTransitionedMapOfMonomorphicTarget(*transitioned_receiver_map)) { + if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) { // Element family is the same, use the "worst" case map. store_mode = GetNonTransitioningStoreMode(store_mode); return isolate()->stub_cache()->ComputeKeyedStoreElement( diff --git a/src/ic.h b/src/ic.h index 3f5a25658b..7113b0b512 100644 --- a/src/ic.h +++ b/src/ic.h @@ -148,11 +148,24 @@ class IC { Object* object, InlineCacheHolderFlag holder); + static inline InlineCacheHolderFlag GetCodeCacheFlag(Type* type); + static inline Handle GetCodeCacheHolder(InlineCacheHolderFlag flag, + Type* type, + Isolate* isolate); + static bool IsCleared(Code* code) { InlineCacheState state = code->ic_state(); return state == UNINITIALIZED || state == PREMONOMORPHIC; } + // Utility functions to convert maps to types and back. There are two special + // cases: + // - The heap_number_map is used as a marker which includes heap numbers as + // well as smis. + // - The oddball map is only used for booleans. + static Handle TypeToMap(Type* type, Isolate* isolate); + static Type* MapToType(Handle type); + protected: // Get the call-site target; used for determining the state. Handle target() const { return target_; } @@ -204,20 +217,22 @@ class IC { UNREACHABLE(); return Handle::null(); } - void UpdateMonomorphicIC(Handle receiver, + + void UpdateMonomorphicIC(Handle type, Handle handler, Handle name); - bool UpdatePolymorphicIC(Handle receiver, + bool UpdatePolymorphicIC(Handle type, Handle name, Handle code); + virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code); + void CopyICToMegamorphicCache(Handle name); - bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map); - void PatchCache(Handle object, + bool IsTransitionOfMonomorphicTarget(Type* type); + void PatchCache(Handle type, Handle name, Handle code); - virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code); virtual Code::Kind kind() const { UNREACHABLE(); return Code::STUB; @@ -512,7 +527,7 @@ class KeyedLoadIC: public LoadIC { return isolate()->builtins()->KeyedLoadIC_Slow(); } - virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } + virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { } private: // Stub accessors. @@ -693,7 +708,7 @@ class KeyedStoreIC: public StoreIC { protected: virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } - virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } + virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { } virtual Handle pre_monomorphic_stub() { return pre_monomorphic_stub(isolate(), strict_mode()); diff --git a/src/list.h b/src/list.h index 41666deb26..ea67b8b0c6 100644 --- a/src/list.h +++ b/src/list.h @@ -197,11 +197,13 @@ class List { }; class Map; +class Type; class Code; template class Handle; typedef List MapList; typedef List CodeList; typedef List > MapHandleList; +typedef List > TypeHandleList; typedef List > CodeHandleList; // Perform binary search for an element in an already sorted diff --git a/src/objects.cc b/src/objects.cc index 2212e575eb..6cb5e21202 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -10550,7 +10550,23 @@ void Code::FindAllMaps(MapHandleList* maps) { for (RelocIterator it(this, mask); !it.done(); it.next()) { RelocInfo* info = it.rinfo(); Object* object = info->target_object(); - if (object->IsMap()) maps->Add(Handle(Map::cast(object))); + if (object->IsMap()) maps->Add(handle(Map::cast(object))); + } +} + + +void Code::FindAllTypes(TypeHandleList* types) { + ASSERT(is_inline_cache_stub()); + DisallowHeapAllocation no_allocation; + int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); + Isolate* isolate = GetIsolate(); + for (RelocIterator it(this, mask); !it.done(); it.next()) { + RelocInfo* info = it.rinfo(); + Object* object = info->target_object(); + if (object->IsMap()) { + Handle map(Map::cast(object)); + types->Add(handle(IC::MapToType(map), isolate)); + } } } diff --git a/src/objects.h b/src/objects.h index 1a2187f123..d44ae28053 100644 --- a/src/objects.h +++ b/src/objects.h @@ -5238,6 +5238,7 @@ class Code: public HeapObject { // Find the first map in an IC stub. Map* FindFirstMap(); void FindAllMaps(MapHandleList* maps); + void FindAllTypes(TypeHandleList* types); void ReplaceFirstMap(Map* replace); // Find the first handler in an IC stub. diff --git a/src/stub-cache.cc b/src/stub-cache.cc index af1f3a12a2..f9918ed62e 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -134,37 +134,40 @@ Handle StubCache::FindHandler(Handle name, Handle StubCache::ComputeMonomorphicIC(Handle name, - Handle object, + Handle type, Handle handler, StrictModeFlag strict_mode) { Code::Kind kind = handler->handler_kind(); - // Use the same cache holder for the IC as for the handler. - InlineCacheHolderFlag cache_holder = - Code::ExtractCacheHolderFromFlags(handler->flags()); - Handle stub_holder(IC::GetCodeCacheHolder( - isolate(), *object, cache_holder)); - Handle stub_holder_map(stub_holder->map()); - Handle ic = FindIC( - name, stub_holder_map, kind, strict_mode, cache_holder); - if (!ic.is_null()) return ic; + InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); + + Handle stub_holder; + Handle ic; + // There are multiple string maps that all use the same prototype. That + // prototype cannot hold multiple handlers, one for each of the string maps, + // for a single name. Hence, turn off caching of the IC. + bool can_be_cached = !type->Is(Type::String()); + if (can_be_cached) { + stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); + ic = FindIC(name, stub_holder, kind, strict_mode, flag); + if (!ic.is_null()) return ic; + } - Handle map(object->GetMarkerMap(isolate())); if (kind == Code::LOAD_IC) { - LoadStubCompiler ic_compiler(isolate(), cache_holder); - ic = ic_compiler.CompileMonomorphicIC(map, handler, name); + LoadStubCompiler ic_compiler(isolate(), flag); + ic = ic_compiler.CompileMonomorphicIC(type, handler, name); } else if (kind == Code::KEYED_LOAD_IC) { - KeyedLoadStubCompiler ic_compiler(isolate(), cache_holder); - ic = ic_compiler.CompileMonomorphicIC(map, handler, name); + KeyedLoadStubCompiler ic_compiler(isolate(), flag); + ic = ic_compiler.CompileMonomorphicIC(type, handler, name); } else if (kind == Code::STORE_IC) { StoreStubCompiler ic_compiler(isolate(), strict_mode); - ic = ic_compiler.CompileMonomorphicIC(map, handler, name); + ic = ic_compiler.CompileMonomorphicIC(type, handler, name); } else { ASSERT(kind == Code::KEYED_STORE_IC); KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); - ic = ic_compiler.CompileMonomorphicIC(map, handler, name); + ic = ic_compiler.CompileMonomorphicIC(type, handler, name); } - HeapObject::UpdateMapCodeCache(stub_holder, name, ic); + if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); return ic; } @@ -584,6 +587,7 @@ Handle StubCache::ComputeCompareNil(Handle receiver_map, } +// TODO(verwaest): Change this method so it takes in a TypeHandleList. Handle StubCache::ComputeLoadElementPolymorphic( MapHandleList* receiver_maps) { Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC); @@ -592,12 +596,15 @@ Handle StubCache::ComputeLoadElementPolymorphic( 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(handle(Type::Class(receiver_maps->at(i)), isolate())); + } CodeHandleList handlers(receiver_maps->length()); KeyedLoadStubCompiler compiler(isolate_); compiler.CompileElementHandlers(receiver_maps, &handlers); Handle code = compiler.CompilePolymorphicIC( - receiver_maps, &handlers, factory()->empty_string(), - Code::NORMAL, ELEMENT); + &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); @@ -606,24 +613,24 @@ Handle StubCache::ComputeLoadElementPolymorphic( } -Handle StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, +Handle StubCache::ComputePolymorphicIC(TypeHandleList* types, CodeHandleList* handlers, - int number_of_valid_maps, + int number_of_valid_types, Handle name, StrictModeFlag strict_mode) { Handle handler = handlers->at(0); Code::Kind kind = handler->handler_kind(); - Code::StubType type = number_of_valid_maps == 1 ? handler->type() - : Code::NORMAL; + Code::StubType type = number_of_valid_types == 1 ? handler->type() + : Code::NORMAL; if (kind == Code::LOAD_IC) { LoadStubCompiler ic_compiler(isolate_); return ic_compiler.CompilePolymorphicIC( - receiver_maps, handlers, name, type, PROPERTY); + types, handlers, name, type, PROPERTY); } else { ASSERT(kind == Code::STORE_IC); StoreStubCompiler ic_compiler(isolate_, strict_mode); return ic_compiler.CompilePolymorphicIC( - receiver_maps, handlers, name, type, PROPERTY); + types, handlers, name, type, PROPERTY); } } @@ -1181,12 +1188,9 @@ Register StoreStubCompiler::HandlerFrontendHeader( } -bool BaseLoadStoreStubCompiler::HasHeapNumberMap(MapHandleList* receiver_maps) { - for (int i = 0; i < receiver_maps->length(); ++i) { - Handle map = receiver_maps->at(i); - if (map.is_identical_to(isolate()->factory()->heap_number_map())) { - return true; - } +bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { + for (int i = 0; i < types->length(); ++i) { + if (types->at(i)->Is(Type::Number())) return true; } return false; } @@ -1353,15 +1357,15 @@ void LoadStubCompiler::GenerateLoadPostInterceptor( Handle BaseLoadStoreStubCompiler::CompileMonomorphicIC( - Handle receiver_map, + Handle type, Handle handler, Handle name) { - MapHandleList receiver_maps(1); - receiver_maps.Add(receiver_map); + TypeHandleList types(1); CodeHandleList handlers(1); + types.Add(type); handlers.Add(handler); - Code::StubType type = handler->type(); - return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); + Code::StubType stub_type = handler->type(); + return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY); } diff --git a/src/stub-cache.h b/src/stub-cache.h index 1daffff4a9..adfa44a3ef 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -93,7 +93,7 @@ class StubCache { StrictModeFlag strict_mode = kNonStrictMode); Handle ComputeMonomorphicIC(Handle name, - Handle receiver, + Handle type, Handle handler, StrictModeFlag strict_mode); @@ -173,7 +173,7 @@ class StubCache { KeyedAccessStoreMode store_mode, StrictModeFlag strict_mode); - Handle ComputePolymorphicIC(MapHandleList* receiver_maps, + Handle ComputePolymorphicIC(TypeHandleList* types, CodeHandleList* handlers, int number_of_valid_maps, Handle name, @@ -532,11 +532,11 @@ class BaseLoadStoreStubCompiler: public StubCompiler { } virtual ~BaseLoadStoreStubCompiler() { } - Handle CompileMonomorphicIC(Handle receiver_map, + Handle CompileMonomorphicIC(Handle type, Handle handler, Handle name); - Handle CompilePolymorphicIC(MapHandleList* receiver_maps, + Handle CompilePolymorphicIC(TypeHandleList* types, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -608,7 +608,7 @@ class BaseLoadStoreStubCompiler: public StubCompiler { void InitializeRegisters(); - bool HasHeapNumberMap(MapHandleList* receiver_maps); + bool IncludesNumberType(TypeHandleList* types); Code::Kind kind_; InlineCacheHolderFlag cache_holder_; diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 431bf47107..a1e8f21116 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -3068,7 +3068,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( Handle BaseLoadStoreStubCompiler::CompilePolymorphicIC( - MapHandleList* receiver_maps, + TypeHandleList* types, CodeHandleList* handlers, Handle name, Code::StubType type, @@ -3080,21 +3080,21 @@ Handle BaseLoadStoreStubCompiler::CompilePolymorphicIC( } Label number_case; - Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss; + Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; __ JumpIfSmi(receiver(), smi_target); Register map_reg = scratch1(); __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); - int receiver_count = receiver_maps->length(); + int receiver_count = types->length(); int number_of_handled_maps = 0; - Handle heap_number_map = isolate()->factory()->heap_number_map(); for (int current = 0; current < receiver_count; ++current) { - Handle map = receiver_maps->at(current); + Handle type = types->at(current); + Handle map = IC::TypeToMap(*type, isolate()); if (!map->is_deprecated()) { number_of_handled_maps++; // Check map and tail call if there's a match - __ Cmp(map_reg, receiver_maps->at(current)); - if (map.is_identical_to(heap_number_map)) { + __ Cmp(map_reg, map); + if (type->Is(Type::Number())) { ASSERT(!number_case.is_unused()); __ bind(&number_case); }