Commit c1aded3c authored by ishell's avatar ishell Committed by Commit bot

[ic] Fixed receiver_map register trashing in KeyedStoreIC megamorphic.

BUG=chromium:571370
LOG=Y

Review URL: https://codereview.chromium.org/1546323002

Cr-Commit-Position: refs/heads/master@{#33057}
parent 2fcf3aa6
......@@ -2091,6 +2091,7 @@ void MacroAssembler::StoreNumberToDoubleElements(
LowDwVfpRegister double_scratch,
Label* fail,
int elements_offset) {
DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1));
Label smi_value, store;
// Handle smi values specially.
......
......@@ -487,8 +487,11 @@ static void KeyedStoreGenerateMegamorphicHelper(
// Fast case: Do the store, could be either Object or double.
__ bind(fast_object);
Register scratch_value = r4;
Register scratch = r4;
Register address = r5;
DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
scratch, address));
if (check_map == kCheckMap) {
__ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
__ cmp(elements_map,
......@@ -501,12 +504,10 @@ static void KeyedStoreGenerateMegamorphicHelper(
// there may be a callback on the element
Label holecheck_passed1;
__ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ ldr(scratch_value,
MemOperand::PointerAddressFromSmiKey(address, key, PreIndex));
__ cmp(scratch_value, Operand(masm->isolate()->factory()->the_hole_value()));
__ ldr(scratch, MemOperand::PointerAddressFromSmiKey(address, key, PreIndex));
__ cmp(scratch, Operand(masm->isolate()->factory()->the_hole_value()));
__ b(ne, &holecheck_passed1);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&holecheck_passed1);
......@@ -516,8 +517,8 @@ static void KeyedStoreGenerateMegamorphicHelper(
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ add(scratch_value, key, Operand(Smi::FromInt(1)));
__ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ add(scratch, key, Operand(Smi::FromInt(1)));
__ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
// It's irrelevant whether array is smi-only or not when writing a smi.
__ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
......@@ -526,22 +527,21 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ bind(&non_smi_value);
// Escape to elements kind transition case.
__ CheckFastObjectElements(receiver_map, scratch_value,
&transition_smi_elements);
__ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
// Fast elements array, store the value to the elements backing store.
__ bind(&finish_object_store);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ add(scratch_value, key, Operand(Smi::FromInt(1)));
__ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ add(scratch, key, Operand(Smi::FromInt(1)));
__ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
__ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ add(address, address, Operand::PointerOffsetFromSmiKey(key));
__ str(value, MemOperand(address));
// Update write barrier for the elements array address.
__ mov(scratch_value, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch_value, kLRHasNotBeenSaved,
__ mov(scratch, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch, kLRHasNotBeenSaved,
kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ Ret();
......@@ -559,33 +559,31 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ add(address, elements,
Operand((FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32)) -
kHeapObjectTag));
__ ldr(scratch_value,
MemOperand(address, key, LSL, kPointerSizeLog2, PreIndex));
__ cmp(scratch_value, Operand(kHoleNanUpper32));
__ ldr(scratch, MemOperand(address, key, LSL, kPointerSizeLog2, PreIndex));
__ cmp(scratch, Operand(kHoleNanUpper32));
__ b(ne, &fast_double_without_map_check);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&fast_double_without_map_check);
__ StoreNumberToDoubleElements(value, key, elements, r3, d0,
__ StoreNumberToDoubleElements(value, key, elements, scratch, d0,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ add(scratch_value, key, Operand(Smi::FromInt(1)));
__ str(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ add(scratch, key, Operand(Smi::FromInt(1)));
__ str(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
__ Ret();
__ bind(&transition_smi_elements);
// Transition the array appropriately depending on the value type.
__ ldr(r4, FieldMemOperand(value, HeapObject::kMapOffset));
__ CompareRoot(r4, Heap::kHeapNumberMapRootIndex);
__ ldr(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
__ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
__ b(ne, &non_double_value);
// Value is a double. Transition FAST_SMI_ELEMENTS ->
// FAST_DOUBLE_ELEMENTS and complete the store.
__ LoadTransitionedArrayMapConditional(
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, r4, slow);
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
AllocationSiteMode mode =
AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
......@@ -596,7 +594,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ bind(&non_double_value);
// Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
receiver_map, r4, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
masm, receiver, key, value, receiver_map, mode, slow);
......@@ -608,7 +606,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
// HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
// transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
receiver_map, r4, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateDoubleToObject(
masm, receiver, key, value, receiver_map, mode, slow);
......
......@@ -477,8 +477,13 @@ static void KeyedStoreGenerateMegamorphicHelper(
// Fast case: Do the store, could be either Object or double.
__ bind(fast_object);
Register scratch_value = t0;
Register scratch = t0;
Register scratch2 = t4;
Register scratch3 = t5;
Register address = t1;
DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
scratch, scratch2, scratch3, address));
if (check_map == kCheckMap) {
__ lw(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
__ Branch(fast_double, ne, elements_map,
......@@ -492,11 +497,10 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ Addu(address, elements, FixedArray::kHeaderSize - kHeapObjectTag);
__ sll(at, key, kPointerSizeLog2 - kSmiTagSize);
__ addu(address, address, at);
__ lw(scratch_value, MemOperand(address));
__ Branch(&holecheck_passed1, ne, scratch_value,
__ lw(scratch, MemOperand(address));
__ Branch(&holecheck_passed1, ne, scratch,
Operand(masm->isolate()->factory()->the_hole_value()));
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&holecheck_passed1);
......@@ -506,35 +510,34 @@ static void KeyedStoreGenerateMegamorphicHelper(
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ Addu(scratch_value, key, Operand(Smi::FromInt(1)));
__ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ Addu(scratch, key, Operand(Smi::FromInt(1)));
__ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
// It's irrelevant whether array is smi-only or not when writing a smi.
__ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize);
__ Addu(address, address, scratch_value);
__ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
__ Addu(address, address, scratch);
__ sw(value, MemOperand(address));
__ Ret();
__ bind(&non_smi_value);
// Escape to elements kind transition case.
__ CheckFastObjectElements(receiver_map, scratch_value,
&transition_smi_elements);
__ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
// Fast elements array, store the value to the elements backing store.
__ bind(&finish_object_store);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ Addu(scratch_value, key, Operand(Smi::FromInt(1)));
__ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ Addu(scratch, key, Operand(Smi::FromInt(1)));
__ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
__ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize);
__ Addu(address, address, scratch_value);
__ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
__ Addu(address, address, scratch);
__ sw(value, MemOperand(address));
// Update write barrier for the elements array address.
__ mov(scratch_value, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch_value, kRAHasNotBeenSaved,
__ mov(scratch, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch, kRAHasNotBeenSaved,
kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ Ret();
......@@ -553,34 +556,31 @@ static void KeyedStoreGenerateMegamorphicHelper(
kHoleNanUpper32Offset - kHeapObjectTag));
__ sll(at, key, kPointerSizeLog2);
__ addu(address, address, at);
__ lw(scratch_value, MemOperand(address));
__ Branch(&fast_double_without_map_check, ne, scratch_value,
__ lw(scratch, MemOperand(address));
__ Branch(&fast_double_without_map_check, ne, scratch,
Operand(kHoleNanUpper32));
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&fast_double_without_map_check);
__ StoreNumberToDoubleElements(value, key,
elements, // Overwritten.
a3, // Scratch regs...
t0, t1, &transition_double_elements);
__ StoreNumberToDoubleElements(value, key, elements, scratch, scratch2,
scratch3, &transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ Addu(scratch_value, key, Operand(Smi::FromInt(1)));
__ sw(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ Addu(scratch, key, Operand(Smi::FromInt(1)));
__ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
__ Ret();
__ bind(&transition_smi_elements);
// Transition the array appropriately depending on the value type.
__ lw(t0, FieldMemOperand(value, HeapObject::kMapOffset));
__ lw(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
__ Branch(&non_double_value, ne, t0, Operand(at));
__ Branch(&non_double_value, ne, scratch, Operand(at));
// Value is a double. Transition FAST_SMI_ELEMENTS ->
// FAST_DOUBLE_ELEMENTS and complete the store.
__ LoadTransitionedArrayMapConditional(
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, t0, slow);
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
AllocationSiteMode mode =
AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
......@@ -591,7 +591,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ bind(&non_double_value);
// Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
receiver_map, t0, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
masm, receiver, key, value, receiver_map, mode, slow);
......@@ -603,7 +603,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
// HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
// transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
receiver_map, t0, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateDoubleToObject(
masm, receiver, key, value, receiver_map, mode, slow);
......
......@@ -474,8 +474,12 @@ static void KeyedStoreGenerateMegamorphicHelper(
// Fast case: Do the store, could be either Object or double.
__ bind(fast_object);
Register scratch_value = a4;
Register scratch = a4;
Register scratch2 = t0;
Register address = a5;
DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
scratch, scratch2, address));
if (check_map == kCheckMap) {
__ ld(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
__ Branch(fast_double, ne, elements_map,
......@@ -489,12 +493,11 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ Daddu(address, elements, FixedArray::kHeaderSize - kHeapObjectTag);
__ SmiScale(at, key, kPointerSizeLog2);
__ daddu(address, address, at);
__ ld(scratch_value, MemOperand(address));
__ ld(scratch, MemOperand(address));
__ Branch(&holecheck_passed1, ne, scratch_value,
__ Branch(&holecheck_passed1, ne, scratch,
Operand(masm->isolate()->factory()->the_hole_value()));
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&holecheck_passed1);
......@@ -504,37 +507,36 @@ static void KeyedStoreGenerateMegamorphicHelper(
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ Daddu(scratch_value, key, Operand(Smi::FromInt(1)));
__ sd(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ Daddu(scratch, key, Operand(Smi::FromInt(1)));
__ sd(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
// It's irrelevant whether array is smi-only or not when writing a smi.
__ Daddu(address, elements,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ SmiScale(scratch_value, key, kPointerSizeLog2);
__ Daddu(address, address, scratch_value);
__ SmiScale(scratch, key, kPointerSizeLog2);
__ Daddu(address, address, scratch);
__ sd(value, MemOperand(address));
__ Ret();
__ bind(&non_smi_value);
// Escape to elements kind transition case.
__ CheckFastObjectElements(receiver_map, scratch_value,
&transition_smi_elements);
__ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
// Fast elements array, store the value to the elements backing store.
__ bind(&finish_object_store);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ Daddu(scratch_value, key, Operand(Smi::FromInt(1)));
__ sd(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ Daddu(scratch, key, Operand(Smi::FromInt(1)));
__ sd(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
__ Daddu(address, elements,
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ SmiScale(scratch_value, key, kPointerSizeLog2);
__ Daddu(address, address, scratch_value);
__ SmiScale(scratch, key, kPointerSizeLog2);
__ Daddu(address, address, scratch);
__ sd(value, MemOperand(address));
// Update write barrier for the elements array address.
__ mov(scratch_value, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch_value, kRAHasNotBeenSaved,
__ mov(scratch, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch, kRAHasNotBeenSaved,
kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ Ret();
......@@ -554,34 +556,31 @@ static void KeyedStoreGenerateMegamorphicHelper(
kHeapObjectTag));
__ SmiScale(at, key, kPointerSizeLog2);
__ daddu(address, address, at);
__ lw(scratch_value, MemOperand(address));
__ Branch(&fast_double_without_map_check, ne, scratch_value,
__ lw(scratch, MemOperand(address));
__ Branch(&fast_double_without_map_check, ne, scratch,
Operand(static_cast<int32_t>(kHoleNanUpper32)));
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&fast_double_without_map_check);
__ StoreNumberToDoubleElements(value, key,
elements, // Overwritten.
a3, // Scratch regs...
a4, &transition_double_elements);
__ StoreNumberToDoubleElements(value, key, elements, scratch, scratch2,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ Daddu(scratch_value, key, Operand(Smi::FromInt(1)));
__ sd(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset));
__ Daddu(scratch, key, Operand(Smi::FromInt(1)));
__ sd(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset));
}
__ Ret();
__ bind(&transition_smi_elements);
// Transition the array appropriately depending on the value type.
__ ld(a4, FieldMemOperand(value, HeapObject::kMapOffset));
__ ld(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
__ Branch(&non_double_value, ne, a4, Operand(at));
__ Branch(&non_double_value, ne, scratch, Operand(at));
// Value is a double. Transition FAST_SMI_ELEMENTS ->
// FAST_DOUBLE_ELEMENTS and complete the store.
__ LoadTransitionedArrayMapConditional(
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, a4, slow);
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
AllocationSiteMode mode =
AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
......@@ -592,7 +591,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ bind(&non_double_value);
// Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
receiver_map, a4, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
masm, receiver, key, value, receiver_map, mode, slow);
......@@ -604,7 +603,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
// HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
// transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
receiver_map, a4, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateDoubleToObject(
masm, receiver, key, value, receiver_map, mode, slow);
......
......@@ -497,13 +497,16 @@ static void KeyedStoreGenerateMegamorphicHelper(
// Fast case: Do the store, could be either Object or double.
__ bind(fast_object);
Register scratch_value = r7;
Register scratch = r7;
Register scratch2 = r0;
Register address = r8;
DCHECK(!AreAliased(value, key, receiver, receiver_map, elements_map, elements,
scratch, scratch2, address));
if (check_map == kCheckMap) {
__ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
__ mov(scratch_value,
Operand(masm->isolate()->factory()->fixed_array_map()));
__ cmp(elements_map, scratch_value);
__ mov(scratch, Operand(masm->isolate()->factory()->fixed_array_map()));
__ cmp(elements_map, scratch);
__ bne(fast_double);
}
......@@ -512,13 +515,12 @@ static void KeyedStoreGenerateMegamorphicHelper(
// there may be a callback on the element
Label holecheck_passed1;
__ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ SmiToPtrArrayOffset(scratch_value, key);
__ LoadPX(scratch_value, MemOperand(address, scratch_value));
__ Cmpi(scratch_value, Operand(masm->isolate()->factory()->the_hole_value()),
r0);
__ SmiToPtrArrayOffset(scratch, key);
__ LoadPX(scratch, MemOperand(address, scratch));
__ Cmpi(scratch, Operand(masm->isolate()->factory()->the_hole_value()),
scratch2);
__ bne(&holecheck_passed1);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&holecheck_passed1);
......@@ -528,35 +530,34 @@ static void KeyedStoreGenerateMegamorphicHelper(
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0);
__ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset),
r0);
__ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2);
__ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset),
scratch2);
}
// It's irrelevant whether array is smi-only or not when writing a smi.
__ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ SmiToPtrArrayOffset(scratch_value, key);
__ StorePX(value, MemOperand(address, scratch_value));
__ SmiToPtrArrayOffset(scratch, key);
__ StorePX(value, MemOperand(address, scratch));
__ Ret();
__ bind(&non_smi_value);
// Escape to elements kind transition case.
__ CheckFastObjectElements(receiver_map, scratch_value,
&transition_smi_elements);
__ CheckFastObjectElements(receiver_map, scratch, &transition_smi_elements);
// Fast elements array, store the value to the elements backing store.
__ bind(&finish_object_store);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0);
__ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset),
r0);
__ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2);
__ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset),
scratch2);
}
__ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ SmiToPtrArrayOffset(scratch_value, key);
__ StorePUX(value, MemOperand(address, scratch_value));
__ SmiToPtrArrayOffset(scratch, key);
__ StorePUX(value, MemOperand(address, scratch));
// Update write barrier for the elements array address.
__ mr(scratch_value, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch_value, kLRHasNotBeenSaved,
__ mr(scratch, value); // Preserve the value which is returned.
__ RecordWrite(elements, address, scratch, kLRHasNotBeenSaved,
kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ Ret();
......@@ -574,21 +575,20 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ addi(address, elements,
Operand((FixedDoubleArray::kHeaderSize + Register::kExponentOffset -
kHeapObjectTag)));
__ SmiToDoubleArrayOffset(scratch_value, key);
__ lwzx(scratch_value, MemOperand(address, scratch_value));
__ Cmpi(scratch_value, Operand(kHoleNanUpper32), r0);
__ SmiToDoubleArrayOffset(scratch, key);
__ lwzx(scratch, MemOperand(address, scratch));
__ Cmpi(scratch, Operand(kHoleNanUpper32), scratch2);
__ bne(&fast_double_without_map_check);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
slow);
__ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch, slow);
__ bind(&fast_double_without_map_check);
__ StoreNumberToDoubleElements(value, key, elements, r6, d0,
__ StoreNumberToDoubleElements(value, key, elements, scratch, d0,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
__ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0);
__ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset),
r0);
__ AddSmiLiteral(scratch, key, Smi::FromInt(1), scratch2);
__ StoreP(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset),
scratch2);
}
__ Ret();
......@@ -601,7 +601,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
// Value is a double. Transition FAST_SMI_ELEMENTS ->
// FAST_DOUBLE_ELEMENTS and complete the store.
__ LoadTransitionedArrayMapConditional(
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, r7, slow);
FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, scratch, slow);
AllocationSiteMode mode =
AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
......@@ -612,7 +612,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
__ bind(&non_double_value);
// Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
receiver_map, r7, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
masm, receiver, key, value, receiver_map, mode, slow);
......@@ -624,7 +624,7 @@ static void KeyedStoreGenerateMegamorphicHelper(
// HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
// transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
__ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
receiver_map, r7, slow);
receiver_map, scratch, slow);
mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
ElementsTransitionGenerator::GenerateDoubleToObject(
masm, receiver, key, value, receiver_map, mode, slow);
......
......@@ -3715,6 +3715,8 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
Register scratch3,
Label* fail,
int elements_offset) {
DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1, scratch2,
scratch3));
Label smi_value, maybe_nan, have_double_value, is_nan, done;
Register mantissa_reg = scratch2;
Register exponent_reg = scratch3;
......@@ -3769,7 +3771,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
Addu(scratch1, scratch1, scratch2);
// scratch1 is now effective address of the double element
Register untagged_value = elements_reg;
Register untagged_value = scratch2;
SmiUntag(untagged_value, value_reg);
mtc1(untagged_value, f2);
cvt_d_w(f0, f2);
......@@ -5675,17 +5677,13 @@ void MacroAssembler::JumpIfDictionaryInPrototypeChain(
}
bool AreAliased(Register reg1,
Register reg2,
Register reg3,
Register reg4,
Register reg5,
Register reg6,
Register reg7,
Register reg8) {
int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() +
reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
reg7.is_valid() + reg8.is_valid();
bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
Register reg5, Register reg6, Register reg7, Register reg8,
Register reg9, Register reg10) {
int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() +
reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
reg7.is_valid() + reg8.is_valid() + reg9.is_valid() +
reg10.is_valid();
RegList regs = 0;
if (reg1.is_valid()) regs |= reg1.bit();
......@@ -5696,6 +5694,8 @@ bool AreAliased(Register reg1,
if (reg6.is_valid()) regs |= reg6.bit();
if (reg7.is_valid()) regs |= reg7.bit();
if (reg8.is_valid()) regs |= reg8.bit();
if (reg9.is_valid()) regs |= reg9.bit();
if (reg10.is_valid()) regs |= reg10.bit();
int n_of_non_aliasing_regs = NumRegs(regs);
return n_of_valid_regs != n_of_non_aliasing_regs;
......
......@@ -99,14 +99,11 @@ Register GetRegisterThatIsNotOneOf(Register reg1,
Register reg5 = no_reg,
Register reg6 = no_reg);
bool AreAliased(Register reg1,
Register reg2,
Register reg3 = no_reg,
Register reg4 = no_reg,
Register reg5 = no_reg,
Register reg6 = no_reg,
Register reg7 = no_reg,
Register reg8 = no_reg);
bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
Register reg4 = no_reg, Register reg5 = no_reg,
Register reg6 = no_reg, Register reg7 = no_reg,
Register reg8 = no_reg, Register reg9 = no_reg,
Register reg10 = no_reg);
// -----------------------------------------------------------------------------
......
......@@ -4039,6 +4039,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
Register scratch2,
Label* fail,
int elements_offset) {
DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1, scratch2));
Label smi_value, done;
// Handle smi values specially.
......@@ -4060,10 +4061,9 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
FPUCanonicalizeNaN(double_result, double_result);
bind(&smi_value);
// scratch1 is now effective address of the double element.
// Untag and transfer.
dsrl32(at, value_reg, 0);
mtc1(at, double_scratch);
dsrl32(scratch1, value_reg, 0);
mtc1(scratch1, double_scratch);
cvt_d_w(double_result, double_scratch);
bind(&done);
......@@ -4072,6 +4072,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
elements_offset));
dsra(scratch2, key_reg, 32 - kDoubleSizeLog2);
Daddu(scratch1, scratch1, scratch2);
// scratch1 is now effective address of the double element.
sdc1(double_result, MemOperand(scratch1, 0));
}
......@@ -6276,17 +6277,13 @@ void MacroAssembler::JumpIfDictionaryInPrototypeChain(
}
bool AreAliased(Register reg1,
Register reg2,
Register reg3,
Register reg4,
Register reg5,
Register reg6,
Register reg7,
Register reg8) {
int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() +
reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
reg7.is_valid() + reg8.is_valid();
bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
Register reg5, Register reg6, Register reg7, Register reg8,
Register reg9, Register reg10) {
int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() +
reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
reg7.is_valid() + reg8.is_valid() + reg9.is_valid() +
reg10.is_valid();
RegList regs = 0;
if (reg1.is_valid()) regs |= reg1.bit();
......@@ -6297,6 +6294,8 @@ bool AreAliased(Register reg1,
if (reg6.is_valid()) regs |= reg6.bit();
if (reg7.is_valid()) regs |= reg7.bit();
if (reg8.is_valid()) regs |= reg8.bit();
if (reg9.is_valid()) regs |= reg9.bit();
if (reg10.is_valid()) regs |= reg10.bit();
int n_of_non_aliasing_regs = NumRegs(regs);
return n_of_valid_regs != n_of_non_aliasing_regs;
......
......@@ -105,14 +105,11 @@ Register GetRegisterThatIsNotOneOf(Register reg1,
Register reg5 = no_reg,
Register reg6 = no_reg);
bool AreAliased(Register reg1,
Register reg2,
Register reg3 = no_reg,
Register reg4 = no_reg,
Register reg5 = no_reg,
Register reg6 = no_reg,
Register reg7 = no_reg,
Register reg8 = no_reg);
bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
Register reg4 = no_reg, Register reg5 = no_reg,
Register reg6 = no_reg, Register reg7 = no_reg,
Register reg8 = no_reg, Register reg9 = no_reg,
Register reg10 = no_reg);
// -----------------------------------------------------------------------------
......
......@@ -1835,6 +1835,7 @@ void MacroAssembler::StoreNumberToDoubleElements(
Register value_reg, Register key_reg, Register elements_reg,
Register scratch1, DoubleRegister double_scratch, Label* fail,
int elements_offset) {
DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1));
Label smi_value, store;
// Handle smi values specially.
......@@ -4206,10 +4207,12 @@ void MacroAssembler::JumpIfDictionaryInPrototypeChain(Register object,
#ifdef DEBUG
bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
Register reg5, Register reg6, Register reg7, Register reg8) {
Register reg5, Register reg6, Register reg7, Register reg8,
Register reg9, Register reg10) {
int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() +
reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
reg7.is_valid() + reg8.is_valid();
reg7.is_valid() + reg8.is_valid() + reg9.is_valid() +
reg10.is_valid();
RegList regs = 0;
if (reg1.is_valid()) regs |= reg1.bit();
......@@ -4220,6 +4223,8 @@ bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
if (reg6.is_valid()) regs |= reg6.bit();
if (reg7.is_valid()) regs |= reg7.bit();
if (reg8.is_valid()) regs |= reg8.bit();
if (reg9.is_valid()) regs |= reg9.bit();
if (reg10.is_valid()) regs |= reg10.bit();
int n_of_non_aliasing_regs = NumRegs(regs);
return n_of_valid_regs != n_of_non_aliasing_regs;
......
......@@ -66,7 +66,8 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg,
bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
Register reg4 = no_reg, Register reg5 = no_reg,
Register reg6 = no_reg, Register reg7 = no_reg,
Register reg8 = no_reg);
Register reg8 = no_reg, Register reg9 = no_reg,
Register reg10 = no_reg);
#endif
// These exist to provide portability between 32 and 64bit
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var val = [0.5];
var arr = [0.5];
for (var i = -1; i < 1; i++) {
arr[i] = val;
}
assertEquals(val, arr[-1]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment