diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 831268e335..9b2ba53bde 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -1308,14 +1308,14 @@ void StoreStubCompiler::HandlerFrontendFooter(Handle name, Label* miss) { Register LoadStubCompiler::CallbackHandlerFrontend( - Handle object, + Handle type, Register object_reg, Handle holder, Handle name, Handle callback) { Label miss; - Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); + Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { ASSERT(!reg.is(scratch2())); @@ -2800,7 +2800,8 @@ Handle StoreStubCompiler::CompileStoreCallback( Handle holder, Handle name, Handle callback) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(IC::CurrentTypeOf(object, isolate()), + receiver(), holder, name); // Stub never generated for non-global objects that require access checks. ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); @@ -2826,7 +2827,8 @@ Handle StoreStubCompiler::CompileStoreCallback( Handle holder, Handle name, const CallOptimization& call_optimization) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(IC::CurrentTypeOf(object, isolate()), + receiver(), holder, name); Register values[] = { value() }; GenerateFastApiCall( @@ -2920,12 +2922,10 @@ Handle StoreStubCompiler::CompileStoreInterceptor( } -Handle LoadStubCompiler::CompileLoadNonexistent( - Handle object, - Handle last, - Handle name, - Handle global) { - NonexistentHandlerFrontend(object, last, name, global); +Handle LoadStubCompiler::CompileLoadNonexistent(Handle type, + Handle last, + Handle name) { + NonexistentHandlerFrontend(type, last, name); // Return undefined if maps of the full prototype chain are still the // same and no global property with this name contains a value. @@ -3021,14 +3021,14 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, Handle LoadStubCompiler::CompileLoadGlobal( - Handle object, + Handle type, Handle global, Handle cell, Handle name, bool is_dont_delete) { Label miss; - HandlerFrontendHeader(object, receiver(), global, name, &miss); + HandlerFrontendHeader(type, receiver(), global, name, &miss); // Get the value from the cell. __ mov(r3, Operand(cell)); diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 58f3708b18..d26210d69c 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -1342,14 +1342,14 @@ void StoreStubCompiler::HandlerFrontendFooter(Handle name, Label* miss) { Register LoadStubCompiler::CallbackHandlerFrontend( - Handle object, + Handle type, Register object_reg, Handle holder, Handle name, Handle callback) { Label miss; - Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); + Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { ASSERT(!reg.is(scratch2())); @@ -2952,7 +2952,8 @@ Handle StoreStubCompiler::CompileStoreCallback( Handle holder, Handle name, Handle callback) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(IC::CurrentTypeOf(object, isolate()), + receiver(), holder, name); __ pop(scratch1()); // remove the return address __ push(receiver()); @@ -2976,7 +2977,8 @@ Handle StoreStubCompiler::CompileStoreCallback( Handle holder, Handle name, const CallOptimization& call_optimization) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(IC::CurrentTypeOf(object, isolate()), + receiver(), holder, name); Register values[] = { value() }; GenerateFastApiCall( @@ -3083,12 +3085,10 @@ Handle KeyedStoreStubCompiler::CompileStorePolymorphic( } -Handle LoadStubCompiler::CompileLoadNonexistent( - Handle object, - Handle last, - Handle name, - Handle global) { - NonexistentHandlerFrontend(object, last, name, global); +Handle LoadStubCompiler::CompileLoadNonexistent(Handle type, + Handle last, + Handle name) { + NonexistentHandlerFrontend(type, last, name); // Return undefined if maps of the full prototype chain are still the // same and no global property with this name contains a value. @@ -3179,14 +3179,14 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, Handle LoadStubCompiler::CompileLoadGlobal( - Handle object, + Handle type, Handle global, Handle cell, Handle name, bool is_dont_delete) { Label miss; - HandlerFrontendHeader(object, receiver(), global, name, &miss); + HandlerFrontendHeader(type, receiver(), global, name, &miss); // Get the value from the cell. if (Serializer::enabled()) { __ mov(eax, Immediate(cell)); diff --git a/src/ic.cc b/src/ic.cc index 5774cf3234..c22f3c17d0 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1145,13 +1145,14 @@ void LoadIC::UpdateCaches(LookupResult* lookup, return; } + Handle type = CurrentTypeOf(object, isolate()); Handle code; if (!lookup->IsCacheable()) { // Bail out if the result is not cacheable. code = slow_stub(); } else if (!lookup->IsProperty()) { if (kind() == Code::LOAD_IC) { - code = isolate()->stub_cache()->ComputeLoadNonexistent(name, object); + code = isolate()->stub_cache()->ComputeLoadNonexistent(name, type); } else { code = slow_stub(); } @@ -1159,7 +1160,7 @@ void LoadIC::UpdateCaches(LookupResult* lookup, code = ComputeHandler(lookup, object, name); } - PatchCache(CurrentTypeOf(object, isolate()), name, code); + PatchCache(type, name, code); TRACE_IC("LoadIC", name); } @@ -1181,7 +1182,7 @@ Handle IC::ComputeHandler(LookupResult* lookup, isolate(), *object, cache_holder)); Handle code = isolate()->stub_cache()->FindHandler( - name, stub_holder, kind(), cache_holder, strict_mode()); + name, handle(stub_holder->map()), kind(), cache_holder, strict_mode()); if (!code.is_null()) return code; code = CompileHandler(lookup, object, name, value, cache_holder); @@ -1205,6 +1206,7 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, return SimpleFieldLoad(length_index); } + Handle type = CurrentTypeOf(object, isolate()); Handle holder(lookup->holder()); LoadStubCompiler compiler(isolate(), cache_holder, kind()); @@ -1217,14 +1219,14 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, lookup->representation()); } return compiler.CompileLoadField( - object, holder, name, field, lookup->representation()); + type, holder, name, field, lookup->representation()); } case CONSTANT: { Handle constant(lookup->GetConstant(), isolate()); // TODO(2803): Don't compute a stub for cons strings because they cannot // be embedded into code. if (constant->IsConsString()) break; - return compiler.CompileLoadConstant(object, holder, name, constant); + return compiler.CompileLoadConstant(type, holder, name, constant); } case NORMAL: if (kind() != Code::LOAD_IC) break; @@ -1233,7 +1235,7 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, Handle cell( global->GetPropertyCell(lookup), isolate()); Handle code = compiler.CompileLoadGlobal( - object, global, cell, name, lookup->IsDontDelete()); + type, global, cell, name, lookup->IsDontDelete()); // TODO(verwaest): Move caching of these NORMAL stubs outside as well. Handle stub_holder(GetCodeCacheHolder( isolate(), *object, cache_holder)); @@ -1263,7 +1265,7 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, Handle::cast(callback); if (v8::ToCData
(info->getter()) == 0) break; if (!info->IsCompatibleReceiver(*object)) break; - return compiler.CompileLoadCallback(object, holder, name, info); + return compiler.CompileLoadCallback(type, holder, name, info); } else if (callback->IsAccessorPair()) { Handle getter(Handle::cast(callback)->getter(), isolate()); @@ -1282,9 +1284,9 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, if (call_optimization.is_simple_api_call() && call_optimization.IsCompatibleReceiver(*object)) { return compiler.CompileLoadCallback( - object, holder, name, call_optimization); + type, holder, name, call_optimization); } - return compiler.CompileLoadViaGetter(object, holder, name, function); + return compiler.CompileLoadViaGetter(type, holder, name, function); } // TODO(dcarney): Handle correctly. if (callback->IsDeclaredAccessorInfo()) break; @@ -1294,7 +1296,7 @@ Handle LoadIC::CompileHandler(LookupResult* lookup, } case INTERCEPTOR: ASSERT(HasInterceptorGetter(*holder)); - return compiler.CompileLoadInterceptor(object, holder, name); + return compiler.CompileLoadInterceptor(type, holder, name); default: break; } diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 756ab27e45..06edc0d687 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -100,21 +100,20 @@ Code* StubCache::Set(Name* name, Map* map, Code* code) { Handle StubCache::FindIC(Handle name, - Handle stub_holder_map, + Handle stub_holder, Code::Kind kind, Code::ExtraICState extra_state, InlineCacheHolderFlag cache_holder) { Code::Flags flags = Code::ComputeMonomorphicFlags( kind, extra_state, cache_holder); - Handle probe(stub_holder_map->FindInCodeCache(*name, flags), - isolate_); + Handle probe(stub_holder->FindInCodeCache(*name, flags), isolate_); if (probe->IsCode()) return Handle::cast(probe); return Handle::null(); } Handle StubCache::FindHandler(Handle name, - Handle stub_holder, + Handle stub_holder, Code::Kind kind, InlineCacheHolderFlag cache_holder, StrictModeFlag strict_mode) { @@ -126,8 +125,7 @@ Handle StubCache::FindHandler(Handle name, Code::Flags flags = Code::ComputeMonomorphicFlags( Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind); - Handle probe(stub_holder->map()->FindInCodeCache(*name, flags), - isolate_); + Handle probe(stub_holder->FindInCodeCache(*name, flags), isolate_); if (probe->IsCode()) return Handle::cast(probe); return Handle::null(); } @@ -173,41 +171,35 @@ Handle StubCache::ComputeMonomorphicIC(Handle name, Handle StubCache::ComputeLoadNonexistent(Handle name, - Handle object) { - InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); - Handle stub_holder(IC::GetCodeCacheHolder( - isolate(), *object, cache_holder)); - // If no global 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 the empty string for the map cache in that case. If - // there are global objects involved, we need to check global - // property cells in the stub and therefore the stub will be - // specific to the name. - Handle cache_name = factory()->empty_string(); - Handle current; - Handle next = stub_holder; - Handle global; - do { - current = Handle::cast(next); - next = Handle(current->GetPrototype(), isolate_); - if (current->IsJSGlobalObject()) { - global = Handle::cast(current); - cache_name = name; - } else if (!current->HasFastProperties()) { - cache_name = name; - } - } while (!next->IsNull()); + Handle type) { + InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); + Handle stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); + // 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 + // the empty string for the map cache in that case. If there are dictionary + // mode objects involved, we need to do negative lookups in the stub and + // therefore the stub will be specific to the name. + Handle current_map = stub_holder; + Handle cache_name = current_map->is_dictionary_map() + ? name : Handle::cast(isolate()->factory()->empty_string()); + Handle next(current_map->prototype(), isolate()); + Handle last = Handle::null(); + while (!next->IsNull()) { + last = Handle::cast(next); + next = handle(current_map->prototype(), isolate()); + current_map = handle(Handle::cast(next)->map()); + if (current_map->is_dictionary_map()) cache_name = name; + } // Compile the stub that is either shared for all names or // name specific if there are global objects involved. Handle handler = FindHandler( - cache_name, stub_holder, Code::LOAD_IC, cache_holder); + cache_name, stub_holder, Code::LOAD_IC, flag); if (!handler.is_null()) return handler; - LoadStubCompiler compiler(isolate_, cache_holder); - handler = - compiler.CompileLoadNonexistent(object, current, cache_name, global); - HeapObject::UpdateMapCodeCache(stub_holder, cache_name, handler); + LoadStubCompiler compiler(isolate_, flag); + handler = compiler.CompileLoadNonexistent(type, last, cache_name); + Map::UpdateCodeCache(stub_holder, cache_name, handler); return handler; } @@ -1135,56 +1127,54 @@ void StubCompiler::LookupPostInterceptor(Handle holder, Register LoadStubCompiler::HandlerFrontendHeader( - Handle object, + Handle type, Register object_reg, Handle holder, Handle name, Label* miss) { - Handle receiver; PrototypeCheckType check_type = CHECK_ALL_MAPS; int function_index = -1; - if (object->IsJSObject()) { - receiver = Handle::cast(object); - check_type = SKIP_RECEIVER; + if (type->Is(Type::String())) { + function_index = Context::STRING_FUNCTION_INDEX; + } else if (type->Is(Type::Symbol())) { + function_index = Context::SYMBOL_FUNCTION_INDEX; + } else if (type->Is(Type::Number())) { + function_index = Context::NUMBER_FUNCTION_INDEX; + } else if (type->Is(Type::Boolean())) { + // Booleans use the generic oddball map, so an additional check is needed to + // ensure the receiver is really a boolean. + GenerateBooleanCheck(object_reg, miss); + function_index = Context::BOOLEAN_FUNCTION_INDEX; } else { - if (object->IsString()) { - function_index = Context::STRING_FUNCTION_INDEX; - } else if (object->IsSymbol()) { - function_index = Context::SYMBOL_FUNCTION_INDEX; - } else if (object->IsNumber()) { - function_index = Context::NUMBER_FUNCTION_INDEX; - } else { - ASSERT(object->IsBoolean()); - // Booleans use the generic oddball map, so an additional check is - // needed to ensure the receiver is really a boolean. - GenerateBooleanCheck(object_reg, miss); - function_index = Context::BOOLEAN_FUNCTION_INDEX; - } + check_type = SKIP_RECEIVER; + } + if (check_type == CHECK_ALL_MAPS) { GenerateDirectLoadGlobalFunctionPrototype( masm(), function_index, scratch1(), miss); - receiver = handle(JSObject::cast(object->GetPrototype(isolate()))); + Object* function = isolate()->native_context()->get(function_index); + Object* prototype = JSFunction::cast(function)->instance_prototype(); + type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate()); object_reg = scratch1(); } // Check that the maps starting from the prototype haven't changed. return CheckPrototypes( - IC::CurrentTypeOf(receiver, isolate()), object_reg, holder, - scratch1(), scratch2(), scratch3(), name, miss, check_type); + type, object_reg, holder, scratch1(), scratch2(), scratch3(), + name, miss, check_type); } // HandlerFrontend for store uses the name register. It has to be restored // before a miss. Register StoreStubCompiler::HandlerFrontendHeader( - Handle object, + Handle type, Register object_reg, Handle holder, Handle name, Label* miss) { - return CheckPrototypes( - IC::CurrentTypeOf(object, isolate()), object_reg, holder, this->name(), - scratch1(), scratch2(), name, miss, SKIP_RECEIVER); + return CheckPrototypes(type, object_reg, holder, this->name(), + scratch1(), scratch2(), name, miss, SKIP_RECEIVER); } @@ -1196,13 +1186,13 @@ bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { } -Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle object, +Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle type, Register object_reg, Handle holder, Handle name) { Label miss; - Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); + Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); HandlerFrontendFooter(name, &miss); @@ -1210,32 +1200,43 @@ Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle object, } -void LoadStubCompiler::NonexistentHandlerFrontend( - Handle object, - Handle last, - Handle name, - Handle global) { +void LoadStubCompiler::NonexistentHandlerFrontend(Handle type, + Handle last, + Handle name) { Label miss; - Register holder = HandlerFrontendHeader( - object, receiver(), last, name, &miss); + Register holder; + Handle last_map; + if (last.is_null()) { + holder = receiver(); + last_map = IC::TypeToMap(*type, isolate()); + // If |type| has null as its prototype, |last| is Handle::null(). + ASSERT(last_map->prototype() == isolate()->heap()->null_value()); + } else { + holder = HandlerFrontendHeader(type, receiver(), last, name, &miss); + last_map = handle(last->map()); + } - if (!last->HasFastProperties() && - !last->IsJSGlobalObject() && - !last->IsJSGlobalProxy()) { + if (last_map->is_dictionary_map() && + !last_map->IsJSGlobalObjectMap() && + !last_map->IsJSGlobalProxyMap()) { if (!name->IsUniqueName()) { ASSERT(name->IsString()); name = factory()->InternalizeString(Handle::cast(name)); } - ASSERT(last->property_dictionary()->FindEntry(*name) == - NameDictionary::kNotFound); + ASSERT(last.is_null() || + last->property_dictionary()->FindEntry(*name) == + NameDictionary::kNotFound); GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, scratch2(), scratch3()); } // If the last object in the prototype chain is a global object, // check that the global property cell is empty. - if (!global.is_null()) { + if (last_map->IsJSGlobalObjectMap()) { + Handle global = last.is_null() + ? Handle::cast(type->AsConstant()) + : Handle::cast(last); GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); } @@ -1244,14 +1245,14 @@ void LoadStubCompiler::NonexistentHandlerFrontend( Handle LoadStubCompiler::CompileLoadField( - Handle object, + Handle type, Handle holder, Handle name, PropertyIndex field, Representation representation) { Label miss; - Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); + Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss); GenerateLoadField(reg, holder, field, representation); @@ -1264,11 +1265,11 @@ Handle LoadStubCompiler::CompileLoadField( Handle LoadStubCompiler::CompileLoadConstant( - Handle object, + Handle type, Handle holder, Handle name, Handle value) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(type, receiver(), holder, name); GenerateLoadConstant(value); // Return the generated code. @@ -1277,12 +1278,12 @@ Handle LoadStubCompiler::CompileLoadConstant( Handle LoadStubCompiler::CompileLoadCallback( - Handle object, + Handle type, Handle holder, Handle name, Handle callback) { Register reg = CallbackHandlerFrontend( - object, receiver(), holder, name, callback); + type, receiver(), holder, name, callback); GenerateLoadCallback(reg, callback); // Return the generated code. @@ -1291,13 +1292,13 @@ Handle LoadStubCompiler::CompileLoadCallback( Handle LoadStubCompiler::CompileLoadCallback( - Handle object, + Handle type, Handle holder, Handle name, const CallOptimization& call_optimization) { ASSERT(call_optimization.is_simple_api_call()); Handle callback = call_optimization.constant_function(); - CallbackHandlerFrontend(object, receiver(), holder, name, callback); + CallbackHandlerFrontend(type, receiver(), holder, name, callback); GenerateLoadCallback(call_optimization); // Return the generated code. @@ -1306,16 +1307,16 @@ Handle LoadStubCompiler::CompileLoadCallback( Handle LoadStubCompiler::CompileLoadInterceptor( - Handle object, + Handle type, Handle holder, Handle name) { LookupResult lookup(isolate()); LookupPostInterceptor(holder, name, &lookup); - Register reg = HandlerFrontend(object, receiver(), holder, name); + Register reg = HandlerFrontend(type, receiver(), holder, name); // TODO(368): Compile in the whole chain: all the interceptors in // prototypes and ultimate answer. - GenerateLoadInterceptor(reg, object, holder, &lookup, name); + GenerateLoadInterceptor(reg, type, holder, &lookup, name); // Return the generated code. return GetCode(kind(), Code::FAST, name); @@ -1337,7 +1338,8 @@ void LoadStubCompiler::GenerateLoadPostInterceptor( // We found FIELD property in prototype chain of interceptor's holder. // Retrieve a field from field's holder. Register reg = HandlerFrontend( - interceptor_holder, interceptor_reg, holder, name); + IC::CurrentTypeOf(interceptor_holder, isolate()), + interceptor_reg, holder, name); GenerateLoadField( reg, holder, field, lookup->representation()); } @@ -1350,7 +1352,8 @@ void LoadStubCompiler::GenerateLoadPostInterceptor( ASSERT(callback->getter() != NULL); Register reg = CallbackHandlerFrontend( - interceptor_holder, interceptor_reg, holder, name, callback); + IC::CurrentTypeOf(interceptor_holder, isolate()), + interceptor_reg, holder, name, callback); GenerateLoadCallback(reg, callback); } } @@ -1370,11 +1373,11 @@ Handle BaseLoadStoreStubCompiler::CompileMonomorphicIC( Handle LoadStubCompiler::CompileLoadViaGetter( - Handle object, + Handle type, Handle holder, Handle name, Handle getter) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(type, receiver(), holder, name); GenerateLoadViaGetter(masm(), receiver(), getter); // Return the generated code. @@ -1406,8 +1409,8 @@ Handle StoreStubCompiler::CompileStoreTransition( } while (holder->GetPrototype()->IsJSObject()); } - Register holder_reg = - HandlerFrontendHeader(object, receiver(), holder, name, &miss); + Register holder_reg = HandlerFrontendHeader( + IC::CurrentTypeOf(object, isolate()), receiver(), holder, name, &miss); // If no property was found, and the holder (the last object in the // prototype chain) is in slow mode, we need to do a negative lookup on the @@ -1444,7 +1447,8 @@ Handle StoreStubCompiler::CompileStoreField(Handle object, Handle name) { Label miss; - HandlerFrontendHeader(object, receiver(), object, name, &miss); + HandlerFrontendHeader(IC::CurrentTypeOf(object, isolate()), + receiver(), object, name, &miss); // Generate store field code. GenerateStoreField(masm(), @@ -1467,7 +1471,8 @@ Handle StoreStubCompiler::CompileStoreViaSetter( Handle holder, Handle name, Handle setter) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(IC::CurrentTypeOf(object, isolate()), + receiver(), holder, name); GenerateStoreViaSetter(masm(), setter); return GetCode(kind(), Code::FAST, name); diff --git a/src/stub-cache.h b/src/stub-cache.h index 5a80ca529b..199fca5fe9 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -87,7 +87,7 @@ class StubCache { InlineCacheHolderFlag cache_holder = OWN_MAP); Handle FindHandler(Handle name, - Handle stub_holder, + Handle map, Code::Kind kind, InlineCacheHolderFlag cache_holder = OWN_MAP, StrictModeFlag strict_mode = kNonStrictMode); @@ -97,7 +97,7 @@ class StubCache { Handle handler, StrictModeFlag strict_mode); - Handle ComputeLoadNonexistent(Handle name, Handle object); + Handle ComputeLoadNonexistent(Handle name, Handle type); Handle ComputeKeyedLoadElement(Handle receiver_map); @@ -549,7 +549,7 @@ class BaseLoadStoreStubCompiler: public StubCompiler { } protected: - virtual Register HandlerFrontendHeader(Handle object, + virtual Register HandlerFrontendHeader(Handle type, Register object_reg, Handle holder, Handle name, @@ -557,7 +557,7 @@ class BaseLoadStoreStubCompiler: public StubCompiler { virtual void HandlerFrontendFooter(Handle name, Label* miss) = 0; - Register HandlerFrontend(Handle object, + Register HandlerFrontend(Handle type, Register object_reg, Handle holder, Handle name); @@ -615,32 +615,32 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler { : BaseLoadStoreStubCompiler(isolate, kind, cache_holder) { } virtual ~LoadStubCompiler() { } - Handle CompileLoadField(Handle object, + Handle CompileLoadField(Handle type, Handle holder, Handle name, PropertyIndex index, Representation representation); - Handle CompileLoadCallback(Handle object, + Handle CompileLoadCallback(Handle type, Handle holder, Handle name, Handle callback); - Handle CompileLoadCallback(Handle object, + Handle CompileLoadCallback(Handle type, Handle holder, Handle name, const CallOptimization& call_optimization); - Handle CompileLoadConstant(Handle object, + Handle CompileLoadConstant(Handle type, Handle holder, Handle name, Handle value); - Handle CompileLoadInterceptor(Handle object, + Handle CompileLoadInterceptor(Handle type, Handle holder, Handle name); - Handle CompileLoadViaGetter(Handle object, + Handle CompileLoadViaGetter(Handle type, Handle holder, Handle name, Handle getter); @@ -649,12 +649,11 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler { Register receiver, Handle getter); - Handle CompileLoadNonexistent(Handle object, + Handle CompileLoadNonexistent(Handle type, Handle last, - Handle name, - Handle global); + Handle name); - Handle CompileLoadGlobal(Handle object, + Handle CompileLoadGlobal(Handle type, Handle holder, Handle cell, Handle name, @@ -663,7 +662,7 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler { static Register* registers(); protected: - virtual Register HandlerFrontendHeader(Handle object, + virtual Register HandlerFrontendHeader(Handle type, Register object_reg, Handle holder, Handle name, @@ -671,15 +670,14 @@ class LoadStubCompiler: public BaseLoadStoreStubCompiler { virtual void HandlerFrontendFooter(Handle name, Label* miss); - Register CallbackHandlerFrontend(Handle object, + Register CallbackHandlerFrontend(Handle type, Register object_reg, Handle holder, Handle name, Handle callback); - void NonexistentHandlerFrontend(Handle object, + void NonexistentHandlerFrontend(Handle type, Handle last, - Handle name, - Handle global); + Handle name); void GenerateLoadField(Register reg, Handle holder, @@ -812,7 +810,7 @@ class StoreStubCompiler: public BaseLoadStoreStubCompiler { } protected: - virtual Register HandlerFrontendHeader(Handle object, + virtual Register HandlerFrontendHeader(Handle type, Register object_reg, Handle holder, Handle name, diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 5a7bd10c11..57c6a353c1 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1284,14 +1284,14 @@ void StoreStubCompiler::HandlerFrontendFooter(Handle name, Label* miss) { Register LoadStubCompiler::CallbackHandlerFrontend( - Handle object, + Handle type, Register object_reg, Handle holder, Handle name, Handle callback) { Label miss; - Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); + Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { ASSERT(!reg.is(scratch2())); @@ -2862,7 +2862,8 @@ Handle StoreStubCompiler::CompileStoreCallback( Handle holder, Handle name, Handle callback) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(IC::CurrentTypeOf(object, isolate()), + receiver(), holder, name); __ PopReturnAddressTo(scratch1()); __ push(receiver()); @@ -2886,7 +2887,8 @@ Handle StoreStubCompiler::CompileStoreCallback( Handle holder, Handle name, const CallOptimization& call_optimization) { - HandlerFrontend(object, receiver(), holder, name); + HandlerFrontend(IC::CurrentTypeOf(object, isolate()), + receiver(), holder, name); Register values[] = { value() }; GenerateFastApiCall( @@ -3000,12 +3002,10 @@ Handle KeyedStoreStubCompiler::CompileStorePolymorphic( } -Handle LoadStubCompiler::CompileLoadNonexistent( - Handle object, - Handle last, - Handle name, - Handle global) { - NonexistentHandlerFrontend(object, last, name, global); +Handle LoadStubCompiler::CompileLoadNonexistent(Handle type, + Handle last, + Handle name) { + NonexistentHandlerFrontend(type, last, name); // Return undefined if maps of the full prototype chain are still the // same and no global property with this name contains a value. @@ -3101,7 +3101,7 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, Handle LoadStubCompiler::CompileLoadGlobal( - Handle object, + Handle type, Handle global, Handle cell, Handle name, @@ -3110,7 +3110,7 @@ Handle LoadStubCompiler::CompileLoadGlobal( // TODO(verwaest): Directly store to rax. Currently we cannot do this, since // rax is used as receiver(), which we would otherwise clobber before a // potential miss. - HandlerFrontendHeader(object, receiver(), global, name, &miss); + HandlerFrontendHeader(type, receiver(), global, name, &miss); // Get the value from the cell. __ Move(rbx, cell);