From: jarin@chromium.org Date: Fri, 11 Apr 2014 06:45:24 +0000 (+0000) Subject: Avoid type assertion on object comparison in Hydrogen - the comparison is unreachable... X-Git-Tag: upstream/4.7.83~9693 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=166ec11e4341f27b070f6fd49096828ed019f8da;p=platform%2Fupstream%2Fv8.git Avoid type assertion on object comparison in Hydrogen - the comparison is unreachable because of previous checks. 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 --- diff --git a/src/hydrogen.cc b/src/hydrogen.cc index a291a87..96f4e78 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -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("Type mismatch between feedback and constant", + Deoptimizer::SOFT); + // The caller expects a branch instruction, so make it happy. + return New(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(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("Type mismatch between feedback and constant", - Deoptimizer::SOFT); - // The caller expects a branch instruction, so make it happy. - return New(graph()->GetConstantTrue()); - } BuildCheckHeapObject(left); Add(left, HCheckInstanceType::IS_STRING); BuildCheckHeapObject(right); diff --git a/test/mjsunit/regress/regress-359491.js b/test/mjsunit/regress/regress-359491.js index 194376b..d72875a 100644 --- a/test/mjsunit/regress/regress-359491.js +++ b/test/mjsunit/regress/regress-359491.js @@ -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); +})();