Chromium Code Reviews| Index: src/ia32/builtins-ia32.cc |
| diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc |
| index efa3456d8e0698de66e0e5d58eddd3452ca2d62e..a7faca9920b5a73f10455c3376e5adb5edcf3f9b 100644 |
| --- a/src/ia32/builtins-ia32.cc |
| +++ b/src/ia32/builtins-ia32.cc |
| @@ -1088,7 +1088,7 @@ 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, |
| - empty_array, not_empty_array; |
| + empty_array, not_empty_array, finish, cant_transition_map, not_double; |
| // 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. |
| @@ -1238,7 +1238,7 @@ static void ArrayNativeCode(MacroAssembler* masm, |
| __ add(edx, Immediate(kPointerSize)); |
| __ bind(&entry); |
| __ dec(ecx); |
| - __ j(greater_equal, &loop); |
| + __ j(greater_equal, &loop, Label::kNear); |
| // Remove caller arguments from the stack and return. |
| // ebx: argc |
| @@ -1247,6 +1247,7 @@ static void ArrayNativeCode(MacroAssembler* masm, |
| // esp[8]: constructor (only if construct_call) |
| // esp[12]: return address |
| // esp[16]: last argument |
| + __ bind(&finish); |
| __ mov(ecx, Operand(esp, last_arg_offset - kPointerSize)); |
| __ pop(eax); |
| __ pop(ebx); |
| @@ -1255,9 +1256,43 @@ static void ArrayNativeCode(MacroAssembler* masm, |
| __ jmp(ecx); |
| __ bind(&has_non_smi_element); |
| + // Double values are handled by the runtime. |
| + __ CheckMap(eax, |
| + masm->isolate()->factory()->heap_number_map(), |
| + ¬_double, |
| + DONT_DO_SMI_CHECK); |
| + __ bind(&cant_transition_map); |
| // Throw away the array that's only been partially constructed. |
| __ pop(eax); |
| __ UndoAllocationInNewSpace(eax); |
| + __ jmp(&prepare_generic_code_call); |
| + |
| + __ bind(¬_double); |
| + // Transition FAST_SMI_ONLY_ELEMENTS to FAST_ELEMENTS |
| + __ mov(ebx, Operand(esp, 0)); |
| + __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); |
| + __ LoadTransitionedArrayMapConditional( |
| + FAST_SMI_ONLY_ELEMENTS, |
| + FAST_ELEMENTS, |
| + edi, |
| + eax, |
| + &cant_transition_map); |
| + __ mov(FieldOperand(ebx, HeapObject::kMapOffset), edi); |
| + __ RecordWriteField(ebx, HeapObject::kMapOffset, edi, eax, |
|
Yang
2012/02/10 10:25:14
where does the value of eax come from?
|
| + kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
| + |
| + // Prepare to re-enter the loop |
| + __ lea(edi, Operand(esp, last_arg_offset)); |
| + |
| + // Finish the array initialization loop. |
| + Label loop2; |
| + __ bind(&loop2); |
| + __ mov(eax, Operand(edi, ecx, times_pointer_size, 0)); |
| + __ mov(Operand(edx, 0), eax); |
| + __ add(edx, Immediate(kPointerSize)); |
| + __ dec(ecx); |
| + __ j(greater_equal, &loop2, Label::kNear); |
| + __ jmp(&finish); |
| // Restore argc and constructor before running the generic code. |
| __ bind(&prepare_generic_code_call); |