summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichaƫl Zasso <targos@protonmail.com>2019-06-04 20:35:47 +0200
committerBeth Griggs <Bethany.Griggs@uk.ibm.com>2019-06-06 19:23:42 +0100
commit609d2b9ea407c77c414e5aa32bf8b007d5783269 (patch)
treec86ea2648dde4e248f87d7f924325daceb185f1d
parent8f780e8f99742e4a2d3a482033de42ee3fe85637 (diff)
downloadnode-new-609d2b9ea407c77c414e5aa32bf8b007d5783269.tar.gz
deps: V8: backport f27ac28
Original commit message: [turbofan] Pin pure unreachable values to effect chain (in rep selection) Currently, if we lower to a pure computation that is unreachable because of some runtime check, we just rename it with DeadValue. This is problematic if the pure computation gets later eliminated - that allows the DeadValue node float above the check that makes it dead. As we conservatively lower DeadValues to debug-break (i.e., crash), we might induce crash where we should not. With this CL, whenever we lower an impossible effectful node (i.e., with Type::None) to a pure node in simplified lowering, we insert an Unreachable node there (pinned to the effect chain) and mark the impossible node dead (and make it depend on the Unreachable node). Bug: chromium:910838 Change-Id: I218991c79b9e283a9dd5beb4d3f0c4664be76cb2 Reviewed-on: https://chromium-review.googlesource.com/c/1365274 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#58066} Refs: https://github.com/v8/v8/commit/f27ac2806c585d8b1e61ac16d78a2a396d536669 PR-URL: https://github.com/nodejs/node/pull/28061 Fixes: https://github.com/nodejs/node/issues/27107 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
-rw-r--r--common.gypi2
-rw-r--r--deps/v8/src/compiler/simplified-lowering.cc86
-rw-r--r--deps/v8/src/compiler/simplified-lowering.h1
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-910838.js20
4 files changed, 73 insertions, 36 deletions
diff --git a/common.gypi b/common.gypi
index 12f4205db2..97fe1f9e92 100644
--- a/common.gypi
+++ b/common.gypi
@@ -33,7 +33,7 @@
# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
- 'v8_embedder_string': '-node.53',
+ 'v8_embedder_string': '-node.54',
# Enable disassembler for `--print-code` v8 options
'v8_enable_disassembler': 1,
diff --git a/deps/v8/src/compiler/simplified-lowering.cc b/deps/v8/src/compiler/simplified-lowering.cc
index f24f000887..334eb49f1a 100644
--- a/deps/v8/src/compiler/simplified-lowering.cc
+++ b/deps/v8/src/compiler/simplified-lowering.cc
@@ -171,21 +171,6 @@ void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
}
}
-void ChangeToPureOp(Node* node, const Operator* new_op) {
- DCHECK(new_op->HasProperty(Operator::kPure));
- if (node->op()->EffectInputCount() > 0) {
- DCHECK_LT(0, node->op()->ControlInputCount());
- // Disconnect the node from effect and control chains.
- Node* control = NodeProperties::GetControlInput(node);
- Node* effect = NodeProperties::GetEffectInput(node);
- ReplaceEffectControlUses(node, effect, control);
- node->TrimInputCount(new_op->ValueInputCount());
- } else {
- DCHECK_EQ(0, node->op()->ControlInputCount());
- }
- NodeProperties::ChangeOp(node, new_op);
-}
-
#ifdef DEBUG
// Helpers for monotonicity checking.
class InputUseInfos {
@@ -750,6 +735,31 @@ class RepresentationSelector {
!GetUpperBound(node->InputAt(1)).Maybe(type);
}
+ void ChangeToPureOp(Node* node, const Operator* new_op) {
+ DCHECK(new_op->HasProperty(Operator::kPure));
+ if (node->op()->EffectInputCount() > 0) {
+ DCHECK_LT(0, node->op()->ControlInputCount());
+ Node* control = NodeProperties::GetControlInput(node);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ if (TypeOf(node).IsNone()) {
+ // If the node is unreachable, insert an Unreachable node and mark the
+ // value dead.
+ // TODO(jarin,tebbi) Find a way to unify/merge this insertion with
+ // InsertUnreachableIfNecessary.
+ Node* unreachable = effect = graph()->NewNode(
+ jsgraph_->common()->Unreachable(), effect, control);
+ new_op = jsgraph_->common()->DeadValue(GetInfo(node)->representation());
+ node->ReplaceInput(0, unreachable);
+ }
+ // Rewire the effect and control chains.
+ node->TrimInputCount(new_op->ValueInputCount());
+ ReplaceEffectControlUses(node, effect, control);
+ } else {
+ DCHECK_EQ(0, node->op()->ControlInputCount());
+ }
+ NodeProperties::ChangeOp(node, new_op);
+ }
+
// Converts input {index} of {node} according to given UseInfo {use},
// assuming the type of the input is {input_type}. If {input_type} is null,
// it takes the input from the input node {TypeOf(node->InputAt(index))}.
@@ -1052,6 +1062,15 @@ class RepresentationSelector {
}
}
+ void MaskShiftOperand(Node* node, Type rhs_type) {
+ if (!rhs_type.Is(type_cache_.kZeroToThirtyOne)) {
+ Node* const rhs = NodeProperties::GetValueInput(node, 1);
+ node->ReplaceInput(1,
+ graph()->NewNode(jsgraph_->machine()->Word32And(), rhs,
+ jsgraph_->Int32Constant(0x1F)));
+ }
+ }
+
static MachineSemantic DeoptValueSemanticOf(Type type) {
// We only need signedness to do deopt correctly.
if (type.Is(Type::Signed32())) {
@@ -1996,7 +2015,8 @@ class RepresentationSelector {
VisitBinop(node, UseInfo::TruncatingWord32(),
UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Shl());
}
return;
}
@@ -2007,7 +2027,8 @@ class RepresentationSelector {
UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Shl());
}
return;
}
@@ -2016,7 +2037,8 @@ class RepresentationSelector {
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Signed32());
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Shl());
}
return;
}
@@ -2025,7 +2047,8 @@ class RepresentationSelector {
VisitBinop(node, UseInfo::TruncatingWord32(),
UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Sar());
}
return;
}
@@ -2036,7 +2059,8 @@ class RepresentationSelector {
UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Sar());
}
return;
}
@@ -2045,7 +2069,8 @@ class RepresentationSelector {
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Signed32());
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Sar());
}
return;
}
@@ -2054,7 +2079,8 @@ class RepresentationSelector {
VisitBinop(node, UseInfo::TruncatingWord32(),
UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Shr());
}
return;
}
@@ -2083,14 +2109,16 @@ class RepresentationSelector {
UseInfo::TruncatingWord32(),
MachineRepresentation::kWord32);
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Shr());
}
return;
}
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
MachineRepresentation::kWord32, Type::Unsigned32());
if (lower()) {
- lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
+ MaskShiftOperand(node, rhs_type);
+ ChangeToPureOp(node, lowering->machine()->Word32Shr());
}
return;
}
@@ -3787,16 +3815,6 @@ void SimplifiedLowering::DoMin(Node* node, Operator const* op,
NodeProperties::ChangeOp(node, common()->Select(rep));
}
-void SimplifiedLowering::DoShift(Node* node, Operator const* op,
- Type rhs_type) {
- if (!rhs_type.Is(type_cache_.kZeroToThirtyOne)) {
- Node* const rhs = NodeProperties::GetValueInput(node, 1);
- node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
- jsgraph()->Int32Constant(0x1F)));
- }
- ChangeToPureOp(node, op);
-}
-
void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
Node* const input = node->InputAt(0);
Node* const zero = jsgraph()->Int32Constant(0);
diff --git a/deps/v8/src/compiler/simplified-lowering.h b/deps/v8/src/compiler/simplified-lowering.h
index b78d5d5cfe..3f62f95efb 100644
--- a/deps/v8/src/compiler/simplified-lowering.h
+++ b/deps/v8/src/compiler/simplified-lowering.h
@@ -37,7 +37,6 @@ class V8_EXPORT_PRIVATE SimplifiedLowering final {
Node* node, RepresentationSelector* selector);
void DoJSToNumberOrNumericTruncatesToWord32(Node* node,
RepresentationSelector* selector);
- void DoShift(Node* node, Operator const* op, Type rhs_type);
void DoIntegral32ToBit(Node* node);
void DoOrderedNumberToBit(Node* node);
void DoNumberToBit(Node* node);
diff --git a/deps/v8/test/mjsunit/compiler/regress-910838.js b/deps/v8/test/mjsunit/compiler/regress-910838.js
new file mode 100644
index 0000000000..6e62a453e0
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-910838.js
@@ -0,0 +1,20 @@
+// Copyright 2018 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(b, s, x) {
+ if (!b) {
+ return (x ? b : s * undefined) ? 1 : 42;
+ }
+}
+
+function g(b, x) {
+ return f(b, 'abc', x);
+}
+
+f(false, 0, 0);
+g(true, 0);
+%OptimizeFunctionOnNextCall(g);
+assertEquals(42, g(false, 0));