| 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);
|
| }
|
|
|
|
|
|
|