Revision: 4664
Author: [email protected]
Date: Mon May 17 07:14:34 2010
Log: Use direct loop when filling small arrays.

r3995 (http://code.google.com/p/v8/source/detail?r=3995) introduce performance
regression for the case when arrat size is small (think new Array(4)).

It turns out that in those cases rep stos is slower than plain loop (apprently
due to ecx increment, but I didn't check this hypothesis.)  The next thing
to try could be direct jump into right place of long sequence of stos'es.

Review URL: http://codereview.chromium.org/2082006
http://code.google.com/p/v8/source/detail?r=4664

Modified:
 /branches/bleeding_edge/src/ia32/assembler-ia32.cc
 /branches/bleeding_edge/src/ia32/assembler-ia32.h
 /branches/bleeding_edge/src/ia32/builtins-ia32.cc
 /branches/bleeding_edge/src/ia32/disasm-ia32.cc
 /branches/bleeding_edge/test/cctest/test-disasm-ia32.cc

=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc Mon May 17 04:19:10 2010 +++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc Mon May 17 07:14:34 2010
@@ -774,6 +774,13 @@
   EMIT(0xF3);
   EMIT(0xAB);
 }
+
+
+void Assembler::stos() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xAB);
+}


 void Assembler::xchg(Register dst, Register src) {
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h Tue Mar 16 09:07:19 2010 +++ /branches/bleeding_edge/src/ia32/assembler-ia32.h Mon May 17 07:14:34 2010
@@ -551,6 +551,7 @@
   // Repetitive string instructions.
   void rep_movs();
   void rep_stos();
+  void stos();

   // Exchange two registers
   void xchg(Register dst, Register src);
=======================================
--- /branches/bleeding_edge/src/ia32/builtins-ia32.cc Wed May 12 09:42:51 2010 +++ /branches/bleeding_edge/src/ia32/builtins-ia32.cc Mon May 17 07:14:34 2010
@@ -806,6 +806,7 @@
                             Label* gc_required) {
   ASSERT(scratch.is(edi));  // rep stos destination
   ASSERT(!fill_with_hole || array_size.is(ecx));  // rep stos count
+  ASSERT(!fill_with_hole || !result.is(eax));  // result is never eax

   // Load the initial map from the array function.
   __ mov(elements_array,
@@ -863,15 +864,22 @@
   if (fill_with_hole) {
     __ lea(edi, Operand(elements_array,
                         FixedArray::kHeaderSize - kHeapObjectTag));
-
-    __ push(eax);
     __ mov(eax, Factory::the_hole_value());
-
     __ cld();
+    // Do not use rep stos when filling less than kRepStosThreshold
+    // words.
+    const int kRepStosThreshold = 16;
+    Label loop, entry, done;
+    __ cmp(ecx, kRepStosThreshold);
+    __ j(below, &loop);  // Note: ecx > 0.
     __ rep_stos();
-
-    // Restore saved registers.
-    __ pop(eax);
+    __ jmp(&done);
+    __ bind(&loop);
+    __ stos();
+    __ bind(&entry);
+    __ cmp(edi, Operand(elements_array_end));
+    __ j(below, &loop);
+    __ bind(&done);
   }
 }

@@ -970,13 +978,14 @@
   AllocateJSArray(masm,
                   edi,
                   ecx,
-                  eax,
                   ebx,
+                  eax,
                   edx,
                   edi,
                   true,
                   &prepare_generic_code_call);
   __ IncrementCounter(&Counters::array_function_native, 1);
+  __ mov(eax, ebx);
   __ pop(ebx);
   if (construct_call) {
     __ pop(edi);
=======================================
--- /branches/bleeding_edge/src/ia32/disasm-ia32.cc     Fri Mar 12 00:36:01 2010
+++ /branches/bleeding_edge/src/ia32/disasm-ia32.cc     Mon May 17 07:14:34 2010
@@ -90,6 +90,7 @@
   {0x99, "cdq", UNSET_OP_ORDER},
   {0x9B, "fwait", UNSET_OP_ORDER},
   {0xFC, "cld", UNSET_OP_ORDER},
+  {0xAB, "stos", UNSET_OP_ORDER},
   {-1, "", UNSET_OP_ORDER}
 };

=======================================
--- /branches/bleeding_edge/test/cctest/test-disasm-ia32.cc Wed Mar 17 03:28:44 2010 +++ /branches/bleeding_edge/test/cctest/test-disasm-ia32.cc Mon May 17 07:14:34 2010
@@ -237,6 +237,7 @@
   __ cld();
   __ rep_movs();
   __ rep_stos();
+  __ stos();

   __ sub(edx, Operand(ebx, ecx, times_4, 10000));
   __ sub(edx, Operand(ebx));

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

Reply via email to