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