Skip to content

Commit 07e130b

Browse files
committed
[GR-49215] DeoptProxyNode is not an ArrayLengthProvider.
PullRequest: graal/15701
2 parents baeb876 + cd77e10 commit 07e130b

File tree

2 files changed

+33
-23
lines changed
  • compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/nodes/util
  • substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/nodes

2 files changed

+33
-23
lines changed

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/nodes/util/GraphUtil.java

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -742,38 +742,53 @@ public static ValueNode arrayLength(ValueNode value, FindLengthMode mode, Consta
742742
return arrayLength(value, mode, constantReflection, null);
743743
}
744744

745+
/**
746+
* Filters out non-constant results when requested.
747+
*/
748+
private static ValueNode filterArrayLengthResult(ValueNode result, boolean allowOnlyConstantResult) {
749+
return result == null || !allowOnlyConstantResult || result.isConstant() ? result : null;
750+
}
751+
745752
private static ValueNode arrayLength(ValueNode value, FindLengthMode mode, ConstantReflectionProvider constantReflection, EconomicMap<ValueNode, ValueNode> visitedPhiInputs) {
746753
Objects.requireNonNull(mode);
747754

748755
EconomicMap<ValueNode, ValueNode> visitedPhiInputMap = visitedPhiInputs;
749756
ValueNode current = value;
750757
StructuredGraph graph = value.graph();
758+
boolean allowOnlyConstantResult = false;
751759
do {
752760
CompilationAlarm.checkProgress(graph);
753761
/*
754762
* PiArrayNode implements ArrayLengthProvider and ValueProxy. We want to treat it as an
755763
* ArrayLengthProvider, therefore we check this case first.
756764
*/
757-
if (current instanceof ArrayLengthProvider) {
758-
return ((ArrayLengthProvider) current).findLength(mode, constantReflection);
765+
if (current instanceof ArrayLengthProvider provider) {
766+
return filterArrayLengthResult(provider.findLength(mode, constantReflection), allowOnlyConstantResult);
759767

760-
} else if (current instanceof ValuePhiNode) {
768+
} else if (current instanceof ValuePhiNode phi) {
761769
if (visitedPhiInputMap == null) {
762770
visitedPhiInputMap = EconomicMap.create();
763771
}
764-
return phiArrayLength((ValuePhiNode) current, mode, constantReflection, visitedPhiInputMap);
772+
return filterArrayLengthResult(phiArrayLength(phi, mode, constantReflection, visitedPhiInputMap), allowOnlyConstantResult);
765773

766-
} else if (current instanceof ValueProxyNode) {
767-
ValueProxyNode proxy = (ValueProxyNode) current;
774+
} else if (current instanceof ValueProxyNode proxy) {
768775
ValueNode length = arrayLength(proxy.getOriginalNode(), mode, constantReflection);
769776
if (mode == ArrayLengthProvider.FindLengthMode.CANONICALIZE_READ && length != null && !length.isConstant()) {
770777
length = new ValueProxyNode(length, proxy.proxyPoint());
771778
}
772-
return length;
779+
return filterArrayLengthResult(length, allowOnlyConstantResult);
773780

774-
} else if (current instanceof ValueProxy) {
775-
/* Written as a loop instead of a recursive call to reduce recursion depth. */
776-
current = ((ValueProxy) current).getOriginalNode();
781+
} else if (current instanceof LimitedValueProxy valueProxy) {
782+
/*
783+
* Note is it usually recommended to check for ValueProxy, not LimitedValueProxy.
784+
* However, in this case we are intentionally unproxifying all LimitedValueProxies,
785+
* as we want constant lengths to be found across DeoptProxyNodes. When the result
786+
* is not a ValueProxy we limit the returned result to constant values.
787+
*/
788+
if (!(valueProxy instanceof ValueProxy)) {
789+
allowOnlyConstantResult = true;
790+
}
791+
current = valueProxy.getOriginalNode();
777792
} else {
778793
return null;
779794
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/nodes/DeoptProxyNode.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
import org.graalvm.compiler.graph.Node;
2929
import org.graalvm.compiler.graph.Node.ValueNumberable;
3030
import org.graalvm.compiler.graph.NodeClass;
31-
import org.graalvm.compiler.nodes.spi.Canonicalizable;
32-
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
3331
import org.graalvm.compiler.nodeinfo.InputType;
3432
import org.graalvm.compiler.nodeinfo.NodeCycles;
3533
import org.graalvm.compiler.nodeinfo.NodeInfo;
@@ -38,16 +36,14 @@
3836
import org.graalvm.compiler.nodes.ParameterNode;
3937
import org.graalvm.compiler.nodes.ValueNode;
4038
import org.graalvm.compiler.nodes.calc.FloatingNode;
41-
import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
39+
import org.graalvm.compiler.nodes.spi.Canonicalizable;
40+
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
4241
import org.graalvm.compiler.nodes.spi.LIRLowerable;
4342
import org.graalvm.compiler.nodes.spi.LimitedValueProxy;
4443
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
45-
import org.graalvm.compiler.nodes.util.GraphUtil;
4644

4745
import com.oracle.svm.core.deopt.Deoptimizer;
4846

49-
import jdk.vm.ci.meta.ConstantReflectionProvider;
50-
5147
/**
5248
* Wraps locals and bytecode stack elements at deoptimization points. DeoptProxyNodes are inserted
5349
* in deoptimization target methods to avoid global value numbering and rescheduling of local
@@ -56,9 +52,14 @@
5652
* This is needed to ensure that the values, which are set by the {@link Deoptimizer} at the
5753
* deoptimization point, are really read from their locations (and not held in a temporary register,
5854
* etc.)
55+
*
56+
* Note the {@link #value} of the DeoptProxyNode may be another DeoptProxyNode (i.e., there may be a
57+
* chain of DeoptProxyNodes leading to the original value). This is by design: linking to the
58+
* preceding DeoptProxyNode allows a given DeoptEntry and its corresponding DeoptProxyNodes to be
59+
* easily removed without causing correctness issues.
5960
*/
6061
@NodeInfo(cycles = NodeCycles.CYCLES_0, size = NodeSize.SIZE_0)
61-
public final class DeoptProxyNode extends FloatingNode implements LimitedValueProxy, ValueNumberable, LIRLowerable, Canonicalizable, IterableNodeType, ArrayLengthProvider {
62+
public final class DeoptProxyNode extends FloatingNode implements LimitedValueProxy, ValueNumberable, LIRLowerable, Canonicalizable, IterableNodeType {
6263
public static final NodeClass<DeoptProxyNode> TYPE = NodeClass.create(DeoptProxyNode.class);
6364

6465
/**
@@ -127,10 +128,4 @@ public boolean hasProxyPoint() {
127128
public ValueNode getProxyPoint() {
128129
return proxyPoint;
129130
}
130-
131-
@Override
132-
public ValueNode findLength(FindLengthMode mode, ConstantReflectionProvider constantReflection) {
133-
ValueNode length = GraphUtil.arrayLength(value, mode, constantReflection);
134-
return length != null && length.isConstant() ? length : null;
135-
}
136131
}

0 commit comments

Comments
 (0)