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:
parent
d6e2065910
commit
e97ea23fa8
@ -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 };
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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, ¬in, &slow);
|
||||
__ sw(a0, mapped_location);
|
||||
__ mov(t5, a0);
|
||||
MemOperand mapped_location = GenerateMappedArgumentsLookup(
|
||||
masm, receiver, key, a3, t0, t1, ¬in, &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(¬in);
|
||||
// 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);
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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, ¬in, &slow);
|
||||
__ sd(a0, mapped_location);
|
||||
__ mov(t1, a0);
|
||||
MemOperand mapped_location = GenerateMappedArgumentsLookup(
|
||||
masm, receiver, key, a3, a4, a5, ¬in, &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(¬in);
|
||||
// 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);
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user