[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:
parent
8fab64cf4c
commit
6d0078e4f8
@ -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 ( )
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
25
test/mjsunit/regress-958725.js
Normal file
25
test/mjsunit/regress-958725.js
Normal 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);
|
Loading…
Reference in New Issue
Block a user