MIPS: KeyedLoadIC should have same register spec as LoadIC.

Port r22103 (2c36867)

Original commit message:
On arm, arm64 and x64 there is a different register specification between LoadIC and KeyedLoadIC.

It would be nicer if these are the same, allowing some key optimizations.

BUG=
R=palfia@homejinni.com

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22168 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d8aefde6
...@@ -1971,25 +1971,15 @@ void InstanceofStub::Generate(MacroAssembler* masm) { ...@@ -1971,25 +1971,15 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
void FunctionPrototypeStub::Generate(MacroAssembler* masm) { void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss; Label miss;
Register receiver; Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
ASSERT(kind() == Code::LOAD_IC ||
kind() == Code::KEYED_LOAD_IC);
if (kind() == Code::KEYED_LOAD_IC) { if (kind() == Code::KEYED_LOAD_IC) {
// ----------- S t a t e ------------- __ Branch(&miss, ne, name,
// -- ra : return address
// -- a0 : key
// -- a1 : receiver
// -----------------------------------
__ Branch(&miss, ne, a0,
Operand(isolate()->factory()->prototype_string())); Operand(isolate()->factory()->prototype_string()));
receiver = a1;
} else {
ASSERT(kind() == Code::LOAD_IC);
// ----------- S t a t e -------------
// -- a2 : name
// -- ra : return address
// -- a0 : receiver
// -- sp[0] : receiver
// -----------------------------------
receiver = a0;
} }
StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3, t0, &miss); StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3, t0, &miss);
......
...@@ -207,9 +207,7 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { ...@@ -207,9 +207,7 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-arm.cc). // Calling convention for keyed IC load (from ic-arm.cc).
Register receiver = KeyedLoadIC::ReceiverRegister(); GenerateLoadICDebugBreak(masm);
Register name = KeyedLoadIC::NameRegister();
Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
} }
......
...@@ -1871,9 +1871,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -1871,9 +1871,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
break; break;
case NAMED_PROPERTY: case NAMED_PROPERTY:
if (expr->is_compound()) { if (expr->is_compound()) {
// We need the receiver both on the stack and in the accumulator. // We need the receiver both on the stack and in the register.
VisitForAccumulatorValue(property->obj()); VisitForStackValue(property->obj());
__ push(result_register()); __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
} else { } else {
VisitForStackValue(property->obj()); VisitForStackValue(property->obj());
} }
...@@ -1882,9 +1882,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -1882,9 +1882,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
// We need the key and receiver on both the stack and in v0 and a1. // We need the key and receiver on both the stack and in v0 and a1.
if (expr->is_compound()) { if (expr->is_compound()) {
VisitForStackValue(property->obj()); VisitForStackValue(property->obj());
VisitForAccumulatorValue(property->key()); VisitForStackValue(property->key());
__ lw(a1, MemOperand(sp, 0)); __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize));
__ push(v0); __ lw(LoadIC::NameRegister(), MemOperand(sp, 0));
} else { } else {
VisitForStackValue(property->obj()); VisitForStackValue(property->obj());
VisitForStackValue(property->key()); VisitForStackValue(property->key());
...@@ -2022,6 +2022,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2022,6 +2022,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
Label l_catch, l_try, l_suspend, l_continuation, l_resume; Label l_catch, l_try, l_suspend, l_continuation, l_resume;
Label l_next, l_call; Label l_next, l_call;
Register load_receiver = LoadIC::ReceiverRegister();
Register load_name = LoadIC::NameRegister();
// Initial send value is undefined. // Initial send value is undefined.
__ LoadRoot(a0, Heap::kUndefinedValueRootIndex); __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
__ Branch(&l_next); __ Branch(&l_next);
...@@ -2030,9 +2033,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2030,9 +2033,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ bind(&l_catch); __ bind(&l_catch);
__ mov(a0, v0); __ mov(a0, v0);
handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
__ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
__ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
__ Push(a2, a3, a0); // "throw", iter, except __ Push(load_name, a3, a0); // "throw", iter, except
__ jmp(&l_call); __ jmp(&l_call);
// try { received = %yield result } // try { received = %yield result }
...@@ -2068,19 +2071,15 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2068,19 +2071,15 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// receiver = iter; f = 'next'; arg = received; // receiver = iter; f = 'next'; arg = received;
__ bind(&l_next); __ bind(&l_next);
Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
Register keyedload_name = KeyedLoadIC::NameRegister();
ASSERT(keyedload_receiver.is(a1));
ASSERT(keyedload_name.is(a0));
__ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next"
__ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
__ Push(a2, a3, a0); // "next", iter, received __ Push(load_name, a3, a0); // "next", iter, received
// result = receiver[f](arg); // result = receiver[f](arg);
__ bind(&l_call); __ bind(&l_call);
__ lw(keyedload_receiver, MemOperand(sp, kPointerSize)); __ lw(load_receiver, MemOperand(sp, kPointerSize));
__ lw(keyedload_name, MemOperand(sp, 2 * kPointerSize)); __ lw(load_name, MemOperand(sp, 2 * kPointerSize));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None()); CallIC(ic, TypeFeedbackId::None());
__ mov(a0, v0); __ mov(a0, v0);
...@@ -2093,16 +2092,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2093,16 +2092,12 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ Drop(1); // The function is still on the stack; drop it. __ Drop(1); // The function is still on the stack; drop it.
// if (!result.done) goto l_try; // if (!result.done) goto l_try;
Register load_receiver = LoadIC::ReceiverRegister(); __ Move(load_receiver, v0);
Register load_name = LoadIC::NameRegister();
ASSERT(load_receiver.is(a0));
ASSERT(load_name.is(a2));
__ mov(load_receiver, v0); __ push(load_receiver); // save result
__ push(v0); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
CallLoadIC(NOT_CONTEXTUAL); // v0=result.done CallLoadIC(NOT_CONTEXTUAL); // v0=result.done
__ mov(load_receiver, v0); __ mov(a0, v0);
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic); CallIC(bool_ic);
__ Branch(&l_try, eq, v0, Operand(zero_reg)); __ Branch(&l_try, eq, v0, Operand(zero_reg));
...@@ -2272,7 +2267,6 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { ...@@ -2272,7 +2267,6 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral(); Literal* key = prop->key()->AsLiteral();
__ mov(LoadIC::ReceiverRegister(), result_register());
__ li(LoadIC::NameRegister(), Operand(key->value())); __ li(LoadIC::NameRegister(), Operand(key->value()));
// Call load IC. It has register arguments receiver and property. // Call load IC. It has register arguments receiver and property.
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
...@@ -2281,7 +2275,6 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { ...@@ -2281,7 +2275,6 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
__ mov(a0, result_register());
// Call keyed load IC. It has register arguments receiver and key. // Call keyed load IC. It has register arguments receiver and key.
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, prop->PropertyFeedbackId()); CallIC(ic, prop->PropertyFeedbackId());
...@@ -2580,16 +2573,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { ...@@ -2580,16 +2573,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj()); VisitForAccumulatorValue(expr->obj());
ASSERT(a0.is(LoadIC::ReceiverRegister())); __ Move(LoadIC::ReceiverRegister(), v0);
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG); PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(v0); context()->Plug(v0);
} else { } else {
VisitForStackValue(expr->obj()); VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key()); VisitForAccumulatorValue(expr->key());
ASSERT(a0.is(KeyedLoadIC::NameRegister())); __ Move(LoadIC::NameRegister(), v0);
ASSERT(a1.is(KeyedLoadIC::ReceiverRegister())); __ pop(LoadIC::ReceiverRegister());
__ pop(KeyedLoadIC::ReceiverRegister());
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
context()->Plug(v0); context()->Plug(v0);
} }
...@@ -2623,7 +2615,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { ...@@ -2623,7 +2615,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else { } else {
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ lw(v0, MemOperand(sp, 0)); __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(callee->AsProperty()); EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver. // Push the target function under the receiver.
...@@ -2641,13 +2633,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, ...@@ -2641,13 +2633,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
Expression* key) { Expression* key) {
// Load the key. // Load the key.
VisitForAccumulatorValue(key); VisitForAccumulatorValue(key);
ASSERT(a0.is(KeyedLoadIC::NameRegister()));
Expression* callee = expr->expression(); Expression* callee = expr->expression();
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
__ Move(LoadIC::NameRegister(), v0);
EmitKeyedPropertyLoad(callee->AsProperty()); EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
...@@ -4093,12 +4085,12 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { ...@@ -4093,12 +4085,12 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
// Push the builtins object as the receiver. // Push the builtins object as the receiver.
__ lw(a0, GlobalObjectOperand()); Register receiver = LoadIC::ReceiverRegister();
__ lw(a0, FieldMemOperand(a0, GlobalObject::kBuiltinsOffset)); __ lw(receiver, GlobalObjectOperand());
__ push(a0); __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
__ push(receiver);
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(a0.is(LoadIC::ReceiverRegister()));
__ li(LoadIC::NameRegister(), Operand(expr->name())); __ li(LoadIC::NameRegister(), Operand(expr->name()));
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
...@@ -4276,16 +4268,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -4276,16 +4268,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ push(at); __ push(at);
} }
if (assign_type == NAMED_PROPERTY) { if (assign_type == NAMED_PROPERTY) {
// Put the object both on the stack and in the accumulator. // Put the object both on the stack and in the register.
VisitForAccumulatorValue(prop->obj()); VisitForStackValue(prop->obj());
__ push(v0); __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(prop); EmitNamedPropertyLoad(prop);
} else { } else {
VisitForStackValue(prop->obj()); VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key()); VisitForStackValue(prop->key());
ASSERT(a1.is(KeyedLoadIC::ReceiverRegister())); __ lw(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize));
__ lw(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); __ lw(LoadIC::NameRegister(), MemOperand(sp, 0));
__ push(v0);
EmitKeyedPropertyLoad(prop); EmitKeyedPropertyLoad(prop);
} }
} }
......
This diff is collapsed.
...@@ -3327,8 +3327,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, ...@@ -3327,8 +3327,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp)); ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); ASSERT(ToRegister(instr->key()).is(LoadIC::NameRegister()));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
......
...@@ -2145,8 +2145,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { ...@@ -2145,8 +2145,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp); LOperand* context = UseFixed(instr->context(), cp);
LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); LOperand* key = UseFixed(instr->key(), LoadIC::NameRegister());
LInstruction* result = LInstruction* result =
DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), v0); DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), v0);
......
...@@ -1256,16 +1256,16 @@ Register* LoadStubCompiler::registers() { ...@@ -1256,16 +1256,16 @@ Register* LoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4. // receiver, name, scratch1, scratch2, scratch3, scratch4.
Register receiver = LoadIC::ReceiverRegister(); Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister(); Register name = LoadIC::NameRegister();
static Register registers[] = { receiver, name, a3, a1, t0, t1 }; static Register registers[] = { receiver, name, a3, a0, t0, t1 };
return registers; return registers;
} }
Register* KeyedLoadStubCompiler::registers() { Register* KeyedLoadStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3, scratch4. // receiver, name, scratch1, scratch2, scratch3, scratch4.
Register receiver = KeyedLoadIC::ReceiverRegister(); Register receiver = LoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister(); Register name = LoadIC::NameRegister();
static Register registers[] = { receiver, name, a2, a3, t0, t1 }; static Register registers[] = { receiver, name, a3, a0, t0, t1 };
return registers; return registers;
} }
...@@ -1466,45 +1466,30 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( ...@@ -1466,45 +1466,30 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
MacroAssembler* masm) { MacroAssembler* masm) {
// ---------- S t a t e -------------- // The return address is in ra.
// -- ra : return address
// -- a0 : key
// -- a1 : receiver
// -----------------------------------
ASSERT(a1.is(KeyedLoadIC::ReceiverRegister()));
ASSERT(a0.is(KeyedLoadIC::NameRegister()));
Label slow, miss; Label slow, miss;
Register key = a0; Register key = LoadIC::NameRegister();
Register receiver = a1; Register receiver = LoadIC::ReceiverRegister();
ASSERT(receiver.is(a1));
ASSERT(key.is(a2));
__ JumpIfNotSmi(key, &miss); __ UntagAndJumpIfNotSmi(t2, key, &miss);
__ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
__ sra(a2, a0, kSmiTagSize); __ LoadFromNumberDictionary(&slow, t0, key, v0, t2, a3, t1);
__ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
__ Ret(); __ Ret();
// Slow case, key and receiver still in a0 and a1. // Slow case, key and receiver still unmodified.
__ bind(&slow); __ bind(&slow);
__ IncrementCounter( __ IncrementCounter(
masm->isolate()->counters()->keyed_load_external_array_slow(), masm->isolate()->counters()->keyed_load_external_array_slow(),
1, a2, a3); 1, a2, a3);
// Entry registers are intact.
// ---------- S t a t e --------------
// -- ra : return address
// -- a0 : key
// -- a1 : receiver
// -----------------------------------
TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
// Miss case, call the runtime. // Miss case, call the runtime.
__ bind(&miss); __ bind(&miss);
// ---------- S t a t e --------------
// -- ra : return address
// -- a0 : key
// -- a1 : receiver
// -----------------------------------
TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment