Skip to content

Commit c60b247

Browse files
author
Christian Wimmer
committed
Canonicalize class initialization checks coming from invocation plugins during InlineBeforeAnalysis / SimulateClassInitializer
1 parent 526a6d7 commit c60b247

File tree

8 files changed

+60
-19
lines changed

8 files changed

+60
-19
lines changed

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/java/BytecodeParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2861,7 +2861,7 @@ protected ConstantNode appendConstant(JavaConstant constant) {
28612861
}
28622862

28632863
@Override
2864-
public <T extends ValueNode> T append(T v) {
2864+
public <T extends Node> T append(T v) {
28652865
assert !graph.trackNodeSourcePosition() || graph.currentNodeSourcePosition() != null || currentBlock == blockMap.getUnwindBlock() || currentBlock instanceof ExceptionDispatchBlock;
28662866
if (v.graph() != null) {
28672867
return v;
@@ -2873,7 +2873,7 @@ public <T extends ValueNode> T append(T v) {
28732873
return added;
28742874
}
28752875

2876-
private <T extends ValueNode> void updateLastInstruction(T v) {
2876+
private <T extends Node> void updateLastInstruction(T v) {
28772877
if (v instanceof FixedNode) {
28782878
FixedNode fixedNode = (FixedNode) v;
28792879
if (lastInstr != null) {

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderContext.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.graalvm.compiler.core.common.type.StampFactory;
3636
import org.graalvm.compiler.core.common.type.StampPair;
3737
import org.graalvm.compiler.debug.GraalError;
38+
import org.graalvm.compiler.graph.Node;
3839
import org.graalvm.compiler.nodes.AbstractBeginNode;
3940
import org.graalvm.compiler.nodes.AbstractMergeNode;
4041
import org.graalvm.compiler.nodes.BeginNode;
@@ -90,7 +91,7 @@ public interface GraphBuilderContext extends GraphBuilderTool {
9091
*
9192
* @param kind the kind to use when type checking this operation
9293
* @param value the value to push to the stack. The value must already have been
93-
* {@linkplain #append(ValueNode) appended}.
94+
* {@linkplain #append(Node) appended}.
9495
*/
9596
void push(JavaKind kind, ValueNode value);
9697

@@ -121,14 +122,24 @@ default ValueNode[] popArguments(int argSize) {
121122
* type checking this operation.
122123
* @return a node equivalent to {@code value} in the graph
123124
*/
124-
default <T extends ValueNode> T add(T value) {
125+
default <T extends Node> T add(T value) {
125126
if (value.graph() != null) {
126127
assert !(value instanceof StateSplit) || ((StateSplit) value).stateAfter() != null;
127128
return value;
128129
}
129130
return setStateAfterIfNecessary(this, append(value));
130131
}
131132

133+
/**
134+
* Maybe performs canonicalization on the provided node. Either the result of the
135+
* canonicalization, or the original node if canonicalization is not possible, is added to the
136+
* graph and returned. Note that the return value can be null when canonicalization determines
137+
* that the node can be deleted.
138+
*/
139+
default Node canonicalizeAndAdd(Node value) {
140+
return add(value);
141+
}
142+
132143
default ValueNode addNonNullCast(ValueNode value) {
133144
AbstractPointerStamp valueStamp = (AbstractPointerStamp) value.stamp(NodeView.DEFAULT);
134145
if (valueStamp.nonNull()) {
@@ -536,7 +547,7 @@ default void replacePluginWithException(GeneratedInvocationPlugin plugin, Resolv
536547
throw GraalError.unimplementedParent(); // ExcludeFromJacocoGeneratedReport
537548
}
538549

539-
static <T extends ValueNode> T setStateAfterIfNecessary(GraphBuilderContext b, T value) {
550+
static <T extends Node> T setStateAfterIfNecessary(GraphBuilderContext b, T value) {
540551
if (value instanceof StateSplit) {
541552
StateSplit stateSplit = (StateSplit) value;
542553
FrameState oldState = stateSplit.stateAfter();

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/nodes/graphbuilderconf/GraphBuilderTool.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
package org.graalvm.compiler.nodes.graphbuilderconf;
2626

2727
import org.graalvm.compiler.debug.DebugContext;
28+
import org.graalvm.compiler.graph.Node;
2829
import org.graalvm.compiler.nodes.StructuredGraph;
29-
import org.graalvm.compiler.nodes.ValueNode;
3030
import org.graalvm.compiler.nodes.spi.CoreProviders;
3131
import org.graalvm.compiler.options.OptionValues;
3232

@@ -43,7 +43,7 @@ public interface GraphBuilderTool extends CoreProviders {
4343
* @param value the node to be added to the graph
4444
* @return either the node added or an equivalent node
4545
*/
46-
<T extends ValueNode> T append(T value);
46+
<T extends Node> T append(T value);
4747

4848
default Assumptions getAssumptions() {
4949
return getGraph().getAssumptions();

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/GraphKit.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.graalvm.compiler.debug.DebugContext;
4242
import org.graalvm.compiler.debug.GraalError;
4343
import org.graalvm.compiler.graph.Graph;
44+
import org.graalvm.compiler.graph.Node;
4445
import org.graalvm.compiler.graph.Node.ValueNumberable;
4546
import org.graalvm.compiler.graph.NodeSourcePosition;
4647
import org.graalvm.compiler.java.FrameStateBuilder;
@@ -153,9 +154,9 @@ public <T extends ValueNode> T add(T node) {
153154
return graph.add(changeToWord(node));
154155
}
155156

156-
public <T extends ValueNode> T changeToWord(T node) {
157-
if (wordTypes != null && wordTypes.isWord(node)) {
158-
node.setStamp(wordTypes.getWordStamp(StampTool.typeOrNull(node)));
157+
public <T extends Node> T changeToWord(T node) {
158+
if (node instanceof ValueNode valueNode && wordTypes != null && wordTypes.isWord(valueNode)) {
159+
valueNode.setStamp(wordTypes.getWordStamp(StampTool.typeOrNull(valueNode)));
159160
}
160161
return node;
161162
}
@@ -170,7 +171,7 @@ public final JavaKind asKind(JavaType type) {
170171
}
171172

172173
@Override
173-
public <T extends ValueNode> T append(T node) {
174+
public <T extends Node> T append(T node) {
174175
if (node.graph() != null) {
175176
return node;
176177
}

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/IntrinsicGraphBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.graalvm.compiler.debug.DebugCloseable;
3535
import org.graalvm.compiler.debug.DebugContext;
3636
import org.graalvm.compiler.debug.GraalError;
37+
import org.graalvm.compiler.graph.Node;
3738
import org.graalvm.compiler.graph.NodeSourcePosition;
3839
import org.graalvm.compiler.java.FrameStateBuilder;
3940
import org.graalvm.compiler.nodes.AbstractBeginNode;
@@ -163,7 +164,7 @@ protected IntrinsicGraphBuilder(OptionValues options,
163164
}
164165
}
165166

166-
private <T extends ValueNode> void updateLastInstruction(T v) {
167+
private <T extends Node> void updateLastInstruction(T v) {
167168
if (v instanceof FixedNode) {
168169
FixedNode fixedNode = (FixedNode) v;
169170
if (lastInstr != null) {
@@ -222,7 +223,7 @@ protected void mergeUnwinds() {
222223
}
223224

224225
@Override
225-
public <T extends ValueNode> T append(T v) {
226+
public <T extends Node> T append(T v) {
226227
if (v.graph() != null) {
227228
return v;
228229
}

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/replacements/PEGraphDecoder.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
import org.graalvm.compiler.nodes.UnwindNode;
9595
import org.graalvm.compiler.nodes.ValueNode;
9696
import org.graalvm.compiler.nodes.WithExceptionNode;
97+
import org.graalvm.compiler.nodes.calc.FloatingNode;
9798
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
9899
import org.graalvm.compiler.nodes.extended.AnchoringNode;
99100
import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode;
@@ -421,7 +422,7 @@ public IntrinsicContext getIntrinsic() {
421422
}
422423

423424
@Override
424-
public <T extends ValueNode> T append(T value) {
425+
public <T extends Node> T append(T value) {
425426
throw unimplementedOverride(); // ExcludeFromJacocoGeneratedReport
426427
}
427428

@@ -550,7 +551,7 @@ public void setStateAfter(StateSplit stateSplit) {
550551

551552
@SuppressWarnings("try")
552553
@Override
553-
public <T extends ValueNode> T append(T v) {
554+
public <T extends Node> T append(T v) {
554555
if (v.graph() != null) {
555556
return v;
556557
}
@@ -563,6 +564,21 @@ public <T extends ValueNode> T append(T v) {
563564
}
564565
}
565566

567+
@Override
568+
public Node canonicalizeAndAdd(Node node) {
569+
Node canonicalized = node;
570+
if (canonicalized instanceof FixedNode fixedNode) {
571+
canonicalized = canonicalizeFixedNode(methodScope, null, fixedNode);
572+
} else if (canonicalized instanceof FloatingNode floatingNode) {
573+
canonicalized = handleFloatingNodeBeforeAdd(methodScope, null, floatingNode);
574+
}
575+
576+
if (canonicalized == null) {
577+
return null;
578+
}
579+
return super.canonicalizeAndAdd(canonicalized);
580+
}
581+
566582
private DebugCloseable withNodeSourcePosition() {
567583
if (getGraph().trackNodeSourcePosition()) {
568584
NodeSourcePosition callerBytecodePosition = methodScope.getCallerNodeSourcePosition();
@@ -573,7 +589,7 @@ private DebugCloseable withNodeSourcePosition() {
573589
return null;
574590
}
575591

576-
private <T extends ValueNode> void updateLastInstruction(T v) {
592+
private <T extends Node> void updateLastInstruction(T v) {
577593
if (v instanceof FixedNode) {
578594
FixedNode fixedNode = (FixedNode) v;
579595
if (lastInstr != null) {
@@ -721,7 +737,7 @@ public void setStateAfter(StateSplit sideEffect) {
721737

722738
@SuppressWarnings("try")
723739
@Override
724-
public <T extends ValueNode> T append(T v) {
740+
public <T extends Node> T append(T v) {
725741
if (v.graph() != null) {
726742
return v;
727743
}
@@ -744,7 +760,7 @@ private DebugCloseable withNodeSourcePosition() {
744760
return null;
745761
}
746762

747-
private <T extends ValueNode> void updateLastInstruction(T value) {
763+
private <T extends Node> void updateLastInstruction(T value) {
748764
if (value instanceof FixedWithNextNode) {
749765
FixedWithNextNode fixed = (FixedWithNextNode) value;
750766
graph.addBeforeFixed(insertBefore, fixed);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/SubstrateClassInitializationPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,6 @@ public boolean apply(GraphBuilderContext builder, ResolvedJavaType type, Supplie
7878
private static void emitEnsureClassInitialized(GraphBuilderContext builder, JavaConstant hubConstant, FrameState frameState) {
7979
ValueNode hub = ConstantNode.forConstant(hubConstant, builder.getMetaAccess(), builder.getGraph());
8080
EnsureClassInitializedNode node = new EnsureClassInitializedNode(hub, frameState);
81-
builder.add(node);
81+
builder.canonicalizeAndAdd(node);
8282
}
8383
}

substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/clinit/TestClassInitialization.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,22 @@ class ReflectionMustBeSafeEarly {
425425
m1 = c1Local.getDeclaredMethod("foo", int.class);
426426
f2 = c2Local.getDeclaredField("field");
427427

428+
/*
429+
* Check that reflective class lookup and the elimination of the class initialization
430+
* check also works when the class name is not constant yet during bytecode parsing.
431+
*/
432+
if (c1Local != Class.forName(forNameMustBeSafeEarly(), true, ReflectionMustBeSafeEarly.class.getClassLoader())) {
433+
throw new Error("wrong class");
434+
}
435+
428436
} catch (ReflectiveOperationException ex) {
429437
throw new Error(ex);
430438
}
431439
}
440+
441+
private static String forNameMustBeSafeEarly() {
442+
return "com.oracle.svm.test.clinit.ForNameMustBeSafeEarly";
443+
}
432444
}
433445

434446
@SuppressWarnings("unused")

0 commit comments

Comments
 (0)