Revision: 11318
Author:   [email protected]
Date:     Fri Apr 13 06:04:51 2012
Log: MIPS: Improve performance of keyed loads/stores which have a HeapNumber index.

Port r11282 (bd2ab07).

Patch by Daniel Kalmar.

Original commit message:

Some GWT compiled code results in array access that has a heap number (e.g. -0)
as an index. Until now this would result in a generic IC.

For example:

a[-0] === a[0] or

a[0.25 * 4] === a[1]

This change detects heap numbers that are representable as a smi
and converts them. As a result we can still use the fast keyed monomorphic
ICs. Optimized code already handles keyed access with a double-key efficiently.

As a result the frame rate on the reported benchmark improves by roughly 2x.

BUG=
TEST=
Review URL: https://chromiumcodereview.appspot.com/10068012
http://code.google.com/p/v8/source/detail?r=11318

Modified:
 /branches/bleeding_edge/src/mips/stub-cache-mips.cc

=======================================
--- /branches/bleeding_edge/src/mips/stub-cache-mips.cc Thu Apr 12 05:30:32 2012 +++ /branches/bleeding_edge/src/mips/stub-cache-mips.cc Fri Apr 13 06:04:51 2012
@@ -3371,6 +3371,45 @@
   }
   return false;
 }
+
+
+static void GenerateSmiKeyCheck(MacroAssembler* masm,
+                                Register key,
+                                Register scratch0,
+                                Register scratch1,
+                                FPURegister double_scratch0,
+                                Label* fail) {
+  if (CpuFeatures::IsSupported(FPU)) {
+    CpuFeatures::Scope scope(FPU);
+    Label key_ok;
+    // Check for smi or a smi inside a heap number.  We convert the heap
+    // number and check if the conversion is exact and fits into the smi
+    // range.
+    __ JumpIfSmi(key, &key_ok);
+    __ CheckMap(key,
+                scratch0,
+                Heap::kHeapNumberMapRootIndex,
+                fail,
+                DONT_DO_SMI_CHECK);
+ __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset));
+    __ EmitFPUTruncate(kRoundToZero,
+                       double_scratch0,
+                       double_scratch0,
+                       scratch0,
+                       scratch1,
+                       kCheckForInexactConversion);
+
+    __ Branch(fail, ne, scratch1, Operand(zero_reg));
+
+    __ mfc1(scratch0, double_scratch0);
+    __ SmiTagCheckOverflow(key, scratch0, scratch1);
+    __ BranchOnOverflow(fail, scratch1);
+    __ bind(&key_ok);
+  } else {
+    // Check that the key is a smi.
+    __ JumpIfNotSmi(key, fail);
+  }
+}


 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
@@ -3389,8 +3428,8 @@
   // This stub is meant to be tail-jumped to, the receiver must already
   // have been verified by the caller to not be a smi.

-  // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);

   __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
   // a3: elements array
@@ -3728,8 +3767,8 @@
   // This stub is meant to be tail-jumped to, the receiver must already
   // have been verified by the caller to not be a smi.

-    // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);

   __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));

@@ -4108,9 +4147,8 @@
   // This stub is meant to be tail-jumped to, the receiver must already
   // have been verified by the caller to not be a smi.

-  // Check that the key is a smi.
-  __ JumpIfNotSmi(a0, &miss_force_generic, at, USE_DELAY_SLOT);
-  // The delay slot can be safely used here, a1 is an object pointer.
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, a0, t0, t1, f2, &miss_force_generic);

   // Get the elements array.
   __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset));
@@ -4160,8 +4198,8 @@
   // This stub is meant to be tail-jumped to, the receiver must already
   // have been verified by the caller to not be a smi.

-  // Check that the key is a smi.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);

   // Get the elements array.
   __ lw(elements_reg,
@@ -4235,8 +4273,8 @@
   // This stub is meant to be tail-jumped to, the receiver must already
   // have been verified by the caller to not be a smi.

-  // Check that the key is a smi.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);

   if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
     __ JumpIfNotSmi(value_reg, &transition_elements_kind);
@@ -4402,7 +4440,9 @@

   // This stub is meant to be tail-jumped to, the receiver must already
   // have been verified by the caller to not be a smi.
-  __ JumpIfNotSmi(key_reg, &miss_force_generic);
+
+  // Check that the key is a smi or a heap number convertible to a smi.
+  GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);

   __ lw(elements_reg,
          FieldMemOperand(receiver_reg, JSObject::kElementsOffset));

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

Reply via email to