Reviewers: Yang,

Description:
Implement elements transitions in ia32 Array constructor with n args.


[email protected]


Please review this at https://chromiumcodereview.appspot.com/9369044/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/ia32/builtins-ia32.cc


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(),
+              &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);


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to