[turbofan] Handle unreachable code gracefully when searching framestates

Bug: chromium:958725
Change-Id: I02d2f3ad19fa60482f8fdd8a539205091f428b68
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1594434
Reviewed-by: Georg Neis <neis@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61196}
This commit is contained in:
Jaroslav Sevcik 2019-05-03 09:18:21 +02:00 committed by Commit Bot
parent 8fab64cf4c
commit 6d0078e4f8
6 changed files with 68 additions and 35 deletions

View File

@ -4396,21 +4396,21 @@ Reduction JSCallReducer::ReduceReturnReceiver(Node* node) {
Reduction JSCallReducer::ReduceSoftDeoptimize(Node* node,
DeoptimizeReason reason) {
if (flags() & kBailoutOnUninitialized) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::FindFrameStateBefore(node);
Node* deoptimize = graph()->NewNode(
common()->Deoptimize(DeoptimizeKind::kSoft, reason, VectorSlotPair()),
frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Revisit(graph()->end());
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Dead());
return Changed(node);
}
return NoChange();
if (!(flags() & kBailoutOnUninitialized)) return NoChange();
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* frame_state =
NodeProperties::FindFrameStateBefore(node, jsgraph()->Dead());
Node* deoptimize = graph()->NewNode(
common()->Deoptimize(DeoptimizeKind::kSoft, reason, VectorSlotPair()),
frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Revisit(graph()->end());
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Dead());
return Changed(node);
}
// ES6 section 22.1.3.18 Array.prototype.push ( )

View File

@ -1486,7 +1486,8 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
Node* receiver = NodeProperties::GetValueInput(node, 0);
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::FindFrameStateBefore(node);
Node* frame_state =
NodeProperties::FindFrameStateBefore(node, jsgraph()->Dead());
if (HasOnlyStringMaps(broker(), receiver_maps)) {
return ReduceElementAccessOnString(node, index, value, access_mode,
@ -1834,21 +1835,21 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
Reduction JSNativeContextSpecialization::ReduceSoftDeoptimize(
Node* node, DeoptimizeReason reason) {
if (flags() & kBailoutOnUninitialized) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::FindFrameStateBefore(node);
Node* deoptimize = graph()->NewNode(
common()->Deoptimize(DeoptimizeKind::kSoft, reason, VectorSlotPair()),
frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Revisit(graph()->end());
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Dead());
return Changed(node);
}
return NoChange();
if (!(flags() & kBailoutOnUninitialized)) return NoChange();
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* frame_state =
NodeProperties::FindFrameStateBefore(node, jsgraph()->Dead());
Node* deoptimize = graph()->NewNode(
common()->Deoptimize(DeoptimizeKind::kSoft, reason, VectorSlotPair()),
frame_state, effect, control);
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
Revisit(graph()->end());
node->TrimInputCount(0);
NodeProperties::ChangeOp(node, common()->Dead());
return Changed(node);
}
Reduction JSNativeContextSpecialization::ReduceJSHasProperty(Node* node) {

View File

@ -501,7 +501,8 @@ Node* JSTypeHintLowering::TryBuildSoftDeopt(FeedbackNexus& nexus, Node* effect,
jsgraph()->common()->Deoptimize(DeoptimizeKind::kSoft, reason,
VectorSlotPair()),
jsgraph()->Dead(), effect, control);
Node* frame_state = NodeProperties::FindFrameStateBefore(deoptimize);
Node* frame_state =
NodeProperties::FindFrameStateBefore(deoptimize, jsgraph()->Dead());
deoptimize->ReplaceInput(0, frame_state);
return deoptimize;
}

View File

@ -254,10 +254,15 @@ void NodeProperties::ChangeOp(Node* node, const Operator* new_op) {
// static
Node* NodeProperties::FindFrameStateBefore(Node* node) {
Node* NodeProperties::FindFrameStateBefore(Node* node,
Node* unreachable_sentinel) {
Node* effect = NodeProperties::GetEffectInput(node);
while (effect->opcode() != IrOpcode::kCheckpoint) {
if (effect->opcode() == IrOpcode::kDead) return effect;
if (effect->opcode() == IrOpcode::kDead ||
effect->opcode() == IrOpcode::kUnreachable) {
return unreachable_sentinel;
}
DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
DCHECK_EQ(1, effect->op()->EffectInputCount());
effect = NodeProperties::GetEffectInput(effect);
}

View File

@ -118,7 +118,8 @@ class V8_EXPORT_PRIVATE NodeProperties final {
// Find the last frame state that is effect-wise before the given node. This
// assumes a linear effect-chain up to a {CheckPoint} node in the graph.
static Node* FindFrameStateBefore(Node* node);
// Returns {unreachable_sentinel} if {node} is determined to be unreachable.
static Node* FindFrameStateBefore(Node* node, Node* unreachable_sentinel);
// Collect the output-value projection for the given output index.
static Node* FindProjection(Node* node, size_t projection_index);

View File

@ -0,0 +1,25 @@
// 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 f(v3) {
Symbol[Symbol.replace] = Object;
const v8 = {};
let i = 0;
do {
const v12 = v3[3];
for (let v17 = 0; v17 < 100000; v17++) {
}
const v18 = Object();
function v19(v20,v21,v22) {
}
i++;;
} while (i < 1);
const v25 = Object.freeze(v8);
}
f(Object);
%OptimizeFunctionOnNextCall(f);
f(Object);