Revision: 4463
Author: whe...@chromium.org
Date: Wed Apr 21 06:33:36 2010
Log: Port inlined quick equality check for non-NaN to x64.
Review URL: http://codereview.chromium.org/1756002
http://code.google.com/p/v8/source/detail?r=4463

Modified:
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/x64/codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Tue Apr 20 10:33:14 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Apr 21 06:33:36 2010
@@ -2773,11 +2773,7 @@
       // number comparison in the stub if it was inlined.
       CompareStub stub(cc, strict, nan_info, !inline_number_compare);
       Result answer = frame_->CallStub(&stub, &left_side, &right_side);
-      if (cc == equal) {
-        __ test(answer.reg(), Operand(answer.reg()));
-      } else {
-        __ cmp(answer.reg(), 0);
-      }
+      __ test(answer.reg(), Operand(answer.reg()));
       answer.Unuse();
       dest->Split(cc);
     } else {
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Mon Apr 19 12:30:11 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Wed Apr 21 06:33:36 2010
@@ -5295,6 +5295,15 @@
     Load(expr);
   }
 }
+
+
+static bool CouldBeNaN(const Result& result) {
+  if (result.type_info().IsSmi()) return false;
+  if (result.type_info().IsInteger32()) return false;
+  if (!result.is_constant()) return true;
+  if (!result.handle()->IsHeapNumber()) return false;
+  return isnan(HeapNumber::cast(*result.handle())->value());
+}


 void CodeGenerator::Comparison(AstNode* node,
@@ -5614,15 +5623,29 @@
       right_side.Unuse();
       dest->Split(cc);
     }
-  } else {  // Neither side is a constant Smi or null.
+  } else {
+ // Neither side is a constant Smi, constant 1-char string, or constant null.
     // If either side is a non-smi constant, skip the smi check.
     bool known_non_smi =
         (left_side.is_constant() && !left_side.handle()->IsSmi()) ||
         (right_side.is_constant() && !right_side.handle()->IsSmi());
+
+    NaNInformation nan_info =
+        (CouldBeNaN(left_side) && CouldBeNaN(right_side)) ?
+        kBothCouldBeNaN :
+        kCantBothBeNaN;
+
     left_side.ToRegister();
     right_side.ToRegister();

     if (known_non_smi) {
+      // If at least one of the objects is not NaN, then if the objects
+      // are identical, they are equal.
+      if (nan_info == kCantBothBeNaN && cc == equal) {
+        __ cmpq(left_side.reg(), right_side.reg());
+        dest->true_target()->Branch(equal);
+      }
+
       // When non-smi, call out to the compare stub.
       CompareStub stub(cc, strict);
       Result answer = frame_->CallStub(&stub, &left_side, &right_side);
@@ -5642,7 +5665,14 @@

       Condition both_smi = masm_->CheckBothSmi(left_reg, right_reg);
       is_smi.Branch(both_smi);
-      // When non-smi, call out to the compare stub.
+      // When non-smi, call out to the compare stub, after inlined checks.
+      // If at least one of the objects is not NaN, then if the objects
+      // are identical, they are equal.
+      if (nan_info == kCantBothBeNaN && cc == equal) {
+        __ cmpq(left_side.reg(), right_side.reg());
+        dest->true_target()->Branch(equal);
+      }
+
       CompareStub stub(cc, strict);
       Result answer = frame_->CallStub(&stub, &left_side, &right_side);
       __ SmiTest(answer.reg());  // Sets both zero and sign flags.

--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to