Avoid type assertion on object comparison in Hydrogen - the comparison is unreachable...
authorjarin@chromium.org <jarin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 11 Apr 2014 06:45:24 +0000 (06:45 +0000)
committerjarin@chromium.org <jarin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 11 Apr 2014 06:45:24 +0000 (06:45 +0000)
BUG=
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/232053004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20666 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen.cc
test/mjsunit/regress/regress-359491.js

index a291a87..96f4e78 100644 (file)
@@ -9833,6 +9833,17 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
 
   if (combined_type->Is(Type::Receiver())) {
     if (Token::IsEqualityOp(op)) {
+      // HCompareObjectEqAndBranch can only deal with object, so
+      // exclude numbers.
+      if ((left->IsConstant() &&
+           HConstant::cast(left)->HasNumberValue()) ||
+          (right->IsConstant() &&
+           HConstant::cast(right)->HasNumberValue())) {
+        Add<HDeoptimize>("Type mismatch between feedback and constant",
+                         Deoptimizer::SOFT);
+        // The caller expects a branch instruction, so make it happy.
+        return New<HBranch>(graph()->GetConstantTrue());
+      }
       // Can we get away with map check and not instance type check?
       HValue* operand_to_check =
           left->block()->block_id() < right->block()->block_id() ? left : right;
@@ -9879,17 +9890,6 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
         New<HCompareObjectEqAndBranch>(left, right);
     return result;
   } else if (combined_type->Is(Type::String())) {
-    // If we have a constant argument, it should be consistent with the type
-    // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch).
-    if ((left->IsConstant() &&
-         !HConstant::cast(left)->HasStringValue()) ||
-        (right->IsConstant() &&
-         !HConstant::cast(right)->HasStringValue())) {
-      Add<HDeoptimize>("Type mismatch between feedback and constant",
-                       Deoptimizer::SOFT);
-      // The caller expects a branch instruction, so make it happy.
-      return New<HBranch>(graph()->GetConstantTrue());
-    }
     BuildCheckHeapObject(left);
     Add<HCheckInstanceType>(left, HCheckInstanceType::IS_STRING);
     BuildCheckHeapObject(right);
index 194376b..d72875a 100644 (file)
@@ -4,28 +4,58 @@
 
 // Flags: --allow-natives-syntax
 
-function f(a, b, mode) {
-  if (mode) {
-    return a === b;
-  } else {
-    return a === b;
+(function () {
+  function f(a, b, mode) {
+    if (mode) {
+      return a === b;
+    } else {
+      return a === b;
+    }
   }
-}
-
-// Gather type feedback for both branches.
-f("a", "b", 1);
-f("c", "d", 1);
-f("a", "b", 0);
-f("c", "d", 0);
-
-function g(mode) {
-  var x = 1e10 | 0;
-  f(x, x, mode);
-}
-
-// Gather type feedback for g, but only on one branch for f.
-g(1);
-g(1);
-%OptimizeFunctionOnNextCall(g);
-// Optimize g, which inlines f. Both branches in f will see the constant.
-g(0);
+
+  // Gather type feedback for both branches.
+  f("a", "b", 1);
+  f("c", "d", 1);
+  f("a", "b", 0);
+  f("c", "d", 0);
+
+  function g(mode) {
+    var x = 1e10 | 0;
+    f(x, x, mode);
+  }
+
+  // Gather type feedback for g, but only on one branch for f.
+  g(1);
+  g(1);
+  %OptimizeFunctionOnNextCall(g);
+  // Optimize g, which inlines f. Both branches in f will see the constant.
+  g(0);
+})();
+
+(function () {
+  function f(a, b, mode) {
+    if (mode) {
+      return a === b;
+    } else {
+      return a === b;
+    }
+  }
+
+  // Gather type feedback for both branches.
+  f({ a : 1}, {b : 1}, 1);
+  f({ c : 1}, {d : 1}, 1);
+  f({ a : 1}, {c : 1}, 0);
+  f({ b : 1}, {d : 1}, 0);
+
+  function g(mode) {
+    var x = 1e10 | 0;
+    f(x, x, mode);
+  }
+
+  // Gather type feedback for g, but only on one branch for f.
+  g(1);
+  g(1);
+  %OptimizeFunctionOnNextCall(g);
+  // Optimize g, which inlines f. Both branches in f will see the constant.
+  g(0);
+})();