| Index: src/arm/code-stubs-arm.cc
|
| ===================================================================
|
| --- src/arm/code-stubs-arm.cc (revision 12826)
|
| +++ src/arm/code-stubs-arm.cc (working copy)
|
| @@ -347,7 +347,8 @@
|
| ? FixedDoubleArray::SizeFor(length)
|
| : FixedArray::SizeFor(length);
|
| }
|
| - int size = JSArray::kSize + elements_size;
|
| + int elements_offset = JSArray::kSize;
|
| + int size = elements_offset + elements_size;
|
|
|
| // Allocate both the JS array and the elements array in one big
|
| // allocation. This avoids multiple limit checks.
|
| @@ -356,27 +357,44 @@
|
| r1,
|
| r2,
|
| fail,
|
| - TAG_OBJECT);
|
| + NO_ALLOCATION_FLAGS);
|
|
|
| // Copy the JS array part.
|
| - for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
|
| - if ((i != JSArray::kElementsOffset) || (length == 0)) {
|
| - __ ldr(r1, FieldMemOperand(r3, i));
|
| - __ str(r1, FieldMemOperand(r0, i));
|
| - }
|
| + __ sub(r3, r3, Operand(kHeapObjectTag));
|
| + STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
|
| + RegList temps = r4.bit() | r5.bit() | r6.bit() | r7.bit();
|
| + __ ldm(ia_w, r3, temps);
|
| + if (length > 0) {
|
| + // Set the pointer to the elements array if it is non-empty. r0 is untagged,
|
| + // so we need to include the tag here.
|
| + STATIC_ASSERT(JSArray::kElementsOffset == 2 * kPointerSize);
|
| + __ add(r6, r0, Operand(elements_offset + kHeapObjectTag));
|
| }
|
| + __ stm(ia_w, r0, temps);
|
|
|
| + // Copy the elements from the boilerplate array, if needed. At this point,
|
| + // r0 points to the beginning of elements.
|
| + int restore_size = JSArray::kSize - kHeapObjectTag;
|
| if (length > 0) {
|
| - // Get hold of the elements array of the boilerplate and setup the
|
| - // elements pointer in the resulting object.
|
| - __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
|
| - __ add(r2, r0, Operand(JSArray::kSize));
|
| - __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset));
|
| -
|
| - // Copy the elements array.
|
| + // Load the elements array from the boilerplate.
|
| + __ ldr(r3, MemOperand(r3, JSArray::kElementsOffset - JSArray::kSize));
|
| ASSERT((elements_size % kPointerSize) == 0);
|
| - __ CopyFields(r2, r3, r1.bit(), elements_size / kPointerSize);
|
| + if (CpuFeatures::IsSupported(VFP2)) {
|
| + CpuFeatures::Scope scope(VFP2);
|
| + SwVfpRegister first_reg = s0;
|
| + SwVfpRegister last_reg = s15;
|
| + __ sub(r3, r3, Operand(kHeapObjectTag));
|
| + __ VFPCopyFields(r0, r3, elements_size / kPointerSize,
|
| + first_reg, last_reg);
|
| + restore_size += elements_size;
|
| + } else {
|
| + __ CopyFields(r6, r3, r1.bit(), elements_size / kPointerSize);
|
| + }
|
| }
|
| +
|
| + // At this point, r0 points to the end of the copied region. Bring it back to
|
| + // the beginning and tag it.
|
| + __ sub(r0, r0, Operand(restore_size));
|
| }
|
|
|
| void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
| @@ -484,10 +502,20 @@
|
|
|
| // Allocate the JS object and copy header together with all in-object
|
| // properties from the boilerplate.
|
| - __ AllocateInNewSpace(size, r0, r1, r2, &slow_case, TAG_OBJECT);
|
| - for (int i = 0; i < size; i += kPointerSize) {
|
| - __ ldr(r1, FieldMemOperand(r3, i));
|
| - __ str(r1, FieldMemOperand(r0, i));
|
| + if (CpuFeatures::IsSupported(VFP2)) {
|
| + CpuFeatures::Scope scope(VFP2);
|
| + __ AllocateInNewSpace(size, r0, r1, r2, &slow_case, NO_ALLOCATION_FLAGS);
|
| + SwVfpRegister first_reg = s0;
|
| + SwVfpRegister last_reg = s15;
|
| + __ sub(r3, r3, Operand(kHeapObjectTag));
|
| + __ VFPCopyFields(r0, r3, size / kPointerSize, first_reg, last_reg);
|
| + __ sub(r0, r0, Operand(size - kHeapObjectTag));
|
| + } else {
|
| + __ AllocateInNewSpace(size, r0, r1, r2, &slow_case, TAG_OBJECT);
|
| + for (int i = 0; i < size; i += kPointerSize) {
|
| + __ ldr(r1, FieldMemOperand(r3, i));
|
| + __ str(r1, FieldMemOperand(r0, i));
|
| + }
|
| }
|
|
|
| // Return and remove the on-stack parameters.
|
|
|