Commit 166ec11e authored by jarin@chromium.org's avatar jarin@chromium.org

Avoid type assertion on object comparison in Hydrogen - the comparison is...

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
parent 7653b6ef
......@@ -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);
......
......@@ -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);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment