diff options
Diffstat (limited to 'src/stub-cache.cc')
-rw-r--r-- | src/stub-cache.cc | 155 |
1 files changed, 108 insertions, 47 deletions
diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 6ebe495f..397988ae 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -441,9 +441,12 @@ Object* StubCache::ComputeKeyedStoreField(String* name, JSObject* receiver, return code; } +#define CALL_LOGGER_TAG(kind, type) \ + (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) Object* StubCache::ComputeCallConstant(int argc, InLoopFlag in_loop, + Code::Kind kind, String* name, Object* object, JSObject* holder, @@ -462,7 +465,7 @@ Object* StubCache::ComputeCallConstant(int argc, } Code::Flags flags = - Code::ComputeMonomorphicFlags(Code::CALL_IC, + Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, in_loop, argc); @@ -474,11 +477,12 @@ Object* StubCache::ComputeCallConstant(int argc, // caches. if (!function->is_compiled()) return Failure::InternalError(); // Compile the stub - only create stubs for fully compiled functions. - CallStubCompiler compiler(argc, in_loop); + CallStubCompiler compiler(argc, in_loop, kind); code = compiler.CompileCallConstant(object, holder, function, name, check); if (code->IsFailure()) return code; ASSERT_EQ(flags, Code::cast(code)->flags()); - PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), + Code::cast(code), name)); Object* result = map->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } @@ -488,6 +492,7 @@ Object* StubCache::ComputeCallConstant(int argc, Object* StubCache::ComputeCallField(int argc, InLoopFlag in_loop, + Code::Kind kind, String* name, Object* object, JSObject* holder, @@ -502,20 +507,21 @@ Object* StubCache::ComputeCallField(int argc, object = holder; } - Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, + Code::Flags flags = Code::ComputeMonomorphicFlags(kind, FIELD, in_loop, argc); Object* code = map->FindInCodeCache(name, flags); if (code->IsUndefined()) { - CallStubCompiler compiler(argc, in_loop); + CallStubCompiler compiler(argc, in_loop, kind); code = compiler.CompileCallField(JSObject::cast(object), holder, index, name); if (code->IsFailure()) return code; ASSERT_EQ(flags, Code::cast(code)->flags()); - PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), + Code::cast(code), name)); Object* result = map->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } @@ -524,6 +530,7 @@ Object* StubCache::ComputeCallField(int argc, Object* StubCache::ComputeCallInterceptor(int argc, + Code::Kind kind, String* name, Object* object, JSObject* holder) { @@ -539,19 +546,20 @@ Object* StubCache::ComputeCallInterceptor(int argc, } Code::Flags flags = - Code::ComputeMonomorphicFlags(Code::CALL_IC, + Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, NOT_IN_LOOP, argc); Object* code = map->FindInCodeCache(name, flags); if (code->IsUndefined()) { - CallStubCompiler compiler(argc, NOT_IN_LOOP); + CallStubCompiler compiler(argc, NOT_IN_LOOP, kind); code = compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); if (code->IsFailure()) return code; ASSERT_EQ(flags, Code::cast(code)->flags()); - PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), + Code::cast(code), name)); Object* result = map->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } @@ -561,9 +569,10 @@ Object* StubCache::ComputeCallInterceptor(int argc, Object* StubCache::ComputeCallNormal(int argc, InLoopFlag in_loop, + Code::Kind kind, String* name, JSObject* receiver) { - Object* code = ComputeCallNormal(argc, in_loop); + Object* code = ComputeCallNormal(argc, in_loop, kind); if (code->IsFailure()) return code; return Set(name, receiver->map(), Code::cast(code)); } @@ -571,13 +580,17 @@ Object* StubCache::ComputeCallNormal(int argc, Object* StubCache::ComputeCallGlobal(int argc, InLoopFlag in_loop, + Code::Kind kind, String* name, JSObject* receiver, GlobalObject* holder, JSGlobalPropertyCell* cell, JSFunction* function) { Code::Flags flags = - Code::ComputeMonomorphicFlags(Code::CALL_IC, NORMAL, in_loop, argc); + Code::ComputeMonomorphicFlags(kind, + NORMAL, + in_loop, + argc); Object* code = receiver->map()->FindInCodeCache(name, flags); if (code->IsUndefined()) { // If the function hasn't been compiled yet, we cannot do it now @@ -585,11 +598,12 @@ Object* StubCache::ComputeCallGlobal(int argc, // internal error which will make sure we do not update any // caches. if (!function->is_compiled()) return Failure::InternalError(); - CallStubCompiler compiler(argc, in_loop); + CallStubCompiler compiler(argc, in_loop, kind); code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); if (code->IsFailure()) return code; ASSERT_EQ(flags, Code::cast(code)->flags()); - PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), + Code::cast(code), name)); Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); if (result->IsFailure()) return result; } @@ -637,9 +651,11 @@ static Object* FillCache(Object* code) { } -Code* StubCache::FindCallInitialize(int argc, InLoopFlag in_loop) { +Code* StubCache::FindCallInitialize(int argc, + InLoopFlag in_loop, + Code::Kind kind) { Code::Flags flags = - Code::ComputeFlags(Code::CALL_IC, in_loop, UNINITIALIZED, NORMAL, argc); + Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc); Object* result = ProbeCache(flags); ASSERT(!result->IsUndefined()); // This might be called during the marking phase of the collector @@ -648,9 +664,11 @@ Code* StubCache::FindCallInitialize(int argc, InLoopFlag in_loop) { } -Object* StubCache::ComputeCallInitialize(int argc, InLoopFlag in_loop) { +Object* StubCache::ComputeCallInitialize(int argc, + InLoopFlag in_loop, + Code::Kind kind) { Code::Flags flags = - Code::ComputeFlags(Code::CALL_IC, in_loop, UNINITIALIZED, NORMAL, argc); + Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc); Object* probe = ProbeCache(flags); if (!probe->IsUndefined()) return probe; StubCompiler compiler; @@ -658,9 +676,11 @@ Object* StubCache::ComputeCallInitialize(int argc, InLoopFlag in_loop) { } -Object* StubCache::ComputeCallPreMonomorphic(int argc, InLoopFlag in_loop) { +Object* StubCache::ComputeCallPreMonomorphic(int argc, + InLoopFlag in_loop, + Code::Kind kind) { Code::Flags flags = - Code::ComputeFlags(Code::CALL_IC, in_loop, PREMONOMORPHIC, NORMAL, argc); + Code::ComputeFlags(kind, in_loop, PREMONOMORPHIC, NORMAL, argc); Object* probe = ProbeCache(flags); if (!probe->IsUndefined()) return probe; StubCompiler compiler; @@ -668,9 +688,11 @@ Object* StubCache::ComputeCallPreMonomorphic(int argc, InLoopFlag in_loop) { } -Object* StubCache::ComputeCallNormal(int argc, InLoopFlag in_loop) { +Object* StubCache::ComputeCallNormal(int argc, + InLoopFlag in_loop, + Code::Kind kind) { Code::Flags flags = - Code::ComputeFlags(Code::CALL_IC, in_loop, MONOMORPHIC, NORMAL, argc); + Code::ComputeFlags(kind, in_loop, MONOMORPHIC, NORMAL, argc); Object* probe = ProbeCache(flags); if (!probe->IsUndefined()) return probe; StubCompiler compiler; @@ -678,9 +700,11 @@ Object* StubCache::ComputeCallNormal(int argc, InLoopFlag in_loop) { } -Object* StubCache::ComputeCallMegamorphic(int argc, InLoopFlag in_loop) { +Object* StubCache::ComputeCallMegamorphic(int argc, + InLoopFlag in_loop, + Code::Kind kind) { Code::Flags flags = - Code::ComputeFlags(Code::CALL_IC, in_loop, MEGAMORPHIC, NORMAL, argc); + Code::ComputeFlags(kind, in_loop, MEGAMORPHIC, NORMAL, argc); Object* probe = ProbeCache(flags); if (!probe->IsUndefined()) return probe; StubCompiler compiler; @@ -688,9 +712,11 @@ Object* StubCache::ComputeCallMegamorphic(int argc, InLoopFlag in_loop) { } -Object* StubCache::ComputeCallMiss(int argc) { - Code::Flags flags = - Code::ComputeFlags(Code::STUB, NOT_IN_LOOP, MEGAMORPHIC, NORMAL, argc); +Object* StubCache::ComputeCallMiss(int argc, Code::Kind kind) { + // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs + // and monomorphic stubs are not mixed up together in the stub cache. + Code::Flags flags = Code::ComputeFlags( + kind, NOT_IN_LOOP, MONOMORPHIC_PROTOTYPE_FAILURE, NORMAL, argc); Object* probe = ProbeCache(flags); if (!probe->IsUndefined()) return probe; StubCompiler compiler; @@ -699,9 +725,9 @@ Object* StubCache::ComputeCallMiss(int argc) { #ifdef ENABLE_DEBUGGER_SUPPORT -Object* StubCache::ComputeCallDebugBreak(int argc) { +Object* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) { Code::Flags flags = - Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc); + Code::ComputeFlags(kind, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc); Object* probe = ProbeCache(flags); if (!probe->IsUndefined()) return probe; StubCompiler compiler; @@ -709,9 +735,9 @@ Object* StubCache::ComputeCallDebugBreak(int argc) { } -Object* StubCache::ComputeCallDebugPrepareStepIn(int argc) { +Object* StubCache::ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) { Code::Flags flags = - Code::ComputeFlags(Code::CALL_IC, + Code::ComputeFlags(kind, NOT_IN_LOOP, DEBUG_PREPARE_STEP_IN, NORMAL, @@ -758,8 +784,8 @@ void StubCache::Clear() { // Support function for computing call IC miss stubs. -Handle<Code> ComputeCallMiss(int argc) { - CALL_HEAP_FUNCTION(StubCache::ComputeCallMiss(argc), Code); +Handle<Code> ComputeCallMiss(int argc, Code::Kind kind) { + CALL_HEAP_FUNCTION(StubCache::ComputeCallMiss(argc, kind), Code); } @@ -966,13 +992,18 @@ Object* KeyedLoadPropertyWithInterceptor(Arguments args) { Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); - CallIC::GenerateInitialize(masm(), argc); + Code::Kind kind = Code::ExtractKindFromFlags(flags); + if (kind == Code::CALL_IC) { + CallIC::GenerateInitialize(masm(), argc); + } else { + KeyedCallIC::GenerateInitialize(masm(), argc); + } Object* result = GetCodeWithFlags(flags, "CompileCallInitialize"); if (!result->IsFailure()) { Counters::call_initialize_stubs.Increment(); Code* code = Code::cast(result); USE(code); - PROFILE(CodeCreateEvent(Logger::CALL_INITIALIZE_TAG, + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), code, code->arguments_count())); } return result; @@ -984,13 +1015,18 @@ Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { int argc = Code::ExtractArgumentsCountFromFlags(flags); // The code of the PreMonomorphic stub is the same as the code // of the Initialized stub. They just differ on the code object flags. - CallIC::GenerateInitialize(masm(), argc); + Code::Kind kind = Code::ExtractKindFromFlags(flags); + if (kind == Code::CALL_IC) { + CallIC::GenerateInitialize(masm(), argc); + } else { + KeyedCallIC::GenerateInitialize(masm(), argc); + } Object* result = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); if (!result->IsFailure()) { Counters::call_premonomorphic_stubs.Increment(); Code* code = Code::cast(result); USE(code); - PROFILE(CodeCreateEvent(Logger::CALL_PRE_MONOMORPHIC_TAG, + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), code, code->arguments_count())); } return result; @@ -1000,13 +1036,18 @@ Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { Object* StubCompiler::CompileCallNormal(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); - CallIC::GenerateNormal(masm(), argc); + Code::Kind kind = Code::ExtractKindFromFlags(flags); + if (kind == Code::CALL_IC) { + CallIC::GenerateNormal(masm(), argc); + } else { + KeyedCallIC::GenerateNormal(masm(), argc); + } Object* result = GetCodeWithFlags(flags, "CompileCallNormal"); if (!result->IsFailure()) { Counters::call_normal_stubs.Increment(); Code* code = Code::cast(result); USE(code); - PROFILE(CodeCreateEvent(Logger::CALL_NORMAL_TAG, + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), code, code->arguments_count())); } return result; @@ -1016,13 +1057,19 @@ Object* StubCompiler::CompileCallNormal(Code::Flags flags) { Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); - CallIC::GenerateMegamorphic(masm(), argc); + Code::Kind kind = Code::ExtractKindFromFlags(flags); + if (kind == Code::CALL_IC) { + CallIC::GenerateMegamorphic(masm(), argc); + } else { + KeyedCallIC::GenerateMegamorphic(masm(), argc); + } + Object* result = GetCodeWithFlags(flags, "CompileCallMegamorphic"); if (!result->IsFailure()) { Counters::call_megamorphic_stubs.Increment(); Code* code = Code::cast(result); USE(code); - PROFILE(CodeCreateEvent(Logger::CALL_MEGAMORPHIC_TAG, + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), code, code->arguments_count())); } return result; @@ -1032,13 +1079,18 @@ Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { Object* StubCompiler::CompileCallMiss(Code::Flags flags) { HandleScope scope; int argc = Code::ExtractArgumentsCountFromFlags(flags); - CallIC::GenerateMiss(masm(), argc); + Code::Kind kind = Code::ExtractKindFromFlags(flags); + if (kind == Code::CALL_IC) { + CallIC::GenerateMiss(masm(), argc); + } else { + KeyedCallIC::GenerateMiss(masm(), argc); + } Object* result = GetCodeWithFlags(flags, "CompileCallMiss"); if (!result->IsFailure()) { Counters::call_megamorphic_stubs.Increment(); Code* code = Code::cast(result); USE(code); - PROFILE(CodeCreateEvent(Logger::CALL_MISS_TAG, + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), code, code->arguments_count())); } return result; @@ -1053,7 +1105,8 @@ Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { if (!result->IsFailure()) { Code* code = Code::cast(result); USE(code); - PROFILE(CodeCreateEvent(Logger::CALL_DEBUG_BREAK_TAG, + Code::Kind kind = Code::ExtractKindFromFlags(flags); + PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG), code, code->arguments_count())); } return result; @@ -1065,18 +1118,26 @@ Object* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { // Use the same code for the the step in preparations as we do for // the miss case. int argc = Code::ExtractArgumentsCountFromFlags(flags); - CallIC::GenerateMiss(masm(), argc); + Code::Kind kind = Code::ExtractKindFromFlags(flags); + if (kind == Code::CALL_IC) { + CallIC::GenerateMiss(masm(), argc); + } else { + KeyedCallIC::GenerateMiss(masm(), argc); + } Object* result = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); if (!result->IsFailure()) { Code* code = Code::cast(result); USE(code); - PROFILE(CodeCreateEvent(Logger::CALL_DEBUG_PREPARE_STEP_IN_TAG, - code, code->arguments_count())); + PROFILE(CodeCreateEvent( + CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), + code, + code->arguments_count())); } return result; } #endif +#undef CALL_LOGGER_TAG Object* StubCompiler::GetCodeWithFlags(Code::Flags flags, const char* name) { // Check for allocation failures during stub compilation. @@ -1167,7 +1228,7 @@ Object* CallStubCompiler::CompileCustomCall(int generator_id, Object* CallStubCompiler::GetCode(PropertyType type, String* name) { int argc = arguments_.immediate(); - Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, + Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, type, in_loop_, argc); |