Index: src/arm/codegen-arm.cc |
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc |
index ce35b97c1841ae74d946919449882139b82ed927..506f9b2d5dcdca0ba2de06d5cabf4ac429747fb9 100644 |
--- a/src/arm/codegen-arm.cc |
+++ b/src/arm/codegen-arm.cc |
@@ -90,11 +90,16 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( |
// -- r3 : target map, scratch for subsequent call |
// -- r4 : scratch (elements) |
// ----------------------------------- |
- Label loop, entry, convert_hole, gc_required; |
+ Label loop, entry, convert_hole, gc_required, only_change_map, done; |
bool vfp3_supported = CpuFeatures::IsSupported(VFP3); |
- __ push(lr); |
+ // Check for empty arrays, which only require a map transition and no changes |
+ // to the backing store. |
__ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); |
+ __ CompareRoot(r4, Heap::kEmptyFixedArrayRootIndex); |
+ __ b(eq, &only_change_map); |
+ |
+ __ push(lr); |
__ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); |
// r4: source FixedArray |
// r5: number of elements (smi-tagged) |
@@ -117,7 +122,7 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( |
r9, |
kLRHasBeenSaved, |
kDontSaveFPRegs, |
- EMIT_REMEMBERED_SET, |
+ OMIT_REMEMBERED_SET, |
OMIT_SMI_CHECK); |
// Replace receiver's backing store with newly created FixedDoubleArray. |
__ add(r3, r6, Operand(kHeapObjectTag)); |
@@ -146,6 +151,18 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( |
__ b(&entry); |
+ __ bind(&only_change_map); |
+ __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
+ __ RecordWriteField(r2, |
+ HeapObject::kMapOffset, |
+ r3, |
+ r9, |
+ kLRHasBeenSaved, |
+ kDontSaveFPRegs, |
+ OMIT_REMEMBERED_SET, |
+ OMIT_SMI_CHECK); |
+ __ b(&done); |
+ |
// Call into runtime if GC is required. |
__ bind(&gc_required); |
__ pop(lr); |
@@ -194,6 +211,7 @@ void ElementsTransitionGenerator::GenerateSmiOnlyToDouble( |
if (!vfp3_supported) __ Pop(r1, r0); |
__ pop(lr); |
+ __ bind(&done); |
} |
@@ -207,10 +225,15 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( |
// -- r3 : target map, scratch for subsequent call |
// -- r4 : scratch (elements) |
// ----------------------------------- |
- Label entry, loop, convert_hole, gc_required; |
+ Label entry, loop, convert_hole, gc_required, only_change_map; |
- __ push(lr); |
+ // Check for empty arrays, which only require a map transition and no changes |
+ // to the backing store. |
__ ldr(r4, FieldMemOperand(r2, JSObject::kElementsOffset)); |
+ __ CompareRoot(r4, Heap::kEmptyFixedArrayRootIndex); |
+ __ b(eq, &only_change_map); |
+ |
+ __ push(lr); |
__ Push(r3, r2, r1, r0); |
__ ldr(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); |
// r4: source FixedDoubleArray |
@@ -280,16 +303,6 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( |
__ b(lt, &loop); |
__ Pop(r3, r2, r1, r0); |
- // Update receiver's map. |
- __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
- __ RecordWriteField(r2, |
- HeapObject::kMapOffset, |
- r3, |
- r9, |
- kLRHasBeenSaved, |
- kDontSaveFPRegs, |
- EMIT_REMEMBERED_SET, |
- OMIT_SMI_CHECK); |
// Replace receiver's backing store with newly created and filled FixedArray. |
__ str(r6, FieldMemOperand(r2, JSObject::kElementsOffset)); |
__ RecordWriteField(r2, |
@@ -301,6 +314,18 @@ void ElementsTransitionGenerator::GenerateDoubleToObject( |
EMIT_REMEMBERED_SET, |
OMIT_SMI_CHECK); |
__ pop(lr); |
+ |
+ __ bind(&only_change_map); |
+ // Update receiver's map. |
+ __ str(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
+ __ RecordWriteField(r2, |
+ HeapObject::kMapOffset, |
+ r3, |
+ r9, |
+ kLRHasNotBeenSaved, |
+ kDontSaveFPRegs, |
+ OMIT_REMEMBERED_SET, |
+ OMIT_SMI_CHECK); |
} |