MIPS: The IC exposes a register definition.

Port r22011 (be22370)

Original commit message:
Centralize a register definition in an IC that provides:
1) symbolic names for the register (like, edx == receiver)
2) defines ordering when passed on the stack

Code that implements or uses the IC should use this definition instead of "knowing" what the registers are. Or at least have the definition to validate it's assumptions.

As a side effect of avoiding runtime static initializers (enforced by tools/check-static-initializers.sh, neat), I gave ownership of the registers array to CodeStubInterfaceDescriptor. This prompted a cleanup of that struct.

BUG=
R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/354863002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22021 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kilvadyb@homejinni.com 2014-06-25 16:17:31 +00:00
parent ace9759359
commit 55126885b7
4 changed files with 119 additions and 166 deletions

View File

@ -18,180 +18,128 @@ namespace internal {
void FastNewClosureStub::InitializeInterfaceDescriptor( void FastNewClosureStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2 }; Register registers[] = { a2 };
descriptor->register_param_count_ = 1; descriptor->Initialize(
descriptor->register_params_ = registers; ARRAY_SIZE(registers), registers,
descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kHiddenNewClosureFromStubFailure)->entry);
Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
} }
void FastNewContextStub::InitializeInterfaceDescriptor( void FastNewContextStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1 }; Register registers[] = { a1 };
descriptor->register_param_count_ = 1; descriptor->Initialize(ARRAY_SIZE(registers), registers);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
} }
void ToNumberStub::InitializeInterfaceDescriptor( void ToNumberStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 }; Register registers[] = { a0 };
descriptor->register_param_count_ = 1; descriptor->Initialize(ARRAY_SIZE(registers), registers);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
} }
void NumberToStringStub::InitializeInterfaceDescriptor( void NumberToStringStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 }; Register registers[] = { a0 };
descriptor->register_param_count_ = 1; descriptor->Initialize(
descriptor->register_params_ = registers; ARRAY_SIZE(registers), registers,
descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kHiddenNumberToString)->entry);
Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry;
} }
void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a3, a2, a1 }; Register registers[] = { a3, a2, a1 };
descriptor->register_param_count_ = 3; Representation representations[] = {
descriptor->register_params_ = registers;
static Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Smi(), Representation::Smi(),
Representation::Tagged() }; Representation::Tagged() };
descriptor->register_param_representations_ = representations; descriptor->Initialize(
descriptor->deoptimization_handler_ = ARRAY_SIZE(registers), registers,
Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry; Runtime::FunctionForId(
Runtime::kHiddenCreateArrayLiteralStubBailout)->entry,
representations);
} }
void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a3, a2, a1, a0 }; Register registers[] = { a3, a2, a1, a0 };
descriptor->register_param_count_ = 4; descriptor->Initialize(
descriptor->register_params_ = registers; ARRAY_SIZE(registers), registers,
descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kHiddenCreateObjectLiteral)->entry);
Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry;
} }
void CreateAllocationSiteStub::InitializeInterfaceDescriptor( void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a3 }; Register registers[] = { a2, a3 };
descriptor->register_param_count_ = 2; descriptor->Initialize(ARRAY_SIZE(registers), registers);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
}
void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
}
void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = {a1, a0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
} }
void RegExpConstructResultStub::InitializeInterfaceDescriptor( void RegExpConstructResultStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a1, a0 }; Register registers[] = { a2, a1, a0 };
descriptor->register_param_count_ = 3; descriptor->Initialize(
descriptor->register_params_ = registers; ARRAY_SIZE(registers), registers,
descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kHiddenRegExpConstructResult)->entry);
Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry;
}
void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry;
} }
void LoadFieldStub::InitializeInterfaceDescriptor( void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 }; Register registers[] = { a0 };
descriptor->register_param_count_ = 1; descriptor->Initialize(ARRAY_SIZE(registers), registers);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
} }
void KeyedLoadFieldStub::InitializeInterfaceDescriptor( void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1 }; Register registers[] = { a1 };
descriptor->register_param_count_ = 1; descriptor->Initialize(ARRAY_SIZE(registers), registers);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
} }
void StringLengthStub::InitializeInterfaceDescriptor( void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0, a2 }; Register registers[] = { a0, a2 };
descriptor->register_param_count_ = 2; descriptor->Initialize(ARRAY_SIZE(registers), registers);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
} }
void KeyedStringLengthStub::InitializeInterfaceDescriptor( void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 }; Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2; descriptor->Initialize(ARRAY_SIZE(registers), registers);
descriptor->register_params_ = registers;
descriptor->deoptimization_handler_ = NULL;
} }
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a1, a0 }; Register registers[] = { a2, a1, a0 };
descriptor->register_param_count_ = 3; descriptor->Initialize(
descriptor->register_params_ = registers; ARRAY_SIZE(registers), registers,
descriptor->deoptimization_handler_ = FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure);
} }
void TransitionElementsKindStub::InitializeInterfaceDescriptor( void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0, a1 }; Register registers[] = { a0, a1 };
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers;
Address entry = Address entry =
Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
descriptor->deoptimization_handler_ = FUNCTION_ADDR(entry); descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(entry));
} }
void CompareNilICStub::InitializeInterfaceDescriptor( void CompareNilICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 }; Register registers[] = { a0 };
descriptor->register_param_count_ = 1; descriptor->Initialize(ARRAY_SIZE(registers), registers,
descriptor->register_params_ = registers; FUNCTION_ADDR(CompareNilIC_Miss));
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(CompareNilIC_Miss);
descriptor->SetMissHandler( descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
} }
@ -204,29 +152,31 @@ static void InitializeArrayConstructorDescriptor(
// a0 -- number of arguments // a0 -- number of arguments
// a1 -- function // a1 -- function
// a2 -- allocation site with elements kind // a2 -- allocation site with elements kind
static Register registers_variable_args[] = { a1, a2, a0 }; Address deopt_handler = Runtime::FunctionForId(
static Register registers_no_args[] = { a1, a2 }; Runtime::kHiddenArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) { if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 2; Register registers[] = { a1, a2 };
descriptor->register_params_ = registers_no_args; descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else { } else {
// stack param count needs (constructor pointer, and single argument) // stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; Register registers[] = { a1, a2, a0 };
descriptor->stack_parameter_count_ = a0; Representation representations[] = {
descriptor->register_param_count_ = 3;
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Tagged(), Representation::Tagged(),
Representation::Integer32() }; Representation::Integer32() };
descriptor->register_param_representations_ = representations; descriptor->Initialize(ARRAY_SIZE(registers), registers,
a0,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
} }
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
} }
@ -236,28 +186,30 @@ static void InitializeInternalArrayConstructorDescriptor(
// register state // register state
// a0 -- number of arguments // a0 -- number of arguments
// a1 -- constructor function // a1 -- constructor function
static Register registers_variable_args[] = { a1, a0 }; Address deopt_handler = Runtime::FunctionForId(
static Register registers_no_args[] = { a1 }; Runtime::kHiddenInternalArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) { if (constant_stack_parameter_count == 0) {
descriptor->register_param_count_ = 1; Register registers[] = { a1 };
descriptor->register_params_ = registers_no_args; descriptor->Initialize(ARRAY_SIZE(registers), registers,
deopt_handler,
NULL,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else { } else {
// stack param count needs (constructor pointer, and single argument) // stack param count needs (constructor pointer, and single argument)
descriptor->handler_arguments_mode_ = PASS_ARGUMENTS; Register registers[] = { a1, a0 };
descriptor->stack_parameter_count_ = a0; Representation representations[] = {
descriptor->register_param_count_ = 2;
descriptor->register_params_ = registers_variable_args;
static Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Integer32() }; Representation::Integer32() };
descriptor->register_param_representations_ = representations; descriptor->Initialize(ARRAY_SIZE(registers), registers,
a0,
deopt_handler,
representations,
constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE,
PASS_ARGUMENTS);
} }
descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
descriptor->deoptimization_handler_ =
Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
} }
@ -281,11 +233,9 @@ void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
void ToBooleanStub::InitializeInterfaceDescriptor( void ToBooleanStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0 }; Register registers[] = { a0 };
descriptor->register_param_count_ = 1; descriptor->Initialize(ARRAY_SIZE(registers), registers,
descriptor->register_params_ = registers; FUNCTION_ADDR(ToBooleanIC_Miss));
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ToBooleanIC_Miss);
descriptor->SetMissHandler( descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate())); ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
} }
@ -311,30 +261,25 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
void StoreGlobalStub::InitializeInterfaceDescriptor( void StoreGlobalStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a2, a0 }; Register registers[] = { a1, a2, a0 };
descriptor->register_param_count_ = 3; descriptor->Initialize(ARRAY_SIZE(registers), registers,
descriptor->register_params_ = registers; FUNCTION_ADDR(StoreIC_MissFromStubFailure));
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(StoreIC_MissFromStubFailure);
} }
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor( void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a0, a3, a1, a2 }; Register registers[] = { a0, a3, a1, a2 };
descriptor->register_param_count_ = 4; descriptor->Initialize(ARRAY_SIZE(registers), registers,
descriptor->register_params_ = registers; FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
} }
void BinaryOpICStub::InitializeInterfaceDescriptor( void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 }; Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2; descriptor->Initialize(ARRAY_SIZE(registers), registers,
descriptor->register_params_ = registers; FUNCTION_ADDR(BinaryOpIC_Miss));
descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
descriptor->SetMissHandler( descriptor->SetMissHandler(
ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate())); ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
} }
@ -342,21 +287,18 @@ void BinaryOpICStub::InitializeInterfaceDescriptor(
void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor( void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a2, a1, a0 }; Register registers[] = { a2, a1, a0 };
descriptor->register_param_count_ = 3; descriptor->Initialize(ARRAY_SIZE(registers), registers,
descriptor->register_params_ = registers; FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
descriptor->deoptimization_handler_ =
FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
} }
void StringAddStub::InitializeInterfaceDescriptor( void StringAddStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
static Register registers[] = { a1, a0 }; Register registers[] = { a1, a0 };
descriptor->register_param_count_ = 2; descriptor->Initialize(
descriptor->register_params_ = registers; ARRAY_SIZE(registers), registers,
descriptor->deoptimization_handler_ = Runtime::FunctionForId(Runtime::kHiddenStringAdd)->entry);
Runtime::FunctionForId(Runtime::kStringAdd)->entry;
} }
@ -466,21 +408,21 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
isolate()->counters()->code_stubs()->Increment(); isolate()->counters()->code_stubs()->Increment();
CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(); CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
int param_count = descriptor->register_param_count_; int param_count = descriptor->register_param_count();
{ {
// Call the runtime system in a fresh internal frame. // Call the runtime system in a fresh internal frame.
FrameScope scope(masm, StackFrame::INTERNAL); FrameScope scope(masm, StackFrame::INTERNAL);
ASSERT(descriptor->register_param_count_ == 0 || ASSERT(descriptor->register_param_count() == 0 ||
a0.is(descriptor->register_params_[param_count - 1])); a0.is(descriptor->GetParameterRegister(param_count - 1)));
// Push arguments, adjust sp. // Push arguments, adjust sp.
__ Subu(sp, sp, Operand(param_count * kPointerSize)); __ Subu(sp, sp, Operand(param_count * kPointerSize));
for (int i = 0; i < param_count; ++i) { for (int i = 0; i < param_count; ++i) {
// Store argument to stack. // Store argument to stack.
__ sw(descriptor->register_params_[i], __ sw(descriptor->GetParameterRegister(i),
MemOperand(sp, (param_count-1-i) * kPointerSize)); MemOperand(sp, (param_count-1-i) * kPointerSize));
} }
ExternalReference miss = descriptor->miss_handler(); ExternalReference miss = descriptor->miss_handler();
__ CallExternalReference(miss, descriptor->register_param_count_); __ CallExternalReference(miss, descriptor->register_param_count());
} }
__ Ret(); __ Ret();

View File

@ -101,7 +101,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
void Deoptimizer::SetPlatformCompiledStubRegisters( void Deoptimizer::SetPlatformCompiledStubRegisters(
FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) { FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) {
ApiFunction function(descriptor->deoptimization_handler_); ApiFunction function(descriptor->deoptimization_handler());
ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_); ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
intptr_t handler = reinterpret_cast<intptr_t>(xref.address()); intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
int params = descriptor->GetHandlerParameterCount(); int params = descriptor->GetHandlerParameterCount();

View File

@ -560,6 +560,13 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
} }
// IC register specifications
const Register LoadIC::ReceiverRegister() { return a0; }
const Register LoadIC::NameRegister() { return a2; }
const Register KeyedLoadIC::ReceiverRegister() { return a1; }
const Register KeyedLoadIC::NameRegister() { return a0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- ra : return address // -- ra : return address

View File

@ -1253,14 +1253,18 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type,
Register* LoadStubCompiler::registers() { Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4. // receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { a0, a2, a3, a1, t0, t1 }; Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
static Register registers[] = { receiver, name, a3, a1, t0, t1 };
return registers; return registers;
} }
Register* KeyedLoadStubCompiler::registers() { Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4. // receiver, name, scratch1, scratch2, scratch3, scratch4.
static Register registers[] = { a1, a0, a2, a3, t0, t1 }; Register receiver = KeyedLoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister();
static Register registers[] = { receiver, name, a2, a3, t0, t1 };
return registers; return registers;
} }