diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index cd905d6729..376147882d 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -87,34 +87,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor( } -void LoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { r0 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedLoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { r1 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void StringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { r0, r2 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedStringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { r1, r0 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { Register registers[] = { r2, r1, r0 }; diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc index d5b55b7d7b..97883199f2 100644 --- a/src/arm/debug-arm.cc +++ b/src/arm/debug-arm.cc @@ -176,15 +176,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Calling convention for IC load (from ic-arm.cc). - // ----------- S t a t e ------------- - // -- r2 : name - // -- lr : return address - // -- r0 : receiver - // -- [sp] : receiver - // ----------------------------------- - // Registers r0 and r2 contain objects that need to be pushed on the - // expression stack of the fake JS frame. - Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit(), 0); + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0); } @@ -203,11 +197,10 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit(), 0); + // Calling convention for keyed IC load (from ic-arm.cc). + Register receiver = KeyedLoadIC::ReceiverRegister(); + Register name = KeyedLoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0); } diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index ada2a8ebad..1f9273bc81 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -1389,8 +1389,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, __ bind(&fast); } - __ ldr(r0, GlobalObjectOperand()); - __ mov(r2, Operand(var->name())); + __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadIC::NameRegister(), Operand(var->name())); ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL : CONTEXTUAL; @@ -1472,10 +1472,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { switch (var->location()) { case Variable::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - // Use inline caching. Variable name is passed in r2 and the global - // object (receiver) in r0. - __ ldr(r0, GlobalObjectOperand()); - __ mov(r2, Operand(var->name())); + __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadIC::NameRegister(), Operand(var->name())); CallLoadIC(CONTEXTUAL); context()->Plug(r0); break; @@ -2053,14 +2051,19 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // receiver = iter; f = 'next'; arg = received; __ bind(&l_next); + Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); + Register keyedload_name = KeyedLoadIC::NameRegister(); + ASSERT(keyedload_receiver.is(r1)); + ASSERT(keyedload_name.is(r0)); + __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter __ Push(r2, r3, r0); // "next", iter, received // result = receiver[f](arg); __ bind(&l_call); - __ ldr(r1, MemOperand(sp, kPointerSize)); - __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); + __ ldr(keyedload_receiver, MemOperand(sp, kPointerSize)); + __ ldr(keyedload_name, MemOperand(sp, 2 * kPointerSize)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ mov(r1, r0); @@ -2073,19 +2076,24 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ bind(&l_loop); - __ push(r0); // save result - __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" - CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + ASSERT(load_receiver.is(r0)); + ASSERT(load_name.is(r2)); + + __ push(load_receiver); // save result + __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" + CallLoadIC(NOT_CONTEXTUAL); // r0=result.done Handle bool_ic = ToBooleanStub::GetUninitialized(isolate()); CallIC(bool_ic); __ cmp(r0, Operand(0)); __ b(eq, &l_try); // result.value - __ pop(r0); // result - __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" - CallLoadIC(NOT_CONTEXTUAL); // result.value in r0 - context()->DropAndPlug(2, r0); // drop iter and g + __ pop(load_receiver); // result + __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" + CallLoadIC(NOT_CONTEXTUAL); // r0=result.value + context()->DropAndPlug(2, r0); // drop iter and g break; } } @@ -2258,15 +2266,15 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); - __ mov(r2, Operand(key->value())); - // Call load IC. It has arguments receiver and property name r0 and r2. + __ mov(LoadIC::NameRegister(), Operand(key->value())); + // Call load IC. It has register arguments receiver and property. CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); } void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); - // Call keyed load IC. It has arguments key and receiver in r0 and r1. + // Call keyed load IC. It has register arguments receiver and key. Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, prop->PropertyFeedbackId()); } @@ -2555,13 +2563,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); + ASSERT(r0.is(LoadIC::ReceiverRegister())); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(r0); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ pop(r1); + ASSERT(r0.is(KeyedLoadIC::NameRegister())); + __ pop(KeyedLoadIC::ReceiverRegister()); EmitKeyedPropertyLoad(expr); context()->Plug(r0); } @@ -2598,7 +2608,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } else { // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ ldr(r0, MemOperand(sp, 0)); + __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. @@ -2616,12 +2626,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { // Load the key. VisitForAccumulatorValue(key); + ASSERT(r0.is(KeyedLoadIC::NameRegister())); Expression* callee = expr->expression(); // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ ldr(r1, MemOperand(sp, 0)); + __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -4039,7 +4050,8 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { __ push(r0); // Load the function from the receiver. - __ mov(r2, Operand(expr->name())); + ASSERT(r0.is(LoadIC::ReceiverRegister())); + __ mov(LoadIC::NameRegister(), Operand(expr->name())); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); // Push the target function under the receiver. @@ -4218,13 +4230,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { if (assign_type == NAMED_PROPERTY) { // Put the object both on the stack and in the accumulator. VisitForAccumulatorValue(prop->obj()); - __ push(r0); + ASSERT(r0.is(LoadIC::ReceiverRegister())); + __ push(LoadIC::ReceiverRegister()); EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); VisitForAccumulatorValue(prop->key()); - __ ldr(r1, MemOperand(sp, 0)); - __ push(r0); + ASSERT(r0.is(KeyedLoadIC::NameRegister())); + __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); + __ push(KeyedLoadIC::NameRegister()); EmitKeyedPropertyLoad(prop); } } @@ -4371,8 +4385,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { VariableProxy* proxy = expr->AsVariableProxy(); if (proxy != NULL && proxy->var()->IsUnallocated()) { Comment cmnt(masm_, "[ Global variable"); - __ ldr(r0, GlobalObjectOperand()); - __ mov(r2, Operand(proxy->name())); + __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadIC::NameRegister(), Operand(proxy->name())); // Use a regular load, not a contextual load, to avoid a reference // error. CallLoadIC(NOT_CONTEXTUAL); diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc index 506ab64d71..85a7cf52e6 100644 --- a/src/arm/ic-arm.cc +++ b/src/arm/ic-arm.cc @@ -316,6 +316,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // -- lr : return address // -- r0 : receiver // ----------------------------------- + ASSERT(r0.is(ReceiverRegister())); + ASSERT(r2.is(NameRegister())); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); @@ -333,6 +335,9 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // -- lr : return address // -- r0 : receiver // ----------------------------------- + ASSERT(r0.is(ReceiverRegister())); + ASSERT(r2.is(NameRegister())); + Label miss, slow; GenerateNameDictionaryReceiverCheck(masm, r0, r1, r3, r4, &miss); @@ -351,18 +356,18 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { } +// A register that isn't one of the parameters to the load ic. +static const Register LoadIC_TempRegister() { return r3; } + + void LoadIC::GenerateMiss(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- r2 : name - // -- lr : return address - // -- r0 : receiver - // ----------------------------------- + // The return address is on the stack. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4); - __ mov(r3, r0); - __ Push(r3, r2); + __ mov(LoadIC_TempRegister(), ReceiverRegister()); + __ Push(LoadIC_TempRegister(), NameRegister()); // Perform tail call to the entry. ExternalReference ref = @@ -372,14 +377,10 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- r2 : name - // -- lr : return address - // -- r0 : receiver - // ----------------------------------- + // The return address is on the stack. - __ mov(r3, r0); - __ Push(r3, r2); + __ mov(LoadIC_TempRegister(), ReceiverRegister()); + __ Push(LoadIC_TempRegister(), NameRegister()); __ TailCallRuntime(Runtime::kGetProperty, 2, 1); } @@ -476,6 +477,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { // -- r0 : key // -- r1 : receiver // ----------------------------------- + ASSERT(r1.is(ReceiverRegister())); + ASSERT(r0.is(NameRegister())); Label slow, notin; MemOperand mapped_location = GenerateMappedArgumentsLookup(masm, r1, r0, r2, r3, r4, ¬in, &slow); @@ -526,16 +529,12 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- + // The return address is on the stack. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); - __ Push(r1, r0); + __ Push(ReceiverRegister(), NameRegister()); // Perform tail call to the entry. ExternalReference ref = @@ -553,13 +552,9 @@ const Register KeyedLoadIC::NameRegister() { return r0; } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- + // The return address is on the stack. - __ Push(r1, r0); + __ Push(ReceiverRegister(), NameRegister()); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); } @@ -574,8 +569,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { Label slow, check_name, index_smi, index_name, property_array_property; Label probe_dictionary, check_number_dictionary; - Register key = r0; - Register receiver = r1; + Register key = NameRegister(); + Register receiver = ReceiverRegister(); + ASSERT(key.is(r0)); + ASSERT(receiver.is(r1)); Isolate* isolate = masm->isolate(); @@ -737,17 +734,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key (index) - // -- r1 : receiver - // ----------------------------------- + // Return address is on the stack. Label miss; - Register receiver = r1; - Register index = r0; + Register receiver = ReceiverRegister(); + Register index = NameRegister(); Register scratch = r3; Register result = r0; + ASSERT(!scratch.is(receiver) && !scratch.is(index)); StringCharAtGenerator char_at_generator(receiver, index, @@ -769,32 +763,35 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- + // Return address is on the stack. Label slow; + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + Register scratch1 = r2; + Register scratch2 = r3; + ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); + ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); + // Check that the receiver isn't a smi. - __ JumpIfSmi(r1, &slow); + __ JumpIfSmi(receiver, &slow); // Check that the key is an array index, that is Uint32. - __ NonNegativeSmiTst(r0); + __ NonNegativeSmiTst(key); __ b(ne, &slow); // Get the map of the receiver. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); + __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); // Check that it has indexed interceptor and access checks // are not enabled for this object. - __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset)); - __ and_(r3, r3, Operand(kSlowCaseBitFieldMask)); - __ cmp(r3, Operand(1 << Map::kHasIndexedInterceptor)); + __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitFieldOffset)); + __ and_(scratch2, scratch2, Operand(kSlowCaseBitFieldMask)); + __ cmp(scratch2, Operand(1 << Map::kHasIndexedInterceptor)); __ b(ne, &slow); // Everything is fine, call runtime. - __ Push(r1, r0); // Receiver, key. + __ Push(receiver, key); // Receiver, key. // Perform tail call to the entry. __ TailCallExternalReference( diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index d1cc422eab..d6ba4d79fb 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -2216,7 +2216,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* global_object = UseFixed(instr->global_object(), r0); + LOperand* global_object = UseFixed(instr->global_object(), + LoadIC::ReceiverRegister()); LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(context, global_object); return MarkAsCall(DefineFixed(result, r0), instr); @@ -2270,7 +2271,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), r0); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(context, object), r0); return MarkAsCall(result, instr); @@ -2330,8 +2331,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), r1); - LOperand* key = UseFixed(instr->key(), r0); + LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); LInstruction* result = DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), r0); diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 92cbe4f661..cb34a8cf63 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -2969,10 +2969,10 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->global_object()).is(r0)); + ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(r0)); - __ mov(r2, Operand(instr->name())); + __ mov(LoadIC::NameRegister(), Operand(instr->name())); ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; Handle ic = LoadIC::initialize_stub(isolate(), mode); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -3088,11 +3088,11 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(r0)); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(r0)); // Name is always in r2. - __ mov(r2, Operand(instr->name())); + __ mov(LoadIC::NameRegister(), Operand(instr->name())); Handle ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); } @@ -3394,8 +3394,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(r1)); - ASSERT(ToRegister(instr->key()).is(r0)); + ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index e807314f33..1c772eec81 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -1479,6 +1479,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( // -- r0 : key // -- r1 : receiver // ----------------------------------- + ASSERT(r1.is(KeyedLoadIC::ReceiverRegister())); + ASSERT(r0.is(KeyedLoadIC::NameRegister())); Label slow, miss; Register key = r0; diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index 2c25b48f19..c8e44cf9fc 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -102,36 +102,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor( } -void LoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - // x0: receiver - Register registers[] = { x0 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedLoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - // x1: receiver - Register registers[] = { x1 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void StringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { x0, x2 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedStringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { x1, x0 }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { // x2: receiver diff --git a/src/arm64/debug-arm64.cc b/src/arm64/debug-arm64.cc index 1a29ffbecd..a5baee7637 100644 --- a/src/arm64/debug-arm64.cc +++ b/src/arm64/debug-arm64.cc @@ -235,15 +235,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Calling convention for IC load (from ic-arm.cc). - // ----------- S t a t e ------------- - // -- x2 : name - // -- lr : return address - // -- x0 : receiver - // -- [sp] : receiver - // ----------------------------------- - // Registers x0 and x2 contain objects that need to be pushed on the - // expression stack of the fake JS frame. - Generate_DebugBreakCallHelper(masm, x0.Bit() | x2.Bit(), 0, x10); + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10); } @@ -262,11 +256,10 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key - // -- x1 : receiver - Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit(), 0, x10); + // Calling convention for keyed IC load (from ic-arm.cc). + Register receiver = KeyedLoadIC::ReceiverRegister(); + Register name = KeyedLoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10); } diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 34a79fc61b..14c1302326 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -1393,8 +1393,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, __ Bind(&fast); } - __ Ldr(x0, GlobalObjectMemOperand()); - __ Mov(x2, Operand(var->name())); + __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); + __ Mov(LoadIC::NameRegister(), Operand(var->name())); ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL : CONTEXTUAL; CallLoadIC(mode); @@ -1472,10 +1472,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { switch (var->location()) { case Variable::UNALLOCATED: { Comment cmnt(masm_, "Global variable"); - // Use inline caching. Variable name is passed in x2 and the global - // object (receiver) in x0. - __ Ldr(x0, GlobalObjectMemOperand()); - __ Mov(x2, Operand(var->name())); + __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); + __ Mov(LoadIC::NameRegister(), Operand(var->name())); CallLoadIC(CONTEXTUAL); context()->Plug(x0); break; @@ -1949,7 +1947,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); - __ Mov(x2, Operand(key->value())); + __ Mov(LoadIC::NameRegister(), Operand(key->value())); // Call load IC. It has arguments receiver and property name x0 and x2. CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); } @@ -2262,13 +2260,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); + ASSERT(x0.is(LoadIC::ReceiverRegister())); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(x0); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ Pop(x1); + ASSERT(x0.is(KeyedLoadIC::NameRegister())); + __ Pop(KeyedLoadIC::ReceiverRegister()); EmitKeyedPropertyLoad(expr); context()->Plug(x0); } @@ -2304,7 +2304,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } else { // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ Peek(x0, 0); + __ Peek(LoadIC::ReceiverRegister(), 0); EmitNamedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. @@ -2321,12 +2321,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { // Load the key. VisitForAccumulatorValue(key); + ASSERT(x0.is(KeyedLoadIC::NameRegister())); Expression* callee = expr->expression(); // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ Peek(x1, 0); + __ Peek(KeyedLoadIC::ReceiverRegister(), 0); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -3746,12 +3747,13 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { if (expr->is_jsruntime()) { // Push the builtins object as the receiver. __ Ldr(x10, GlobalObjectMemOperand()); - __ Ldr(x0, FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); - __ Push(x0); + __ Ldr(LoadIC::ReceiverRegister(), + FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); + __ Push(LoadIC::ReceiverRegister()); // Load the function from the receiver. Handle name = expr->name(); - __ Mov(x2, Operand(name)); + __ Mov(LoadIC::NameRegister(), Operand(name)); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); // Push the target function under the receiver. @@ -3927,14 +3929,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { if (assign_type == NAMED_PROPERTY) { // Put the object both on the stack and in the accumulator. VisitForAccumulatorValue(prop->obj()); - __ Push(x0); + ASSERT(x0.is(LoadIC::ReceiverRegister())); + __ Push(LoadIC::ReceiverRegister()); EmitNamedPropertyLoad(prop); } else { // KEYED_PROPERTY VisitForStackValue(prop->obj()); VisitForAccumulatorValue(prop->key()); - __ Peek(x1, 0); - __ Push(x0); + ASSERT(x0.is(KeyedLoadIC::NameRegister())); + __ Peek(KeyedLoadIC::ReceiverRegister(), 0); + __ Push(KeyedLoadIC::NameRegister()); EmitKeyedPropertyLoad(prop); } } @@ -4084,8 +4088,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { VariableProxy* proxy = expr->AsVariableProxy(); if (proxy != NULL && proxy->var()->IsUnallocated()) { Comment cmnt(masm_, "Global variable"); - __ Ldr(x0, GlobalObjectMemOperand()); - __ Mov(x2, Operand(proxy->name())); + __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand()); + __ Mov(LoadIC::NameRegister(), Operand(proxy->name())); // Use a regular load, not a contextual load, to avoid a reference // error. CallLoadIC(NOT_CONTEXTUAL); @@ -4433,14 +4437,19 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // receiver = iter; f = 'next'; arg = received; __ Bind(&l_next); + Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); + Register keyedload_name = KeyedLoadIC::NameRegister(); + ASSERT(keyedload_receiver.is(x1)); + ASSERT(keyedload_name.is(x0)); + __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next" __ Peek(x3, 1 * kPointerSize); // iter __ Push(x2, x3, x0); // "next", iter, received // result = receiver[f](arg); __ Bind(&l_call); - __ Peek(x1, 1 * kPointerSize); - __ Peek(x0, 2 * kPointerSize); + __ Peek(keyedload_receiver, 1 * kPointerSize); + __ Peek(keyedload_name, 2 * kPointerSize); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ Mov(x1, x0); @@ -4453,19 +4462,23 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ Bind(&l_loop); - __ Push(x0); // save result - __ LoadRoot(x2, Heap::kdone_stringRootIndex); // "done" - CallLoadIC(NOT_CONTEXTUAL); // result.done in x0 + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + ASSERT(load_receiver.is(x0)); + ASSERT(load_name.is(x2)); + __ Push(load_receiver); // save result + __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" + CallLoadIC(NOT_CONTEXTUAL); // x0=result.done // The ToBooleanStub argument (result.done) is in x0. Handle bool_ic = ToBooleanStub::GetUninitialized(isolate()); CallIC(bool_ic); __ Cbz(x0, &l_try); // result.value - __ Pop(x0); // result - __ LoadRoot(x2, Heap::kvalue_stringRootIndex); // "value" - CallLoadIC(NOT_CONTEXTUAL); // result.value in x0 - context()->DropAndPlug(2, x0); // drop iter and g + __ Pop(load_receiver); // result + __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" + CallLoadIC(NOT_CONTEXTUAL); // x0=result.value + context()->DropAndPlug(2, x0); // drop iter and g break; } } diff --git a/src/arm64/ic-arm64.cc b/src/arm64/ic-arm64.cc index d42e68a36c..f1de3fa790 100644 --- a/src/arm64/ic-arm64.cc +++ b/src/arm64/ic-arm64.cc @@ -412,6 +412,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // -- lr : return address // -- x0 : receiver // ----------------------------------- + ASSERT(x0.is(ReceiverRegister())); + ASSERT(x2.is(NameRegister())); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); @@ -429,6 +431,8 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // -- lr : return address // -- x0 : receiver // ----------------------------------- + ASSERT(x0.is(ReceiverRegister())); + ASSERT(x2.is(NameRegister())); Label miss, slow; GenerateNameDictionaryReceiverCheck(masm, x0, x1, x3, x4, &miss); @@ -448,18 +452,14 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- x2 : name - // -- lr : return address - // -- x0 : receiver - // ----------------------------------- + // The return address is on the stack. Isolate* isolate = masm->isolate(); ASM_LOCATION("LoadIC::GenerateMiss"); __ IncrementCounter(isolate->counters()->load_miss(), 1, x3, x4); // Perform tail call to the entry. - __ Push(x0, x2); + __ Push(ReceiverRegister(), NameRegister()); ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate); __ TailCallExternalReference(ref, 2, 1); @@ -467,13 +467,8 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- x2 : name - // -- lr : return address - // -- x0 : receiver - // ----------------------------------- - - __ Push(x0, x2); + // The return address is on the stack. + __ Push(ReceiverRegister(), NameRegister()); __ TailCallRuntime(Runtime::kGetProperty, 2, 1); } @@ -485,8 +480,11 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { // -- x1 : receiver // ----------------------------------- Register result = x0; - Register key = x0; - Register receiver = x1; + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + ASSERT(receiver.is(x1)); + ASSERT(key.is(x0)); + Label miss, unmapped; Register map_scratch = x2; @@ -518,7 +516,6 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { // -- x1 : key // -- x2 : receiver // ----------------------------------- - Label slow, notin; Register value = x0; @@ -563,16 +560,12 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key - // -- x1 : receiver - // ----------------------------------- + // The return address is on the stack. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11); - __ Push(x1, x0); + __ Push(ReceiverRegister(), NameRegister()); // Perform tail call to the entry. ExternalReference ref = @@ -590,15 +583,8 @@ const Register KeyedLoadIC::NameRegister() { return x0; } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key - // -- x1 : receiver - // ----------------------------------- - Register key = x0; - Register receiver = x1; - - __ Push(receiver, key); + // The return address is on the stack. + __ Push(ReceiverRegister(), NameRegister()); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); } @@ -774,8 +760,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // ----------------------------------- Label slow, check_name, index_smi, index_name; - Register key = x0; - Register receiver = x1; + Register key = NameRegister(); + Register receiver = ReceiverRegister(); + ASSERT(key.is(x0)); + ASSERT(receiver.is(x1)); __ JumpIfNotSmi(key, &check_name); __ Bind(&index_smi); @@ -802,17 +790,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key (index) - // -- x1 : receiver - // ----------------------------------- + // Return address is on the stack. Label miss; - Register index = x0; - Register receiver = x1; + Register receiver = ReceiverRegister(); + Register index = NameRegister(); Register result = x0; Register scratch = x3; + ASSERT(!scratch.is(receiver) && !scratch.is(index)); StringCharAtGenerator char_at_generator(receiver, index, @@ -834,14 +819,15 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key - // -- x1 : receiver - // ----------------------------------- + // Return address is on the stack. Label slow; - Register key = x0; - Register receiver = x1; + + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + Register scratch1 = x2; + Register scratch2 = x3; + ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); + ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); // Check that the receiver isn't a smi. __ JumpIfSmi(receiver, &slow); @@ -850,16 +836,16 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { __ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow); // Get the map of the receiver. - Register map = x2; + Register map = scratch1; __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); // Check that it has indexed interceptor and access checks // are not enabled for this object. - __ Ldrb(x3, FieldMemOperand(map, Map::kBitFieldOffset)); + __ Ldrb(scratch2, FieldMemOperand(map, Map::kBitFieldOffset)); ASSERT(kSlowCaseBitFieldMask == ((1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor))); - __ Tbnz(x3, Map::kIsAccessCheckNeeded, &slow); - __ Tbz(x3, Map::kHasIndexedInterceptor, &slow); + __ Tbnz(scratch2, Map::kIsAccessCheckNeeded, &slow); + __ Tbz(scratch2, Map::kHasIndexedInterceptor, &slow); // Everything is fine, call runtime. __ Push(receiver, key); diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 2af833b4ec..a5d59be6f1 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -1658,7 +1658,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* global_object = UseFixed(instr->global_object(), x0); + LOperand* global_object = UseFixed(instr->global_object(), + LoadIC::ReceiverRegister()); LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(context, global_object); return MarkAsCall(DefineFixed(result, x0), instr); @@ -1714,8 +1715,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), x1); - LOperand* key = UseFixed(instr->key(), x0); + LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); LInstruction* result = DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), x0); @@ -1731,7 +1732,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), x0); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(context, object), x0); return MarkAsCall(result, instr); diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 3925923a09..3f33089dae 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -3399,9 +3399,9 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->global_object()).Is(x0)); + ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).Is(x0)); - __ Mov(x2, Operand(instr->name())); + __ Mov(LoadIC::NameRegister(), Operand(instr->name())); ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; Handle ic = LoadIC::initialize_stub(isolate(), mode); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -3653,8 +3653,8 @@ void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).Is(x1)); - ASSERT(ToRegister(instr->key()).Is(x0)); + ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -3704,9 +3704,10 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - // LoadIC expects x2 to hold the name, and x0 to hold the receiver. + // LoadIC expects name and receiver in registers. + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->object()).is(x0)); - __ Mov(x2, Operand(instr->name())); + __ Mov(LoadIC::NameRegister(), Operand(instr->name())); Handle ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); CallCode(ic, RelocInfo::CODE_TARGET, instr); diff --git a/src/arm64/stub-cache-arm64.cc b/src/arm64/stub-cache-arm64.cc index 211c8923ee..dc0220cada 100644 --- a/src/arm64/stub-cache-arm64.cc +++ b/src/arm64/stub-cache-arm64.cc @@ -1454,6 +1454,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( // -- x0 : key // -- x1 : receiver // ----------------------------------- + ASSERT(x1.is(KeyedLoadIC::ReceiverRegister())); + ASSERT(x0.is(KeyedLoadIC::NameRegister())); Label slow, miss; Register result = x0; diff --git a/src/code-stubs.cc b/src/code-stubs.cc index f60e0a7a08..0ac07de0dd 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -614,6 +614,36 @@ void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( } +void LoadFieldStub::InitializeInterfaceDescriptor( + CodeStubInterfaceDescriptor* descriptor) { + Register registers[] = { LoadIC::ReceiverRegister() }; + descriptor->Initialize(ARRAY_SIZE(registers), registers); +} + + +void KeyedLoadFieldStub::InitializeInterfaceDescriptor( + CodeStubInterfaceDescriptor* descriptor) { + Register registers[] = { KeyedLoadIC::ReceiverRegister() }; + descriptor->Initialize(ARRAY_SIZE(registers), registers); +} + + +void StringLengthStub::InitializeInterfaceDescriptor( + CodeStubInterfaceDescriptor* descriptor) { + Register registers[] = { LoadIC::ReceiverRegister(), + LoadIC::NameRegister() }; + descriptor->Initialize(ARRAY_SIZE(registers), registers); +} + + +void KeyedStringLengthStub::InitializeInterfaceDescriptor( + CodeStubInterfaceDescriptor* descriptor) { + Register registers[] = { KeyedLoadIC::ReceiverRegister(), + KeyedLoadIC::NameRegister() }; + descriptor->Initialize(ARRAY_SIZE(registers), registers); +} + + void KeyedLoadDictionaryElementPlatformStub::Generate( MacroAssembler* masm) { KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index c3738ccbeb..a39952a2df 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -93,34 +93,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor( } -void LoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { edx }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedLoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { edx }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void StringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { edx, ecx }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedStringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { edx, ecx }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { Register registers[] = { edx, ecx, eax }; diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc index 7572d3e0dd..e641905913 100644 --- a/src/ia32/debug-ia32.cc +++ b/src/ia32/debug-ia32.cc @@ -180,11 +180,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Register state for IC load call (from ic-ia32.cc). - // ----------- S t a t e ------------- - // -- ecx : name - // -- edx : receiver - // ----------------------------------- - Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false); + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); } @@ -202,11 +200,9 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { // Register state for keyed IC load call (from ic-ia32.cc). - // ----------- S t a t e ------------- - // -- ecx : key - // -- edx : receiver - // ----------------------------------- - Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false); + Register receiver = KeyedLoadIC::ReceiverRegister(); + Register name = KeyedLoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); } diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 772cfbaba7..31066f0849 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -1337,8 +1337,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, // All extension objects were empty and it is safe to use a global // load IC call. - __ mov(edx, GlobalObjectOperand()); - __ mov(ecx, var->name()); + __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadIC::NameRegister(), var->name()); ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL : CONTEXTUAL; @@ -1418,10 +1418,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { switch (var->location()) { case Variable::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - // Use inline caching. Variable name is passed in ecx and the global - // object in eax. - __ mov(edx, GlobalObjectOperand()); - __ mov(ecx, var->name()); + __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadIC::NameRegister(), var->name()); CallLoadIC(CONTEXTUAL); context()->Plug(eax); break; @@ -2011,14 +2009,20 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // receiver = iter; f = iter.next; arg = received; __ bind(&l_next); - __ mov(ecx, isolate()->factory()->next_string()); // "next" - __ push(ecx); + Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); + Register keyedload_name = KeyedLoadIC::NameRegister(); + ASSERT(keyedload_receiver.is(edx)); + ASSERT(keyedload_name.is(ecx)); + + __ mov(keyedload_name, + isolate()->factory()->next_string()); // "next" + __ push(keyedload_name); __ push(Operand(esp, 2 * kPointerSize)); // iter __ push(eax); // received // result = receiver[f](arg); __ bind(&l_call); - __ mov(edx, Operand(esp, kPointerSize)); + __ mov(keyedload_receiver, Operand(esp, kPointerSize)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ mov(edi, eax); @@ -2032,8 +2036,13 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ bind(&l_loop); __ push(eax); // save result - __ mov(edx, eax); // result - __ mov(ecx, isolate()->factory()->done_string()); // "done" + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + ASSERT(load_receiver.is(edx)); + ASSERT(load_name.is(ecx)); + __ mov(load_receiver, eax); // result + __ mov(load_name, + isolate()->factory()->done_string()); // "done" CallLoadIC(NOT_CONTEXTUAL); // result.done in eax Handle bool_ic = ToBooleanStub::GetUninitialized(isolate()); CallIC(bool_ic); @@ -2041,8 +2050,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { __ j(zero, &l_try); // result.value - __ pop(edx); // result - __ mov(ecx, isolate()->factory()->value_string()); // "value" + __ pop(load_receiver); // result + __ mov(load_name, + isolate()->factory()->value_string()); // "value" CallLoadIC(NOT_CONTEXTUAL); // result.value in eax context()->DropAndPlug(2, eax); // drop iter and g break; @@ -2202,7 +2212,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); ASSERT(!key->value()->IsSmi()); - __ mov(ecx, Immediate(key->value())); + __ mov(LoadIC::NameRegister(), Immediate(key->value())); CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); } @@ -2500,15 +2510,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); - __ mov(edx, result_register()); + __ mov(LoadIC::ReceiverRegister(), result_register()); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(eax); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ pop(edx); // Object. - __ mov(ecx, result_register()); // Key. + __ pop(KeyedLoadIC::ReceiverRegister()); // Object. + __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key. EmitKeyedPropertyLoad(expr); context()->Plug(eax); } @@ -2541,7 +2551,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } else { // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ mov(edx, Operand(esp, 0)); + __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. @@ -2563,9 +2573,9 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ mov(edx, Operand(esp, 0)); + __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); // Move the key into the right register for the keyed load IC. - __ mov(ecx, eax); + __ mov(KeyedLoadIC::NameRegister(), eax); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -4023,8 +4033,8 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); // Load the function from the receiver. - __ mov(edx, Operand(esp, 0)); - __ mov(ecx, Immediate(expr->name())); + __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); + __ mov(LoadIC::NameRegister(), Immediate(expr->name())); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); // Push the target function under the receiver. @@ -4207,14 +4217,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { if (assign_type == NAMED_PROPERTY) { // Put the object both on the stack and in edx. VisitForAccumulatorValue(prop->obj()); + ASSERT(!eax.is(LoadIC::ReceiverRegister())); __ push(eax); - __ mov(edx, eax); + __ mov(LoadIC::ReceiverRegister(), eax); EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); VisitForStackValue(prop->key()); - __ mov(edx, Operand(esp, kPointerSize)); // Object. - __ mov(ecx, Operand(esp, 0)); // Key. + __ mov(KeyedLoadIC::ReceiverRegister(), + Operand(esp, kPointerSize)); // Object. + __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key. EmitKeyedPropertyLoad(prop); } } @@ -4371,8 +4383,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { if (proxy != NULL && proxy->var()->IsUnallocated()) { Comment cmnt(masm_, "[ Global variable"); - __ mov(edx, GlobalObjectOperand()); - __ mov(ecx, Immediate(proxy->name())); + __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ mov(LoadIC::NameRegister(), Immediate(proxy->name())); // Use a regular load, not a contextual load, to avoid a reference // error. CallLoadIC(NOT_CONTEXTUAL); diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc index 0b3d110d11..f2899964e4 100644 --- a/src/ia32/ic-ia32.cc +++ b/src/ia32/ic-ia32.cc @@ -388,6 +388,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // -- edx : receiver // -- esp[0] : return address // ----------------------------------- + ASSERT(edx.is(ReceiverRegister())); + ASSERT(ecx.is(NameRegister())); Label slow, check_name, index_smi, index_name, property_array_property; Label probe_dictionary, check_number_dictionary; @@ -560,18 +562,25 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { } +// 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) { - // ----------- S t a t e ------------- - // -- ecx : key (index) - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- + // Return address is on the stack. Label miss; - Register receiver = edx; - Register index = ecx; - Register scratch = ebx; + Register receiver = ReceiverRegister(); + Register index = NameRegister(); + Register scratch = KeyedLoadIC_TempRegister(); Register result = eax; + ASSERT(!result.is(scratch)); StringCharAtGenerator char_at_generator(receiver, index, @@ -593,35 +602,36 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- + // Return address is on the stack. Label slow; + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + Register scratch = eax; + ASSERT(!scratch.is(receiver) && !scratch.is(key)); + // Check that the receiver isn't a smi. - __ JumpIfSmi(edx, &slow); + __ JumpIfSmi(receiver, &slow); // Check that the key is an array index, that is Uint32. - __ test(ecx, Immediate(kSmiTagMask | kSmiSignMask)); + __ test(key, Immediate(kSmiTagMask | kSmiSignMask)); __ j(not_zero, &slow); // Get the map of the receiver. - __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset)); + __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); // Check that it has indexed interceptor and access checks // are not enabled for this object. - __ movzx_b(eax, FieldOperand(eax, Map::kBitFieldOffset)); - __ and_(eax, Immediate(kSlowCaseBitFieldMask)); - __ cmp(eax, Immediate(1 << Map::kHasIndexedInterceptor)); + __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); + __ and_(scratch, Immediate(kSlowCaseBitFieldMask)); + __ cmp(scratch, Immediate(1 << Map::kHasIndexedInterceptor)); __ j(not_zero, &slow); // Everything is fine, call runtime. - __ pop(eax); - __ push(edx); // receiver - __ push(ecx); // key - __ push(eax); // return address + __ pop(scratch); + __ push(receiver); // receiver + __ push(key); // key + __ push(scratch); // return address // Perform tail call to the entry. ExternalReference ref = @@ -640,6 +650,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { // -- edx : receiver // -- esp[0] : return address // ----------------------------------- + ASSERT(edx.is(ReceiverRegister())); + ASSERT(ecx.is(NameRegister())); Label slow, notin; Factory* factory = masm->isolate()->factory(); Operand mapped_location = @@ -930,6 +942,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // -- edx : receiver // -- esp[0] : return address // ----------------------------------- + ASSERT(edx.is(ReceiverRegister())); + ASSERT(ecx.is(NameRegister())); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); @@ -947,6 +961,9 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // -- edx : receiver // -- esp[0] : return address // ----------------------------------- + ASSERT(edx.is(ReceiverRegister())); + ASSERT(ecx.is(NameRegister())); + Label miss, slow; GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); @@ -967,18 +984,13 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : name - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - + // Return address is on the stack. __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); - __ pop(ebx); - __ push(edx); // receiver - __ push(ecx); // name - __ push(ebx); // return address + __ pop(LoadIC_TempRegister()); + __ push(ReceiverRegister()); // receiver + __ push(NameRegister()); // name + __ push(LoadIC_TempRegister()); // return address // Perform tail call to the entry. ExternalReference ref = @@ -988,16 +1000,11 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - - __ pop(ebx); - __ push(edx); // receiver - __ push(ecx); // name - __ push(ebx); // return address + // Return address is on the stack. + __ pop(LoadIC_TempRegister()); + __ push(ReceiverRegister()); // receiver + __ push(NameRegister()); // name + __ push(LoadIC_TempRegister()); // return address // Perform tail call to the entry. __ TailCallRuntime(Runtime::kGetProperty, 2, 1); @@ -1005,18 +1012,13 @@ void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - + // Return address is on the stack. __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1); - __ pop(ebx); - __ push(edx); // receiver - __ push(ecx); // name - __ push(ebx); // return address + __ pop(KeyedLoadIC_TempRegister()); + __ push(ReceiverRegister()); // receiver + __ push(NameRegister()); // name + __ push(KeyedLoadIC_TempRegister()); // return address // Perform tail call to the entry. ExternalReference ref = @@ -1039,16 +1041,11 @@ const Register KeyedLoadIC::NameRegister() { return LoadIC::NameRegister(); } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - - __ pop(ebx); - __ push(edx); // receiver - __ push(ecx); // name - __ push(ebx); // return address + // Return address is on the stack. + __ pop(KeyedLoadIC_TempRegister()); + __ push(ReceiverRegister()); // receiver + __ push(NameRegister()); // name + __ push(KeyedLoadIC_TempRegister()); // return address // Perform tail call to the entry. __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 334386ba4b..8bb53f9d81 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -2832,10 +2832,10 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { ASSERT(ToRegister(instr->context()).is(esi)); - ASSERT(ToRegister(instr->global_object()).is(edx)); + ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(eax)); - __ mov(ecx, instr->name()); + __ mov(LoadIC::NameRegister(), instr->name()); ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; Handle ic = LoadIC::initialize_stub(isolate(), mode); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -2966,10 +2966,10 @@ void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(esi)); - ASSERT(ToRegister(instr->object()).is(edx)); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(eax)); - __ mov(ecx, instr->name()); + __ mov(LoadIC::NameRegister(), instr->name()); Handle ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3207,8 +3207,8 @@ Operand LCodeGen::BuildFastArrayOperand( void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(esi)); - ASSERT(ToRegister(instr->object()).is(edx)); - ASSERT(ToRegister(instr->key()).is(ecx)); + ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index d5118fb0e1..a18528c5a9 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2090,7 +2090,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LOperand* context = UseFixed(instr->context(), esi); - LOperand* global_object = UseFixed(instr->global_object(), edx); + LOperand* global_object = UseFixed(instr->global_object(), + LoadIC::ReceiverRegister()); LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(context, global_object); return MarkAsCall(DefineFixed(result, eax), instr); @@ -2145,7 +2146,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LOperand* context = UseFixed(instr->context(), esi); - LOperand* object = UseFixed(instr->object(), edx); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object); return MarkAsCall(DefineFixed(result, eax), instr); } @@ -2203,8 +2204,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), esi); - LOperand* object = UseFixed(instr->object(), edx); - LOperand* key = UseFixed(instr->key(), ecx); + LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); LLoadKeyedGeneric* result = new(zone()) LLoadKeyedGeneric(context, object, key); diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index a69619495b..ca6a5bbb31 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -1454,6 +1454,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( // -- edx : receiver // -- esp[0] : return address // ----------------------------------- + ASSERT(edx.is(KeyedLoadIC::ReceiverRegister())); + ASSERT(ecx.is(KeyedLoadIC::NameRegister())); Label slow, miss; // This stub is meant to be tail-jumped to, the receiver must already diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 935571846f..e8ff2446c6 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -89,34 +89,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor( } -void LoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { rax }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedLoadFieldStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { rdx }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void StringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { rax, rcx }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - -void KeyedStringLengthStub::InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { rdx, rax }; - descriptor->Initialize(ARRAY_SIZE(registers), registers); -} - - void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { Register registers[] = { rdx, rcx, rax }; diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc index 4703e42354..f0f8198c16 100644 --- a/src/x64/debug-x64.cc +++ b/src/x64/debug-x64.cc @@ -162,11 +162,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { // Register state for IC load call (from ic-x64.cc). - // ----------- S t a t e ------------- - // -- rax : receiver - // -- rcx : name - // ----------------------------------- - Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), 0, false); + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); } @@ -184,11 +182,9 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { // Register state for keyed IC load call (from ic-x64.cc). - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // ----------------------------------- - Generate_DebugBreakCallHelper(masm, rax.bit() | rdx.bit(), 0, false); + Register receiver = KeyedLoadIC::ReceiverRegister(); + Register name = KeyedLoadIC::NameRegister(); + Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); } diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 55a57d7a81..67c959fe38 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -1372,8 +1372,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, // All extension objects were empty and it is safe to use a global // load IC call. - __ movp(rax, GlobalObjectOperand()); - __ Move(rcx, var->name()); + __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); + __ Move(LoadIC::NameRegister(), var->name()); ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL : CONTEXTUAL; @@ -1452,10 +1452,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { switch (var->location()) { case Variable::UNALLOCATED: { Comment cmnt(masm_, "[ Global variable"); - // Use inline caching. Variable name is passed in rcx and the global - // object on the stack. - __ Move(rcx, var->name()); - __ movp(rax, GlobalObjectOperand()); + __ Move(LoadIC::NameRegister(), var->name()); + __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); CallLoadIC(CONTEXTUAL); context()->Plug(rax); break; @@ -2044,6 +2042,11 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // receiver = iter; f = 'next'; arg = received; __ bind(&l_next); + Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); + Register keyedload_name = KeyedLoadIC::NameRegister(); + ASSERT(keyedload_receiver.is(rdx)); + ASSERT(keyedload_name.is(rax)); + __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next" __ Push(rcx); __ Push(Operand(rsp, 2 * kPointerSize)); // iter @@ -2051,8 +2054,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // result = receiver[f](arg); __ bind(&l_call); - __ movp(rdx, Operand(rsp, kPointerSize)); - __ movp(rax, Operand(rsp, 2 * kPointerSize)); + __ movp(keyedload_receiver, Operand(rsp, kPointerSize)); + __ movp(keyedload_name, Operand(rsp, 2 * kPointerSize)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ movp(rdi, rax); @@ -2065,17 +2068,22 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ bind(&l_loop); - __ Push(rax); // save result - __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" - CallLoadIC(NOT_CONTEXTUAL); // result.done in rax + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + ASSERT(load_receiver.is(rax)); + ASSERT(load_name.is(rcx)); + + __ Push(load_receiver); // save result + __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" + CallLoadIC(NOT_CONTEXTUAL); // rax=result.done Handle bool_ic = ToBooleanStub::GetUninitialized(isolate()); CallIC(bool_ic); __ testp(result_register(), result_register()); __ j(zero, &l_try); // result.value - __ Pop(rax); // result - __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" + __ Pop(load_receiver); // result + __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" CallLoadIC(NOT_CONTEXTUAL); // result.value in rax context()->DropAndPlug(2, rax); // drop iter and g break; @@ -2236,7 +2244,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { SetSourcePosition(prop->position()); Literal* key = prop->key()->AsLiteral(); - __ Move(rcx, key->value()); + __ Move(LoadIC::NameRegister(), key->value()); CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); } @@ -2495,13 +2503,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); + ASSERT(rax.is(LoadIC::ReceiverRegister())); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(rax); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ Pop(rdx); + ASSERT(rax.is(KeyedLoadIC::NameRegister())); + __ Pop(KeyedLoadIC::ReceiverRegister()); EmitKeyedPropertyLoad(expr); context()->Plug(rax); } @@ -2534,7 +2544,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { } else { // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ movp(rax, Operand(rsp, 0)); + __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. @@ -2551,12 +2561,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { // Load the key. VisitForAccumulatorValue(key); + ASSERT(rax.is(KeyedLoadIC::NameRegister())); Expression* callee = expr->expression(); // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ movp(rdx, Operand(rsp, 0)); + __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -4034,8 +4045,8 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); // Load the function from the receiver. - __ movp(rax, Operand(rsp, 0)); - __ Move(rcx, expr->name()); + __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); + __ Move(LoadIC::NameRegister(), expr->name()); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); // Push the target function under the receiver. @@ -4214,13 +4225,17 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } if (assign_type == NAMED_PROPERTY) { VisitForAccumulatorValue(prop->obj()); + ASSERT(rax.is(LoadIC::ReceiverRegister())); __ Push(rax); // Copy of receiver, needed for later store. EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); VisitForAccumulatorValue(prop->key()); - __ movp(rdx, Operand(rsp, 0)); // Leave receiver on stack - __ Push(rax); // Copy of key, needed for later store. + ASSERT(rax.is(KeyedLoadIC::NameRegister())); + // Leave receiver on stack + __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); + // Copy of key, needed for later store. + __ Push(KeyedLoadIC::NameRegister()); EmitKeyedPropertyLoad(prop); } } @@ -4373,8 +4388,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { if (proxy != NULL && proxy->var()->IsUnallocated()) { Comment cmnt(masm_, "[ Global variable"); - __ Move(rcx, proxy->name()); - __ movp(rax, GlobalObjectOperand()); + __ Move(LoadIC::NameRegister(), proxy->name()); + __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); // Use a regular load, not a contextual load, to avoid a reference // error. CallLoadIC(NOT_CONTEXTUAL); diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc index 60403c6cfb..a03eba17f8 100644 --- a/src/x64/ic-x64.cc +++ b/src/x64/ic-x64.cc @@ -332,6 +332,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- + ASSERT(rdx.is(ReceiverRegister())); + ASSERT(rax.is(NameRegister())); Label slow, check_name, index_smi, index_name, property_array_property; Label probe_dictionary, check_number_dictionary; @@ -490,17 +492,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- + // Return address is on the stack. Label miss; - Register receiver = rdx; - Register index = rax; + Register receiver = ReceiverRegister(); + Register index = NameRegister(); Register scratch = rcx; Register result = rax; + ASSERT(!scratch.is(receiver) && !scratch.is(index)); StringCharAtGenerator char_at_generator(receiver, index, @@ -522,35 +521,36 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- + // Return address is on the stack. Label slow; + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + Register scratch = rcx; + ASSERT(!scratch.is(receiver) && !scratch.is(key)); + // Check that the receiver isn't a smi. - __ JumpIfSmi(rdx, &slow); + __ JumpIfSmi(receiver, &slow); // Check that the key is an array index, that is Uint32. STATIC_ASSERT(kSmiValueSize <= 32); - __ JumpUnlessNonNegativeSmi(rax, &slow); + __ JumpUnlessNonNegativeSmi(key, &slow); // Get the map of the receiver. - __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); + __ movp(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); // Check that it has indexed interceptor and access checks // are not enabled for this object. - __ movb(rcx, FieldOperand(rcx, Map::kBitFieldOffset)); - __ andb(rcx, Immediate(kSlowCaseBitFieldMask)); - __ cmpb(rcx, Immediate(1 << Map::kHasIndexedInterceptor)); + __ movb(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); + __ andb(scratch, Immediate(kSlowCaseBitFieldMask)); + __ cmpb(scratch, Immediate(1 << Map::kHasIndexedInterceptor)); __ j(not_zero, &slow); // Everything is fine, call runtime. - __ PopReturnAddressTo(rcx); - __ Push(rdx); // receiver - __ Push(rax); // key - __ PushReturnAddressFrom(rcx); + __ PopReturnAddressTo(scratch); + __ Push(receiver); // receiver + __ Push(key); // key + __ PushReturnAddressFrom(scratch); // Perform tail call to the entry. __ TailCallExternalReference( @@ -892,6 +892,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- + ASSERT(rdx.is(ReceiverRegister())); + ASSERT(rax.is(NameRegister())); Label slow, notin; Operand mapped_location = GenerateMappedArgumentsLookup( @@ -956,6 +958,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { // -- rcx : name // -- rsp[0] : return address // ----------------------------------- + ASSERT(rax.is(ReceiverRegister())); + ASSERT(rcx.is(NameRegister())); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); @@ -972,6 +976,8 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // -- rcx : name // -- rsp[0] : return address // ----------------------------------- + ASSERT(rax.is(ReceiverRegister())); + ASSERT(rcx.is(NameRegister())); Label miss, slow; GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); @@ -991,20 +997,25 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { } +// A register that isn't one of the parameters to the load ic. +static const Register LoadIC_TempRegister() { return rbx; } + + +static const Register KeyedLoadIC_TempRegister() { + return rbx; +} + + void LoadIC::GenerateMiss(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : receiver - // -- rcx : name - // -- rsp[0] : return address - // ----------------------------------- + // The return address is on the stack. Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->load_miss(), 1); - __ PopReturnAddressTo(rbx); - __ Push(rax); // receiver - __ Push(rcx); // name - __ PushReturnAddressFrom(rbx); + __ PopReturnAddressTo(LoadIC_TempRegister()); + __ Push(ReceiverRegister()); // receiver + __ Push(NameRegister()); // name + __ PushReturnAddressFrom(LoadIC_TempRegister()); // Perform tail call to the entry. ExternalReference ref = @@ -1014,16 +1025,12 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : receiver - // -- rcx : name - // -- rsp[0] : return address - // ----------------------------------- + // The return address is on the stack. - __ PopReturnAddressTo(rbx); - __ Push(rax); // receiver - __ Push(rcx); // name - __ PushReturnAddressFrom(rbx); + __ PopReturnAddressTo(LoadIC_TempRegister()); + __ Push(ReceiverRegister()); // receiver + __ Push(NameRegister()); // name + __ PushReturnAddressFrom(LoadIC_TempRegister()); // Perform tail call to the entry. __ TailCallRuntime(Runtime::kGetProperty, 2, 1); @@ -1031,19 +1038,14 @@ void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- - + // The return address is on the stack. Counters* counters = masm->isolate()->counters(); __ IncrementCounter(counters->keyed_load_miss(), 1); - __ PopReturnAddressTo(rbx); - __ Push(rdx); // receiver - __ Push(rax); // name - __ PushReturnAddressFrom(rbx); + __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); + __ Push(ReceiverRegister()); // receiver + __ Push(NameRegister()); // name + __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); // Perform tail call to the entry. ExternalReference ref = @@ -1060,16 +1062,12 @@ const Register KeyedLoadIC::NameRegister() { return rax; } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- + // The return address is on the stack. - __ PopReturnAddressTo(rbx); - __ Push(rdx); // receiver - __ Push(rax); // name - __ PushReturnAddressFrom(rbx); + __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); + __ Push(ReceiverRegister()); // receiver + __ Push(NameRegister()); // name + __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); // Perform tail call to the entry. __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 65dce51646..04d555168b 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -2849,10 +2849,10 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { ASSERT(ToRegister(instr->context()).is(rsi)); - ASSERT(ToRegister(instr->global_object()).is(rax)); + ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(rax)); - __ Move(rcx, instr->name()); + __ Move(LoadIC::NameRegister(), instr->name()); ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; Handle ic = LoadIC::initialize_stub(isolate(), mode); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -2989,10 +2989,10 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(rsi)); - ASSERT(ToRegister(instr->object()).is(rax)); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); ASSERT(ToRegister(instr->result()).is(rax)); - __ Move(rcx, instr->name()); + __ Move(LoadIC::NameRegister(), instr->name()); Handle ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3286,8 +3286,8 @@ Operand LCodeGen::BuildFastArrayOperand( void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(rsi)); - ASSERT(ToRegister(instr->object()).is(rdx)); - ASSERT(ToRegister(instr->key()).is(rax)); + ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 6d772c01c6..c1022fbc17 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -2040,7 +2040,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LOperand* context = UseFixed(instr->context(), rsi); - LOperand* global_object = UseFixed(instr->global_object(), rax); + LOperand* global_object = UseFixed(instr->global_object(), + LoadIC::ReceiverRegister()); LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(context, global_object); return MarkAsCall(DefineFixed(result, rax), instr); @@ -2107,7 +2108,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LOperand* context = UseFixed(instr->context(), rsi); - LOperand* object = UseFixed(instr->object(), rax); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object); return MarkAsCall(DefineFixed(result, rax), instr); } @@ -2193,8 +2194,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), rsi); - LOperand* object = UseFixed(instr->object(), rdx); - LOperand* key = UseFixed(instr->key(), rax); + LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); LLoadKeyedGeneric* result = new(zone()) LLoadKeyedGeneric(context, object, key); diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index 2356f584a6..f7b2fe5b40 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1398,6 +1398,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- + ASSERT(rdx.is(KeyedLoadIC::ReceiverRegister())); + ASSERT(rax.is(KeyedLoadIC::NameRegister())); Label slow, miss; // This stub is meant to be tail-jumped to, the receiver must already