From 351ed4c8a1a6e58fe78e5b140f6c76c4c6f79d8a Mon Sep 17 00:00:00 2001 From: "mvstanton@chromium.org" Date: Mon, 30 Jun 2014 15:56:50 +0000 Subject: [PATCH] KeyedLoadIC should have same register spec as LoadIC. On arm, arm64 and x64 there is a different register specification between LoadIC and KeyedLoadIC. It would be nicer if these are the same, allowing some key optimizations. R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/338963003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22103 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 24 ++--- src/arm/debug-arm.cc | 4 +- src/arm/full-codegen-arm.cc | 72 +++++++------- src/arm/ic-arm.cc | 148 +++++++++++++---------------- src/arm/lithium-arm.cc | 4 +- src/arm/lithium-codegen-arm.cc | 4 +- src/arm/stub-cache-arm.cc | 36 +++---- src/arm64/code-stubs-arm64.cc | 25 ++--- src/arm64/debug-arm64.cc | 4 +- src/arm64/full-codegen-arm64.cc | 65 ++++++------- src/arm64/ic-arm64.cc | 81 +++++++--------- src/arm64/lithium-arm64.cc | 4 +- src/arm64/lithium-codegen-arm64.cc | 5 +- src/arm64/stub-cache-arm64.cc | 26 +++-- src/code-stubs.cc | 24 ++--- src/ia32/builtins-ia32.cc | 18 ++-- src/ia32/debug-ia32.cc | 4 +- src/ia32/full-codegen-ia32.cc | 65 ++++++------- src/ia32/ic-ia32.cc | 105 +++++++++----------- src/ia32/lithium-codegen-ia32.cc | 4 +- src/ia32/lithium-ia32.cc | 4 +- src/ia32/stub-cache-ia32.cc | 8 +- src/ic.h | 3 - src/x64/builtins-x64.cc | 18 ++-- src/x64/code-stubs-x64.cc | 23 ++--- src/x64/debug-x64.cc | 4 +- src/x64/full-codegen-x64.cc | 67 ++++++------- src/x64/ic-x64.cc | 140 +++++++++++++-------------- src/x64/lithium-codegen-x64.cc | 4 +- src/x64/lithium-x64.cc | 4 +- src/x64/stub-cache-x64.cc | 30 +++--- 31 files changed, 443 insertions(+), 584 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index f50e7dd2dd..e1f39fa925 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -1856,25 +1856,15 @@ void InstanceofStub::Generate(MacroAssembler* masm) { void FunctionPrototypeStub::Generate(MacroAssembler* masm) { Label miss; - Register receiver; + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + + ASSERT(kind() == Code::LOAD_IC || + kind() == Code::KEYED_LOAD_IC); + if (kind() == Code::KEYED_LOAD_IC) { - // ----------- S t a t e ------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- - __ cmp(r0, Operand(isolate()->factory()->prototype_string())); + __ cmp(name, Operand(isolate()->factory()->prototype_string())); __ b(ne, &miss); - receiver = r1; - } else { - ASSERT(kind() == Code::LOAD_IC); - // ----------- S t a t e ------------- - // -- r2 : name - // -- lr : return address - // -- r0 : receiver - // -- sp[0] : receiver - // ----------------------------------- - receiver = r0; } StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r3, r4, &miss); diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc index aad40c2f38..8526dd0681 100644 --- a/src/arm/debug-arm.cc +++ b/src/arm/debug-arm.cc @@ -198,9 +198,7 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { // 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); + GenerateLoadICDebugBreak(masm); } diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index f1e6380a5c..dd2cab4d18 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -1857,9 +1857,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { break; case NAMED_PROPERTY: if (expr->is_compound()) { - // We need the receiver both on the stack and in the accumulator. - VisitForAccumulatorValue(property->obj()); - __ push(result_register()); + // We need the receiver both on the stack and in the register. + VisitForStackValue(property->obj()); + __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); } else { VisitForStackValue(property->obj()); } @@ -1867,9 +1867,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case KEYED_PROPERTY: if (expr->is_compound()) { VisitForStackValue(property->obj()); - VisitForAccumulatorValue(property->key()); - __ ldr(r1, MemOperand(sp, 0)); - __ push(r0); + VisitForStackValue(property->key()); + __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize)); + __ ldr(LoadIC::NameRegister(), MemOperand(sp, 0)); } else { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); @@ -2008,6 +2008,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { Label l_catch, l_try, l_suspend, l_continuation, l_resume; Label l_next, l_call, l_loop; + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + // Initial send value is undefined. __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); __ b(&l_next); @@ -2015,9 +2018,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } __ bind(&l_catch); handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); - __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw" - __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter - __ Push(r2, r3, r0); // "throw", iter, except + __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" + __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter + __ Push(load_name, r3, r0); // "throw", iter, except __ jmp(&l_call); // try { received = %yield result } @@ -2051,19 +2054,15 @@ 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 + __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" + __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter + __ Push(load_name, r3, r0); // "next", iter, received // result = receiver[f](arg); __ bind(&l_call); - __ ldr(keyedload_receiver, MemOperand(sp, kPointerSize)); - __ ldr(keyedload_name, MemOperand(sp, 2 * kPointerSize)); + __ ldr(load_receiver, MemOperand(sp, kPointerSize)); + __ ldr(load_name, MemOperand(sp, 2 * kPointerSize)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ mov(r1, r0); @@ -2076,10 +2075,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ bind(&l_loop); - Register load_receiver = LoadIC::ReceiverRegister(); - Register load_name = LoadIC::NameRegister(); - ASSERT(load_receiver.is(r0)); - ASSERT(load_name.is(r2)); + __ Move(load_receiver, r0); __ push(load_receiver); // save result __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" @@ -2563,15 +2559,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); - ASSERT(r0.is(LoadIC::ReceiverRegister())); + __ Move(LoadIC::ReceiverRegister(), r0); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(r0); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - ASSERT(r0.is(KeyedLoadIC::NameRegister())); - __ pop(KeyedLoadIC::ReceiverRegister()); + __ Move(LoadIC::NameRegister(), r0); + __ pop(LoadIC::ReceiverRegister()); EmitKeyedPropertyLoad(expr); context()->Plug(r0); } @@ -2626,13 +2622,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(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); + __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); + __ Move(LoadIC::NameRegister(), r0); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -4045,12 +4041,12 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { if (expr->is_jsruntime()) { // Push the builtins object as the receiver. - __ ldr(r0, GlobalObjectOperand()); - __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); - __ push(r0); + Register receiver = LoadIC::ReceiverRegister(); + __ ldr(receiver, GlobalObjectOperand()); + __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); + __ push(receiver); // Load the function from the receiver. - ASSERT(r0.is(LoadIC::ReceiverRegister())); __ mov(LoadIC::NameRegister(), Operand(expr->name())); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); @@ -4228,17 +4224,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ push(ip); } if (assign_type == NAMED_PROPERTY) { - // Put the object both on the stack and in the accumulator. - VisitForAccumulatorValue(prop->obj()); - ASSERT(r0.is(LoadIC::ReceiverRegister())); - __ push(LoadIC::ReceiverRegister()); + // Put the object both on the stack and in the register. + VisitForStackValue(prop->obj()); + __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); - VisitForAccumulatorValue(prop->key()); - ASSERT(r0.is(KeyedLoadIC::NameRegister())); - __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); - __ push(KeyedLoadIC::NameRegister()); + VisitForStackValue(prop->key()); + __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize)); + __ ldr(LoadIC::NameRegister(), MemOperand(sp, 0)); EmitKeyedPropertyLoad(prop); } } diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc index 24c6fa5144..fc32a48dd7 100644 --- a/src/arm/ic-arm.cc +++ b/src/arm/ic-arm.cc @@ -311,18 +311,16 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- r2 : name - // -- lr : return address - // -- r0 : receiver - // ----------------------------------- - ASSERT(r0.is(ReceiverRegister())); - ASSERT(r2.is(NameRegister())); + // The return address is in lr. + Register receiver = ReceiverRegister(); + Register name = NameRegister(); + ASSERT(receiver.is(r1)); + ASSERT(name.is(r2)); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); masm->isolate()->stub_cache()->GenerateProbe( - masm, flags, r0, r2, r3, r4, r5, r6); + masm, flags, receiver, name, r3, r4, r5, r6); // Cache miss: Jump to runtime. GenerateMiss(masm); @@ -333,17 +331,17 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r2 : name // -- lr : return address - // -- r0 : receiver + // -- r1 : receiver // ----------------------------------- - ASSERT(r0.is(ReceiverRegister())); + ASSERT(r1.is(ReceiverRegister())); ASSERT(r2.is(NameRegister())); Label miss, slow; - GenerateNameDictionaryReceiverCheck(masm, r0, r1, r3, r4, &miss); + GenerateNameDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss); - // r1: elements - GenerateDictionaryLoad(masm, &slow, r1, r2, r0, r3, r4); + // r0: elements + GenerateDictionaryLoad(masm, &slow, r0, r2, r0, r3, r4); __ Ret(); // Dictionary load failed, go slow (but don't miss). @@ -361,7 +359,7 @@ static const Register LoadIC_TempRegister() { return r3; } void LoadIC::GenerateMiss(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4); @@ -377,7 +375,7 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. __ mov(LoadIC_TempRegister(), ReceiverRegister()); __ Push(LoadIC_TempRegister(), NameRegister()); @@ -472,27 +470,26 @@ static MemOperand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- - ASSERT(r1.is(ReceiverRegister())); - ASSERT(r0.is(NameRegister())); + // The return address is in lr. + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + ASSERT(receiver.is(r1)); + ASSERT(key.is(r2)); + Label slow, notin; MemOperand mapped_location = - GenerateMappedArgumentsLookup(masm, r1, r0, r2, r3, r4, ¬in, &slow); + GenerateMappedArgumentsLookup( + masm, receiver, key, r0, r3, r4, ¬in, &slow); __ ldr(r0, mapped_location); __ Ret(); __ bind(¬in); - // The unmapped lookup expects that the parameter map is in r2. + // The unmapped lookup expects that the parameter map is in r0. MemOperand unmapped_location = - GenerateUnmappedArgumentsLookup(masm, r0, r2, r3, &slow); - __ ldr(r2, unmapped_location); + GenerateUnmappedArgumentsLookup(masm, key, r0, r3, &slow); + __ ldr(r0, unmapped_location); __ LoadRoot(r3, Heap::kTheHoleValueRootIndex); - __ cmp(r2, r3); + __ cmp(r0, r3); __ b(eq, &slow); - __ mov(r0, r2); __ Ret(); __ bind(&slow); GenerateMiss(masm); @@ -529,7 +526,7 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); @@ -545,14 +542,12 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { // IC register specifications -const Register LoadIC::ReceiverRegister() { return r0; } +const Register LoadIC::ReceiverRegister() { return r1; } const Register LoadIC::NameRegister() { return r2; } -const Register KeyedLoadIC::ReceiverRegister() { return r1; } -const Register KeyedLoadIC::NameRegister() { return r0; } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. __ Push(ReceiverRegister(), NameRegister()); @@ -561,17 +556,13 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- + // The return address is in lr. Label slow, check_name, index_smi, index_name, property_array_property; Label probe_dictionary, check_number_dictionary; Register key = NameRegister(); Register receiver = ReceiverRegister(); - ASSERT(key.is(r0)); + ASSERT(key.is(r2)); ASSERT(receiver.is(r1)); Isolate* isolate = masm->isolate(); @@ -583,14 +574,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // where a numeric string is converted to a smi. GenerateKeyedLoadReceiverCheck( - masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow); + masm, receiver, r0, r3, Map::kHasIndexedInterceptor, &slow); // Check the receiver's map to see if it has fast elements. - __ CheckFastElements(r2, r3, &check_number_dictionary); + __ CheckFastElements(r0, r3, &check_number_dictionary); GenerateFastArrayLoad( - masm, receiver, key, r4, r3, r2, r0, NULL, &slow); - __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r2, r3); + masm, receiver, key, r0, r3, r4, r0, NULL, &slow); + __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r4, r3); __ Ret(); __ bind(&check_number_dictionary); @@ -598,31 +589,30 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); // Check whether the elements is a number dictionary. - // r0: key // r3: elements map // r4: elements __ LoadRoot(ip, Heap::kHashTableMapRootIndex); __ cmp(r3, ip); __ b(ne, &slow); - __ SmiUntag(r2, r0); - __ LoadFromNumberDictionary(&slow, r4, r0, r0, r2, r3, r5); + __ SmiUntag(r0, key); + __ LoadFromNumberDictionary(&slow, r4, key, r0, r0, r3, r5); __ Ret(); - // Slow case, key and receiver still in r0 and r1. + // Slow case, key and receiver still in r2 and r1. __ bind(&slow); __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), - 1, r2, r3); + 1, r4, r3); GenerateRuntimeGetProperty(masm); __ bind(&check_name); - GenerateKeyNameCheck(masm, key, r2, r3, &index_name, &slow); + GenerateKeyNameCheck(masm, key, r0, r3, &index_name, &slow); GenerateKeyedLoadReceiverCheck( - masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow); + masm, receiver, r0, r3, Map::kHasNamedInterceptor, &slow); // If the receiver is a fast-case object, check the keyed lookup // cache. Otherwise probe the dictionary. - __ ldr(r3, FieldMemOperand(r1, JSObject::kPropertiesOffset)); + __ ldr(r3, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); __ LoadRoot(ip, Heap::kHashTableMapRootIndex); __ cmp(r4, ip); @@ -630,9 +620,9 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // Load the map of the receiver, compute the keyed lookup cache hash // based on 32 bits of the map pointer and the name hash. - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift)); - __ ldr(r4, FieldMemOperand(r0, Name::kHashFieldOffset)); + __ ldr(r0, FieldMemOperand(receiver, HeapObject::kMapOffset)); + __ mov(r3, Operand(r0, ASR, KeyedLookupCache::kMapHashShift)); + __ ldr(r4, FieldMemOperand(key, Name::kHashFieldOffset)); __ eor(r3, r3, Operand(r4, ASR, Name::kHashShift)); int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask; __ And(r3, r3, Operand(mask)); @@ -652,26 +642,24 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { Label try_next_entry; // Load map and move r4 to next entry. __ ldr(r5, MemOperand(r4, kPointerSize * 2, PostIndex)); - __ cmp(r2, r5); + __ cmp(r0, r5); __ b(ne, &try_next_entry); __ ldr(r5, MemOperand(r4, -kPointerSize)); // Load name - __ cmp(r0, r5); + __ cmp(key, r5); __ b(eq, &hit_on_nth_entry[i]); __ bind(&try_next_entry); } // Last entry: Load map and move r4 to name. __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); - __ cmp(r2, r5); + __ cmp(r0, r5); __ b(ne, &slow); __ ldr(r5, MemOperand(r4)); - __ cmp(r0, r5); + __ cmp(key, r5); __ b(ne, &slow); // Get field offset. - // r0 : key - // r1 : receiver - // r2 : receiver's map + // r0 : receiver's map // r3 : lookup cache index ExternalReference cache_field_offsets = ExternalReference::keyed_lookup_cache_field_offsets(isolate); @@ -684,7 +672,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ add(r3, r3, Operand(i)); } __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); - __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); + __ ldrb(r6, FieldMemOperand(r0, Map::kInObjectPropertiesOffset)); __ sub(r5, r5, r6, SetCC); __ b(ge, &property_array_property); if (i != 0) { @@ -694,36 +682,34 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // Load in-object property. __ bind(&load_in_object_property); - __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); + __ ldrb(r6, FieldMemOperand(r0, Map::kInstanceSizeOffset)); __ add(r6, r6, r5); // Index from start of object. - __ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag. - __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2)); + __ sub(receiver, receiver, Operand(kHeapObjectTag)); // Remove the heap tag. + __ ldr(r0, MemOperand(receiver, r6, LSL, kPointerSizeLog2)); __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), - 1, r2, r3); + 1, r4, r3); __ Ret(); // Load property array property. __ bind(&property_array_property); - __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset)); - __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2)); + __ ldr(receiver, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); + __ add(receiver, receiver, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); + __ ldr(r0, MemOperand(receiver, r5, LSL, kPointerSizeLog2)); __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), - 1, r2, r3); + 1, r4, r3); __ Ret(); // Do a quick inline probe of the receiver's dictionary, if it // exists. __ bind(&probe_dictionary); - // r1: receiver - // r0: key // r3: elements - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); - __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); - GenerateGlobalInstanceTypeCheck(masm, r2, &slow); + __ ldr(r0, FieldMemOperand(receiver, HeapObject::kMapOffset)); + __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); + GenerateGlobalInstanceTypeCheck(masm, r0, &slow); // Load the property to r0. - GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4); + GenerateDictionaryLoad(masm, &slow, r3, key, r0, r5, r4); __ IncrementCounter( - isolate->counters()->keyed_load_generic_symbol(), 1, r2, r3); + isolate->counters()->keyed_load_generic_symbol(), 1, r4, r3); __ Ret(); __ bind(&index_name); @@ -734,7 +720,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) { - // Return address is on the stack. + // Return address is in lr. Label miss; Register receiver = ReceiverRegister(); @@ -763,13 +749,13 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { - // Return address is on the stack. + // Return address is in lr. Label slow; Register receiver = ReceiverRegister(); Register key = NameRegister(); - Register scratch1 = r2; - Register scratch2 = r3; + Register scratch1 = r3; + Register scratch2 = r4; ASSERT(!scratch1.is(receiver) && !scratch1.is(key)); ASSERT(!scratch2.is(receiver) && !scratch2.is(key)); diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 5071f04b12..0ed62d7965 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -2199,8 +2199,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); - LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), LoadIC::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 f02a7dabe6..fb89186631 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -3375,8 +3375,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); - ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(LoadIC::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 1c772eec81..ab83e864cc 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -1265,16 +1265,16 @@ Register* LoadStubCompiler::registers() { // receiver, name, scratch1, scratch2, scratch3, scratch4. Register receiver = LoadIC::ReceiverRegister(); Register name = LoadIC::NameRegister(); - static Register registers[] = { receiver, name, r3, r1, r4, r5 }; + static Register registers[] = { receiver, name, r3, r0, r4, r5 }; return registers; } Register* KeyedLoadStubCompiler::registers() { // receiver, name, scratch1, scratch2, scratch3, scratch4. - Register receiver = KeyedLoadIC::ReceiverRegister(); - Register name = KeyedLoadIC::NameRegister(); - static Register registers[] = { receiver, name, r2, r3, r4, r5 }; + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + static Register registers[] = { receiver, name, r3, r0, r4, r5 }; return registers; } @@ -1474,21 +1474,17 @@ Handle KeyedStoreStubCompiler::CompileStorePolymorphic( void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- - ASSERT(r1.is(KeyedLoadIC::ReceiverRegister())); - ASSERT(r0.is(KeyedLoadIC::NameRegister())); + // The return address is in lr. Label slow, miss; - Register key = r0; - Register receiver = r1; + Register key = LoadIC::NameRegister(); + Register receiver = LoadIC::ReceiverRegister(); + ASSERT(receiver.is(r1)); + ASSERT(key.is(r2)); - __ UntagAndJumpIfNotSmi(r2, key, &miss); + __ UntagAndJumpIfNotSmi(r6, key, &miss); __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); - __ LoadFromNumberDictionary(&slow, r4, key, r0, r2, r3, r5); + __ LoadFromNumberDictionary(&slow, r4, key, r0, r6, r3, r5); __ Ret(); __ bind(&slow); @@ -1496,21 +1492,11 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( masm->isolate()->counters()->keyed_load_external_array_slow(), 1, r2, r3); - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); // Miss case, call the runtime. __ bind(&miss); - // ---------- S t a t e -------------- - // -- lr : return address - // -- r0 : key - // -- r1 : receiver - // ----------------------------------- TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); } diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index 427f82a73f..6dc564da4a 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -1727,26 +1727,15 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { void FunctionPrototypeStub::Generate(MacroAssembler* masm) { Label miss; - Register receiver; + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + + ASSERT(kind() == Code::LOAD_IC || + kind() == Code::KEYED_LOAD_IC); + if (kind() == Code::KEYED_LOAD_IC) { - // ----------- S t a t e ------------- - // -- lr : return address - // -- x1 : receiver - // -- x0 : key - // ----------------------------------- - Register key = x0; - receiver = x1; - __ Cmp(key, Operand(isolate()->factory()->prototype_string())); + __ Cmp(name, Operand(isolate()->factory()->prototype_string())); __ B(ne, &miss); - } else { - ASSERT(kind() == Code::LOAD_IC); - // ----------- S t a t e ------------- - // -- lr : return address - // -- x2 : name - // -- x0 : receiver - // -- sp[0] : receiver - // ----------------------------------- - receiver = x0; } StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, x10, x11, &miss); diff --git a/src/arm64/debug-arm64.cc b/src/arm64/debug-arm64.cc index a5baee7637..43684d5157 100644 --- a/src/arm64/debug-arm64.cc +++ b/src/arm64/debug-arm64.cc @@ -257,9 +257,7 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { // 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); + GenerateLoadICDebugBreak(masm); } diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 6401d31b6e..6b8e49c462 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -1858,9 +1858,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { break; case NAMED_PROPERTY: if (expr->is_compound()) { - // We need the receiver both on the stack and in the accumulator. - VisitForAccumulatorValue(property->obj()); - __ Push(result_register()); + // We need the receiver both on the stack and in the register. + VisitForStackValue(property->obj()); + __ Peek(LoadIC::ReceiverRegister(), 0); } else { VisitForStackValue(property->obj()); } @@ -1868,9 +1868,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case KEYED_PROPERTY: if (expr->is_compound()) { VisitForStackValue(property->obj()); - VisitForAccumulatorValue(property->key()); - __ Peek(x1, 0); - __ Push(x0); + VisitForStackValue(property->key()); + __ Peek(LoadIC::ReceiverRegister(), 1 * kPointerSize); + __ Peek(LoadIC::NameRegister(), 0); } else { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); @@ -2260,15 +2260,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); - ASSERT(x0.is(LoadIC::ReceiverRegister())); + __ Move(LoadIC::ReceiverRegister(), x0); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(x0); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - ASSERT(x0.is(KeyedLoadIC::NameRegister())); - __ Pop(KeyedLoadIC::ReceiverRegister()); + __ Move(LoadIC::NameRegister(), x0); + __ Pop(LoadIC::ReceiverRegister()); EmitKeyedPropertyLoad(expr); context()->Plug(x0); } @@ -2321,13 +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(KeyedLoadIC::ReceiverRegister(), 0); + __ Peek(LoadIC::ReceiverRegister(), 0); + __ Move(LoadIC::NameRegister(), x0); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -3927,18 +3927,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ Push(xzr); } if (assign_type == NAMED_PROPERTY) { - // Put the object both on the stack and in the accumulator. - VisitForAccumulatorValue(prop->obj()); - ASSERT(x0.is(LoadIC::ReceiverRegister())); - __ Push(LoadIC::ReceiverRegister()); + // Put the object both on the stack and in the register. + VisitForStackValue(prop->obj()); + __ Peek(LoadIC::ReceiverRegister(), 0); EmitNamedPropertyLoad(prop); } else { // KEYED_PROPERTY VisitForStackValue(prop->obj()); - VisitForAccumulatorValue(prop->key()); - ASSERT(x0.is(KeyedLoadIC::NameRegister())); - __ Peek(KeyedLoadIC::ReceiverRegister(), 0); - __ Push(KeyedLoadIC::NameRegister()); + VisitForStackValue(prop->key()); + __ Peek(LoadIC::ReceiverRegister(), 1 * kPointerSize); + __ Peek(LoadIC::NameRegister(), 0); EmitKeyedPropertyLoad(prop); } } @@ -4389,6 +4387,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { Label l_catch, l_try, l_suspend, l_continuation, l_resume; Label l_next, l_call, l_loop; + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + // Initial send value is undefined. __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); __ B(&l_next); @@ -4396,9 +4397,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } __ Bind(&l_catch); handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); - __ LoadRoot(x2, Heap::kthrow_stringRootIndex); // "throw" - __ Peek(x3, 1 * kPointerSize); // iter - __ Push(x2, x3, x0); // "throw", iter, except + __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" + __ Peek(x3, 1 * kPointerSize); // iter + __ Push(load_name, x3, x0); // "throw", iter, except __ B(&l_call); // try { received = %yield result } @@ -4437,19 +4438,15 @@ 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 + __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" + __ Peek(x3, 1 * kPointerSize); // iter + __ Push(load_name, x3, x0); // "next", iter, received // result = receiver[f](arg); __ Bind(&l_call); - __ Peek(keyedload_receiver, 1 * kPointerSize); - __ Peek(keyedload_name, 2 * kPointerSize); + __ Peek(load_receiver, 1 * kPointerSize); + __ Peek(load_name, 2 * kPointerSize); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ Mov(x1, x0); @@ -4462,10 +4459,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ Bind(&l_loop); - Register load_receiver = LoadIC::ReceiverRegister(); - Register load_name = LoadIC::NameRegister(); - ASSERT(load_receiver.is(x0)); - ASSERT(load_name.is(x2)); + __ Move(load_receiver, x0); + __ Push(load_receiver); // save result __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" CallLoadIC(NOT_CONTEXTUAL); // x0=result.done diff --git a/src/arm64/ic-arm64.cc b/src/arm64/ic-arm64.cc index 8340cf1ebd..6e6e8ce08c 100644 --- a/src/arm64/ic-arm64.cc +++ b/src/arm64/ic-arm64.cc @@ -407,18 +407,16 @@ static MemOperand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- x2 : name - // -- lr : return address - // -- x0 : receiver - // ----------------------------------- - ASSERT(x0.is(ReceiverRegister())); - ASSERT(x2.is(NameRegister())); + // The return address is in lr. + Register receiver = ReceiverRegister(); + Register name = NameRegister(); + ASSERT(receiver.is(x1)); + ASSERT(name.is(x2)); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); masm->isolate()->stub_cache()->GenerateProbe( - masm, flags, x0, x2, x3, x4, x5, x6); + masm, flags, receiver, name, x3, x4, x5, x6); // Cache miss: Jump to runtime. GenerateMiss(masm); @@ -429,16 +427,16 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- x2 : name // -- lr : return address - // -- x0 : receiver + // -- x1 : receiver // ----------------------------------- - ASSERT(x0.is(ReceiverRegister())); + ASSERT(x1.is(ReceiverRegister())); ASSERT(x2.is(NameRegister())); Label miss, slow; - GenerateNameDictionaryReceiverCheck(masm, x0, x1, x3, x4, &miss); + GenerateNameDictionaryReceiverCheck(masm, x1, x0, x3, x4, &miss); - // x1 now holds the property dictionary. - GenerateDictionaryLoad(masm, &slow, x1, x2, x0, x3, x4); + // x0 now holds the property dictionary. + GenerateDictionaryLoad(masm, &slow, x0, x2, x0, x3, x4); __ Ret(); // Dictionary load failed, go slow (but don't miss). @@ -452,7 +450,7 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. Isolate* isolate = masm->isolate(); ASM_LOCATION("LoadIC::GenerateMiss"); @@ -467,27 +465,23 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. __ Push(ReceiverRegister(), NameRegister()); __ TailCallRuntime(Runtime::kGetProperty, 2, 1); } void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key - // -- x1 : receiver - // ----------------------------------- + // The return address is in lr. Register result = x0; Register receiver = ReceiverRegister(); Register key = NameRegister(); ASSERT(receiver.is(x1)); - ASSERT(key.is(x0)); + ASSERT(key.is(x2)); Label miss, unmapped; - Register map_scratch = x2; + Register map_scratch = x0; MemOperand mapped_location = GenerateMappedArgumentsLookup( masm, receiver, key, map_scratch, x3, x4, &unmapped, &miss); __ Ldr(result, mapped_location); @@ -497,10 +491,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { // Parameter map is left in map_scratch when a jump on unmapped is done. MemOperand unmapped_location = GenerateUnmappedArgumentsLookup(masm, key, map_scratch, x3, &miss); - __ Ldr(x2, unmapped_location); - __ JumpIfRoot(x2, Heap::kTheHoleValueRootIndex, &miss); - // Move the result in x0. x0 must be preserved on miss. - __ Mov(result, x2); + __ Ldr(result, unmapped_location); + __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss); __ Ret(); __ Bind(&miss); @@ -560,7 +552,7 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. Isolate* isolate = masm->isolate(); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11); @@ -576,14 +568,12 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { // IC register specifications -const Register LoadIC::ReceiverRegister() { return x0; } +const Register LoadIC::ReceiverRegister() { return x1; } const Register LoadIC::NameRegister() { return x2; } -const Register KeyedLoadIC::ReceiverRegister() { return x1; } -const Register KeyedLoadIC::NameRegister() { return x0; } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is on the stack. + // The return address is in lr. __ Push(ReceiverRegister(), NameRegister()); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); } @@ -753,34 +743,30 @@ static void GenerateKeyedLoadWithNameKey(MacroAssembler* masm, void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key - // -- x1 : receiver - // ----------------------------------- + // The return address is in lr. Label slow, check_name, index_smi, index_name; Register key = NameRegister(); Register receiver = ReceiverRegister(); - ASSERT(key.is(x0)); + ASSERT(key.is(x2)); ASSERT(receiver.is(x1)); __ JumpIfNotSmi(key, &check_name); __ Bind(&index_smi); // Now the key is known to be a smi. This place is also jumped to from below // where a numeric string is converted to a smi. - GenerateKeyedLoadWithSmiKey(masm, key, receiver, x2, x3, x4, x5, x6, &slow); + GenerateKeyedLoadWithSmiKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow); - // Slow case, key and receiver still in x0 and x1. + // Slow case. __ Bind(&slow); __ IncrementCounter( - masm->isolate()->counters()->keyed_load_generic_slow(), 1, x2, x3); + masm->isolate()->counters()->keyed_load_generic_slow(), 1, x4, x3); GenerateRuntimeGetProperty(masm); __ Bind(&check_name); - GenerateKeyNameCheck(masm, key, x2, x3, &index_name, &slow); + GenerateKeyNameCheck(masm, key, x0, x3, &index_name, &slow); - GenerateKeyedLoadWithNameKey(masm, key, receiver, x2, x3, x4, x5, x6, &slow); + GenerateKeyedLoadWithNameKey(masm, key, receiver, x7, x3, x4, x5, x6, &slow); __ Bind(&index_name); __ IndexFromHash(x3, key); @@ -790,7 +776,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) { - // Return address is on the stack. + // Return address is in lr. Label miss; Register receiver = ReceiverRegister(); @@ -819,15 +805,14 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { - // Return address is on the stack. + // Return address is in lr. Label slow; 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)); + Register scratch1 = x3; + Register scratch2 = x4; + ASSERT(!AreAliased(scratch1, scratch2, receiver, key)); // Check that the receiver isn't a smi. __ JumpIfSmi(receiver, &slow); diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index b56ae8fa28..1ed1e14a11 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -1713,8 +1713,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), cp); - LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); - LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), LoadIC::NameRegister()); LInstruction* result = DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), x0); diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 8fa4fbfa83..52f2b45436 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -3643,8 +3643,8 @@ void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); - ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(LoadIC::NameRegister())); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -3696,7 +3696,6 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(cp)); // LoadIC expects name and receiver in registers. ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); - ASSERT(ToRegister(instr->object()).is(x0)); __ Mov(LoadIC::NameRegister(), Operand(instr->name())); Handle ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); diff --git a/src/arm64/stub-cache-arm64.cc b/src/arm64/stub-cache-arm64.cc index dc0220cada..e3d4f8d13d 100644 --- a/src/arm64/stub-cache-arm64.cc +++ b/src/arm64/stub-cache-arm64.cc @@ -1247,16 +1247,16 @@ Register* LoadStubCompiler::registers() { // receiver, name, scratch1, scratch2, scratch3, scratch4. Register receiver = LoadIC::ReceiverRegister(); Register name = LoadIC::NameRegister(); - static Register registers[] = { receiver, name, x3, x1, x4, x5 }; + static Register registers[] = { receiver, name, x3, x0, x4, x5 }; return registers; } Register* KeyedLoadStubCompiler::registers() { // receiver, name, scratch1, scratch2, scratch3, scratch4. - Register receiver = KeyedLoadIC::ReceiverRegister(); - Register name = KeyedLoadIC::NameRegister(); - static Register registers[] = { receiver, name, x2, x3, x4, x5 }; + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + static Register registers[] = { receiver, name, x3, x0, x4, x5 }; return registers; } @@ -1449,27 +1449,23 @@ Handle KeyedStoreStubCompiler::CompileStorePolymorphic( void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( MacroAssembler* masm) { - // ---------- S t a t e -------------- - // -- lr : return address - // -- x0 : key - // -- x1 : receiver - // ----------------------------------- - ASSERT(x1.is(KeyedLoadIC::ReceiverRegister())); - ASSERT(x0.is(KeyedLoadIC::NameRegister())); + // The return address is in lr. Label slow, miss; Register result = x0; - Register key = x0; - Register receiver = x1; + Register key = LoadIC::NameRegister(); + Register receiver = LoadIC::ReceiverRegister(); + ASSERT(receiver.is(x1)); + ASSERT(key.is(x2)); __ JumpIfNotSmi(key, &miss); __ Ldr(x4, FieldMemOperand(receiver, JSObject::kElementsOffset)); - __ LoadFromNumberDictionary(&slow, x4, key, result, x2, x3, x5, x6); + __ LoadFromNumberDictionary(&slow, x4, key, result, x7, x3, x5, x6); __ Ret(); __ Bind(&slow); __ IncrementCounter( - masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x2, x3); + masm->isolate()->counters()->keyed_load_external_array_slow(), 1, x4, x3); TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); // Miss case, call the runtime. diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 0ac07de0dd..b96013306c 100644 --- a/src/code-stubs.cc +++ b/src/code-stubs.cc @@ -585,9 +585,9 @@ void JSEntryStub::FinishCode(Handle code) { void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { KeyedLoadIC::ReceiverRegister(), - KeyedLoadIC::NameRegister() }; - STATIC_ASSERT(KeyedLoadIC::kRegisterArgumentCount == 2); + Register registers[] = { LoadIC::ReceiverRegister(), + LoadIC::NameRegister() }; + STATIC_ASSERT(LoadIC::kRegisterArgumentCount == 2); descriptor->Initialize(ARRAY_SIZE(registers), registers, FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure)); } @@ -595,9 +595,9 @@ void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { KeyedLoadIC::ReceiverRegister(), - KeyedLoadIC::NameRegister() }; - STATIC_ASSERT(KeyedLoadIC::kRegisterArgumentCount == 2); + Register registers[] = { LoadIC::ReceiverRegister(), + LoadIC::NameRegister() }; + STATIC_ASSERT(LoadIC::kRegisterArgumentCount == 2); descriptor->Initialize(ARRAY_SIZE(registers), registers, FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure)); } @@ -605,9 +605,9 @@ void KeyedLoadDictionaryElementStub::InitializeInterfaceDescriptor( void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { KeyedLoadIC::ReceiverRegister(), - KeyedLoadIC::NameRegister() }; - STATIC_ASSERT(KeyedLoadIC::kRegisterArgumentCount == 2); + Register registers[] = { LoadIC::ReceiverRegister(), + LoadIC::NameRegister() }; + STATIC_ASSERT(LoadIC::kRegisterArgumentCount == 2); descriptor->Initialize( ARRAY_SIZE(registers), registers, Runtime::FunctionForId(Runtime::kKeyedGetProperty)->entry); @@ -623,7 +623,7 @@ void LoadFieldStub::InitializeInterfaceDescriptor( void KeyedLoadFieldStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { KeyedLoadIC::ReceiverRegister() }; + Register registers[] = { LoadIC::ReceiverRegister() }; descriptor->Initialize(ARRAY_SIZE(registers), registers); } @@ -638,8 +638,8 @@ void StringLengthStub::InitializeInterfaceDescriptor( void KeyedStringLengthStub::InitializeInterfaceDescriptor( CodeStubInterfaceDescriptor* descriptor) { - Register registers[] = { KeyedLoadIC::ReceiverRegister(), - KeyedLoadIC::NameRegister() }; + Register registers[] = { LoadIC::ReceiverRegister(), + LoadIC::NameRegister() }; descriptor->Initialize(ARRAY_SIZE(registers), registers); } diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc index db86549382..0a1c0a5e6e 100644 --- a/src/ia32/builtins-ia32.cc +++ b/src/ia32/builtins-ia32.cc @@ -995,10 +995,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Copy all arguments from the array to the stack. Label entry, loop; - __ mov(ecx, Operand(ebp, kIndexOffset)); + Register receiver = LoadIC::ReceiverRegister(); + Register key = LoadIC::NameRegister(); + __ mov(key, Operand(ebp, kIndexOffset)); __ jmp(&entry); __ bind(&loop); - __ mov(edx, Operand(ebp, kArgumentsOffset)); // load arguments + __ mov(receiver, Operand(ebp, kArgumentsOffset)); // load arguments // Use inline caching to speed up access to arguments. Handle ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize(); @@ -1011,19 +1013,19 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Push the nth argument. __ push(eax); - // Update the index on the stack and in register eax. - __ mov(ecx, Operand(ebp, kIndexOffset)); - __ add(ecx, Immediate(1 << kSmiTagSize)); - __ mov(Operand(ebp, kIndexOffset), ecx); + // Update the index on the stack and in register key. + __ mov(key, Operand(ebp, kIndexOffset)); + __ add(key, Immediate(1 << kSmiTagSize)); + __ mov(Operand(ebp, kIndexOffset), key); __ bind(&entry); - __ cmp(ecx, Operand(ebp, kLimitOffset)); + __ cmp(key, Operand(ebp, kLimitOffset)); __ j(not_equal, &loop); // Call the function. Label call_proxy; - __ mov(eax, ecx); ParameterCount actual(eax); + __ Move(eax, key); __ SmiUntag(eax); __ mov(edi, Operand(ebp, kFunctionOffset)); __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc index e641905913..68cf0dd1e7 100644 --- a/src/ia32/debug-ia32.cc +++ b/src/ia32/debug-ia32.cc @@ -200,9 +200,7 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { // Register state for keyed IC load call (from ic-ia32.cc). - Register receiver = KeyedLoadIC::ReceiverRegister(); - Register name = KeyedLoadIC::NameRegister(); - Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); + GenerateLoadICDebugBreak(masm); } diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 89f8dad3d9..c286d575d4 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -1811,9 +1811,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { break; case NAMED_PROPERTY: if (expr->is_compound()) { - // We need the receiver both on the stack and in edx. + // We need the receiver both on the stack and in the register. VisitForStackValue(property->obj()); - __ mov(edx, Operand(esp, 0)); + __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); } else { VisitForStackValue(property->obj()); } @@ -1822,8 +1822,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { if (expr->is_compound()) { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); - __ mov(edx, Operand(esp, kPointerSize)); // Object. - __ mov(ecx, Operand(esp, 0)); // Key. + __ mov(LoadIC::ReceiverRegister(), Operand(esp, kPointerSize)); + __ mov(LoadIC::NameRegister(), Operand(esp, 0)); } else { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); @@ -1964,6 +1964,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { Label l_catch, l_try, l_suspend, l_continuation, l_resume; Label l_next, l_call, l_loop; + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + // Initial send value is undefined. __ mov(eax, isolate()->factory()->undefined_value()); __ jmp(&l_next); @@ -1971,10 +1974,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } __ bind(&l_catch); handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); - __ mov(ecx, isolate()->factory()->throw_string()); // "throw" - __ push(ecx); // "throw" - __ push(Operand(esp, 2 * kPointerSize)); // iter - __ push(eax); // exception + __ mov(load_name, isolate()->factory()->throw_string()); // "throw" + __ push(load_name); // "throw" + __ push(Operand(esp, 2 * kPointerSize)); // iter + __ push(eax); // exception __ jmp(&l_call); // try { received = %yield result } @@ -2009,20 +2012,15 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // receiver = iter; f = iter.next; arg = received; __ bind(&l_next); - 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 + __ mov(load_name, isolate()->factory()->next_string()); + __ push(load_name); // "next" + __ push(Operand(esp, 2 * kPointerSize)); // iter + __ push(eax); // received // result = receiver[f](arg); __ bind(&l_call); - __ mov(keyedload_receiver, Operand(esp, kPointerSize)); + __ mov(load_receiver, Operand(esp, kPointerSize)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ mov(edi, eax); @@ -2036,11 +2034,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ bind(&l_loop); __ push(eax); // save result - 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 + __ Move(load_receiver, eax); // result __ mov(load_name, isolate()->factory()->done_string()); // "done" CallLoadIC(NOT_CONTEXTUAL); // result.done in eax @@ -2510,15 +2504,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); - __ mov(LoadIC::ReceiverRegister(), result_register()); + __ Move(LoadIC::ReceiverRegister(), result_register()); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(eax); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - __ pop(KeyedLoadIC::ReceiverRegister()); // Object. - __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key. + __ pop(LoadIC::ReceiverRegister()); // Object. + __ Move(LoadIC::NameRegister(), result_register()); // Key. EmitKeyedPropertyLoad(expr); context()->Plug(eax); } @@ -2573,9 +2567,8 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, // Load the function from the receiver. ASSERT(callee->IsProperty()); - __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); - // Move the key into the right register for the keyed load IC. - __ mov(KeyedLoadIC::NameRegister(), eax); + __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); + __ mov(LoadIC::NameRegister(), eax); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -4215,18 +4208,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ push(Immediate(Smi::FromInt(0))); } 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(LoadIC::ReceiverRegister(), eax); + // Put the object both on the stack and in the register. + VisitForStackValue(prop->obj()); + __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); VisitForStackValue(prop->key()); - __ mov(KeyedLoadIC::ReceiverRegister(), - Operand(esp, kPointerSize)); // Object. - __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key. + __ mov(LoadIC::ReceiverRegister(), + Operand(esp, kPointerSize)); // Object. + __ mov(LoadIC::NameRegister(), Operand(esp, 0)); // Key. EmitKeyedPropertyLoad(prop); } } diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc index 847443211c..4536103c4d 100644 --- a/src/ia32/ic-ia32.cc +++ b/src/ia32/ic-ia32.cc @@ -383,43 +383,40 @@ static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - ASSERT(edx.is(ReceiverRegister())); - ASSERT(ecx.is(NameRegister())); + // The return address is on the stack. Label slow, check_name, index_smi, index_name, property_array_property; Label probe_dictionary, check_number_dictionary; + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + ASSERT(receiver.is(edx)); + ASSERT(key.is(ecx)); + // Check that the key is a smi. - __ JumpIfNotSmi(ecx, &check_name); + __ JumpIfNotSmi(key, &check_name); __ bind(&index_smi); // Now the key is known to be a smi. This place is also jumped to from // where a numeric string is converted to a smi. GenerateKeyedLoadReceiverCheck( - masm, edx, eax, Map::kHasIndexedInterceptor, &slow); + masm, receiver, eax, Map::kHasIndexedInterceptor, &slow); // Check the receiver's map to see if it has fast elements. __ CheckFastElements(eax, &check_number_dictionary); - GenerateFastArrayLoad(masm, edx, ecx, eax, eax, NULL, &slow); + GenerateFastArrayLoad(masm, receiver, key, eax, eax, NULL, &slow); Isolate* isolate = masm->isolate(); Counters* counters = isolate->counters(); __ IncrementCounter(counters->keyed_load_generic_smi(), 1); __ ret(0); __ bind(&check_number_dictionary); - __ mov(ebx, ecx); + __ mov(ebx, key); __ SmiUntag(ebx); - __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); + __ mov(eax, FieldOperand(receiver, JSObject::kElementsOffset)); // Check whether the elements is a number dictionary. - // edx: receiver // ebx: untagged index - // ecx: key // eax: elements __ CheckMap(eax, isolate->factory()->hash_table_map(), @@ -428,32 +425,30 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { Label slow_pop_receiver; // Push receiver on the stack to free up a register for the dictionary // probing. - __ push(edx); - __ LoadFromNumberDictionary(&slow_pop_receiver, eax, ecx, ebx, edx, edi, eax); + __ push(receiver); + __ LoadFromNumberDictionary(&slow_pop_receiver, eax, key, ebx, edx, edi, eax); // Pop receiver before returning. - __ pop(edx); + __ pop(receiver); __ ret(0); __ bind(&slow_pop_receiver); // Pop the receiver from the stack and jump to runtime. - __ pop(edx); + __ pop(receiver); __ bind(&slow); // Slow case: jump to runtime. - // edx: receiver - // ecx: key __ IncrementCounter(counters->keyed_load_generic_slow(), 1); GenerateRuntimeGetProperty(masm); __ bind(&check_name); - GenerateKeyNameCheck(masm, ecx, eax, ebx, &index_name, &slow); + GenerateKeyNameCheck(masm, key, eax, ebx, &index_name, &slow); GenerateKeyedLoadReceiverCheck( - masm, edx, eax, Map::kHasNamedInterceptor, &slow); + masm, receiver, eax, Map::kHasNamedInterceptor, &slow); // If the receiver is a fast-case object, check the keyed lookup // cache. Otherwise probe the dictionary. - __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset)); + __ mov(ebx, FieldOperand(receiver, JSObject::kPropertiesOffset)); __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), Immediate(isolate->factory()->hash_table_map())); __ j(equal, &probe_dictionary); @@ -461,12 +456,12 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // The receiver's map is still in eax, compute the keyed lookup cache hash // based on 32 bits of the map pointer and the string hash. if (FLAG_debug_code) { - __ cmp(eax, FieldOperand(edx, HeapObject::kMapOffset)); + __ cmp(eax, FieldOperand(receiver, HeapObject::kMapOffset)); __ Check(equal, kMapIsNoLongerInEax); } __ mov(ebx, eax); // Keep the map around for later. __ shr(eax, KeyedLookupCache::kMapHashShift); - __ mov(edi, FieldOperand(ecx, String::kHashFieldOffset)); + __ mov(edi, FieldOperand(key, String::kHashFieldOffset)); __ shr(edi, String::kHashShift); __ xor_(eax, edi); __ and_(eax, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); @@ -489,7 +484,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); __ j(not_equal, &try_next_entry); __ add(edi, Immediate(kPointerSize)); - __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys)); + __ cmp(key, Operand::StaticArray(edi, times_1, cache_keys)); __ j(equal, &hit_on_nth_entry[i]); __ bind(&try_next_entry); } @@ -500,14 +495,12 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys)); __ j(not_equal, &slow); __ add(edi, Immediate(kPointerSize)); - __ cmp(ecx, Operand::StaticArray(edi, times_1, cache_keys)); + __ cmp(key, Operand::StaticArray(edi, times_1, cache_keys)); __ j(not_equal, &slow); // Get field offset. - // edx : receiver - // ebx : receiver's map - // ecx : key - // eax : lookup cache index + // ebx : receiver's map + // eax : lookup cache index ExternalReference cache_field_offsets = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); @@ -531,13 +524,13 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ bind(&load_in_object_property); __ movzx_b(eax, FieldOperand(ebx, Map::kInstanceSizeOffset)); __ add(eax, edi); - __ mov(eax, FieldOperand(edx, eax, times_pointer_size, 0)); + __ mov(eax, FieldOperand(receiver, eax, times_pointer_size, 0)); __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); __ ret(0); // Load property array property. __ bind(&property_array_property); - __ mov(eax, FieldOperand(edx, JSObject::kPropertiesOffset)); + __ mov(eax, FieldOperand(receiver, JSObject::kPropertiesOffset)); __ mov(eax, FieldOperand(eax, edi, times_pointer_size, FixedArray::kHeaderSize)); __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); @@ -547,16 +540,16 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // exists. __ bind(&probe_dictionary); - __ mov(eax, FieldOperand(edx, JSObject::kMapOffset)); + __ mov(eax, FieldOperand(receiver, JSObject::kMapOffset)); __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); GenerateGlobalInstanceTypeCheck(masm, eax, &slow); - GenerateDictionaryLoad(masm, &slow, ebx, ecx, eax, edi, eax); + GenerateDictionaryLoad(masm, &slow, ebx, key, eax, edi, eax); __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); __ ret(0); __ bind(&index_name); - __ IndexFromHash(ebx, ecx); + __ IndexFromHash(ebx, key); // Now jump to the place where smi keys are handled. __ jmp(&index_smi); } @@ -645,23 +638,23 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : key - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - ASSERT(edx.is(ReceiverRegister())); - ASSERT(ecx.is(NameRegister())); + // The return address is on the stack. + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + ASSERT(receiver.is(edx)); + ASSERT(key.is(ecx)); + Label slow, notin; Factory* factory = masm->isolate()->factory(); Operand mapped_location = - GenerateMappedArgumentsLookup(masm, edx, ecx, ebx, eax, ¬in, &slow); + GenerateMappedArgumentsLookup( + masm, receiver, key, ebx, eax, ¬in, &slow); __ mov(eax, mapped_location); __ Ret(); __ bind(¬in); // The unmapped lookup expects that the parameter map is in ebx. Operand unmapped_location = - GenerateUnmappedArgumentsLookup(masm, ecx, ebx, eax, &slow); + GenerateUnmappedArgumentsLookup(masm, key, ebx, eax, &slow); __ cmp(unmapped_location, factory->the_hole_value()); __ j(equal, &slow); __ mov(eax, unmapped_location); @@ -937,18 +930,16 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- ecx : name - // -- edx : receiver - // -- esp[0] : return address - // ----------------------------------- - ASSERT(edx.is(ReceiverRegister())); - ASSERT(ecx.is(NameRegister())); + // The return address is on the stack. + Register receiver = ReceiverRegister(); + Register name = NameRegister(); + ASSERT(receiver.is(edx)); + ASSERT(name.is(ecx)); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); masm->isolate()->stub_cache()->GenerateProbe( - masm, flags, edx, ecx, ebx, eax); + masm, flags, receiver, name, ebx, eax); // Cache miss: Jump to runtime. GenerateMiss(masm); @@ -1032,14 +1023,6 @@ const Register LoadIC::ReceiverRegister() { return edx; } const Register LoadIC::NameRegister() { return ecx; } -const Register KeyedLoadIC::ReceiverRegister() { - return LoadIC::ReceiverRegister(); -} - - -const Register KeyedLoadIC::NameRegister() { return LoadIC::NameRegister(); } - - void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { // Return address is on the stack. __ pop(KeyedLoadIC_TempRegister()); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 8bb53f9d81..a918298eb1 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -3207,8 +3207,8 @@ Operand LCodeGen::BuildFastArrayOperand( void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(esi)); - ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); - ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(LoadIC::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 a18528c5a9..bd1863d1f4 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2204,8 +2204,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), esi); - LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); - LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), LoadIC::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 ca6a5bbb31..bf4d04a349 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -1292,8 +1292,8 @@ Register* LoadStubCompiler::registers() { Register* KeyedLoadStubCompiler::registers() { // receiver, name, scratch1, scratch2, scratch3, scratch4. - Register receiver = KeyedLoadIC::ReceiverRegister(); - Register name = KeyedLoadIC::NameRegister(); + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); static Register registers[] = { receiver, name, ebx, eax, edi, no_reg }; return registers; } @@ -1454,8 +1454,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( // -- edx : receiver // -- esp[0] : return address // ----------------------------------- - ASSERT(edx.is(KeyedLoadIC::ReceiverRegister())); - ASSERT(ecx.is(KeyedLoadIC::NameRegister())); + ASSERT(edx.is(LoadIC::ReceiverRegister())); + ASSERT(ecx.is(LoadIC::NameRegister())); Label slow, miss; // This stub is meant to be tail-jumped to, the receiver must already diff --git a/src/ic.h b/src/ic.h index 7c999daf30..c2d0c32e31 100644 --- a/src/ic.h +++ b/src/ic.h @@ -506,9 +506,6 @@ class KeyedLoadIC: public LoadIC { ASSERT(target()->is_keyed_load_stub()); } - static const Register ReceiverRegister(); - static const Register NameRegister(); - MUST_USE_RESULT MaybeHandle Load(Handle object, Handle key); diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc index 1a36341a92..2aea7b9fdb 100644 --- a/src/x64/builtins-x64.cc +++ b/src/x64/builtins-x64.cc @@ -1066,10 +1066,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Copy all arguments from the array to the stack. Label entry, loop; - __ movp(rax, Operand(rbp, kIndexOffset)); + Register receiver = LoadIC::ReceiverRegister(); + Register key = LoadIC::NameRegister(); + __ movp(key, Operand(rbp, kIndexOffset)); __ jmp(&entry); __ bind(&loop); - __ movp(rdx, Operand(rbp, kArgumentsOffset)); // load arguments + __ movp(receiver, Operand(rbp, kArgumentsOffset)); // load arguments // Use inline caching to speed up access to arguments. Handle ic = @@ -1083,19 +1085,19 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { // Push the nth argument. __ Push(rax); - // Update the index on the stack and in register rax. - __ movp(rax, Operand(rbp, kIndexOffset)); - __ SmiAddConstant(rax, rax, Smi::FromInt(1)); - __ movp(Operand(rbp, kIndexOffset), rax); + // Update the index on the stack and in register key. + __ movp(key, Operand(rbp, kIndexOffset)); + __ SmiAddConstant(key, key, Smi::FromInt(1)); + __ movp(Operand(rbp, kIndexOffset), key); __ bind(&entry); - __ cmpp(rax, Operand(rbp, kLimitOffset)); + __ cmpp(key, Operand(rbp, kLimitOffset)); __ j(not_equal, &loop); // Call the function. Label call_proxy; ParameterCount actual(rax); - __ SmiToInteger32(rax, rax); + __ SmiToInteger32(rax, key); __ movp(rdi, Operand(rbp, kFunctionOffset)); __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); __ j(not_equal, &call_proxy); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index ce142b7a2e..c08e38b509 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -780,24 +780,15 @@ void MathPowStub::Generate(MacroAssembler* masm) { void FunctionPrototypeStub::Generate(MacroAssembler* masm) { Label miss; - Register receiver; + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + + ASSERT(kind() == Code::LOAD_IC || + kind() == Code::KEYED_LOAD_IC); + if (kind() == Code::KEYED_LOAD_IC) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- - __ Cmp(rax, isolate()->factory()->prototype_string()); + __ Cmp(name, isolate()->factory()->prototype_string()); __ j(not_equal, &miss); - receiver = rdx; - } else { - ASSERT(kind() == Code::LOAD_IC); - // ----------- S t a t e ------------- - // -- rax : receiver - // -- rcx : name - // -- rsp[0] : return address - // ----------------------------------- - receiver = rax; } StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, r9, &miss); diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc index f0f8198c16..1870384a52 100644 --- a/src/x64/debug-x64.cc +++ b/src/x64/debug-x64.cc @@ -182,9 +182,7 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { // Register state for keyed IC load call (from ic-x64.cc). - Register receiver = KeyedLoadIC::ReceiverRegister(); - Register name = KeyedLoadIC::NameRegister(); - Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); + GenerateLoadICDebugBreak(masm); } diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index b9c26a3cfd..a154107623 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -1844,9 +1844,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { break; case NAMED_PROPERTY: if (expr->is_compound()) { - // We need the receiver both on the stack and in the accumulator. - VisitForAccumulatorValue(property->obj()); - __ Push(result_register()); + // We need the receiver both on the stack and in the register. + VisitForStackValue(property->obj()); + __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); } else { VisitForStackValue(property->obj()); } @@ -1854,9 +1854,9 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case KEYED_PROPERTY: { if (expr->is_compound()) { VisitForStackValue(property->obj()); - VisitForAccumulatorValue(property->key()); - __ movp(rdx, Operand(rsp, 0)); - __ Push(rax); + VisitForStackValue(property->key()); + __ movp(LoadIC::ReceiverRegister(), Operand(rsp, kPointerSize)); + __ movp(LoadIC::NameRegister(), Operand(rsp, 0)); } else { VisitForStackValue(property->obj()); VisitForStackValue(property->key()); @@ -1997,6 +1997,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) { Label l_catch, l_try, l_suspend, l_continuation, l_resume; Label l_next, l_call, l_loop; + Register load_receiver = LoadIC::ReceiverRegister(); + Register load_name = LoadIC::NameRegister(); + // Initial send value is undefined. __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); __ jmp(&l_next); @@ -2004,10 +2007,10 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } __ bind(&l_catch); handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); - __ LoadRoot(rcx, Heap::kthrow_stringRootIndex); // "throw" - __ Push(rcx); - __ Push(Operand(rsp, 2 * kPointerSize)); // iter - __ Push(rax); // exception + __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" + __ Push(load_name); + __ Push(Operand(rsp, 2 * kPointerSize)); // iter + __ Push(rax); // exception __ jmp(&l_call); // try { received = %yield result } @@ -2042,20 +2045,15 @@ 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 - __ Push(rax); // received + __ LoadRoot(load_name, Heap::knext_stringRootIndex); + __ Push(load_name); // "next" + __ Push(Operand(rsp, 2 * kPointerSize)); // iter + __ Push(rax); // received // result = receiver[f](arg); __ bind(&l_call); - __ movp(keyedload_receiver, Operand(rsp, kPointerSize)); - __ movp(keyedload_name, Operand(rsp, 2 * kPointerSize)); + __ movp(load_receiver, Operand(rsp, kPointerSize)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallIC(ic, TypeFeedbackId::None()); __ movp(rdi, rax); @@ -2068,11 +2066,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) { // if (!result.done) goto l_try; __ bind(&l_loop); - Register load_receiver = LoadIC::ReceiverRegister(); - Register load_name = LoadIC::NameRegister(); - ASSERT(load_receiver.is(rax)); - ASSERT(load_name.is(rcx)); - + __ Move(load_receiver, rax); __ Push(load_receiver); // save result __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" CallLoadIC(NOT_CONTEXTUAL); // rax=result.done @@ -2503,15 +2497,16 @@ void FullCodeGenerator::VisitProperty(Property* expr) { if (key->IsPropertyName()) { VisitForAccumulatorValue(expr->obj()); - ASSERT(rax.is(LoadIC::ReceiverRegister())); + ASSERT(!rax.is(LoadIC::ReceiverRegister())); + __ movp(LoadIC::ReceiverRegister(), rax); EmitNamedPropertyLoad(expr); PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(rax); } else { VisitForStackValue(expr->obj()); VisitForAccumulatorValue(expr->key()); - ASSERT(rax.is(KeyedLoadIC::NameRegister())); - __ Pop(KeyedLoadIC::ReceiverRegister()); + __ Move(LoadIC::NameRegister(), rax); + __ Pop(LoadIC::ReceiverRegister()); EmitKeyedPropertyLoad(expr); context()->Plug(rax); } @@ -2561,13 +2556,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(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); + __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); + __ Move(LoadIC::NameRegister(), rax); EmitKeyedPropertyLoad(callee->AsProperty()); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); @@ -4224,18 +4219,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { __ Push(Smi::FromInt(0)); } if (assign_type == NAMED_PROPERTY) { - VisitForAccumulatorValue(prop->obj()); - ASSERT(rax.is(LoadIC::ReceiverRegister())); - __ Push(rax); // Copy of receiver, needed for later store. + VisitForStackValue(prop->obj()); + __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); EmitNamedPropertyLoad(prop); } else { VisitForStackValue(prop->obj()); - VisitForAccumulatorValue(prop->key()); - ASSERT(rax.is(KeyedLoadIC::NameRegister())); + VisitForStackValue(prop->key()); // Leave receiver on stack - __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); + __ movp(LoadIC::ReceiverRegister(), Operand(rsp, kPointerSize)); // Copy of key, needed for later store. - __ Push(KeyedLoadIC::NameRegister()); + __ movp(LoadIC::NameRegister(), Operand(rsp, 0)); EmitKeyedPropertyLoad(prop); } } diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc index e08366504a..43d3228e51 100644 --- a/src/x64/ic-x64.cc +++ b/src/x64/ic-x64.cc @@ -327,32 +327,31 @@ static void GenerateKeyNameCheck(MacroAssembler* masm, void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- - ASSERT(rdx.is(ReceiverRegister())); - ASSERT(rax.is(NameRegister())); + // The return address is on the stack. Label slow, check_name, index_smi, index_name, property_array_property; Label probe_dictionary, check_number_dictionary; + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + ASSERT(receiver.is(rdx)); + ASSERT(key.is(rcx)); + // Check that the key is a smi. - __ JumpIfNotSmi(rax, &check_name); + __ JumpIfNotSmi(key, &check_name); __ bind(&index_smi); // Now the key is known to be a smi. This place is also jumped to from below // where a numeric string is converted to a smi. GenerateKeyedLoadReceiverCheck( - masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow); + masm, receiver, rax, Map::kHasIndexedInterceptor, &slow); // Check the receiver's map to see if it has fast elements. - __ CheckFastElements(rcx, &check_number_dictionary); + __ CheckFastElements(rax, &check_number_dictionary); GenerateFastArrayLoad(masm, - rdx, + receiver, + key, rax, - rcx, rbx, rax, NULL, @@ -362,50 +361,46 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { __ ret(0); __ bind(&check_number_dictionary); - __ SmiToInteger32(rbx, rax); - __ movp(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); + __ SmiToInteger32(rbx, key); + __ movp(rax, FieldOperand(receiver, JSObject::kElementsOffset)); // Check whether the elements is a number dictionary. - // rdx: receiver - // rax: key // rbx: key as untagged int32 - // rcx: elements - __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), + // rax: elements + __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), Heap::kHashTableMapRootIndex); __ j(not_equal, &slow); - __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax); + __ LoadFromNumberDictionary(&slow, rax, key, rbx, r9, rdi, rax); __ ret(0); __ bind(&slow); // Slow case: Jump to runtime. - // rdx: receiver - // rax: key __ IncrementCounter(counters->keyed_load_generic_slow(), 1); GenerateRuntimeGetProperty(masm); __ bind(&check_name); - GenerateKeyNameCheck(masm, rax, rcx, rbx, &index_name, &slow); + GenerateKeyNameCheck(masm, key, rax, rbx, &index_name, &slow); GenerateKeyedLoadReceiverCheck( - masm, rdx, rcx, Map::kHasNamedInterceptor, &slow); + masm, receiver, rax, Map::kHasNamedInterceptor, &slow); // If the receiver is a fast-case object, check the keyed lookup - // cache. Otherwise probe the dictionary leaving result in rcx. - __ movp(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); + // cache. Otherwise probe the dictionary leaving result in key. + __ movp(rbx, FieldOperand(receiver, JSObject::kPropertiesOffset)); __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), Heap::kHashTableMapRootIndex); __ j(equal, &probe_dictionary); // Load the map of the receiver, compute the keyed lookup cache hash // based on 32 bits of the map pointer and the string hash. - __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); - __ movl(rcx, rbx); - __ shrl(rcx, Immediate(KeyedLookupCache::kMapHashShift)); - __ movl(rdi, FieldOperand(rax, String::kHashFieldOffset)); + __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset)); + __ movl(rax, rbx); + __ shrl(rax, Immediate(KeyedLookupCache::kMapHashShift)); + __ movl(rdi, FieldOperand(key, String::kHashFieldOffset)); __ shrl(rdi, Immediate(String::kHashShift)); - __ xorp(rcx, rdi); + __ xorp(rax, rdi); int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); - __ andp(rcx, Immediate(mask)); + __ andp(rax, Immediate(mask)); // Load the key (consisting of map and internalized string) from the cache and // check for match. @@ -417,13 +412,13 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { for (int i = 0; i < kEntriesPerBucket - 1; i++) { Label try_next_entry; - __ movp(rdi, rcx); + __ movp(rdi, rax); __ shlp(rdi, Immediate(kPointerSizeLog2 + 1)); __ LoadAddress(kScratchRegister, cache_keys); int off = kPointerSize * i * 2; __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); __ j(not_equal, &try_next_entry); - __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); + __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); __ j(equal, &hit_on_nth_entry[i]); __ bind(&try_next_entry); } @@ -431,7 +426,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { int off = kPointerSize * (kEntriesPerBucket - 1) * 2; __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); __ j(not_equal, &slow); - __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); + __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); __ j(not_equal, &slow); // Get field offset, which is a 32-bit integer. @@ -442,12 +437,12 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { for (int i = kEntriesPerBucket - 1; i >= 0; i--) { __ bind(&hit_on_nth_entry[i]); if (i != 0) { - __ addl(rcx, Immediate(i)); + __ addl(rax, Immediate(i)); } __ LoadAddress(kScratchRegister, cache_field_offsets); - __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0)); - __ movzxbp(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); - __ subp(rdi, rcx); + __ movl(rdi, Operand(kScratchRegister, rax, times_4, 0)); + __ movzxbp(rax, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); + __ subp(rdi, rax); __ j(above_equal, &property_array_property); if (i != 0) { __ jmp(&load_in_object_property); @@ -456,15 +451,15 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // Load in-object property. __ bind(&load_in_object_property); - __ movzxbp(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset)); - __ addp(rcx, rdi); - __ movp(rax, FieldOperand(rdx, rcx, times_pointer_size, 0)); + __ movzxbp(rax, FieldOperand(rbx, Map::kInstanceSizeOffset)); + __ addp(rax, rdi); + __ movp(rax, FieldOperand(receiver, rax, times_pointer_size, 0)); __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); __ ret(0); // Load property array property. __ bind(&property_array_property); - __ movp(rax, FieldOperand(rdx, JSObject::kPropertiesOffset)); + __ movp(rax, FieldOperand(receiver, JSObject::kPropertiesOffset)); __ movp(rax, FieldOperand(rax, rdi, times_pointer_size, FixedArray::kHeaderSize)); __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); @@ -473,20 +468,18 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { // Do a quick inline probe of the receiver's dictionary, if it // exists. __ bind(&probe_dictionary); - // rdx: receiver - // rax: key // rbx: elements - __ movp(rcx, FieldOperand(rdx, JSObject::kMapOffset)); - __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); - GenerateGlobalInstanceTypeCheck(masm, rcx, &slow); + __ movp(rax, FieldOperand(receiver, JSObject::kMapOffset)); + __ movb(rax, FieldOperand(rax, Map::kInstanceTypeOffset)); + GenerateGlobalInstanceTypeCheck(masm, rax, &slow); - GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax); + GenerateDictionaryLoad(masm, &slow, rbx, key, rax, rdi, rax); __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); __ ret(0); __ bind(&index_name); - __ IndexFromHash(rbx, rax); + __ IndexFromHash(rbx, key); __ jmp(&index_smi); } @@ -497,7 +490,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) { Register receiver = ReceiverRegister(); Register index = NameRegister(); - Register scratch = rcx; + Register scratch = rbx; Register result = rax; ASSERT(!scratch.is(receiver) && !scratch.is(index)); @@ -526,7 +519,7 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { Register receiver = ReceiverRegister(); Register key = NameRegister(); - Register scratch = rcx; + Register scratch = rax; ASSERT(!scratch.is(receiver) && !scratch.is(key)); // Check that the receiver isn't a smi. @@ -887,23 +880,22 @@ static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : key - // -- rdx : receiver - // -- rsp[0] : return address - // ----------------------------------- - ASSERT(rdx.is(ReceiverRegister())); - ASSERT(rax.is(NameRegister())); + // The return address is on the stack. + Register receiver = ReceiverRegister(); + Register key = NameRegister(); + ASSERT(receiver.is(rdx)); + ASSERT(key.is(rcx)); + Label slow, notin; Operand mapped_location = GenerateMappedArgumentsLookup( - masm, rdx, rax, rbx, rcx, rdi, ¬in, &slow); + masm, receiver, key, rbx, rax, rdi, ¬in, &slow); __ movp(rax, mapped_location); __ Ret(); __ bind(¬in); // The unmapped lookup expects that the parameter map is in rbx. Operand unmapped_location = - GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow); + GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow); __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); __ j(equal, &slow); __ movp(rax, unmapped_location); @@ -953,18 +945,16 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- rax : receiver - // -- rcx : name - // -- rsp[0] : return address - // ----------------------------------- - ASSERT(rax.is(ReceiverRegister())); - ASSERT(rcx.is(NameRegister())); + // The return address is on the stack. + Register receiver = ReceiverRegister(); + Register name = NameRegister(); + ASSERT(receiver.is(rdx)); + ASSERT(name.is(rcx)); // Probe the stub cache. Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); masm->isolate()->stub_cache()->GenerateProbe( - masm, flags, rax, rcx, rbx, rdx); + masm, flags, receiver, name, rbx, rax); GenerateMiss(masm); } @@ -972,19 +962,19 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { void LoadIC::GenerateNormal(MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- rax : receiver + // -- rdx : receiver // -- rcx : name // -- rsp[0] : return address // ----------------------------------- - ASSERT(rax.is(ReceiverRegister())); + ASSERT(rdx.is(ReceiverRegister())); ASSERT(rcx.is(NameRegister())); Label miss, slow; - GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); + GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss); - // rdx: elements + // rax: elements // Search the dictionary placing the result in rax. - GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax); + GenerateDictionaryLoad(masm, &slow, rax, rcx, rbx, rdi, rax); __ ret(0); // Dictionary load failed, go slow (but don't miss). @@ -1055,10 +1045,8 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { // IC register specifications -const Register LoadIC::ReceiverRegister() { return rax; } +const Register LoadIC::ReceiverRegister() { return rdx; } const Register LoadIC::NameRegister() { return rcx; } -const Register KeyedLoadIC::ReceiverRegister() { return rdx; } -const Register KeyedLoadIC::NameRegister() { return rax; } void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 04d555168b..df3c5897da 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -3286,8 +3286,8 @@ Operand LCodeGen::BuildFastArrayOperand( void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->context()).is(rsi)); - ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister())); - ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister())); + ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); + ASSERT(ToRegister(instr->key()).is(LoadIC::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 c1022fbc17..b9de0488bb 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -2194,8 +2194,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* context = UseFixed(instr->context(), rsi); - LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister()); - LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister()); + LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister()); + LOperand* key = UseFixed(instr->key(), LoadIC::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 f7b2fe5b40..0298617cbb 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1224,16 +1224,16 @@ Register* LoadStubCompiler::registers() { // receiver, name, scratch1, scratch2, scratch3, scratch4. Register receiver = LoadIC::ReceiverRegister(); Register name = LoadIC::NameRegister(); - static Register registers[] = { receiver, name, rdx, rbx, rdi, r8 }; + static Register registers[] = { receiver, name, rax, rbx, rdi, r8 }; return registers; } Register* KeyedLoadStubCompiler::registers() { // receiver, name, scratch1, scratch2, scratch3, scratch4. - Register receiver = KeyedLoadIC::ReceiverRegister(); - Register name = KeyedLoadIC::NameRegister(); - static Register registers[] = { receiver, name, rbx, rcx, rdi, r8 }; + Register receiver = LoadIC::ReceiverRegister(); + Register name = LoadIC::NameRegister(); + static Register registers[] = { receiver, name, rax, rbx, rdi, r8 }; return registers; } @@ -1394,32 +1394,32 @@ Handle BaseLoadStoreStubCompiler::CompilePolymorphicIC( void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( MacroAssembler* masm) { // ----------- S t a t e ------------- - // -- rax : key + // -- rcx : key // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- - ASSERT(rdx.is(KeyedLoadIC::ReceiverRegister())); - ASSERT(rax.is(KeyedLoadIC::NameRegister())); + ASSERT(rdx.is(LoadIC::ReceiverRegister())); + ASSERT(rcx.is(LoadIC::NameRegister())); Label slow, miss; // This stub is meant to be tail-jumped to, the receiver must already // have been verified by the caller to not be a smi. - __ JumpIfNotSmi(rax, &miss); - __ SmiToInteger32(rbx, rax); - __ movp(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); + __ JumpIfNotSmi(rcx, &miss); + __ SmiToInteger32(rbx, rcx); + __ movp(rax, FieldOperand(rdx, JSObject::kElementsOffset)); // Check whether the elements is a number dictionary. // rdx: receiver - // rax: key + // rcx: key // rbx: key as untagged int32 - // rcx: elements - __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax); + // rax: elements + __ LoadFromNumberDictionary(&slow, rax, rcx, rbx, r9, rdi, rax); __ ret(0); __ bind(&slow); // ----------- S t a t e ------------- - // -- rax : key + // -- rcx : key // -- rdx : receiver // -- rsp[0] : return address // ----------------------------------- @@ -1427,7 +1427,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( __ bind(&miss); // ----------- S t a t e ------------- - // -- rax : key + // -- rcx : key // -- rdx : receiver // -- rsp[0] : return address // -----------------------------------