| Index: src/ia32/builtins-ia32.cc
|
| diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
|
| index 0ff5077565b564c8c5cce155fd59063e200be451..888b5b8552e39562ea00b61503c89f464efb8b05 100644
|
| --- a/src/ia32/builtins-ia32.cc
|
| +++ b/src/ia32/builtins-ia32.cc
|
| @@ -797,38 +797,23 @@ static void AllocateEmptyJSArray(MacroAssembler* masm,
|
| // register elements_array 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,
|
| Register elements_array_end,
|
| Register scratch,
|
| bool fill_with_hole,
|
| Label* gc_required) {
|
| - Label not_empty, allocated;
|
| + ASSERT(scratch.is(edi)); // rep stos destination
|
| + ASSERT(!fill_with_hole || array_size.is(ecx)); // rep stos count
|
|
|
| // Load the initial map from the array function.
|
| __ mov(elements_array,
|
| FieldOperand(array_function,
|
| JSFunction::kPrototypeOrInitialMapOffset));
|
|
|
| - // Check whether an empty sized array is requested.
|
| - __ test(array_size, Operand(array_size));
|
| - __ j(not_zero, ¬_empty);
|
| -
|
| - // 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(kPreallocatedArrayElements);
|
| - __ AllocateInNewSpace(size,
|
| - result,
|
| - elements_array_end,
|
| - scratch,
|
| - gc_required,
|
| - TAG_OBJECT);
|
| - __ jmp(&allocated);
|
| -
|
| // Allocate the JSArray object together with space for a FixedArray with the
|
| // requested elements.
|
| - __ bind(¬_empty);
|
| ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
|
| __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
|
| times_half_pointer_size, // array_size is a smi.
|
| @@ -845,7 +830,6 @@ static void AllocateJSArray(MacroAssembler* masm,
|
| // elements_array: initial map
|
| // elements_array_end: start of next object
|
| // array_size: size of array (smi)
|
| - __ bind(&allocated);
|
| __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array);
|
| __ mov(elements_array, Factory::empty_fixed_array());
|
| __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
|
| @@ -869,15 +853,6 @@ static void AllocateJSArray(MacroAssembler* masm,
|
| __ SmiUntag(array_size); // Convert from smi to value.
|
| __ mov(FieldOperand(elements_array, JSObject::kMapOffset),
|
| Factory::fixed_array_map());
|
| - Label not_empty_2, fill_array;
|
| - __ test(array_size, Operand(array_size));
|
| - __ j(not_zero, ¬_empty_2);
|
| - // Length of the FixedArray is the number of pre-allocated elements even
|
| - // though the actual JSArray has length 0.
|
| - __ mov(FieldOperand(elements_array, Array::kLengthOffset),
|
| - Immediate(kPreallocatedArrayElements));
|
| - __ jmp(&fill_array);
|
| - __ bind(¬_empty_2);
|
| // For non-empty JSArrays the length of the FixedArray and the JSArray is the
|
| // same.
|
| __ mov(FieldOperand(elements_array, Array::kLengthOffset), array_size);
|
| @@ -885,20 +860,18 @@ static void AllocateJSArray(MacroAssembler* masm,
|
| // Fill the allocated FixedArray with the hole value if requested.
|
| // result: JSObject
|
| // elements_array: elements array
|
| - // elements_array_end: start of next object
|
| - __ bind(&fill_array);
|
| if (fill_with_hole) {
|
| - Label loop, entry;
|
| - __ mov(scratch, Factory::the_hole_value());
|
| - __ lea(elements_array, Operand(elements_array,
|
| - FixedArray::kHeaderSize - kHeapObjectTag));
|
| - __ jmp(&entry);
|
| - __ bind(&loop);
|
| - __ mov(Operand(elements_array, 0), scratch);
|
| - __ add(Operand(elements_array), Immediate(kPointerSize));
|
| - __ bind(&entry);
|
| - __ cmp(elements_array, Operand(elements_array_end));
|
| - __ j(below, &loop);
|
| + __ lea(edi, Operand(elements_array,
|
| + FixedArray::kHeaderSize - kHeapObjectTag));
|
| +
|
| + __ push(eax);
|
| + __ mov(eax, Factory::the_hole_value());
|
| +
|
| + __ cld();
|
| + __ rep_stos();
|
| +
|
| + // Restore saved registers.
|
| + __ pop(eax);
|
| }
|
| }
|
|
|
| @@ -920,7 +893,8 @@ static void AllocateJSArray(MacroAssembler* masm,
|
| static void ArrayNativeCode(MacroAssembler* masm,
|
| bool construct_call,
|
| Label* call_generic_code) {
|
| - Label argc_one_or_more, argc_two_or_more, prepare_generic_code_call;
|
| + Label argc_one_or_more, argc_two_or_more, prepare_generic_code_call,
|
| + empty_array, not_empty_array;
|
|
|
| // Push the constructor and argc. No need to tag argc as a smi, as there will
|
| // be no garbage collection with this on the stack.
|
| @@ -936,6 +910,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
|
| __ test(eax, Operand(eax));
|
| __ j(not_zero, &argc_one_or_more);
|
|
|
| + __ bind(&empty_array);
|
| // Handle construction of an empty array.
|
| AllocateEmptyJSArray(masm,
|
| edi,
|
| @@ -958,30 +933,41 @@ static void ArrayNativeCode(MacroAssembler* masm,
|
| __ cmp(eax, 1);
|
| __ j(not_equal, &argc_two_or_more);
|
| ASSERT(kSmiTag == 0);
|
| - __ test(Operand(esp, (push_count + 1) * kPointerSize),
|
| - Immediate(kIntptrSignBit | kSmiTagMask));
|
| + __ mov(ecx, Operand(esp, (push_count + 1) * kPointerSize));
|
| + __ test(ecx, Operand(ecx));
|
| + __ j(not_zero, ¬_empty_array);
|
| +
|
| + // Case above assumes there is only a single slot to drop in
|
| + // ret, but we have two.
|
| + for (int i = push_count; i >= 0; i--) {
|
| + __ mov(eax, Operand(esp, i * kPointerSize));
|
| + __ mov(Operand(esp, (i + 1) * kPointerSize), eax);
|
| + }
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| + __ jmp(&empty_array);
|
| +
|
| + __ bind(¬_empty_array);
|
| + __ test(ecx, Immediate(kIntptrSignBit | kSmiTagMask));
|
| __ j(not_zero, &prepare_generic_code_call);
|
|
|
| // Handle construction of an empty array of a certain size. Get the size from
|
| // the stack and bail out if size is to large to actually allocate an elements
|
| // array.
|
| - __ mov(edx, Operand(esp, (push_count + 1) * kPointerSize));
|
| - ASSERT(kSmiTag == 0);
|
| - __ cmp(edx, JSObject::kInitialMaxFastElementArray << kSmiTagSize);
|
| + __ cmp(ecx, JSObject::kInitialMaxFastElementArray << kSmiTagSize);
|
| __ j(greater_equal, &prepare_generic_code_call);
|
|
|
| // edx: array_size (smi)
|
| // edi: constructor
|
| - // esp[0]: argc
|
| + // esp[0]: argc (cannot be 0 here)
|
| // esp[4]: constructor (only if construct_call)
|
| // esp[8]: return address
|
| // esp[C]: argument
|
| AllocateJSArray(masm,
|
| edi,
|
| - edx,
|
| + ecx,
|
| eax,
|
| ebx,
|
| - ecx,
|
| + edx,
|
| edi,
|
| true,
|
| &prepare_generic_code_call);
|
|
|