| Index: src/arm/builtins-arm.cc
|
| ===================================================================
|
| --- src/arm/builtins-arm.cc (revision 9808)
|
| +++ src/arm/builtins-arm.cc (working copy)
|
| @@ -86,12 +86,6 @@
|
| }
|
|
|
|
|
| -// This constant has the same value as JSArray::kPreallocatedArrayElements and
|
| -// if JSArray::kPreallocatedArrayElements is changed handling of loop unfolding
|
| -// below should be reconsidered.
|
| -static const int kLoopUnfoldLimit = 4;
|
| -
|
| -
|
| // Allocate an empty JSArray. The allocated array is put into the result
|
| // register. An elements backing store is allocated with size initial_capacity
|
| // and filled with the hole values.
|
| @@ -101,9 +95,9 @@
|
| Register scratch1,
|
| Register scratch2,
|
| Register scratch3,
|
| - int initial_capacity,
|
| Label* gc_required) {
|
| - ASSERT(initial_capacity > 0);
|
| + const int initial_capacity = JSArray::kPreallocatedArrayElements;
|
| + STATIC_ASSERT(initial_capacity >= 0);
|
| // Load the initial map from the array function.
|
| __ ldr(scratch1, FieldMemOperand(array_function,
|
| JSFunction::kPrototypeOrInitialMapOffset));
|
| @@ -153,12 +147,24 @@
|
| ASSERT_EQ(1 * kPointerSize, FixedArray::kLengthOffset);
|
| __ str(scratch3, MemOperand(scratch1, kPointerSize, PostIndex));
|
|
|
| - // Fill the FixedArray with the hole value.
|
| + // Fill the FixedArray with the hole value. Inline the code if short.
|
| + if (initial_capacity == 0) return;
|
| ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
|
| - ASSERT(initial_capacity <= kLoopUnfoldLimit);
|
| __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex);
|
| - for (int i = 0; i < initial_capacity; i++) {
|
| + static const int kLoopUnfoldLimit = 4;
|
| + if (initial_capacity <= kLoopUnfoldLimit) {
|
| + for (int i = 0; i < initial_capacity; i++) {
|
| + __ str(scratch3, MemOperand(scratch1, kPointerSize, PostIndex));
|
| + }
|
| + } else {
|
| + Label loop, entry;
|
| + __ add(scratch2, scratch1, Operand(initial_capacity * kPointerSize));
|
| + __ b(&entry);
|
| + __ bind(&loop);
|
| __ str(scratch3, MemOperand(scratch1, kPointerSize, PostIndex));
|
| + __ bind(&entry);
|
| + __ cmp(scratch1, scratch2);
|
| + __ b(lt, &loop);
|
| }
|
| }
|
|
|
| @@ -173,7 +179,7 @@
|
| // register elements_array_storage is scratched.
|
| static void AllocateJSArray(MacroAssembler* masm,
|
| Register array_function, // Array function.
|
| - Register array_size, // As a smi.
|
| + Register array_size, // As a smi, cannot be 0.
|
| Register result,
|
| Register elements_array_storage,
|
| Register elements_array_end,
|
| @@ -181,32 +187,18 @@
|
| Register scratch2,
|
| bool fill_with_hole,
|
| Label* gc_required) {
|
| - Label not_empty, allocated;
|
| -
|
| // Load the initial map from the array function.
|
| __ ldr(elements_array_storage,
|
| FieldMemOperand(array_function,
|
| JSFunction::kPrototypeOrInitialMapOffset));
|
|
|
| - // Check whether an empty sized array is requested.
|
| - __ tst(array_size, array_size);
|
| - __ b(ne, ¬_empty);
|
| + if (FLAG_debug_code) { // Assert that array size is not zero.
|
| + __ tst(array_size, array_size);
|
| + __ Assert(ne, "array size is unexpectedly 0");
|
| + }
|
|
|
| - // If an empty array is requested allocate a small elements array anyway. This
|
| - // keeps the code below free of special casing for the empty array.
|
| - int size = JSArray::kSize +
|
| - FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
|
| - __ AllocateInNewSpace(size,
|
| - result,
|
| - elements_array_end,
|
| - scratch1,
|
| - gc_required,
|
| - TAG_OBJECT);
|
| - __ jmp(&allocated);
|
| -
|
| // Allocate the JSArray object together with space for a FixedArray with the
|
| // requested number of elements.
|
| - __ bind(¬_empty);
|
| STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
|
| __ mov(elements_array_end,
|
| Operand((JSArray::kSize + FixedArray::kHeaderSize) / kPointerSize));
|
| @@ -226,7 +218,6 @@
|
| // result: JSObject
|
| // elements_array_storage: initial map
|
| // array_size: size of array (smi)
|
| - __ bind(&allocated);
|
| __ str(elements_array_storage, FieldMemOperand(result, JSObject::kMapOffset));
|
| __ LoadRoot(elements_array_storage, Heap::kEmptyFixedArrayRootIndex);
|
| __ str(elements_array_storage,
|
| @@ -256,14 +247,6 @@
|
| ASSERT_EQ(0 * kPointerSize, FixedArray::kMapOffset);
|
| __ str(scratch1, MemOperand(elements_array_storage, kPointerSize, PostIndex));
|
| STATIC_ASSERT(kSmiTag == 0);
|
| - __ tst(array_size, array_size);
|
| - // Length of the FixedArray is the number of pre-allocated elements if
|
| - // the actual JSArray has length 0 and the size of the JSArray for non-empty
|
| - // JSArrays. The length of a FixedArray is stored as a smi.
|
| - __ mov(array_size,
|
| - Operand(Smi::FromInt(JSArray::kPreallocatedArrayElements)),
|
| - LeaveCC,
|
| - eq);
|
| ASSERT_EQ(1 * kPointerSize, FixedArray::kLengthOffset);
|
| __ str(array_size,
|
| MemOperand(elements_array_storage, kPointerSize, PostIndex));
|
| @@ -311,20 +294,20 @@
|
| static void ArrayNativeCode(MacroAssembler* masm,
|
| Label* call_generic_code) {
|
| Counters* counters = masm->isolate()->counters();
|
| - Label argc_one_or_more, argc_two_or_more;
|
| + Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array;
|
|
|
| // Check for array construction with zero arguments or one.
|
| __ cmp(r0, Operand(0, RelocInfo::NONE));
|
| __ b(ne, &argc_one_or_more);
|
|
|
| // Handle construction of an empty array.
|
| + __ bind(&empty_array);
|
| AllocateEmptyJSArray(masm,
|
| r1,
|
| r2,
|
| r3,
|
| r4,
|
| r5,
|
| - JSArray::kPreallocatedArrayElements,
|
| call_generic_code);
|
| __ IncrementCounter(counters->array_function_native(), 1, r3, r4);
|
| // Setup return value, remove receiver from stack and return.
|
| @@ -339,6 +322,13 @@
|
| __ b(ne, &argc_two_or_more);
|
| STATIC_ASSERT(kSmiTag == 0);
|
| __ ldr(r2, MemOperand(sp)); // Get the argument from the stack.
|
| + __ tst(r2, r2);
|
| + __ b(ne, ¬_empty_array);
|
| + __ Drop(1); // Adjust stack.
|
| + __ mov(r0, Operand(0)); // Treat this as a call with argc of zero.
|
| + __ b(&empty_array);
|
| +
|
| + __ bind(¬_empty_array);
|
| __ and_(r3, r2, Operand(kIntptrSignBit | kSmiTagMask), SetCC);
|
| __ b(ne, call_generic_code);
|
|
|
| @@ -1027,9 +1017,9 @@
|
| __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
|
|
|
| // Set up the roots register.
|
| - ExternalReference roots_address =
|
| - ExternalReference::roots_address(masm->isolate());
|
| - __ mov(r10, Operand(roots_address));
|
| + ExternalReference roots_array_start =
|
| + ExternalReference::roots_array_start(masm->isolate());
|
| + __ mov(r10, Operand(roots_array_start));
|
|
|
| // Push the function and the receiver onto the stack.
|
| __ push(r1);
|
|
|