Commit ec4d45a8 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Handle exceptional edges when inserting unreachable node.

... more precisely, do not mess up the exceptional edges.

Bug: chromium:924151
Change-Id: I3541a1c339c07f509519d4ece6d677dd499f181e
Reviewed-on: https://chromium-review.googlesource.com/c/1429860Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59063}
parent 58837341
......@@ -1527,9 +1527,10 @@ class RepresentationSelector {
if (node->op()->ValueOutputCount() > 0 &&
node->op()->EffectOutputCount() > 0 &&
node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) {
Node* control = node->op()->ControlOutputCount() > 0
? node
: NodeProperties::GetControlInput(node, 0);
Node* control =
(node->op()->ControlOutputCount() == 0)
? NodeProperties::GetControlInput(node, 0)
: NodeProperties::FindSuccessfulControlProjection(node);
Node* unreachable =
graph()->NewNode(common()->Unreachable(), node, control);
......@@ -1537,9 +1538,18 @@ class RepresentationSelector {
// Insert unreachable node and replace all the effect uses of the {node}
// with the new unreachable node.
for (Edge edge : node->use_edges()) {
if (NodeProperties::IsEffectEdge(edge) && edge.from() != unreachable) {
edge.UpdateTo(unreachable);
if (!NodeProperties::IsEffectEdge(edge)) continue;
// Make sure to not overwrite the unreachable node's input. That would
// create a cycle.
if (edge.from() == unreachable) continue;
// Avoid messing up the exceptional path.
if (edge.from()->opcode() == IrOpcode::kIfException) {
DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
DCHECK_EQ(NodeProperties::GetControlInput(edge.from()), node);
continue;
}
edge.UpdateTo(unreachable);
}
}
}
......
......@@ -166,6 +166,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
if (!node->op()->HasProperty(Operator::kNoThrow)) {
Node* discovered_if_exception = nullptr;
Node* discovered_if_success = nullptr;
Node* discovered_direct_use = nullptr;
int total_number_of_control_uses = 0;
for (Edge edge : node->use_edges()) {
if (!NodeProperties::IsControlEdge(edge)) {
......@@ -176,10 +177,11 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
if (control_use->opcode() == IrOpcode::kIfSuccess) {
CHECK_NULL(discovered_if_success); // Only one allowed.
discovered_if_success = control_use;
}
if (control_use->opcode() == IrOpcode::kIfException) {
} else if (control_use->opcode() == IrOpcode::kIfException) {
CHECK_NULL(discovered_if_exception); // Only one allowed.
discovered_if_exception = control_use;
} else {
discovered_direct_use = control_use;
}
}
if (discovered_if_success && !discovered_if_exception) {
......@@ -196,8 +198,13 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
node->id(), node->op()->mnemonic(), discovered_if_exception->id(),
discovered_if_exception->op()->mnemonic());
}
if (discovered_if_success || discovered_if_exception) {
CHECK_EQ(2, total_number_of_control_uses);
if ((discovered_if_success || discovered_if_exception) &&
total_number_of_control_uses != 2) {
FATAL(
"#%d:%s if followed by IfSuccess/IfException, there should be "
"no direct control uses, but direct use #%d:%s was found",
node->id(), node->op()->mnemonic(), discovered_direct_use->id(),
discovered_direct_use->op()->mnemonic());
}
}
}
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function g(code) {
try {
if (typeof code === 'function') {
+Symbol();
} else {
eval();
}
} catch (e) {
return;
}
dummy();
}
function f() {
g(g);
}
try { g(); } catch(e) {; }
f();
%OptimizeFunctionOnNextCall(f);
f();
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