Handlify the remaining stub compiler functions for call ICs.

Handlify StubCompiler functions for CallIC and KeyedCallIC cases
Megamorphic, Arguments, DebugBreak, and DebugPrepareStepIn.

R=ulan@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/8372029

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9750 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2011-10-24 10:55:00 +00:00
parent ec007b46d1
commit ef31d0480a
8 changed files with 65 additions and 127 deletions

View File

@ -382,10 +382,10 @@ Object* CallIC_Miss(Arguments args);
// The generated code does not accept smi keys. // The generated code does not accept smi keys.
// The generated code falls through if both probes miss. // The generated code falls through if both probes miss.
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
int argc, int argc,
Code::Kind kind, Code::Kind kind,
Code::ExtraICState extra_ic_state) { Code::ExtraICState extra_state) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- r1 : receiver // -- r1 : receiver
// -- r2 : name // -- r2 : name
@ -395,7 +395,7 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(kind, Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC, MONOMORPHIC,
extra_ic_state, extra_state,
NORMAL, NORMAL,
argc); argc);
Isolate::Current()->stub_cache()->GenerateProbe( Isolate::Current()->stub_cache()->GenerateProbe(

View File

@ -860,10 +860,10 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// The generated code does not accept smi keys. // The generated code does not accept smi keys.
// The generated code falls through if both probes miss. // The generated code falls through if both probes miss.
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
int argc, int argc,
Code::Kind kind, Code::Kind kind,
Code::ExtraICState extra_ic_state) { Code::ExtraICState extra_state) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- ecx : name // -- ecx : name
// -- edx : receiver // -- edx : receiver
@ -873,11 +873,11 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(kind, Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC, MONOMORPHIC,
extra_ic_state, extra_state,
NORMAL, NORMAL,
argc); argc);
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, Isolate* isolate = masm->isolate();
eax); isolate->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, eax);
// If the stub cache probing failed, the receiver might be a value. // If the stub cache probing failed, the receiver might be a value.
// For value objects, we use the map of the prototype objects for // For value objects, we use the map of the prototype objects for
@ -903,9 +903,9 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Check for boolean. // Check for boolean.
__ bind(&non_string); __ bind(&non_string);
__ cmp(edx, FACTORY->true_value()); __ cmp(edx, isolate->factory()->true_value());
__ j(equal, &boolean); __ j(equal, &boolean);
__ cmp(edx, FACTORY->false_value()); __ cmp(edx, isolate->factory()->false_value());
__ j(not_equal, &miss); __ j(not_equal, &miss);
__ bind(&boolean); __ bind(&boolean);
StubCompiler::GenerateLoadGlobalFunctionPrototype( StubCompiler::GenerateLoadGlobalFunctionPrototype(
@ -913,8 +913,7 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Probe the stub cache for the value object. // Probe the stub cache for the value object.
__ bind(&probe); __ bind(&probe);
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, isolate->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, no_reg);
no_reg);
__ bind(&miss); __ bind(&miss);
} }
@ -1044,7 +1043,7 @@ void CallICBase::GenerateMiss(MacroAssembler* masm,
void CallIC::GenerateMegamorphic(MacroAssembler* masm, void CallIC::GenerateMegamorphic(MacroAssembler* masm,
int argc, int argc,
Code::ExtraICState extra_ic_state) { Code::ExtraICState extra_state) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- ecx : name // -- ecx : name
// -- esp[0] : return address // -- esp[0] : return address
@ -1055,9 +1054,10 @@ void CallIC::GenerateMegamorphic(MacroAssembler* masm,
// Get the receiver of the function from the stack; 1 ~ return address. // Get the receiver of the function from the stack; 1 ~ return address.
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state); CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC,
extra_state);
GenerateMiss(masm, argc, extra_ic_state); GenerateMiss(masm, argc, extra_state);
} }
@ -1159,10 +1159,8 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
__ bind(&lookup_monomorphic_cache); __ bind(&lookup_monomorphic_cache);
__ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
GenerateMonomorphicCacheProbe(masm, CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC,
argc, Code::kNoExtraICState);
Code::KEYED_CALL_IC,
Code::kNoExtraICState);
// Fall through on miss. // Fall through on miss.
__ bind(&slow_call); __ bind(&slow_call);

View File

@ -165,25 +165,23 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
Register scratch, Register scratch,
Register extra, Register extra,
Register extra2) { Register extra2) {
Isolate* isolate = Isolate::Current();
Label miss; Label miss;
USE(extra2); // The register extra2 is not used on the ia32 platform.
// Make sure that code is valid. The shifting code relies on the // Assert that code is valid. The shifting code relies on the entry size
// entry size being 8. // being 8.
ASSERT(sizeof(Entry) == 8); ASSERT(sizeof(Entry) == 8);
// Make sure the flags does not name a specific type. // Assert the flags do not name a specific type.
ASSERT(Code::ExtractTypeFromFlags(flags) == 0); ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
// Make sure that there are no register conflicts. // Assert that there are no register conflicts.
ASSERT(!scratch.is(receiver)); ASSERT(!scratch.is(receiver));
ASSERT(!scratch.is(name)); ASSERT(!scratch.is(name));
ASSERT(!extra.is(receiver)); ASSERT(!extra.is(receiver));
ASSERT(!extra.is(name)); ASSERT(!extra.is(name));
ASSERT(!extra.is(scratch)); ASSERT(!extra.is(scratch));
// Check scratch and extra registers are valid, and extra2 is unused. // Assert scratch and extra registers are valid, and extra2 is unused.
ASSERT(!scratch.is(no_reg)); ASSERT(!scratch.is(no_reg));
ASSERT(extra2.is(no_reg)); ASSERT(extra2.is(no_reg));
@ -197,7 +195,7 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
__ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
// Probe the primary table. // Probe the primary table.
ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra); ProbeTable(isolate(), masm, flags, kPrimary, name, scratch, extra);
// Primary miss: Compute hash for secondary probe. // Primary miss: Compute hash for secondary probe.
__ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
@ -209,7 +207,7 @@ void StubCache::GenerateProbe(MacroAssembler* masm,
__ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize);
// Probe the secondary table. // Probe the secondary table.
ProbeTable(isolate, masm, flags, kSecondary, name, scratch, extra); ProbeTable(isolate(), masm, flags, kSecondary, name, scratch, extra);
// Cache miss: Fall-through and let caller handle the miss by // Cache miss: Fall-through and let caller handle the miss by
// entering the runtime system. // entering the runtime system.

View File

@ -245,6 +245,11 @@ class CallICBase: public IC {
static void GenerateNormal(MacroAssembler* masm, int argc); static void GenerateNormal(MacroAssembler* masm, int argc);
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
int argc,
Code::Kind kind,
Code::ExtraICState extra_state);
Code::Kind kind_; Code::Kind kind_;
friend class IC; friend class IC;

View File

