Commit eb71dfee authored by danno@chromium.org's avatar danno@chromium.org

Implement elements transitions in ia32 Array constructor with n args.

R=yangguo@chromium.org

Review URL: https://chromiumcodereview.appspot.com/9369044

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10674 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f0c4b87f
......@@ -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(),
&not_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(&not_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,
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment