}
-void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { r2, r1, r0 };
- descriptor->Initialize(
- ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
-}
-
-
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r0, r1 };
}
-void StoreGlobalStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { r1, r2, r0 };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(StoreIC_MissFromStubFailure));
-}
-
-
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r0, r3, r1, r2 };
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC store (from ic-arm.cc).
- // ----------- S t a t e -------------
- // -- r0 : value
- // -- r1 : receiver
- // -- r2 : name
- // -- lr : return address
- // -----------------------------------
- // Registers r0, r1, and r2 contain objects that need to be pushed on the
- // expression stack of the fake JS frame.
- Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.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::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- r0 : value
- // -- r1 : key
- // -- r2 : receiver
- // -- lr : return address
- Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit() | r2.bit(), 0);
+ // Calling convention for IC keyed store call (from ic-arm.cc).
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ Register value = KeyedStoreIC::ValueRegister();
+ Generate_DebugBreakCallHelper(
+ masm, receiver.bit() | name.bit() | value.bit(), 0);
}
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
- __ mov(r2, Operand(key->value()));
- __ ldr(r1, MemOperand(sp));
+ ASSERT(StoreIC::ValueRegister().is(r0));
+ __ mov(StoreIC::NameRegister(), Operand(key->value()));
+ __ ldr(StoreIC::ReceiverRegister(), MemOperand(sp));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
case NAMED_PROPERTY: {
__ push(r0); // Preserve value.
VisitForAccumulatorValue(prop->obj());
- __ mov(r1, r0);
- __ pop(r0); // Restore value.
- __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
+ __ Move(StoreIC::ReceiverRegister(), r0);
+ __ pop(StoreIC::ValueRegister()); // Restore value.
+ __ mov(StoreIC::NameRegister(),
+ Operand(prop->key()->AsLiteral()->value()));
CallStoreIC();
break;
}
__ push(r0); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
- __ mov(r1, r0);
- __ Pop(r0, r2); // r0 = restored value.
+ __ Move(KeyedStoreIC::NameRegister(), r0);
+ __ Pop(KeyedStoreIC::ValueRegister(), KeyedStoreIC::ReceiverRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
if (var->IsUnallocated()) {
// Global var, const, or let.
- __ mov(r2, Operand(var->name()));
- __ ldr(r1, GlobalObjectOperand());
+ __ mov(StoreIC::NameRegister(), Operand(var->name()));
+ __ ldr(StoreIC::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
- __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
- __ pop(r1);
-
+ __ mov(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value()));
+ __ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
// Record source code position before IC call.
SetSourcePosition(expr->position());
- __ Pop(r2, r1); // r1 = key.
+ __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
+ ASSERT(KeyedStoreIC::ValueRegister().is(r0));
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
}
break;
case NAMED_PROPERTY: {
- __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
- __ pop(r1);
+ __ mov(StoreIC::NameRegister(),
+ Operand(prop->key()->AsLiteral()->value()));
+ __ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
break;
}
case KEYED_PROPERTY: {
- __ Pop(r2, r1); // r1 = key. r2 = receiver.
+ __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- r0 : value
- // -- r1 : key
- // -- r2 : receiver
- // -- lr : return address
- // -----------------------------------
+ Register receiver = ReceiverRegister();
+ Register key = NameRegister();
+ Register value = ValueRegister();
+ ASSERT(receiver.is(r2));
+ ASSERT(key.is(r1));
+ ASSERT(value.is(r0));
+
Label slow, notin;
- MemOperand mapped_location =
- GenerateMappedArgumentsLookup(masm, r2, r1, r3, r4, r5, ¬in, &slow);
- __ str(r0, mapped_location);
+ MemOperand mapped_location = GenerateMappedArgumentsLookup(
+ masm, receiver, key, r3, r4, r5, ¬in, &slow);
+ __ str(value, mapped_location);
__ add(r6, r3, r5);
- __ mov(r9, r0);
+ __ mov(r9, value);
__ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs);
__ Ret();
__ bind(¬in);
// The unmapped lookup expects that the parameter map is in r3.
MemOperand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, r1, r3, r4, &slow);
- __ str(r0, unmapped_location);
+ GenerateUnmappedArgumentsLookup(masm, key, r3, r4, &slow);
+ __ str(value, unmapped_location);
__ add(r6, r3, r4);
- __ mov(r9, r0);
+ __ mov(r9, value);
__ RecordWrite(r3, r6, r9, kLRHasNotBeenSaved, kDontSaveFPRegs);
__ Ret();
__ bind(&slow);
const Register LoadIC::NameRegister() { return r2; }
+const Register StoreIC::ReceiverRegister() { return r1; }
+const Register StoreIC::NameRegister() { return r2; }
+const Register StoreIC::ValueRegister() { return r0; }
+
+
+const Register KeyedStoreIC::ReceiverRegister() { return r2; }
+const Register KeyedStoreIC::NameRegister() { return r1; }
+const Register KeyedStoreIC::ValueRegister() { return r0; }
+
+
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- r0 : value
- // -- r1 : key
- // -- r2 : receiver
- // -- lr : return address
- // -----------------------------------
-
// Push receiver, key and value for runtime call.
- __ Push(r2, r1, r0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
void StoreIC::GenerateSlow(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- r0 : value
- // -- r2 : key
- // -- r1 : receiver
- // -- lr : return address
- // -----------------------------------
-
// Push receiver, key and value for runtime call.
- __ Push(r1, r2, r0);
+ __ 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.
void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- r0 : value
- // -- r1 : key
- // -- r2 : receiver
- // -- lr : return address
- // -----------------------------------
-
// Push receiver, key and value for runtime call.
- __ Push(r2, r1, r0);
+ __ 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.
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ---------- S t a t e --------------
- // -- r0 : value
- // -- r1 : key
- // -- r2 : receiver
- // -- lr : return address
- // -----------------------------------
-
// Push receiver, key and value for runtime call.
- __ Push(r2, r1, r0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
__ mov(r0, Operand(Smi::FromInt(strict_mode))); // Strict mode.
__ Push(r0);
Label array, extra, check_if_double_array;
// Register usage.
- Register value = r0;
- Register key = r1;
- Register receiver = r2;
+ Register value = ValueRegister();
+ Register key = NameRegister();
+ Register receiver = ReceiverRegister();
+ ASSERT(receiver.is(r2));
+ ASSERT(key.is(r1));
+ ASSERT(value.is(r0));
Register receiver_map = r3;
Register elements_map = r6;
Register elements = r9; // Elements array of the receiver.
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- r0 : value
- // -- r1 : receiver
- // -- r2 : name
- // -- lr : return address
- // -----------------------------------
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ ASSERT(receiver.is(r1));
+ ASSERT(name.is(r2));
+ ASSERT(ValueRegister().is(r0));
// 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, r1, r2, r3, r4, r5, r6);
+ masm, flags, receiver, name, r3, r4, r5, r6);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
void StoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- r0 : value
- // -- r1 : receiver
- // -- r2 : name
- // -- lr : return address
- // -----------------------------------
-
- __ Push(r1, r2, r0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// Perform tail call to the entry.
ExternalReference ref =
void StoreIC::GenerateNormal(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- r0 : value
- // -- r1 : receiver
- // -- r2 : name
- // -- lr : return address
- // -----------------------------------
Label miss;
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ Register value = ValueRegister();
+ ASSERT(receiver.is(r1));
+ ASSERT(name.is(r2));
+ ASSERT(value.is(r0));
- GenerateNameDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss);
+ GenerateNameDictionaryReceiverCheck(masm, receiver, r3, r4, r5, &miss);
- GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5);
+ GenerateDictionaryStore(masm, &miss, r3, name, value, r4, r5);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->store_normal_hit(),
1, r4, r5);
void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- r0 : value
- // -- r1 : receiver
- // -- r2 : name
- // -- lr : return address
- // -----------------------------------
-
- __ Push(r1, r2, r0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
__ mov(r0, Operand(Smi::FromInt(strict_mode)));
__ Push(r0);
LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
- LOperand* obj = UseFixed(instr->object(), r2);
- LOperand* key = UseFixed(instr->key(), r1);
- LOperand* val = UseFixed(instr->value(), r0);
+ 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());
LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
- LOperand* obj = UseFixed(instr->object(), r1);
- LOperand* val = UseFixed(instr->value(), r0);
+ 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);
void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(r1));
- ASSERT(ToRegister(instr->value()).is(r0));
+ ASSERT(ToRegister(instr->object()).is(StoreIC::ReceiverRegister()));
+ ASSERT(ToRegister(instr->value()).is(StoreIC::ValueRegister()));
- // Name is always in r2.
- __ mov(r2, Operand(instr->name()));
+ __ mov(StoreIC::NameRegister(), Operand(instr->name()));
Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(r2));
- ASSERT(ToRegister(instr->key()).is(r1));
- ASSERT(ToRegister(instr->value()).is(r0));
+ 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()
Register StoreStubCompiler::value() {
- return r0;
+ return StoreIC::ValueRegister();
}
Register* StoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
- static Register registers[] = { r1, r2, r3, r4, r5 };
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ static Register registers[] = { receiver, name, r3, r4, r5 };
return registers;
}
Register* KeyedStoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
- static Register registers[] = { r2, r1, r3, r4, r5 };
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ static Register registers[] = { receiver, name, r3, r4, r5 };
return registers;
}
}
-void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // x2: receiver
- // x1: key
- // x0: value
- Register registers[] = { x2, x1, x0 };
- descriptor->Initialize(
- ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
-}
-
-
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: value (js_array)
}
-void StoreGlobalStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // x1: receiver
- // x2: key (unused)
- // x0: value
- Register registers[] = { x1, x2, x0 };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(StoreIC_MissFromStubFailure));
-}
-
-
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: value
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
- // Calling convention for IC store (from ic-arm.cc).
- // ----------- S t a t e -------------
- // -- x0 : value
- // -- x1 : receiver
- // -- x2 : name
- // -- lr : return address
- // -----------------------------------
- // Registers x0, x1, and x2 contain objects that need to be pushed on the
- // expression stack of the fake JS frame.
- Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit() | x2.Bit(), 0, x10);
+ // Calling convention for IC store (from ic-arm64.cc).
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ Register value = StoreIC::ValueRegister();
+ Generate_DebugBreakCallHelper(
+ masm, receiver.Bit() | name.Bit() | value.Bit(), 0, x10);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
- // ---------- S t a t e --------------
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -- lr : return address
- Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit() | x2.Bit(), 0, x10);
+ // Calling convention for IC keyed store call (from ic-arm64.cc).
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ Register value = KeyedStoreIC::ValueRegister();
+ Generate_DebugBreakCallHelper(
+ masm, receiver.Bit() | name.Bit() | value.Bit(), 0, x10);
}
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
- __ Mov(x2, Operand(key->value()));
- __ Peek(x1, 0);
+ ASSERT(StoreIC::ValueRegister().is(x0));
+ __ Mov(StoreIC::NameRegister(), Operand(key->value()));
+ __ Peek(StoreIC::ReceiverRegister(), 0);
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
VisitForAccumulatorValue(prop->obj());
// TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid
// this copy.
- __ Mov(x1, x0);
- __ Pop(x0); // Restore value.
- __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
+ __ Mov(StoreIC::ReceiverRegister(), x0);
+ __ Pop(StoreIC::ValueRegister()); // Restore value.
+ __ Mov(StoreIC::NameRegister(),
+ Operand(prop->key()->AsLiteral()->value()));
CallStoreIC();
break;
}
__ Push(x0); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
- __ Mov(x1, x0);
- __ Pop(x2, x0);
+ __ Mov(KeyedStoreIC::NameRegister(), x0);
+ __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::ValueRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment");
if (var->IsUnallocated()) {
// Global var, const, or let.
- __ Mov(x2, Operand(var->name()));
- __ Ldr(x1, GlobalObjectMemOperand());
+ __ Mov(StoreIC::NameRegister(), Operand(var->name()));
+ __ Ldr(StoreIC::ReceiverRegister(), GlobalObjectMemOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
- __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
- __ Pop(x1);
-
+ __ Mov(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value()));
+ __ Pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
// Record source code position before IC call.
SetSourcePosition(expr->position());
// TODO(all): Could we pass this in registers rather than on the stack?
- __ Pop(x1, x2); // Key and object holding the property.
+ __ Pop(KeyedStoreIC::NameRegister(), KeyedStoreIC::ReceiverRegister());
+ ASSERT(KeyedStoreIC::ValueRegister().is(x0));
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
}
break;
case NAMED_PROPERTY: {
- __ Mov(x2, Operand(prop->key()->AsLiteral()->value()));
- __ Pop(x1);
+ __ Mov(StoreIC::NameRegister(),
+ Operand(prop->key()->AsLiteral()->value()));
+ __ Pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
break;
}
case KEYED_PROPERTY: {
- __ Pop(x1); // Key.
- __ Pop(x2); // Receiver.
+ __ Pop(KeyedStoreIC::NameRegister());
+ __ Pop(KeyedStoreIC::ReceiverRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
ASM_LOCATION("KeyedStoreIC::GenerateSloppyArguments");
- // ---------- S t a t e --------------
- // -- lr : return address
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -----------------------------------
Label slow, notin;
+ Register value = ValueRegister();
+ Register key = NameRegister();
+ Register receiver = ReceiverRegister();
+ ASSERT(receiver.is(x2));
+ ASSERT(key.is(x1));
+ ASSERT(value.is(x0));
- Register value = x0;
- Register key = x1;
- Register receiver = x2;
Register map = x3;
// These registers are used by GenerateMappedArgumentsLookup to build a
const Register LoadIC::NameRegister() { return x2; }
+const Register StoreIC::ReceiverRegister() { return x1; }
+const Register StoreIC::NameRegister() { return x2; }
+const Register StoreIC::ValueRegister() { return x0; }
+
+
+const Register KeyedStoreIC::ReceiverRegister() { return x2; }
+const Register KeyedStoreIC::NameRegister() { return x1; }
+const Register KeyedStoreIC::ValueRegister() { return x0; }
+
+
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is in lr.
__ Push(ReceiverRegister(), NameRegister());
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
ASM_LOCATION("KeyedStoreIC::GenerateMiss");
- // ---------- S t a t e --------------
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -- lr : return address
- // -----------------------------------
// Push receiver, key and value for runtime call.
- __ Push(x2, x1, x0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
ExternalReference ref =
ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
ASM_LOCATION("KeyedStoreIC::GenerateSlow");
- // ---------- S t a t e --------------
- // -- lr : return address
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -----------------------------------
// Push receiver, key and value for runtime call.
- __ Push(x2, x1, x0);
+ __ 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.
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
ASM_LOCATION("KeyedStoreIC::GenerateRuntimeSetProperty");
- // ---------- S t a t e --------------
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -- lr : return address
- // -----------------------------------
// Push receiver, key and value for runtime call.
- __ Push(x2, x1, x0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// Push strict_mode for runtime call.
__ Mov(x10, Smi::FromInt(strict_mode));
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictMode strict_mode) {
ASM_LOCATION("KeyedStoreIC::GenerateGeneric");
- // ---------- S t a t e --------------
- // -- x0 : value
- // -- x1 : key
- // -- x2 : receiver
- // -- lr : return address
- // -----------------------------------
Label slow;
Label array;
Label fast_object;
Label fast_double_grow;
Label fast_double;
- Register value = x0;
- Register key = x1;
- Register receiver = x2;
+ Register value = ValueRegister();
+ Register key = NameRegister();
+ Register receiver = ReceiverRegister();
+ ASSERT(receiver.is(x2));
+ ASSERT(key.is(x1));
+ ASSERT(value.is(x0));
+
Register receiver_map = x3;
Register elements = x4;
Register elements_map = x5;
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- x0 : value
- // -- x1 : receiver
- // -- x2 : name
- // -- lr : return address
- // -----------------------------------
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ ASSERT(!AreAliased(receiver, name, ValueRegister(), x3, x4, x5, x6));
// Probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
masm->isolate()->stub_cache()->GenerateProbe(
- masm, flags, x1, x2, x3, x4, x5, x6);
+ masm, flags, receiver, name, x3, x4, x5, x6);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
void StoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- x0 : value
- // -- x1 : receiver
- // -- x2 : name
- // -- lr : return address
- // -----------------------------------
-
- __ Push(x1, x2, x0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
// Tail call to the entry.
ExternalReference ref =
void StoreIC::GenerateNormal(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- x0 : value
- // -- x1 : receiver
- // -- x2 : name
- // -- lr : return address
- // -----------------------------------
Label miss;
- Register value = x0;
- Register receiver = x1;
- Register name = x2;
+ Register value = ValueRegister();
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
Register dictionary = x3;
+ ASSERT(!AreAliased(value, receiver, name, x3, x4, x5));
GenerateNameDictionaryReceiverCheck(
masm, receiver, dictionary, x4, x5, &miss);
void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
ASM_LOCATION("StoreIC::GenerateRuntimeSetProperty");
- // ----------- S t a t e -------------
- // -- x0 : value
- // -- x1 : receiver
- // -- x2 : name
- // -- lr : return address
- // -----------------------------------
- __ Push(x1, x2, x0);
+ __ Push(ReceiverRegister(), NameRegister(), ValueRegister());
__ Mov(x10, Smi::FromInt(strict_mode));
__ Push(x10);
// -----------------------------------
// Push receiver, name and value for runtime call.
- __ Push(x1, x2, x0);
+ __ 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.
LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
- LOperand* object = UseFixed(instr->object(), x2);
- LOperand* key = UseFixed(instr->key(), x1);
- LOperand* value = UseFixed(instr->value(), x0);
+ LOperand* object = UseFixed(instr->object(),
+ KeyedStoreIC::ReceiverRegister());
+ LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister());
+ LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister());
ASSERT(instr->object()->representation().IsTagged());
ASSERT(instr->key()->representation().IsTagged());
LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp);
- LOperand* object = UseFixed(instr->object(), x1);
- LOperand* value = UseFixed(instr->value(), x0);
+ LOperand* object = UseFixed(instr->object(), StoreIC::ReceiverRegister());
+ LOperand* value = UseFixed(instr->value(), StoreIC::ValueRegister());
+
LInstruction* result = new(zone()) LStoreNamedGeneric(context, object, value);
return MarkAsCall(result, instr);
}
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).Is(x2));
- ASSERT(ToRegister(instr->key()).Is(x1));
- ASSERT(ToRegister(instr->value()).Is(x0));
+ 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()
void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->value()).is(x0));
- ASSERT(ToRegister(instr->object()).is(x1));
+ ASSERT(ToRegister(instr->object()).is(StoreIC::ReceiverRegister()));
+ ASSERT(ToRegister(instr->value()).is(StoreIC::ValueRegister()));
- // Name must be in x2.
- __ Mov(x2, Operand(instr->name()));
+ __ Mov(StoreIC::NameRegister(), Operand(instr->name()));
Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
Register StoreStubCompiler::value() {
- return x0;
+ return StoreIC::ValueRegister();
}
Register* StoreStubCompiler::registers() {
// receiver, value, scratch1, scratch2, scratch3.
- static Register registers[] = { x1, x2, x3, x4, x5 };
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ static Register registers[] = { receiver, name, x3, x4, x5 };
return registers;
}
Register* KeyedStoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
- static Register registers[] = { x2, x1, x3, x4, x5 };
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ static Register registers[] = { receiver, name, x3, x4, x5 };
return registers;
}
template <>
HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() {
BuildUncheckedMonomorphicElementAccess(
- GetParameter(0), GetParameter(1), GetParameter(2),
+ GetParameter(StoreIC::kReceiverIndex),
+ GetParameter(StoreIC::kNameIndex),
+ GetParameter(StoreIC::kValueIndex),
casted_stub()->is_js_array(), casted_stub()->elements_kind(),
STORE, NEVER_RETURN_HOLE, casted_stub()->store_mode());
Handle<PropertyCell> placeholder_cell =
isolate()->factory()->NewPropertyCell(placeholer_value);
- HParameter* value = GetParameter(2);
+ HParameter* value = GetParameter(StoreIC::kValueIndex);
if (stub->check_global()) {
// Check that the map of the global has not changed: use a placeholder map
}
+void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
+ CodeStubInterfaceDescriptor* descriptor) {
+ Register registers[] = { KeyedStoreIC::ReceiverRegister(),
+ KeyedStoreIC::NameRegister(),
+ KeyedStoreIC::ValueRegister() };
+ descriptor->Initialize(
+ ARRAY_SIZE(registers), registers,
+ FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
+}
+
+
+void StoreGlobalStub::InitializeInterfaceDescriptor(
+ CodeStubInterfaceDescriptor* descriptor) {
+ Register registers[] = { StoreIC::ReceiverRegister(),
+ StoreIC::NameRegister(),
+ StoreIC::ValueRegister() };
+ descriptor->Initialize(ARRAY_SIZE(registers), registers,
+ FUNCTION_ADDR(StoreIC_MissFromStubFailure));
+}
+
+
void KeyedLoadDictionaryElementPlatformStub::Generate(
MacroAssembler* masm) {
KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
}
-void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { edx, ecx, eax };
- descriptor->Initialize(
- ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
-}
-
-
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { eax, ebx };
}
-void StoreGlobalStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { edx, ecx, eax };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(StoreIC_MissFromStubFailure));
-}
-
-
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { eax, ebx, ecx, edx };
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Register state for IC store call (from ic-ia32.cc).
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : name
- // -- edx : receiver
- // -----------------------------------
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ Register value = StoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
- masm, eax.bit() | ecx.bit() | edx.bit(), 0, false);
+ masm, receiver.bit() | name.bit() | value.bit(), 0, false);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
- // Register state for keyed IC load call (from ic-ia32.cc).
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -----------------------------------
+ // Register state for keyed IC store call (from ic-ia32.cc).
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ Register value = KeyedStoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
- masm, eax.bit() | ecx.bit() | edx.bit(), 0, false);
+ masm, receiver.bit() | name.bit() | value.bit(), 0, false);
}
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
- __ mov(ecx, Immediate(key->value()));
- __ mov(edx, Operand(esp, 0));
+ ASSERT(StoreIC::ValueRegister().is(eax));
+ __ mov(StoreIC::NameRegister(), Immediate(key->value()));
+ __ mov(StoreIC::ReceiverRegister(), Operand(esp, 0));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
case NAMED_PROPERTY: {
__ push(eax); // Preserve value.
VisitForAccumulatorValue(prop->obj());
- __ mov(edx, eax);
- __ pop(eax); // Restore value.
- __ mov(ecx, prop->key()->AsLiteral()->value());
+ __ Move(StoreIC::ReceiverRegister(), eax);
+ __ pop(StoreIC::ValueRegister()); // Restore value.
+ __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value());
CallStoreIC();
break;
}
__ push(eax); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
- __ mov(ecx, eax);
- __ pop(edx); // Receiver.
- __ pop(eax); // Restore value.
+ __ Move(KeyedStoreIC::NameRegister(), eax);
+ __ pop(KeyedStoreIC::ReceiverRegister()); // Receiver.
+ __ pop(KeyedStoreIC::ValueRegister()); // Restore value.
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
Token::Value op) {
if (var->IsUnallocated()) {
// Global var, const, or let.
- __ mov(ecx, var->name());
- __ mov(edx, GlobalObjectOperand());
+ __ mov(StoreIC::NameRegister(), var->name());
+ __ mov(StoreIC::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
- __ mov(ecx, prop->key()->AsLiteral()->value());
- __ pop(edx);
+ __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value());
+ __ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
context()->Plug(eax);
// esp[0] : key
// esp[kPointerSize] : receiver
- __ pop(ecx); // Key.
- __ pop(edx);
+ __ pop(KeyedStoreIC::NameRegister()); // Key.
+ __ pop(KeyedStoreIC::ReceiverRegister());
+ ASSERT(KeyedStoreIC::ValueRegister().is(eax));
// Record source code position before IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = strict_mode() == SLOPPY
}
break;
case NAMED_PROPERTY: {
- __ mov(ecx, prop->key()->AsLiteral()->value());
- __ pop(edx);
+ __ mov(StoreIC::NameRegister(), prop->key()->AsLiteral()->value());
+ __ pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
break;
}
case KEYED_PROPERTY: {
- __ pop(ecx);
- __ pop(edx);
+ __ pop(KeyedStoreIC::NameRegister());
+ __ pop(KeyedStoreIC::ReceiverRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
}
-// A register that isn't one of the parameters to the load ic.
-static const Register LoadIC_TempRegister() { return ebx; }
-
-
-// A register that isn't one of the parameters to the load ic.
-static const Register KeyedLoadIC_TempRegister() {
- return LoadIC_TempRegister();
-}
-
-
void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// Return address is on the stack.
Label miss;
Register receiver = ReceiverRegister();
Register index = NameRegister();
- Register scratch = KeyedLoadIC_TempRegister();
+ Register scratch = ebx;
+ ASSERT(!scratch.is(receiver) && !scratch.is(index));
Register result = eax;
ASSERT(!result.is(scratch));
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
Label slow, notin;
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ Register value = ValueRegister();
+ ASSERT(receiver.is(edx));
+ ASSERT(name.is(ecx));
+ ASSERT(value.is(eax));
+
Operand mapped_location =
- GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, edi, ¬in, &slow);
- __ mov(mapped_location, eax);
+ GenerateMappedArgumentsLookup(masm, receiver, name, ebx, edi, ¬in,
+ &slow);
+ __ mov(mapped_location, value);
__ lea(ecx, mapped_location);
- __ mov(edx, eax);
+ __ mov(edx, value);
__ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs);
__ Ret();
__ bind(¬in);
// The unmapped lookup expects that the parameter map is in ebx.
Operand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, ecx, ebx, edi, &slow);
- __ mov(unmapped_location, eax);
+ GenerateUnmappedArgumentsLookup(masm, name, ebx, edi, &slow);
+ __ mov(unmapped_location, value);
__ lea(edi, unmapped_location);
- __ mov(edx, eax);
+ __ mov(edx, value);
__ RecordWrite(ebx, edi, edx, kDontSaveFPRegs);
__ Ret();
__ bind(&slow);
Label transition_smi_elements;
Label finish_object_store, non_double_value, transition_double_elements;
Label fast_double_without_map_check;
- // eax: value
- // ecx: key (a smi)
- // edx: receiver
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register key = KeyedStoreIC::NameRegister();
+ Register value = KeyedStoreIC::ValueRegister();
+ ASSERT(receiver.is(edx));
+ ASSERT(key.is(ecx));
+ ASSERT(value.is(eax));
+ // key is a smi.
// ebx: FixedArray receiver->elements
// edi: receiver map
// Fast case: Do the store, could either Object or double.
// We have to go to the runtime if the current value is the hole because
// there may be a callback on the element
Label holecheck_passed1;
- __ cmp(FixedArrayElementOperand(ebx, ecx),
+ __ cmp(FixedArrayElementOperand(ebx, key),
masm->isolate()->factory()->the_hole_value());
__ j(not_equal, &holecheck_passed1);
- __ JumpIfDictionaryInPrototypeChain(edx, ebx, edi, slow);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ JumpIfDictionaryInPrototypeChain(receiver, ebx, edi, slow);
+ __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
__ bind(&holecheck_passed1);
// Smi stores don't require further checks.
Label non_smi_value;
- __ JumpIfNotSmi(eax, &non_smi_value);
+ __ JumpIfNotSmi(value, &non_smi_value);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ add(FieldOperand(edx, JSArray::kLengthOffset),
+ __ add(FieldOperand(receiver, JSArray::kLengthOffset),
Immediate(Smi::FromInt(1)));
}
// It's irrelevant whether array is smi-only or not when writing a smi.
- __ mov(FixedArrayElementOperand(ebx, ecx), eax);
+ __ mov(FixedArrayElementOperand(ebx, key), value);
__ ret(0);
__ bind(&non_smi_value);
// Escape to elements kind transition case.
- __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
+ __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset));
__ CheckFastObjectElements(edi, &transition_smi_elements);
// Fast elements array, store the value to the elements backing store.
__ bind(&finish_object_store);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ add(FieldOperand(edx, JSArray::kLengthOffset),
+ __ add(FieldOperand(receiver, JSArray::kLengthOffset),
Immediate(Smi::FromInt(1)));
}
- __ mov(FixedArrayElementOperand(ebx, ecx), eax);
+ __ mov(FixedArrayElementOperand(ebx, key), value);
// Update write barrier for the elements array address.
- __ mov(edx, eax); // Preserve the value which is returned.
+ __ mov(edx, value); // Preserve the value which is returned.
__ RecordWriteArray(
- ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ ret(0);
__ bind(fast_double);
// We have to see if the double version of the hole is present. If so
// go to the runtime.
uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
- __ cmp(FieldOperand(ebx, ecx, times_4, offset), Immediate(kHoleNanUpper32));
+ __ cmp(FieldOperand(ebx, key, times_4, offset), Immediate(kHoleNanUpper32));
__ j(not_equal, &fast_double_without_map_check);
- __ JumpIfDictionaryInPrototypeChain(edx, ebx, edi, slow);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ JumpIfDictionaryInPrototypeChain(receiver, ebx, edi, slow);
+ __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
__ bind(&fast_double_without_map_check);
- __ StoreNumberToDoubleElements(eax, ebx, ecx, edi, xmm0,
+ __ StoreNumberToDoubleElements(value, ebx, key, edi, xmm0,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ add(FieldOperand(edx, JSArray::kLengthOffset),
+ __ add(FieldOperand(receiver, JSArray::kLengthOffset),
Immediate(Smi::FromInt(1)));
}
__ ret(0);
__ bind(&transition_smi_elements);
- __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
+ __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset));
// Transition the array appropriately depending on the value type.
- __ CheckMap(eax,
+ __ CheckMap(value,
masm->isolate()->factory()->heap_number_map(),
&non_double_value,
DONT_DO_SMI_CHECK);
AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS,
FAST_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&fast_double_without_map_check);
__ bind(&non_double_value);
mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
slow);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
__ bind(&transition_double_elements);
// Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
// HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
// transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
- __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
+ __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset));
__ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
FAST_ELEMENTS,
ebx,
slow);
mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
}
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
Label slow, fast_object, fast_object_grow;
Label fast_double, fast_double_grow;
Label array, extra, check_if_double_array;
+ Register receiver = ReceiverRegister();
+ Register key = NameRegister();
+ ASSERT(receiver.is(edx));
+ ASSERT(key.is(ecx));
// Check that the object isn't a smi.
- __ JumpIfSmi(edx, &slow);
+ __ JumpIfSmi(receiver, &slow);
// Get the map from the receiver.
- __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
+ __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset));
// Check that the receiver does not require access checks and is not observed.
// The generic stub does not perform map checks or handle observed objects.
__ test_b(FieldOperand(edi, Map::kBitFieldOffset),
1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved);
__ j(not_zero, &slow);
// Check that the key is a smi.
- __ JumpIfNotSmi(ecx, &slow);
+ __ JumpIfNotSmi(key, &slow);
__ CmpInstanceType(edi, JS_ARRAY_TYPE);
__ j(equal, &array);
// Check that the object is some kind of JSObject.
__ j(below, &slow);
// Object case: Check key against length in the elements array.
- // eax: value
- // edx: JSObject
- // ecx: key (a smi)
+ // Key is a smi.
// edi: receiver map
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
// Check array bounds. Both the key and the length of FixedArray are smis.
- __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
+ __ cmp(key, FieldOperand(ebx, FixedArray::kLengthOffset));
__ j(below, &fast_object);
// Slow case: call runtime.
// perform the store and update the length. Used for adding one
// element to the array by writing to array[array.length].
__ bind(&extra);
- // eax: value
- // edx: receiver, a JSArray
- // ecx: key, a smi.
+ // receiver is a JSArray.
+ // key is a smi.
// ebx: receiver->elements, a FixedArray
// edi: receiver map
- // flags: compare (ecx, edx.length())
+ // flags: compare (key, receiver.length())
// do not leave holes in the array:
__ j(not_equal, &slow);
- __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
+ __ cmp(key, FieldOperand(ebx, FixedArray::kLengthOffset));
__ j(above_equal, &slow);
__ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
__ cmp(edi, masm->isolate()->factory()->fixed_array_map());
// array. Check that the array is in fast mode (and writable); if it
// is the length is always a smi.
__ bind(&array);
- // eax: value
- // edx: receiver, a JSArray
- // ecx: key, a smi.
+ // receiver is a JSArray.
+ // key is a smi.
// edi: receiver map
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset));
// Check the key against the length in the array and fall through to the
// common store code.
- __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
+ __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset)); // Compare smis.
__ j(above_equal, &extra);
KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
}
+static void LoadIC_PushArgs(MacroAssembler* masm) {
+ Register receiver = LoadIC::ReceiverRegister();
+ Register name = LoadIC::NameRegister();
+ ASSERT(!ebx.is(receiver) && !ebx.is(name));
+
+ __ pop(ebx);
+ __ push(receiver);
+ __ push(name);
+ __ push(ebx);
+}
+
+
void LoadIC::GenerateMiss(MacroAssembler* masm) {
// Return address is on the stack.
__ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
- __ pop(LoadIC_TempRegister());
- __ push(ReceiverRegister()); // receiver
- __ push(NameRegister()); // name
- __ push(LoadIC_TempRegister()); // return address
+ LoadIC_PushArgs(masm);
// Perform tail call to the entry.
ExternalReference ref =
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
- __ pop(LoadIC_TempRegister());
- __ push(ReceiverRegister()); // receiver
- __ push(NameRegister()); // name
- __ push(LoadIC_TempRegister()); // return address
+ LoadIC_PushArgs(masm);
// Perform tail call to the entry.
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
// Return address is on the stack.
__ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1);
- __ pop(KeyedLoadIC_TempRegister());
- __ push(ReceiverRegister()); // receiver
- __ push(NameRegister()); // name
- __ push(KeyedLoadIC_TempRegister()); // return address
+ LoadIC_PushArgs(masm);
// Perform tail call to the entry.
ExternalReference ref =
const Register LoadIC::NameRegister() { return ecx; }
+const Register StoreIC::ReceiverRegister() { return edx; }
+const Register StoreIC::NameRegister() { return ecx; }
+const Register StoreIC::ValueRegister() { return eax; }
+
+
+const Register KeyedStoreIC::ReceiverRegister() {
+ return StoreIC::ReceiverRegister();
+}
+
+
+const Register KeyedStoreIC::NameRegister() {
+ return StoreIC::NameRegister();
+}
+
+
+const Register KeyedStoreIC::ValueRegister() {
+ return StoreIC::ValueRegister();
+}
+
+
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
- __ pop(KeyedLoadIC_TempRegister());
- __ push(ReceiverRegister()); // receiver
- __ push(NameRegister()); // name
- __ push(KeyedLoadIC_TempRegister()); // return address
+ LoadIC_PushArgs(masm);
// Perform tail call to the entry.
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : name
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
masm->isolate()->stub_cache()->GenerateProbe(
- masm, flags, edx, ecx, ebx, no_reg);
+ masm, flags, ReceiverRegister(), NameRegister(),
+ ebx, no_reg);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
}
-void StoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : name
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ Register value = StoreIC::ValueRegister();
+
+ ASSERT(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value));
__ pop(ebx);
- __ push(edx);
- __ push(ecx);
- __ push(eax);
+ __ push(receiver);
+ __ push(name);
+ __ push(value);
__ push(ebx);
+}
+
+
+void StoreIC::GenerateMiss(MacroAssembler* masm) {
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Perform tail call to the entry.
ExternalReference ref =
void StoreIC::GenerateNormal(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : name
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
+ // Return address is on the stack.
Label miss, restore_miss;
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ Register value = ValueRegister();
- GenerateNameDictionaryReceiverCheck(masm, edx, ebx, edi, &miss);
+ GenerateNameDictionaryReceiverCheck(masm, receiver, ebx, edi, &miss);
// A lot of registers are needed for storing to slow case
// objects. Push and restore receiver but rely on
// GenerateDictionaryStore preserving the value and name.
- __ push(edx);
- GenerateDictionaryStore(masm, &restore_miss, ebx, ecx, eax, edx, edi);
+ __ push(receiver);
+ GenerateDictionaryStore(masm, &restore_miss, ebx, name, value, receiver, edi);
__ Drop(1);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->store_normal_hit(), 1);
__ ret(0);
__ bind(&restore_miss);
- __ pop(edx);
+ __ pop(receiver);
__ bind(&miss);
__ IncrementCounter(counters->store_normal_miss(), 1);
void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : name
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
+ ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) &&
+ !ebx.is(ValueRegister()));
__ pop(ebx);
- __ push(edx);
- __ push(ecx);
- __ push(eax);
+ __ push(ReceiverRegister());
+ __ push(NameRegister());
+ __ push(ValueRegister());
__ push(Immediate(Smi::FromInt(strict_mode)));
__ push(ebx); // return address
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
+ // Return address is on the stack.
+ ASSERT(!ebx.is(ReceiverRegister()) && !ebx.is(NameRegister()) &&
+ !ebx.is(ValueRegister()));
__ pop(ebx);
- __ push(edx);
- __ push(ecx);
- __ push(eax);
- __ push(Immediate(Smi::FromInt(strict_mode))); // Strict mode.
- __ push(ebx); // return address
+ __ push(ReceiverRegister());
+ __ push(NameRegister());
+ __ push(ValueRegister());
+ __ push(Immediate(Smi::FromInt(strict_mode)));
+ __ push(ebx); // return address
// Do tail-call to runtime routine.
__ TailCallRuntime(Runtime::kSetProperty, 4, 1);
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
- __ pop(ebx);
- __ push(edx);
- __ push(ecx);
- __ push(eax);
- __ push(ebx);
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref =
void StoreIC::GenerateSlow(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
- __ pop(ebx);
- __ push(edx);
- __ push(ecx);
- __ push(eax);
- __ push(ebx); // return address
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(kStoreIC_Slow), masm->isolate());
void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
- __ pop(ebx);
- __ push(edx);
- __ push(ecx);
- __ push(eax);
- __ push(ebx); // return address
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
- ASSERT(ToRegister(instr->object()).is(edx));
- ASSERT(ToRegister(instr->value()).is(eax));
+ ASSERT(ToRegister(instr->object()).is(StoreIC::ReceiverRegister()));
+ ASSERT(ToRegister(instr->value()).is(StoreIC::ValueRegister()));
- __ mov(ecx, instr->name());
+ __ mov(StoreIC::NameRegister(), instr->name());
Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
- ASSERT(ToRegister(instr->object()).is(edx));
- ASSERT(ToRegister(instr->key()).is(ecx));
- ASSERT(ToRegister(instr->value()).is(eax));
+ 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()
LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi);
- LOperand* object = UseFixed(instr->object(), edx);
- LOperand* key = UseFixed(instr->key(), ecx);
- LOperand* value = UseFixed(instr->value(), eax);
+ LOperand* object = UseFixed(instr->object(),
+ KeyedStoreIC::ReceiverRegister());
+ LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister());
+ LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister());
ASSERT(instr->object()->representation().IsTagged());
ASSERT(instr->key()->representation().IsTagged());
LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi);
- LOperand* object = UseFixed(instr->object(), edx);
- LOperand* value = UseFixed(instr->value(), eax);
+ LOperand* object = UseFixed(instr->object(), StoreIC::ReceiverRegister());
+ LOperand* value = UseFixed(instr->value(), StoreIC::ValueRegister());
LStoreNamedGeneric* result =
new(zone()) LStoreNamedGeneric(context, object, value);
Register StoreStubCompiler::value() {
- return eax;
+ return StoreIC::ValueRegister();
}
Register* StoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
- static Register registers[] = { edx, ecx, ebx, edi, no_reg };
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ static Register registers[] = { receiver, name, ebx, edi, no_reg };
return registers;
}
Register* KeyedStoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
- static Register registers[] = { edx, ecx, ebx, edi, no_reg };
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ static Register registers[] = { receiver, name, ebx, edi, no_reg };
return registers;
}
static const ExtraICState kStrictModeState =
1 << StrictModeState::kShift;
+ enum RegisterInfo {
+ kReceiverIndex,
+ kNameIndex,
+ kValueIndex,
+ kRegisterArgumentCount
+ };
+ static const Register ReceiverRegister();
+ static const Register NameRegister();
+ static const Register ValueRegister();
+
StoreIC(FrameDepth depth, Isolate* isolate)
: IC(depth, isolate) {
ASSERT(IsStoreStub());
return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
}
+ static const Register ReceiverRegister();
+ static const Register NameRegister();
+ static const Register ValueRegister();
+
KeyedStoreIC(FrameDepth depth, Isolate* isolate)
: StoreIC(depth, isolate) {
ASSERT(target()->is_keyed_store_stub());
}
-void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { rdx, rcx, rax };
- descriptor->Initialize(
- ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(KeyedStoreIC_MissFromStubFailure));
-}
-
-
void TransitionElementsKindStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rax, rbx };
}
-void StoreGlobalStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { rdx, rcx, rax };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(StoreIC_MissFromStubFailure));
-}
-
-
void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rax, rbx, rcx, rdx };
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Register state for IC store call (from ic-x64.cc).
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -----------------------------------
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ Register value = StoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
- masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false);
+ masm, receiver.bit() | name.bit() | value.bit(), 0, false);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
- // Register state for keyed IC load call (from ic-x64.cc).
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -----------------------------------
+ // Register state for keyed IC store call (from ic-x64.cc).
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ Register value = KeyedStoreIC::ValueRegister();
Generate_DebugBreakCallHelper(
- masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false);
+ masm, receiver.bit() | name.bit() | value.bit(), 0, false);
}
if (key->value()->IsInternalizedString()) {
if (property->emit_store()) {
VisitForAccumulatorValue(value);
- __ Move(rcx, key->value());
- __ movp(rdx, Operand(rsp, 0));
+ ASSERT(StoreIC::ValueRegister().is(rax));
+ __ Move(StoreIC::NameRegister(), key->value());
+ __ movp(StoreIC::ReceiverRegister(), Operand(rsp, 0));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
} else {
case NAMED_PROPERTY: {
__ Push(rax); // Preserve value.
VisitForAccumulatorValue(prop->obj());
- __ movp(rdx, rax);
- __ Pop(rax); // Restore value.
- __ Move(rcx, prop->key()->AsLiteral()->value());
+ __ Move(StoreIC::ReceiverRegister(), rax);
+ __ Pop(StoreIC::ValueRegister()); // Restore value.
+ __ Move(StoreIC::NameRegister(), prop->key()->AsLiteral()->value());
CallStoreIC();
break;
}
__ Push(rax); // Preserve value.
VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key());
- __ movp(rcx, rax);
- __ Pop(rdx);
- __ Pop(rax); // Restore value.
+ __ Move(KeyedStoreIC::NameRegister(), rax);
+ __ Pop(KeyedStoreIC::ReceiverRegister());
+ __ Pop(KeyedStoreIC::ValueRegister()); // Restore value.
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
Token::Value op) {
if (var->IsUnallocated()) {
// Global var, const, or let.
- __ Move(rcx, var->name());
- __ movp(rdx, GlobalObjectOperand());
+ __ Move(StoreIC::NameRegister(), var->name());
+ __ movp(StoreIC::ReceiverRegister(), GlobalObjectOperand());
CallStoreIC();
} else if (op == Token::INIT_CONST_LEGACY) {
// Record source code position before IC call.
SetSourcePosition(expr->position());
- __ Move(rcx, prop->key()->AsLiteral()->value());
- __ Pop(rdx);
+ __ Move(StoreIC::NameRegister(), prop->key()->AsLiteral()->value());
+ __ Pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
- __ Pop(rcx);
- __ Pop(rdx);
+ __ Pop(KeyedStoreIC::NameRegister()); // Key.
+ __ Pop(KeyedStoreIC::ReceiverRegister());
+ ASSERT(KeyedStoreIC::ValueRegister().is(rax));
// Record source code position before IC call.
SetSourcePosition(expr->position());
Handle<Code> ic = strict_mode() == SLOPPY
}
break;
case NAMED_PROPERTY: {
- __ Move(rcx, prop->key()->AsLiteral()->value());
- __ Pop(rdx);
+ __ Move(StoreIC::NameRegister(), prop->key()->AsLiteral()->value());
+ __ Pop(StoreIC::ReceiverRegister());
CallStoreIC(expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
break;
}
case KEYED_PROPERTY: {
- __ Pop(rcx);
- __ Pop(rdx);
+ __ Pop(KeyedStoreIC::NameRegister());
+ __ Pop(KeyedStoreIC::ReceiverRegister());
Handle<Code> ic = strict_mode() == SLOPPY
? isolate()->builtins()->KeyedStoreIC_Initialize()
: isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
Label transition_smi_elements;
Label finish_object_store, non_double_value, transition_double_elements;
Label fast_double_without_map_check;
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register key = KeyedStoreIC::NameRegister();
+ Register value = KeyedStoreIC::ValueRegister();
+ ASSERT(receiver.is(rdx));
+ ASSERT(key.is(rcx));
+ ASSERT(value.is(rax));
// Fast case: Do the store, could be either Object or double.
__ bind(fast_object);
- // rax: value
// rbx: receiver's elements array (a FixedArray)
- // rcx: index
- // rdx: receiver (a JSArray)
+ // receiver is a JSArray.
// r9: map of receiver
if (check_map == kCheckMap) {
__ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
// there may be a callback on the element
Label holecheck_passed1;
__ movp(kScratchRegister, FieldOperand(rbx,
- rcx,
+ key,
times_pointer_size,
FixedArray::kHeaderSize));
__ CompareRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &holecheck_passed1);
- __ JumpIfDictionaryInPrototypeChain(rdx, rdi, kScratchRegister, slow);
+ __ JumpIfDictionaryInPrototypeChain(receiver, rdi, kScratchRegister, slow);
__ bind(&holecheck_passed1);
// Smi stores don't require further checks.
Label non_smi_value;
- __ JumpIfNotSmi(rax, &non_smi_value);
+ __ JumpIfNotSmi(value, &non_smi_value);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ __ leal(rdi, Operand(key, 1));
+ __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
}
// It's irrelevant whether array is smi-only or not when writing a smi.
- __ movp(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
- rax);
+ __ movp(FieldOperand(rbx, key, times_pointer_size, FixedArray::kHeaderSize),
+ value);
__ ret(0);
__ bind(&non_smi_value);
__ bind(&finish_object_store);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ __ leal(rdi, Operand(key, 1));
+ __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
}
- __ movp(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
- rax);
- __ movp(rdx, rax); // Preserve the value which is returned.
+ __ movp(FieldOperand(rbx, key, times_pointer_size, FixedArray::kHeaderSize),
+ value);
+ __ movp(rdx, value); // Preserve the value which is returned.
__ RecordWriteArray(
- rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ rbx, rdx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ ret(0);
__ bind(fast_double);
// We have to see if the double version of the hole is present. If so
// go to the runtime.
uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
- __ cmpl(FieldOperand(rbx, rcx, times_8, offset), Immediate(kHoleNanUpper32));
+ __ cmpl(FieldOperand(rbx, key, times_8, offset), Immediate(kHoleNanUpper32));
__ j(not_equal, &fast_double_without_map_check);
- __ JumpIfDictionaryInPrototypeChain(rdx, rdi, kScratchRegister, slow);
+ __ JumpIfDictionaryInPrototypeChain(receiver, rdi, kScratchRegister, slow);
__ bind(&fast_double_without_map_check);
- __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0,
+ __ StoreNumberToDoubleElements(value, rbx, key, xmm0,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ __ leal(rdi, Operand(key, 1));
+ __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
}
__ ret(0);
__ bind(&transition_smi_elements);
- __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
+ __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
// Transition the array appropriately depending on the value type.
- __ movp(r9, FieldOperand(rax, HeapObject::kMapOffset));
+ __ movp(r9, FieldOperand(value, HeapObject::kMapOffset));
__ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &non_double_value);
AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS,
FAST_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&fast_double_without_map_check);
__ bind(&non_double_value);
mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
slow);
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
__ bind(&transition_double_elements);
// Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
// HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
// transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
- __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
+ __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
__ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
FAST_ELEMENTS,
rbx,
slow);
mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
}
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
Label slow, slow_with_tagged_index, fast_object, fast_object_grow;
Label fast_double, fast_double_grow;
Label array, extra, check_if_double_array;
+ Register receiver = ReceiverRegister();
+ Register key = NameRegister();
+ ASSERT(receiver.is(rdx));
+ ASSERT(key.is(rcx));
// Check that the object isn't a smi.
- __ JumpIfSmi(rdx, &slow_with_tagged_index);
+ __ JumpIfSmi(receiver, &slow_with_tagged_index);
// Get the map from the receiver.
- __ movp(r9, FieldOperand(rdx, HeapObject::kMapOffset));
+ __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset));
// Check that the receiver does not require access checks and is not observed.
// The generic stub does not perform map checks or handle observed objects.
__ testb(FieldOperand(r9, Map::kBitFieldOffset),
Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
__ j(not_zero, &slow_with_tagged_index);
// Check that the key is a smi.
- __ JumpIfNotSmi(rcx, &slow_with_tagged_index);
- __ SmiToInteger32(rcx, rcx);
+ __ JumpIfNotSmi(key, &slow_with_tagged_index);
+ __ SmiToInteger32(key, key);
__ CmpInstanceType(r9, JS_ARRAY_TYPE);
__ j(equal, &array);
__ j(below, &slow);
// Object case: Check key against length in the elements array.
- // rax: value
- // rdx: JSObject
- // rcx: index
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
// Check array bounds.
- __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
- // rax: value
+ __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key);
// rbx: FixedArray
- // rcx: index
__ j(above, &fast_object);
// Slow case: call runtime.
__ bind(&slow);
- __ Integer32ToSmi(rcx, rcx);
+ __ Integer32ToSmi(key, key);
__ bind(&slow_with_tagged_index);
GenerateRuntimeSetProperty(masm, strict_mode);
// Never returns to here.
// perform the store and update the length. Used for adding one
// element to the array by writing to array[array.length].
__ bind(&extra);
- // rax: value
- // rdx: receiver (a JSArray)
+ // receiver is a JSArray.
// rbx: receiver's elements array (a FixedArray)
- // rcx: index
- // flags: smicompare (rdx.length(), rbx)
+ // flags: smicompare (receiver.length(), rbx)
__ j(not_equal, &slow); // do not leave holes in the array
- __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
+ __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key);
__ j(below_equal, &slow);
// Increment index to get new length.
__ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
// array. Check that the array is in fast mode (and writable); if it
// is the length is always a smi.
__ bind(&array);
- // rax: value
- // rdx: receiver (a JSArray)
- // rcx: index
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ // receiver is a JSArray.
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
// Check the key against the length in the array, compute the
// address to store into and fall through to fast case.
- __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
+ __ SmiCompareInteger32(FieldOperand(receiver, JSArray::kLengthOffset), key);
__ j(below_equal, &extra);
KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // The return address is on the stack.
Label slow, notin;
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ Register value = ValueRegister();
+ ASSERT(receiver.is(rdx));
+ ASSERT(name.is(rcx));
+ ASSERT(value.is(rax));
+
Operand mapped_location = GenerateMappedArgumentsLookup(
- masm, rdx, rcx, rbx, rdi, r8, ¬in, &slow);
- __ movp(mapped_location, rax);
+ masm, receiver, name, rbx, rdi, r8, ¬in, &slow);
+ __ movp(mapped_location, value);
__ leap(r9, mapped_location);
- __ movp(r8, rax);
+ __ movp(r8, value);
__ RecordWrite(rbx,
r9,
r8,
__ bind(¬in);
// The unmapped lookup expects that the parameter map is in rbx.
Operand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rdi, &slow);
- __ movp(unmapped_location, rax);
+ GenerateUnmappedArgumentsLookup(masm, name, rbx, rdi, &slow);
+ __ movp(unmapped_location, value);
__ leap(r9, unmapped_location);
- __ movp(r8, rax);
+ __ movp(r8, value);
__ RecordWrite(rbx,
r9,
r8,
const Register LoadIC::NameRegister() { return rcx; }
+const Register StoreIC::ReceiverRegister() { return rdx; }
+const Register StoreIC::NameRegister() { return rcx; }
+const Register StoreIC::ValueRegister() { return rax; }
+
+
+const Register KeyedStoreIC::ReceiverRegister() {
+ return StoreIC::ReceiverRegister();
+}
+
+
+const Register KeyedStoreIC::NameRegister() {
+ return StoreIC::NameRegister();
+}
+
+
+const Register KeyedStoreIC::ValueRegister() {
+ return StoreIC::ValueRegister();
+}
+
+
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is on the stack.
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // The return address is on the stack.
// 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, rdx, rcx, rbx, no_reg);
+ masm, flags, ReceiverRegister(), NameRegister(), rbx, no_reg);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
}
-void StoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ Register value = StoreIC::ValueRegister();
+
+ ASSERT(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value));
__ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // name
- __ Push(rax); // value
+ __ Push(receiver);
+ __ Push(name);
+ __ Push(value);
__ PushReturnAddressFrom(rbx);
+}
+
+
+void StoreIC::GenerateMiss(MacroAssembler* masm) {
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Perform tail call to the entry.
ExternalReference ref =
void StoreIC::GenerateNormal(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ Register value = ValueRegister();
Label miss;
- GenerateNameDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
+ GenerateNameDictionaryReceiverCheck(masm, receiver, rbx, rdi, &miss);
- GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
+ GenerateDictionaryStore(masm, &miss, rbx, name, value, r8, r9);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->store_normal_hit(), 1);
__ ret(0);
void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
+ ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) &&
+ !rbx.is(ValueRegister()));
+
__ PopReturnAddressTo(rbx);
- __ Push(rdx);
- __ Push(rcx);
- __ Push(rax);
+ __ Push(ReceiverRegister());
+ __ Push(NameRegister());
+ __ Push(ValueRegister());
__ Push(Smi::FromInt(strict_mode));
__ PushReturnAddressFrom(rbx);
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
+ ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) &&
+ !rbx.is(ValueRegister()));
__ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
+ __ Push(ReceiverRegister());
+ __ Push(NameRegister());
+ __ Push(ValueRegister());
__ Push(Smi::FromInt(strict_mode)); // Strict mode.
__ PushReturnAddressFrom(rbx);
void StoreIC::GenerateSlow(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
-
- __ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
- __ PushReturnAddressFrom(rbx);
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(kStoreIC_Slow), masm->isolate());
void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
-
- __ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
- __ PushReturnAddressFrom(rbx);
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
-
- __ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
- __ PushReturnAddressFrom(rbx);
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref =
void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(rsi));
- ASSERT(ToRegister(instr->object()).is(rdx));
- ASSERT(ToRegister(instr->value()).is(rax));
+ ASSERT(ToRegister(instr->object()).is(StoreIC::ReceiverRegister()));
+ ASSERT(ToRegister(instr->value()).is(StoreIC::ValueRegister()));
- __ Move(rcx, instr->hydrogen()->name());
+ __ Move(StoreIC::NameRegister(), instr->hydrogen()->name());
Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(rsi));
- ASSERT(ToRegister(instr->object()).is(rdx));
- ASSERT(ToRegister(instr->key()).is(rcx));
- ASSERT(ToRegister(instr->value()).is(rax));
+ 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()
LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), rsi);
- LOperand* object = UseFixed(instr->object(), rdx);
- LOperand* key = UseFixed(instr->key(), rcx);
- LOperand* value = UseFixed(instr->value(), rax);
+ LOperand* object = UseFixed(instr->object(),
+ KeyedStoreIC::ReceiverRegister());
+ LOperand* key = UseFixed(instr->key(), KeyedStoreIC::NameRegister());
+ LOperand* value = UseFixed(instr->value(), KeyedStoreIC::ValueRegister());
ASSERT(instr->object()->representation().IsTagged());
ASSERT(instr->key()->representation().IsTagged());
LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), rsi);
- LOperand* object = UseFixed(instr->object(), rdx);
- LOperand* value = UseFixed(instr->value(), rax);
+ LOperand* object = UseFixed(instr->object(), StoreIC::ReceiverRegister());
+ LOperand* value = UseFixed(instr->value(), StoreIC::ValueRegister());
LStoreNamedGeneric* result =
new(zone()) LStoreNamedGeneric(context, object, value);
Register StoreStubCompiler::value() {
- return rax;
+ return StoreIC::ValueRegister();
}
Register* StoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
- static Register registers[] = { rdx, rcx, rbx, rdi, r8 };
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ static Register registers[] = { receiver, name, rbx, rdi, r8 };
return registers;
}
Register* KeyedStoreStubCompiler::registers() {
// receiver, name, scratch1, scratch2, scratch3.
- static Register registers[] = { rdx, rcx, rbx, rdi, r8 };
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register name = KeyedStoreIC::NameRegister();
+ static Register registers[] = { receiver, name, rbx, rdi, r8 };
return registers;
}