MIPS: Use a register spec for StoreIC and KeyedStoreIC.

Port r22328 (92275b7a)

Original commit message:
This continues refactoring already applied for LoadIC in r22035 (https://code.google.com/p/v8/source/detail?r=22035).

BUG=
R=gergely@homejinni.com

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22336 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
akos.palfi@imgtec.com 2014-07-11 01:50:12 +00:00
parent d6e2065910
commit e97ea23fa8
14 changed files with 213 additions and 301 deletions

View File

@ -87,15 +87,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a2, a1, a0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
}
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a0, a1 };
@ -230,14 +221,6 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
}
void StoreGlobalStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a1, a2, a0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(StoreIC_MissFromStubFailure));
}
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a0, a3, a1, a2 };

View File

@ -193,31 +193,27 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC store (from ic-mips.cc).
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
// Registers a0, a1, and a2 contain objects that need to be pushed on the
// expression stack of the fake JS frame.
Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit() | a2.bit(), 0);
Register receiver = StoreIC::ReceiverRegister();
Register name = StoreIC::NameRegister();
Register value = StoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
masm, receiver.bit() | name.bit() | value.bit(), 0);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-arm.cc).
// Calling convention for keyed IC load (from ic-mips.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit() | a2.bit(), 0);
// Calling convention for IC keyed store call (from ic-mips.cc).
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
Register value = KeyedStoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
masm, receiver.bit() | name.bit() | value.bit(), 0);
}

View File