@ -384,10 +384,10 @@ Object* CallIC_Miss(Arguments args);
// The generated code does not accept smi keys. // The generated code does not accept smi keys.
// The generated code falls through if both probes miss. // The generated code falls through if both probes miss.
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
int argc, int argc,
Code::Kind kind, Code::Kind kind,
Code::ExtraICState extra_ic_state) { Code::ExtraICState extra_state) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- a1 : receiver // -- a1 : receiver
// -- a2 : name // -- a2 : name
@ -397,7 +397,7 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(kind, Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC, MONOMORPHIC,
extra_ic_state, extra_state,
NORMAL, NORMAL,
argc); argc);
Isolate::Current()->stub_cache()->GenerateProbe( Isolate::Current()->stub_cache()->GenerateProbe(

View File

@ -1508,14 +1508,6 @@ Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) { Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
CALL_HEAP_FUNCTION(isolate(),
(set_failure(NULL), TryCompileCallMegamorphic(flags)),
Code);
}
MaybeObject* StubCompiler::TryCompileCallMegamorphic(Code::Flags flags) {
HandleScope scope(isolate());
int argc = Code::ExtractArgumentsCountFromFlags(flags); int argc = Code::ExtractArgumentsCountFromFlags(flags);
Code::Kind kind = Code::ExtractKindFromFlags(flags); Code::Kind kind = Code::ExtractKindFromFlags(flags);
Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
@ -1524,46 +1516,26 @@ MaybeObject* StubCompiler::TryCompileCallMegamorphic(Code::Flags flags) {
} else { } else {
KeyedCallIC::GenerateMegamorphic(masm(), argc); KeyedCallIC::GenerateMegamorphic(masm(), argc);
} }
Object* result; Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic");
{ MaybeObject* maybe_result =
TryGetCodeWithFlags(flags, "CompileCallMegamorphic");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
isolate()->counters()->call_megamorphic_stubs()->Increment(); isolate()->counters()->call_megamorphic_stubs()->Increment();
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(), PROFILE(isolate(),
CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
code, code->arguments_count())); *code, code->arguments_count()));
GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
return result; return code;
} }
Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) { Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
CALL_HEAP_FUNCTION(isolate(),
(set_failure(NULL), TryCompileCallArguments(flags)),
Code);
}
MaybeObject* StubCompiler::TryCompileCallArguments(Code::Flags flags) {
HandleScope scope(isolate());
int argc = Code::ExtractArgumentsCountFromFlags(flags); int argc = Code::ExtractArgumentsCountFromFlags(flags);
KeyedCallIC::GenerateNonStrictArguments(masm(), argc); KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
Code::Kind kind = Code::ExtractKindFromFlags(flags); Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments");
Object* result;
{ MaybeObject* maybe_result =
TryGetCodeWithFlags(flags, "CompileCallArguments");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(), PROFILE(isolate(),
CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
code, code->arguments_count())); CALL_MEGAMORPHIC_TAG),
GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code))); *code, code->arguments_count()));
return result; GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
return code;
} }
@ -1615,43 +1587,19 @@ MaybeObject* StubCompiler::TryCompileCallMiss(Code::Flags flags) {
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) { Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
CALL_HEAP_FUNCTION(isolate(),
(set_failure(NULL), TryCompileCallDebugBreak(flags)),
Code);
}
MaybeObject* StubCompiler::TryCompileCallDebugBreak(Code::Flags flags) {
HandleScope scope(isolate());
Debug::GenerateCallICDebugBreak(masm()); Debug::GenerateCallICDebugBreak(masm());
Object* result; Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak");
{ MaybeObject* maybe_result =
TryGetCodeWithFlags(flags, "CompileCallDebugBreak");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Code* code = Code::cast(result);
USE(code);
Code::Kind kind = Code::ExtractKindFromFlags(flags);
USE(kind);
PROFILE(isolate(), PROFILE(isolate(),
CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG), CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
code, code->arguments_count())); CALL_DEBUG_BREAK_TAG),
return result; *code, code->arguments_count()));
return code;
} }
Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
CALL_HEAP_FUNCTION( // Use the same code for the the step in preparations as we do for the
isolate(), // miss case.
(set_failure(NULL), TryCompileCallDebugPrepareStepIn(flags)),
Code);
}
MaybeObject* StubCompiler::TryCompileCallDebugPrepareStepIn(Code::Flags flags) {
HandleScope scope(isolate());
// Use the same code for the the step in preparations as we do for
// the miss case.
int argc = Code::ExtractArgumentsCountFromFlags(flags); int argc = Code::ExtractArgumentsCountFromFlags(flags);
Code::Kind kind = Code::ExtractKindFromFlags(flags); Code::Kind kind = Code::ExtractKindFromFlags(flags);
if (kind == Code::CALL_IC) { if (kind == Code::CALL_IC) {
@ -1660,24 +1608,19 @@ MaybeObject* StubCompiler::TryCompileCallDebugPrepareStepIn(Code::Flags flags) {
} else { } else {
KeyedCallIC::GenerateMiss(masm(), argc); KeyedCallIC::GenerateMiss(masm(), argc);
} }
Object* result; Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
{ MaybeObject* maybe_result =
TryGetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
if (!maybe_result->ToObject(&result)) return maybe_result;
}
Code* code = Code::cast(result);
USE(code);
PROFILE(isolate(), PROFILE(isolate(),
CodeCreateEvent( CodeCreateEvent(
CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
code, *code,
code->arguments_count())); code->arguments_count()));
return result; return code;
} }
#endif #endif // ENABLE_DEBUGGER_SUPPORT
#undef CALL_LOGGER_TAG #undef CALL_LOGGER_TAG
Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
const char* name) { const char* name) {
// Create code object in the heap. // Create code object in the heap.

View File

@ -392,17 +392,11 @@ class StubCompiler BASE_EMBEDDED {
Handle<Code> CompileCallArguments(Code::Flags flags); Handle<Code> CompileCallArguments(Code::Flags flags);
Handle<Code> CompileCallMiss(Code::Flags flags); Handle<Code> CompileCallMiss(Code::Flags flags);
MUST_USE_RESULT MaybeObject* TryCompileCallMegamorphic(Code::Flags flags);
MUST_USE_RESULT MaybeObject* TryCompileCallArguments(Code::Flags flags);
MUST_USE_RESULT MaybeObject* TryCompileCallMiss(Code::Flags flags); MUST_USE_RESULT MaybeObject* TryCompileCallMiss(Code::Flags flags);
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
Handle<Code> CompileCallDebugBreak(Code::Flags flags); Handle<Code> CompileCallDebugBreak(Code::Flags flags);
Handle<Code> CompileCallDebugPrepareStepIn(Code::Flags flags); Handle<Code> CompileCallDebugPrepareStepIn(Code::Flags flags);
MUST_USE_RESULT MaybeObject* TryCompileCallDebugBreak(Code::Flags flags);
MUST_USE_RESULT MaybeObject* TryCompileCallDebugPrepareStepIn(
Code::Flags flags);
#endif #endif
// Static functions for generating parts of stubs. // Static functions for generating parts of stubs.

View File

@ -735,10 +735,10 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// The generated code does not accept smi keys. // The generated code does not accept smi keys.
// The generated code falls through if both probes miss. // The generated code falls through if both probes miss.
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, void CallICBase::GenerateMonomorphicCacheProbe(MacroAssembler* masm,
int argc, int argc,
Code::Kind kind, Code::Kind kind,
Code::ExtraICState extra_ic_state) { Code::ExtraICState extra_state) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// rcx : function name // rcx : function name
// rdx : receiver // rdx : receiver
@ -748,7 +748,7 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(kind, Code::Flags flags = Code::ComputeFlags(kind,
MONOMORPHIC, MONOMORPHIC,
extra_ic_state, extra_state,
NORMAL, NORMAL,
argc); argc);
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx, Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,