Skip to content

Commit d9e7607

Browse files
committed
[GR-69630] Fix canonicalization of always-null guarded values.
PullRequest: graal/22174
2 parents c784c6d + f48aa34 commit d9e7607

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/common/CanonicalizerPhase.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.graalvm.collections.EconomicSet;
3939
import org.graalvm.collections.Pair;
4040

41+
import jdk.graal.compiler.core.common.type.AbstractObjectStamp;
4142
import jdk.graal.compiler.core.common.type.Stamp;
4243
import jdk.graal.compiler.debug.Assertions;
4344
import jdk.graal.compiler.debug.CounterKey;
@@ -77,6 +78,7 @@
7778
import jdk.graal.compiler.nodes.calc.ConditionalNode;
7879
import jdk.graal.compiler.nodes.calc.FloatingNode;
7980
import jdk.graal.compiler.nodes.cfg.ControlFlowGraph;
81+
import jdk.graal.compiler.nodes.extended.GuardedNode;
8082
import jdk.graal.compiler.nodes.extended.GuardingNode;
8183
import jdk.graal.compiler.nodes.loop.InductionVariable;
8284
import jdk.graal.compiler.nodes.spi.Canonicalizable;
@@ -615,11 +617,16 @@ private boolean processNode(Node node, Tool tool, NodeBitMap singleShotList) {
615617
if (tryCanonicalize(node, nodeClass, tool)) {
616618
return true;
617619
}
618-
if (node instanceof ValueNode) {
619-
ValueNode valueNode = (ValueNode) node;
620+
if (node instanceof ValueNode valueNode) {
620621
boolean improvedStamp = tryInferStamp(valueNode, tool);
621622
Constant constant = valueNode.stamp(NodeView.DEFAULT).asConstant();
622-
if (constant != null && !(node instanceof ConstantNode)) {
623+
if (constant != null && !(node instanceof ConstantNode) && !isAnchoredNullConstant(valueNode)) {
624+
/*
625+
* Do not fold always-null Pis to null constants. Doing so could lead to dependent
626+
* reads floating above safety checks, potentially causing runtime segfaults. By
627+
* contrast, folding integer constants that could cause out-of-bounds reads is safe
628+
* as JVMCI detects these and fails gracefully.
629+
*/
623630
ConstantNode stampConstant = ConstantNode.forConstant(valueNode.stamp(NodeView.DEFAULT), constant, tool.context.getMetaAccess(), graph);
624631
valueNode.replaceAtUsages(stampConstant, InputType.Value);
625632
GraphUtil.tryKillUnused(valueNode);
@@ -640,6 +647,16 @@ private boolean processNode(Node node, Tool tool, NodeBitMap singleShotList) {
640647
return false;
641648
}
642649

650+
/**
651+
* Tests if {@code node} is an always-null value that is anchored.
652+
*/
653+
private static boolean isAnchoredNullConstant(ValueNode node) {
654+
if (node instanceof GuardedNode guarded && guarded.getGuard() != null) {
655+
return node.stamp(NodeView.DEFAULT).isObjectStamp() && ((AbstractObjectStamp) node.stamp(NodeView.DEFAULT)).alwaysNull();
656+
}
657+
return false;
658+
}
659+
643660
public static boolean gvn(Node node, NodeClass<?> nodeClass) {
644661
if (nodeClass.valueNumberable()) {
645662
Node newNode = node.graph().findDuplicate(node);

web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasmgc/codegen/WebImageWasmGCNodeLowerer.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import com.oracle.svm.webimage.wasmgc.WasmGCJSConversion;
8080

8181
import jdk.graal.compiler.core.common.type.AbstractObjectStamp;
82+
import jdk.graal.compiler.core.common.type.AbstractPointerStamp;
8283
import jdk.graal.compiler.core.common.type.PrimitiveStamp;
8384
import jdk.graal.compiler.core.common.type.Stamp;
8485
import jdk.graal.compiler.core.common.type.TypeReference;
@@ -242,6 +243,37 @@ protected Instruction lowerReturn(ReturnNode returnNode) {
242243
return new Instruction.Return(result);
243244
}
244245

246+
@Override
247+
protected Instruction lowerExpression(ValueNode n, WasmIRWalker.Requirements reqs) {
248+
Instruction inst = super.lowerExpression(n, reqs);
249+
250+
/*
251+
* Produce a constant null value for always-null stamps.
252+
*
253+
* Always null stamps are a bit of a special case because they often don't have concrete
254+
* type information, which is required in WasmGC because even null-constant have a static
255+
* type. For that reason, the actual instruction are emitted as a top-level instruction and
256+
* dropped (since it may have a side effect) and we simply return a "ref.null none", which
257+
* represents the bottom type and thus satisfies all subtype checks, at all usages.
258+
*/
259+
if (n.stamp(NodeView.DEFAULT) instanceof AbstractPointerStamp pointerStamp && pointerStamp.alwaysNull()) {
260+
if (!(inst instanceof Instruction.LocalGet)) {
261+
/*
262+
* We can't just not emit the instruction, it may have side effects, so we just emit
263+
* it in the same block and ignore its output (which is guaranteed to be null).
264+
*
265+
* If the node's value was stored in a variable and would be just loaded here, we
266+
* can omit this, as there are no side-effects.
267+
*/
268+
masm.genInst(new Instruction.Drop(inst));
269+
}
270+
271+
return new Instruction.RefNull(WasmRefType.NONE);
272+
} else {
273+
return inst;
274+
}
275+
}
276+
245277
protected Instruction lowerUnwind(UnwindNode n) {
246278
return new Instruction.Call(masm().getKnownIds().throwTemplate.requestFunctionId(), lowerExpression(n.exception()));
247279
}

web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasmgc/types/WasmRefType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public abstract class WasmRefType implements WasmValType {
5555
public static final WasmRefType ANYREF = Kind.ANY.nullable();
5656
public static final WasmRefType FUNCREF = Kind.FUNC.nullable();
5757
public static final WasmRefType EXTERNREF = Kind.EXTERN.nullable();
58+
public static final WasmRefType NONE = Kind.NONE.nullable();
5859

5960
/**
6061
* Enum of all {@link AbsHeap} types. Pulled up to the superclass for convenience.

0 commit comments

Comments
 (0)