@ -1689,9 +1689,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
__ mov(a0, result_register());
__ li(a2, Operand(key->value()));
__ lw(a1, MemOperand(sp));
__ mov(StoreIC::ValueRegister(), result_register());
ASSERT(StoreIC::ValueRegister().is(a0));
__ li(StoreIC::NameRegister(), Operand(key->value()));
__ lw(StoreIC::ReceiverRegister(), MemOperand(sp));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
@ -2414,9 +2415,10 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
case NAMED_PROPERTY: {
__ push(result_register()); // Preserve value.
VisitForAccumulatorValue(prop->obj());
__ mov(a1, result_register());
__ pop(a0); // Restore value.
__ li(a2, Operand(prop->key()->AsLiteral()->value()));
__ mov(StoreIC::ReceiverRegister(), result_register());
__ pop(StoreIC::ValueRegister()); // Restore value.
__ li(StoreIC::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
CallStoreIC();
break;
}
@ -2424,8 +2426,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ push(result_register()); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
__ mov(a1, result_register());
__ Pop(a0, a2); // a0 = restored value.
__ mov(KeyedStoreIC::NameRegister(), result_register());
__ Pop(KeyedStoreIC::ValueRegister(), KeyedStoreIC::ReceiverRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
@ -2462,9 +2464,9 @@ void FullCodeGenerator::EmitCallStoreContextSlot(
void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
if (var->IsUnallocated()) {
// Global var, const, or let.
__ mov(a0, result_register());
__ li(a2, Operand(var->name()));
__ lw(a1, GlobalObjectOperand());
__ mov(StoreIC::ValueRegister(), result_register());
__ li(StoreIC::NameRegister(), Operand(var->name()));
__ lw(StoreIC::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
@ -2533,10 +2535,9 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(a0, result_register()); // Load the value.
__ li(a2, Operand(prop->key()->AsLiteral()->value()));
__ pop(a1);
__ mov(StoreIC::ValueRegister(), result_register());
__ li(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value()));
__ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
@ -2554,8 +2555,9 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// - a0 is the value,
// - a1 is the key,
// - a2 is the receiver.
__ mov(a0, result_register());
__ Pop(a2, a1); // a1 = key.
__ mov(KeyedStoreIC::ValueRegister(), result_register());
__ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
ASSERT(KeyedStoreIC::ValueRegister().is(a0));
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
@ -4387,9 +4389,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
break;
case NAMED_PROPERTY: {
__ mov(a0, result_register()); // Value.
__ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name.
__ pop(a1); // Receiver.
__ mov(StoreIC::ValueRegister(), result_register());
__ li(StoreIC::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
__ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@ -4402,8 +4405,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
}
case KEYED_PROPERTY: {
__ mov(a0, result_register()); // Value.
__ Pop(a2, a1); // a1 = key, a2 = receiver.
__ mov(KeyedStoreIC::ValueRegister(), result_register());
__ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();

View File

@ -507,30 +507,31 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- lr : return address
// -----------------------------------
Register receiver = ReceiverRegister();
Register key = NameRegister();
Register value = ValueRegister();
ASSERT(receiver.is(a2));
ASSERT(key.is(a1));
ASSERT(value.is(a0));
Label slow, notin;
// Store address is returned in register (of MemOperand) mapped_location.
MemOperand mapped_location =
GenerateMappedArgumentsLookup(masm, a2, a1, a3, t0, t1, &notin, &slow);
__ sw(a0, mapped_location);
__ mov(t5, a0);
MemOperand mapped_location = GenerateMappedArgumentsLookup(
masm, receiver, key, a3, t0, t1, &notin, &slow);
__ sw(value, mapped_location);
__ mov(t5, value);
ASSERT_EQ(mapped_location.offset(), 0);
__ RecordWrite(a3, mapped_location.rm(), t5,
kRAHasNotBeenSaved, kDontSaveFPRegs);
__ Ret(USE_DELAY_SLOT);
__ mov(v0, a0); // (In delay slot) return the value stored in v0.
__ mov(v0, value); // (In delay slot) return the value stored in v0.
__ bind(&notin);
// The unmapped lookup expects that the parameter map is in a3.
// Store address is returned in register (of MemOperand) unmapped_location.
MemOperand unmapped_location =
GenerateUnmappedArgumentsLookup(masm, a1, a3, t0, &slow);
__ sw(a0, unmapped_location);
__ mov(t5, a0);
GenerateUnmappedArgumentsLookup(masm, key, a3, t0, &slow);
__ sw(value, unmapped_location);
__ mov(t5, value);
ASSERT_EQ(unmapped_location.offset(), 0);
__ RecordWrite(a3, unmapped_location.rm(), t5,
kRAHasNotBeenSaved, kDontSaveFPRegs);
@ -562,6 +563,16 @@ const Register LoadIC::ReceiverRegister() { return a1; }
const Register LoadIC::NameRegister() { return a2; }
const Register StoreIC::ReceiverRegister() { return a1; }
const Register StoreIC::NameRegister() { return a2; }
const Register StoreIC::ValueRegister() { return a0; }
const Register KeyedStoreIC::ReceiverRegister() { return a2; }
const Register KeyedStoreIC::NameRegister() { return a1; }
const Register KeyedStoreIC::ValueRegister() { return a0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
@ -772,15 +783,8 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
__ Push(a2, a1, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
__ li(a0, Operand(Smi::FromInt(strict_mode))); // Strict mode.
__ Push(a0);
@ -974,9 +978,12 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
Label array, extra, check_if_double_array;
// Register usage.
Register value = a0;
Register key = a1;
Register receiver = a2;
Register value = ValueRegister();
Register key = NameRegister();
Register receiver = ReceiverRegister();
ASSERT(receiver.is(a2));
ASSERT(key.is(a1));
ASSERT(value.is(a0));
Register receiver_map = a3;
Register elements_map = t2;
Register elements = t3; // Elements array of the receiver.
@ -1095,15 +1102,8 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
__ Push(a2, a1, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
@ -1112,15 +1112,8 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
void StoreIC::GenerateSlow(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a2 : key
// -- a1 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
__ Push(a1, a2, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
@ -1131,16 +1124,9 @@ void StoreIC::GenerateSlow(MacroAssembler* masm) {
void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
// We can't use MultiPush as the order of the registers is important.
__ Push(a2, a1, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
@ -1152,17 +1138,16 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
Register receiver = ReceiverRegister();
Register name = NameRegister();
ASSERT(receiver.is(a1));
ASSERT(name.is(a2));
ASSERT(ValueRegister().is(a0));
// Get the receiver from the stack and probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
masm->isolate()->stub_cache()->GenerateProbe(
masm, flags, a1, a2, a3, t0, t1, t2);
masm, flags, receiver, name, a3, t0, t1, t2);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
@ -1170,14 +1155,7 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
void StoreIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
__ Push(a1, a2, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// Perform tail call to the entry.
ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss),
masm->isolate());
@ -1186,17 +1164,17 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) {
void StoreIC::GenerateNormal(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
Label miss;
Register receiver = ReceiverRegister();
Register name = NameRegister();
Register value = ValueRegister();
ASSERT(receiver.is(a1));
ASSERT(name.is(a2));
ASSERT(value.is(a0));
GenerateNameDictionaryReceiverCheck(masm, a1, a3, t0, t1, &miss);
GenerateNameDictionaryReceiverCheck(masm, receiver, a3, t0, t1, &miss);
GenerateDictionaryStore(masm, &miss, a3, a2, a0, t0, t1);
GenerateDictionaryStore(masm, &miss, a3, name, value, t0, t1);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->store_normal_hit(), 1, t0, t1);
__ Ret();
@ -1209,14 +1187,7 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) {
void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
__ Push(a1, a2, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
__ li(a0, Operand(Smi::FromInt(strict_mode)));
__ Push(a0);

View File

@ -4131,11 +4131,10 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).is(a1));
ASSERT(ToRegister(instr->value()).is(a0));
ASSERT(ToRegister(instr->object()).is(StoreIC::ReceiverRegister()));
ASSERT(ToRegister(instr->value()).is(StoreIC::ValueRegister()));
// Name is always in a2.
__ li(a2, Operand(instr->name()));
__ li(StoreIC::NameRegister(), Operand(instr->name()));
Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -4363,9 +4362,9 @@ void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).is(a2));
ASSERT(ToRegister(instr->key()).is(a1));
ASSERT(ToRegister(instr->value()).is(a0));
ASSERT(ToRegister(instr->object()).is(KeyedStoreIC::ReceiverRegister()));
ASSERT(ToRegister(instr->key()).is(KeyedStoreIC::NameRegister()));
ASSERT(ToRegister(instr->value()).is(KeyedStoreIC::ValueRegister()));
Handle<Code> ic = (instr->strict_mode() == STRICT)
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()

View File

@ -2201,9 +2201,9 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* obj = UseFixed(instr->object(), a2);
LOperand* key = UseFixed(instr->key(), a1);
LOperand* val = UseFixed(instr->value(), a0);
LOperand* obj = UseFixed(instr->object(), KeyedStoreIC::ReceiverRegister());
LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister());
LOperand* val = UseFixed(instr->value(), KeyedStoreIC::ValueRegister());
ASSERT(instr->object()->representation().IsTagged());
ASSERT(instr->key()->representation().IsTagged());
@ -2277,8 +2277,8 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* obj = UseFixed(instr->object(), a1);
LOperand* val = UseFixed(instr->value(), a0);
LOperand* obj = UseFixed(instr->object(), StoreIC::ReceiverRegister());
LOperand* val = UseFixed(instr->value(), StoreIC::ValueRegister());
LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val);
return MarkAsCall(result, instr);

View File

@ -1270,20 +1270,24 @@ Register* KeyedLoadStubCompiler::registers() {
Register StoreStubCompiler::value() {
return a0;
return StoreIC::ValueRegister();
}
Register* StoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
static Register registers[] = { a1, a2, a3, t0, t1 };
Register receiver = StoreIC::ReceiverRegister();
Register name = StoreIC::NameRegister();
static Register registers[] = { receiver, name, a3, t0, t1 };
return registers;
}
Register* KeyedStoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
static Register registers[] = { a2, a1, a3, t0, t1 };
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
static Register registers[] = { receiver, name, a3, t0, t1 };
return registers;
}

View File

@ -87,15 +87,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a2, a1, a0 };
descriptor->Initialize(
ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
}
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a0, a1 };
@ -230,14 +221,6 @@ void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
}
void StoreGlobalStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a1, a2, a0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers,
FUNCTION_ADDR(StoreIC_MissFromStubFailure));
}
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { a0, a3, a1, a2 };

