| Index: src/ia32/builtins-ia32.cc
|
| diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
|
| index e12e79af765225a03cf79d2fc763e2c0742a8448..28a9b0fadccfb253d535eb69ebb482877e371628 100644
|
| --- a/src/ia32/builtins-ia32.cc
|
| +++ b/src/ia32/builtins-ia32.cc
|
| @@ -1238,37 +1238,42 @@ static void ArrayNativeCode(MacroAssembler* masm,
|
| false,
|
| &prepare_generic_code_call);
|
| __ IncrementCounter(counters->array_function_native(), 1);
|
| - __ mov(eax, ebx);
|
| - __ pop(ebx);
|
| - if (construct_call) {
|
| - __ pop(edi);
|
| - }
|
| - __ push(eax);
|
| - // eax: JSArray
|
| + __ push(ebx);
|
| + __ mov(ebx, Operand(esp, kPointerSize));
|
| // ebx: argc
|
| // edx: elements_array_end (untagged)
|
| // esp[0]: JSArray
|
| - // esp[4]: return address
|
| - // esp[8]: last argument
|
| + // esp[4]: argc
|
| + // esp[8]: constructor (only if construct_call)
|
| + // esp[12]: return address
|
| + // esp[16]: last argument
|
|
|
| // Location of the last argument
|
| - __ lea(edi, Operand(esp, 2 * kPointerSize));
|
| + int last_arg_offset = (construct_call ? 4 : 3) * kPointerSize;
|
| + __ lea(edi, Operand(esp, last_arg_offset));
|
|
|
| // Location of the first array element (Parameter fill_with_holes to
|
| - // AllocateJSArrayis false, so the FixedArray is returned in ecx).
|
| + // AllocateJSArray is false, so the FixedArray is returned in ecx).
|
| __ lea(edx, Operand(ecx, FixedArray::kHeaderSize - kHeapObjectTag));
|
|
|
| + Label has_non_smi_element;
|
| +
|
| // ebx: argc
|
| // edx: location of the first array element
|
| // edi: location of the last argument
|
| // esp[0]: JSArray
|
| - // esp[4]: return address
|
| - // esp[8]: last argument
|
| + // esp[4]: argc
|
| + // esp[8]: constructor (only if construct_call)
|
| + // esp[12]: return address
|
| + // esp[16]: last argument
|
| Label loop, entry;
|
| __ mov(ecx, ebx);
|
| __ jmp(&entry);
|
| __ bind(&loop);
|
| __ mov(eax, Operand(edi, ecx, times_pointer_size, 0));
|
| + if (FLAG_smi_only_arrays) {
|
| + __ JumpIfNotSmi(eax, &has_non_smi_element);
|
| + }
|
| __ mov(Operand(edx, 0), eax);
|
| __ add(edx, Immediate(kPointerSize));
|
| __ bind(&entry);
|
| @@ -1278,13 +1283,20 @@ static void ArrayNativeCode(MacroAssembler* masm,
|
| // Remove caller arguments from the stack and return.
|
| // ebx: argc
|
| // esp[0]: JSArray
|
| - // esp[4]: return address
|
| - // esp[8]: last argument
|
| + // esp[4]: argc
|
| + // esp[8]: constructor (only if construct_call)
|
| + // esp[12]: return address
|
| + // esp[16]: last argument
|
| + __ mov(ecx, Operand(esp, last_arg_offset - kPointerSize));
|
| + __ pop(eax);
|
| + __ pop(ebx);
|
| + __ lea(esp, Operand(esp, ebx, times_pointer_size,
|
| + last_arg_offset - kPointerSize));
|
| + __ jmp(ecx);
|
| +
|
| + __ bind(&has_non_smi_element);
|
| + // Throw away the array that's only been partially constructed.
|
| __ pop(eax);
|
| - __ pop(ecx);
|
| - __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
|
| - __ push(ecx);
|
| - __ ret(0);
|
|
|
| // Restore argc and constructor before running the generic code.
|
| __ bind(&prepare_generic_code_call);
|
|
|