Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1478)

Unified Diff: src/x64/ic-x64.cc

Issue 381633002: Use a register spec for StoreIC and KeyedStoreIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Code comments. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/ic-x64.cc
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 43d3228e51faf64aba9aaf35b8efccc94db21376..caa8d4c83fbe029ca74cc0e7ecb864f466d2198a 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -567,12 +567,16 @@ static void KeyedStoreGenerateGenericHelper(
Label transition_smi_elements;
Label finish_object_store, non_double_value, transition_double_elements;
Label fast_double_without_map_check;
+ Register receiver = KeyedStoreIC::ReceiverRegister();
+ Register key = KeyedStoreIC::NameRegister();
+ Register value = KeyedStoreIC::ValueRegister();
+ ASSERT(receiver.is(rdx));
+ ASSERT(key.is(rcx));
+ ASSERT(value.is(rax));
// Fast case: Do the store, could be either Object or double.
__ bind(fast_object);
- // rax: value
// rbx: receiver's elements array (a FixedArray)
- // rcx: index
- // rdx: receiver (a JSArray)
+ // receiver is a JSArray.
// r9: map of receiver
if (check_map == kCheckMap) {
__ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
@@ -585,26 +589,26 @@ static void KeyedStoreGenerateGenericHelper(
// there may be a callback on the element
Label holecheck_passed1;
__ movp(kScratchRegister, FieldOperand(rbx,
- rcx,
+ key,
times_pointer_size,
FixedArray::kHeaderSize));
__ CompareRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &holecheck_passed1);
- __ JumpIfDictionaryInPrototypeChain(rdx, rdi, kScratchRegister, slow);
+ __ JumpIfDictionaryInPrototypeChain(receiver, rdi, kScratchRegister, slow);
__ bind(&holecheck_passed1);
// Smi stores don't require further checks.
Label non_smi_value;
- __ JumpIfNotSmi(rax, &non_smi_value);
+ __ JumpIfNotSmi(value, &non_smi_value);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ __ leal(rdi, Operand(key, 1));
+ __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
}
// It's irrelevant whether array is smi-only or not when writing a smi.
- __ movp(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
- rax);
+ __ movp(FieldOperand(rbx, key, times_pointer_size, FixedArray::kHeaderSize),
+ value);
__ ret(0);
__ bind(&non_smi_value);
@@ -615,14 +619,14 @@ static void KeyedStoreGenerateGenericHelper(
__ bind(&finish_object_store);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ __ leal(rdi, Operand(key, 1));
+ __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
}
- __ movp(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
- rax);
- __ movp(rdx, rax); // Preserve the value which is returned.
+ __ movp(FieldOperand(rbx, key, times_pointer_size, FixedArray::kHeaderSize),
+ value);
+ __ movp(rdx, value); // Preserve the value which is returned.
__ RecordWriteArray(
- rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+ rbx, rdx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ ret(0);
__ bind(fast_double);
@@ -638,25 +642,25 @@ static void KeyedStoreGenerateGenericHelper(
// We have to see if the double version of the hole is present. If so
// go to the runtime.
uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
- __ cmpl(FieldOperand(rbx, rcx, times_8, offset), Immediate(kHoleNanUpper32));
+ __ cmpl(FieldOperand(rbx, key, times_8, offset), Immediate(kHoleNanUpper32));
__ j(not_equal, &fast_double_without_map_check);
- __ JumpIfDictionaryInPrototypeChain(rdx, rdi, kScratchRegister, slow);
+ __ JumpIfDictionaryInPrototypeChain(receiver, rdi, kScratchRegister, slow);
__ bind(&fast_double_without_map_check);
- __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0,
+ __ StoreNumberToDoubleElements(value, rbx, key, xmm0,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
- __ leal(rdi, Operand(rcx, 1));
- __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
+ __ leal(rdi, Operand(key, 1));
+ __ Integer32ToSmiField(FieldOperand(receiver, JSArray::kLengthOffset), rdi);
}
__ ret(0);
__ bind(&transition_smi_elements);
- __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
+ __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
// Transition the array appropriately depending on the value type.
- __ movp(r9, FieldOperand(rax, HeapObject::kMapOffset));
+ __ movp(r9, FieldOperand(value, HeapObject::kMapOffset));
__ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
__ j(not_equal, &non_double_value);
@@ -670,7 +674,7 @@ static void KeyedStoreGenerateGenericHelper(
AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS,
FAST_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow);
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&fast_double_without_map_check);
__ bind(&non_double_value);
@@ -683,14 +687,14 @@ static void KeyedStoreGenerateGenericHelper(
mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode,
slow);
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
__ bind(&transition_double_elements);
// Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
// HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
// transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
- __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
+ __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
__ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
FAST_ELEMENTS,
rbx,
@@ -698,35 +702,34 @@ static void KeyedStoreGenerateGenericHelper(
slow);
mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow);
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
__ jmp(&finish_object_store);
}
void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
Label slow, slow_with_tagged_index, fast_object, fast_object_grow;
Label fast_double, fast_double_grow;
Label array, extra, check_if_double_array;
+ Register receiver = ReceiverRegister();
+ Register key = NameRegister();
+ ASSERT(receiver.is(rdx));
+ ASSERT(key.is(rcx));
// Check that the object isn't a smi.
- __ JumpIfSmi(rdx, &slow_with_tagged_index);
+ __ JumpIfSmi(receiver, &slow_with_tagged_index);
// Get the map from the receiver.
- __ movp(r9, FieldOperand(rdx, HeapObject::kMapOffset));
+ __ movp(r9, FieldOperand(receiver, HeapObject::kMapOffset));
// Check that the receiver does not require access checks and is not observed.
// The generic stub does not perform map checks or handle observed objects.
__ testb(FieldOperand(r9, Map::kBitFieldOffset),
Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
__ j(not_zero, &slow_with_tagged_index);
// Check that the key is a smi.
- __ JumpIfNotSmi(rcx, &slow_with_tagged_index);
- __ SmiToInteger32(rcx, rcx);
+ __ JumpIfNotSmi(key, &slow_with_tagged_index);
+ __ SmiToInteger32(key, key);
__ CmpInstanceType(r9, JS_ARRAY_TYPE);
__ j(equal, &array);
@@ -735,20 +738,15 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
__ j(below, &slow);
// Object case: Check key against length in the elements array.
- // rax: value
- // rdx: JSObject
- // rcx: index
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
// Check array bounds.
- __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
- // rax: value
+ __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key);
// rbx: FixedArray
- // rcx: index
__ j(above, &fast_object);
// Slow case: call runtime.
__ bind(&slow);
- __ Integer32ToSmi(rcx, rcx);
+ __ Integer32ToSmi(key, key);
__ bind(&slow_with_tagged_index);
GenerateRuntimeSetProperty(masm, strict_mode);
// Never returns to here.
@@ -757,13 +755,11 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// perform the store and update the length. Used for adding one
// element to the array by writing to array[array.length].
__ bind(&extra);
- // rax: value
- // rdx: receiver (a JSArray)
+ // receiver is a JSArray.
// rbx: receiver's elements array (a FixedArray)
- // rcx: index
- // flags: smicompare (rdx.length(), rbx)
+ // flags: smicompare (receiver.length(), rbx)
__ j(not_equal, &slow); // do not leave holes in the array
- __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
+ __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), key);
__ j(below_equal, &slow);
// Increment index to get new length.
__ movp(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
@@ -781,14 +777,12 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
// array. Check that the array is in fast mode (and writable); if it
// is the length is always a smi.
__ bind(&array);
- // rax: value
- // rdx: receiver (a JSArray)
- // rcx: index
- __ movp(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
+ // receiver is a JSArray.
+ __ movp(rbx, FieldOperand(receiver, JSObject::kElementsOffset));
// Check the key against the length in the array, compute the
// address to store into and fall through to fast case.
- __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
+ __ SmiCompareInteger32(FieldOperand(receiver, JSArray::kLengthOffset), key);
__ j(below_equal, &extra);
KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double,
@@ -906,18 +900,20 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // The return address is on the stack.
Label slow, notin;
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ Register value = ValueRegister();
+ ASSERT(receiver.is(rdx));
+ ASSERT(name.is(rcx));
+ ASSERT(value.is(rax));
+
Operand mapped_location = GenerateMappedArgumentsLookup(
- masm, rdx, rcx, rbx, rdi, r8, &notin, &slow);
- __ movp(mapped_location, rax);
+ masm, receiver, name, rbx, rdi, r8, &notin, &slow);
+ __ movp(mapped_location, value);
__ leap(r9, mapped_location);
- __ movp(r8, rax);
+ __ movp(r8, value);
__ RecordWrite(rbx,
r9,
r8,
@@ -928,10 +924,10 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
__ bind(&notin);
// The unmapped lookup expects that the parameter map is in rbx.
Operand unmapped_location =
- GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rdi, &slow);
- __ movp(unmapped_location, rax);
+ GenerateUnmappedArgumentsLookup(masm, name, rbx, rdi, &slow);
+ __ movp(unmapped_location, value);
__ leap(r9, unmapped_location);
- __ movp(r8, rax);
+ __ movp(r8, value);
__ RecordWrite(rbx,
r9,
r8,
@@ -1049,6 +1045,26 @@ const Register LoadIC::ReceiverRegister() { return rdx; }
const Register LoadIC::NameRegister() { return rcx; }
+const Register StoreIC::ReceiverRegister() { return rdx; }
+const Register StoreIC::NameRegister() { return rcx; }
+const Register StoreIC::ValueRegister() { return rax; }
+
+
+const Register KeyedStoreIC::ReceiverRegister() {
+ return StoreIC::ReceiverRegister();
+}
+
+
+const Register KeyedStoreIC::NameRegister() {
+ return StoreIC::NameRegister();
+}
+
+
+const Register KeyedStoreIC::ValueRegister() {
+ return StoreIC::ValueRegister();
+}
+
+
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is on the stack.
@@ -1063,36 +1079,36 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // The return address is on the stack.
// Get the receiver from the stack and probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::STORE_IC);
masm->isolate()->stub_cache()->GenerateProbe(
- masm, flags, rdx, rcx, rbx, no_reg);
+ masm, flags, ReceiverRegister(), NameRegister(), rbx, no_reg);
// Cache miss: Jump to runtime.
GenerateMiss(masm);
}
-void StoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+static void StoreIC_PushArgs(MacroAssembler* masm) {
+ Register receiver = StoreIC::ReceiverRegister();
+ Register name = StoreIC::NameRegister();
+ Register value = StoreIC::ValueRegister();
+
+ ASSERT(!rbx.is(receiver) && !rbx.is(name) && !rbx.is(value));
__ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // name
- __ Push(rax); // value
+ __ Push(receiver);
+ __ Push(name);
+ __ Push(value);
__ PushReturnAddressFrom(rbx);
+}
+
+
+void StoreIC::GenerateMiss(MacroAssembler* masm) {
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Perform tail call to the entry.
ExternalReference ref =
@@ -1102,18 +1118,16 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) {
void StoreIC::GenerateNormal(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
+ Register receiver = ReceiverRegister();
+ Register name = NameRegister();
+ Register value = ValueRegister();
Label miss;
- GenerateNameDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
+ GenerateNameDictionaryReceiverCheck(masm, receiver, rbx, rdi, &miss);
- GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
+ GenerateDictionaryStore(masm, &miss, rbx, name, value, r8, r9);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->store_normal_hit(), 1);
__ ret(0);
@@ -1126,16 +1140,14 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) {
void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : name
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
+ ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) &&
+ !rbx.is(ValueRegister()));
+
__ PopReturnAddressTo(rbx);
- __ Push(rdx);
- __ Push(rcx);
- __ Push(rax);
+ __ Push(ReceiverRegister());
+ __ Push(NameRegister());
+ __ Push(ValueRegister());
__ Push(Smi::FromInt(strict_mode));
__ PushReturnAddressFrom(rbx);
@@ -1146,17 +1158,14 @@ void StoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
StrictMode strict_mode) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
+ ASSERT(!rbx.is(ReceiverRegister()) && !rbx.is(NameRegister()) &&
+ !rbx.is(ValueRegister()));
__ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
+ __ Push(ReceiverRegister());
+ __ Push(NameRegister());
+ __ Push(ValueRegister());
__ Push(Smi::FromInt(strict_mode)); // Strict mode.
__ PushReturnAddressFrom(rbx);
@@ -1166,18 +1175,8 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
void StoreIC::GenerateSlow(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
-
- __ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
- __ PushReturnAddressFrom(rbx);
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(kStoreIC_Slow), masm->isolate());
@@ -1186,18 +1185,8 @@ void StoreIC::GenerateSlow(MacroAssembler* masm) {
void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
-
- __ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
- __ PushReturnAddressFrom(rbx);
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref(IC_Utility(kKeyedStoreIC_Slow), masm->isolate());
@@ -1206,18 +1195,8 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) {
void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- rax : value
- // -- rcx : key
- // -- rdx : receiver
- // -- rsp[0] : return address
- // -----------------------------------
-
- __ PopReturnAddressTo(rbx);
- __ Push(rdx); // receiver
- __ Push(rcx); // key
- __ Push(rax); // value
- __ PushReturnAddressFrom(rbx);
+ // Return address is on the stack.
+ StoreIC_PushArgs(masm);
// Do tail-call to runtime routine.
ExternalReference ref =
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698