View File

@ -195,32 +195,27 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC store (from ic-mips.cc).
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
// Registers a0, a1, and a2 contain objects that need to be pushed on the
// expression stack of the fake JS frame.
Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit() | a2.bit(), 0);
Register receiver = StoreIC::ReceiverRegister();
Register name = StoreIC::NameRegister();
Register value = StoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
masm, receiver.bit() | name.bit() | value.bit(), 0);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-arm.cc).
// Calling convention for keyed IC load (from ic-mips64.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
Generate_DebugBreakCallHelper(masm, a0.bit() | a1.bit() | a2.bit(), 0);
// Calling convention for IC keyed store call (from ic-mips64.cc).
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
Register value = KeyedStoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
masm, receiver.bit() | name.bit() | value.bit(), 0);
}

View File

@ -1686,9 +1686,10 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
__ mov(a0, result_register());
__ li(a2, Operand(key->value()));
__ ld(a1, MemOperand(sp));
__ mov(StoreIC::ValueRegister(), result_register());
ASSERT(StoreIC::ValueRegister().is(a0));
__ li(StoreIC::NameRegister(), Operand(key->value()));
__ ld(StoreIC::ReceiverRegister(), MemOperand(sp));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
@ -2409,9 +2410,10 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
case NAMED_PROPERTY: {
__ push(result_register()); // Preserve value.
VisitForAccumulatorValue(prop->obj());
__ mov(a1, result_register());
__ pop(a0); // Restore value.
__ li(a2, Operand(prop->key()->AsLiteral()->value()));
__ mov(StoreIC::ReceiverRegister(), result_register());
__ pop(StoreIC::ValueRegister()); // Restore value.
__ li(StoreIC::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
CallStoreIC();
break;
}
@ -2419,8 +2421,8 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ push(result_register()); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
__ mov(a1, result_register());
__ Pop(a0, a2); // a0 = restored value.
__ Move(KeyedStoreIC::NameRegister(), result_register());
__ Pop(KeyedStoreIC::ValueRegister(), KeyedStoreIC::ReceiverRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
@ -2457,9 +2459,9 @@ void FullCodeGenerator::EmitCallStoreContextSlot(
void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
if (var->IsUnallocated()) {
// Global var, const, or let.
__ mov(a0, result_register());
__ li(a2, Operand(var->name()));
__ ld(a1, GlobalObjectOperand());
__ mov(StoreIC::ValueRegister(), result_register());
__ li(StoreIC::NameRegister(), Operand(var->name()));
__ ld(StoreIC::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
// Const initializers need a write barrier.
@ -2527,10 +2529,9 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(a0, result_register()); // Load the value.
__ li(a2, Operand(prop->key()->AsLiteral()->value()));
__ pop(a1);
__ mov(StoreIC::ValueRegister(), result_register());
__ li(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value()));
__ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
@ -2548,8 +2549,9 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// - a0 is the value,
// - a1 is the key,
// - a2 is the receiver.
__ mov(a0, result_register());
__ Pop(a2, a1); // a1 = key.
__ mov(KeyedStoreIC::ValueRegister(), result_register());
__ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
ASSERT(KeyedStoreIC::ValueRegister().is(a0));
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
@ -4380,9 +4382,10 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
break;
case NAMED_PROPERTY: {
__ mov(a0, result_register()); // Value.
__ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name.
__ pop(a1); // Receiver.
__ mov(StoreIC::ValueRegister(), result_register());
__ li(StoreIC::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
__ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
@ -4395,8 +4398,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
break;
}
case KEYED_PROPERTY: {
__ mov(a0, result_register()); // Value.
__ Pop(a2, a1); // a1 = key, a2 = receiver.
__ mov(KeyedStoreIC::ValueRegister(), result_register());
__ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();

View File

@ -507,30 +507,31 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- lr : return address
// -----------------------------------
Register receiver = ReceiverRegister();
Register key = NameRegister();
Register value = ValueRegister();
ASSERT(receiver.is(a2));
ASSERT(key.is(a1));
ASSERT(value.is(a0));
Label slow, notin;
// Store address is returned in register (of MemOperand) mapped_location.
MemOperand mapped_location =
GenerateMappedArgumentsLookup(masm, a2, a1, a3, a4, a5, &notin, &slow);
__ sd(a0, mapped_location);
__ mov(t1, a0);
MemOperand mapped_location = GenerateMappedArgumentsLookup(
masm, receiver, key, a3, a4, a5, &notin, &slow);
__ sd(value, mapped_location);
__ mov(t1, value);
ASSERT_EQ(mapped_location.offset(), 0);
__ RecordWrite(a3, mapped_location.rm(), t1,
kRAHasNotBeenSaved, kDontSaveFPRegs);
__ Ret(USE_DELAY_SLOT);
__ mov(v0, a0); // (In delay slot) return the value stored in v0.
__ mov(v0, value); // (In delay slot) return the value stored in v0.
__ bind(&notin);
// The unmapped lookup expects that the parameter map is in a3.
// Store address is returned in register (of MemOperand) unmapped_location.
MemOperand unmapped_location =
GenerateUnmappedArgumentsLookup(masm, a1, a3, a4, &slow);
__ sd(a0, unmapped_location);
__ mov(t1, a0);
GenerateUnmappedArgumentsLookup(masm, key, a3, a4, &slow);
__ sd(value, unmapped_location);
__ mov(t1, value);
ASSERT_EQ(unmapped_location.offset(), 0);
__ RecordWrite(a3, unmapped_location.rm(), t1,
kRAHasNotBeenSaved, kDontSaveFPRegs);
@ -562,6 +563,16 @@ const Register LoadIC::ReceiverRegister() { return a1; }
const Register LoadIC::NameRegister() { return a2; }
const Register StoreIC::ReceiverRegister() { return a1; }
const Register StoreIC::NameRegister() { return a2; }
const Register StoreIC::ValueRegister() { return a0; }
const Register KeyedStoreIC::ReceiverRegister() { return a2; }
const Register KeyedStoreIC::NameRegister() { return a1; }
const Register KeyedStoreIC::ValueRegister() { return a0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in ra.
@ -779,15 +790,9 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
__ Push(a2, a1, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
__ li(a0, Operand(Smi::FromInt(strict_mode))); // Strict mode.
__ Push(a0);
@ -984,9 +989,12 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
Label array, extra, check_if_double_array;
// Register usage.
Register value = a0;
Register key = a1;
Register receiver = a2;
Register value = ValueRegister();
Register key = NameRegister();
Register receiver = ReceiverRegister();
ASSERT(receiver.is(a2));
ASSERT(key.is(a1));
ASSERT(value.is(a0));
Register receiver_map = a3;
Register elements_map = a6;
Register elements = a7; // Elements array of the receiver.
@ -1105,15 +1113,8 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
__ Push(a2, a1, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
@ -1122,15 +1123,8 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
void StoreIC::GenerateSlow(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a2 : key
// -- a1 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
__ Push(a1, a2, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
@ -1141,16 +1135,9 @@ void StoreIC::GenerateSlow(MacroAssembler* masm) {
void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- a0 : value
// -- a1 : key
// -- a2 : receiver
// -- ra : return address
// -----------------------------------
// Push receiver, key and value for runtime call.
// We can't use MultiPush as the order of the registers is important.
__ Push(a2, a1, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// The slow case calls into the runtime to complete the store without causing
// an IC miss that would otherwise cause a transition to the generic stub.
ExternalReference ref =
@ -1161,17 +1148,16 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
Register receiver = ReceiverRegister();
Register name = NameRegister();
ASSERT(receiver.is(a1));
ASSERT(name.is(a2));
ASSERT(ValueRegister().is(a0));
// Get the receiver from the stack and probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
masm->isolate()->stub_cache()->GenerateProbe(
masm, flags, a1, a2, a3, a4, a5, a6);
masm, flags, receiver, name, a3, a4, a5, a6);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
@ -1179,14 +1165,7 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
void StoreIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
__ Push(a1, a2, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// Perform tail call to the entry.
ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss),
masm->isolate());
@ -1195,17 +1174,17 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) {
void StoreIC::GenerateNormal(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
Label miss;
Register receiver = ReceiverRegister();
Register name = NameRegister();
Register value = ValueRegister();
ASSERT(receiver.is(a1));
ASSERT(name.is(a2));
ASSERT(value.is(a0));
GenerateNameDictionaryReceiverCheck(masm, a1, a3, a4, a5, &miss);
GenerateNameDictionaryReceiverCheck(masm, receiver, a3, a4, a5, &miss);
GenerateDictionaryStore(masm, &miss, a3, a2, a0, a4, a5);
GenerateDictionaryStore(masm, &miss, a3, name, value, a4, a5);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->store_normal_hit(), 1, a4, a5);
__ Ret();
@ -1218,14 +1197,7 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) {
void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
// ----------- S t a t e -------------
// -- a0 : value
// -- a1 : receiver
// -- a2 : name
// -- ra : return address
// -----------------------------------
__ Push(a1, a2, a0);
__ Push(ReceiverRegister(), NameRegister(), ValueRegister());
__ li(a0, Operand(Smi::FromInt(strict_mode)));
__ Push(a0);

View File

@ -4189,11 +4189,10 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).is(a1));
ASSERT(ToRegister(instr->value()).is(a0));
ASSERT(ToRegister(instr->object()).is(StoreIC::ReceiverRegister()));
ASSERT(ToRegister(instr->value()).is(StoreIC::ValueRegister()));
// Name is always in a2.
__ li(a2, Operand(instr->name()));
__ li(StoreIC::NameRegister(), Operand(instr->name()));
Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@ -4454,9 +4453,9 @@ void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).is(a2));
ASSERT(ToRegister(instr->key()).is(a1));
ASSERT(ToRegister(instr->value()).is(a0));
ASSERT(ToRegister(instr->object()).is(KeyedStoreIC::ReceiverRegister()));
ASSERT(ToRegister(instr->key()).is(KeyedStoreIC::NameRegister()));
ASSERT(ToRegister(instr->value()).is(KeyedStoreIC::ValueRegister()));
Handle<Code> ic = (instr->strict_mode() == STRICT)
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()

View File

@ -2200,9 +2200,9 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* obj = UseFixed(instr->object(), a2);
LOperand* key = UseFixed(instr->key(), a1);
LOperand* val = UseFixed(instr->value(), a0);
LOperand* obj = UseFixed(instr->object(), KeyedStoreIC::ReceiverRegister());
LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister());
LOperand* val = UseFixed(instr->value(), KeyedStoreIC::ValueRegister());
ASSERT(instr->object()->representation().IsTagged());
ASSERT(instr->key()->representation().IsTagged());
@ -2276,8 +2276,8 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* obj = UseFixed(instr->object(), a1);
LOperand* val = UseFixed(instr->value(), a0);
LOperand* obj = UseFixed(instr->object(), StoreIC::ReceiverRegister());
LOperand* val = UseFixed(instr->value(), StoreIC::ValueRegister());
LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val);
return MarkAsCall(result, instr);

View File

@ -1270,20 +1270,24 @@ Register* KeyedLoadStubCompiler::registers() {
Register StoreStubCompiler::value() {
return a0;
return StoreIC::ValueRegister();
}
Register* StoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
static Register registers[] = { a1, a2, a3, a4, a5 };
Register receiver = StoreIC::ReceiverRegister();
Register name = StoreIC::NameRegister();
static Register registers[] = { receiver, name, a3, a4, a5 };
return registers;
}
Register* KeyedStoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
static Register registers[] = { a2, a1, a3, a4, a5 };
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
static Register registers[] = { receiver, name, a3, a4, a5 };
return registers;
}