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); |