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 { ...@@ -1527,9 +1527,10 @@ class RepresentationSelector {
if (node->op()->ValueOutputCount() > 0 && if (node->op()->ValueOutputCount() > 0 &&
node->op()->EffectOutputCount() > 0 && node->op()->EffectOutputCount() > 0 &&
node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) { node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) {
Node* control = node->op()->ControlOutputCount() > 0 Node* control =
? node (node->op()->ControlOutputCount() == 0)
: NodeProperties::GetControlInput(node, 0); ? NodeProperties::GetControlInput(node, 0)
: NodeProperties::FindSuccessfulControlProjection(node);
Node* unreachable = Node* unreachable =
graph()->NewNode(common()->Unreachable(), node, control); graph()->NewNode(common()->Unreachable(), node, control);
...@@ -1537,9 +1538,18 @@ class RepresentationSelector { ...@@ -1537,9 +1538,18 @@ class RepresentationSelector {
// Insert unreachable node and replace all the effect uses of the {node} // Insert unreachable node and replace all the effect uses of the {node}
// with the new unreachable node. // with the new unreachable node.
for (Edge edge : node->use_edges()) { for (Edge edge : node->use_edges()) {
if (NodeProperties::IsEffectEdge(edge) && edge.from() != unreachable) { if (!NodeProperties::IsEffectEdge(edge)) continue;
edge.UpdateTo(unreachable); // 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) { ...@@ -166,6 +166,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
if (!node->op()->HasProperty(Operator::kNoThrow)) { if (!node->op()->HasProperty(Operator::kNoThrow)) {
Node* discovered_if_exception = nullptr; Node* discovered_if_exception = nullptr;
Node* discovered_if_success = nullptr; Node* discovered_if_success = nullptr;
Node* discovered_direct_use = nullptr;
int total_number_of_control_uses = 0; int total_number_of_control_uses = 0;
for (Edge edge : node->use_edges()) { for (Edge edge : node->use_edges()) {
if (!NodeProperties::IsControlEdge(edge)) { if (!NodeProperties::IsControlEdge(edge)) {
...@@ -176,10 +177,11 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { ...@@ -176,10 +177,11 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
if (control_use->opcode() == IrOpcode::kIfSuccess) { if (control_use->opcode() == IrOpcode::kIfSuccess) {
CHECK_NULL(discovered_if_success); // Only one allowed. CHECK_NULL(discovered_if_success); // Only one allowed.
discovered_if_success = control_use; discovered_if_success = control_use;
} } else if (control_use->opcode() == IrOpcode::kIfException) {
if (control_use->opcode() == IrOpcode::kIfException) {
CHECK_NULL(discovered_if_exception); // Only one allowed. CHECK_NULL(discovered_if_exception); // Only one allowed.
discovered_if_exception = control_use; discovered_if_exception = control_use;
} else {
discovered_direct_use = control_use;
} }
} }
if (discovered_if_success && !discovered_if_exception) { if (discovered_if_success && !discovered_if_exception) {
...@@ -196,8 +198,13 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { ...@@ -196,8 +198,13 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
node->id(), node->op()->mnemonic(), discovered_if_exception->id(), node->id(), node->op()->mnemonic(), discovered_if_exception->id(),
discovered_if_exception->op()->mnemonic()); discovered_if_exception->op()->mnemonic());
} }
if (discovered_if_success || discovered_if_exception) { if ((discovered_if_success || discovered_if_exception) &&
CHECK_EQ(2, total_number_of_control_uses); 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