Skip to content

Commit 76b385f

Browse files
author
Christian Wimmer
committed
Add verification for invoke receiver types
1 parent ab3a2ae commit 76b385f

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,4 +620,7 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, String ol
620620
@APIOption(name = "configure-reflection-metadata")//
621621
@Option(help = "Limit method reflection metadata to configuration entries instead of including it for all reachable methods")//
622622
public static final HostedOptionKey<Boolean> ConfigureReflectionMetadata = new HostedOptionKey<>(true);
623+
624+
@Option(help = "Verify type states computed by the static analysis at run time", type = Debug)//
625+
public static final HostedOptionKey<Boolean> VerifyTypes = new HostedOptionKey<>(true);
623626
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/NonSnippetLowerings.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,19 @@
3333
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
3434
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
3535
import org.graalvm.compiler.core.common.type.StampPair;
36+
import org.graalvm.compiler.core.common.type.TypeReference;
3637
import org.graalvm.compiler.debug.DebugHandlersFactory;
3738
import org.graalvm.compiler.graph.Node;
3839
import org.graalvm.compiler.graph.NodeInputList;
40+
import org.graalvm.compiler.nodes.BeginNode;
3941
import org.graalvm.compiler.nodes.CallTargetNode;
4042
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
4143
import org.graalvm.compiler.nodes.ConstantNode;
4244
import org.graalvm.compiler.nodes.DirectCallTargetNode;
4345
import org.graalvm.compiler.nodes.FixedGuardNode;
4446
import org.graalvm.compiler.nodes.FixedNode;
47+
import org.graalvm.compiler.nodes.FixedWithNextNode;
48+
import org.graalvm.compiler.nodes.IfNode;
4549
import org.graalvm.compiler.nodes.IndirectCallTargetNode;
4650
import org.graalvm.compiler.nodes.Invoke;
4751
import org.graalvm.compiler.nodes.InvokeNode;
@@ -54,11 +58,14 @@
5458
import org.graalvm.compiler.nodes.StructuredGraph;
5559
import org.graalvm.compiler.nodes.ValueNode;
5660
import org.graalvm.compiler.nodes.calc.IsNullNode;
61+
import org.graalvm.compiler.nodes.extended.BranchProbabilityNode;
5762
import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode;
5863
import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode.BytecodeExceptionKind;
5964
import org.graalvm.compiler.nodes.extended.ForeignCallNode;
6065
import org.graalvm.compiler.nodes.extended.GetClassNode;
6166
import org.graalvm.compiler.nodes.extended.LoadHubNode;
67+
import org.graalvm.compiler.nodes.extended.OpaqueNode;
68+
import org.graalvm.compiler.nodes.java.InstanceOfNode;
6269
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
6370
import org.graalvm.compiler.nodes.memory.OnHeapMemoryAccess.BarrierType;
6471
import org.graalvm.compiler.nodes.memory.ReadNode;
@@ -73,6 +80,7 @@
7380
import org.graalvm.word.LocationIdentity;
7481

7582
import com.oracle.svm.core.FrameAccess;
83+
import com.oracle.svm.core.SubstrateOptions;
7684
import com.oracle.svm.core.code.CodeInfoTable;
7785
import com.oracle.svm.core.graal.code.SubstrateBackend;
7886
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
@@ -81,6 +89,8 @@
8189
import com.oracle.svm.core.meta.SharedMethod;
8290
import com.oracle.svm.core.meta.SubstrateObjectConstant;
8391
import com.oracle.svm.core.snippets.ImplicitExceptions;
92+
import com.oracle.svm.core.snippets.SnippetRuntime;
93+
import com.oracle.svm.core.snippets.SubstrateForeignCallTarget;
8494
import com.oracle.svm.core.util.VMError;
8595

8696
import jdk.vm.ci.code.CallingConvention;
@@ -93,9 +103,19 @@
93103

94104
public abstract class NonSnippetLowerings {
95105

106+
public static final SnippetRuntime.SubstrateForeignCallDescriptor REPORT_VERIFY_TYPES_ERROR = SnippetRuntime.findForeignCall(NonSnippetLowerings.class, "reportVerifyTypesError", false,
107+
LocationIdentity.any());
108+
96109
private final RuntimeConfiguration runtimeConfig;
97110
private final Predicate<ResolvedJavaMethod> mustNotAllocatePredicate;
98111

112+
final boolean verifyTypes = SubstrateOptions.VerifyTypes.getValue();
113+
114+
@SubstrateForeignCallTarget(stubCallingConvention = true)
115+
private static void reportVerifyTypesError(Object object, String message) {
116+
throw VMError.shouldNotReachHere("VerifyTypes found a type error for object " + (object == null ? "null" : object.getClass().getTypeName()) + ": " + message);
117+
}
118+
99119
@SuppressWarnings("unused")
100120
protected NonSnippetLowerings(RuntimeConfiguration runtimeConfig, Predicate<ResolvedJavaMethod> mustNotAllocatePredicate, OptionValues options, Iterable<DebugHandlersFactory> factories,
101121
Providers providers, SnippetReflectionProvider snippetReflection, Map<Class<? extends Node>, NodeLoweringProvider<?>> lowerings) {
@@ -251,6 +271,24 @@ public void lower(FixedNode node, LoweringTool tool) {
251271
JavaType[] signature = method.getSignature().toParameterTypes(callTarget.isStatic() ? null : method.getDeclaringClass());
252272
CallingConvention.Type callType = method.getCallingConventionKind().toType(true);
253273

274+
if (verifyTypes && !callTarget.isStatic() && receiver.getStackKind() == JavaKind.Object) {
275+
ValueNode opaqueReceiver = graph.unique(new OpaqueNode(receiver));
276+
LogicNode instanceOf = graph.addOrUniqueWithInputs(InstanceOfNode.create(TypeReference.createTrustedWithoutAssumptions(method.getDeclaringClass()), opaqueReceiver));
277+
BeginNode passingBegin = graph.add(new BeginNode());
278+
BeginNode failingBegin = graph.add(new BeginNode());
279+
IfNode ifNode = graph.add(new IfNode(instanceOf, passingBegin, failingBegin, BranchProbabilityNode.EXTREMELY_FAST_PATH_PROFILE));
280+
281+
FixedWithNextNode pred = (FixedWithNextNode) node.predecessor();
282+
pred.setNext(ifNode);
283+
passingBegin.setNext(node);
284+
285+
ConstantNode errorMessage = ConstantNode.forConstant(tool.getConstantReflection().forString("Invoke of " + method.format("%H.%n(%p)%r")), tool.getMetaAccess(), graph);
286+
ForeignCallNode reportError = graph.add(new ForeignCallNode(REPORT_VERIFY_TYPES_ERROR, opaqueReceiver, errorMessage));
287+
reportError.setStateAfter(invoke.stateAfter().duplicateModifiedDuringCall(invoke.bci(), node.getStackKind()));
288+
failingBegin.setNext(reportError);
289+
reportError.setNext(graph.add(new LoweredDeadEndNode()));
290+
}
291+
254292
InvokeKind invokeKind = callTarget.invokeKind();
255293
SharedMethod[] implementations = method.getImplementations();
256294
LoadHubNode hub = null;

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/ImplicitExceptionsFeature.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@
2525
package com.oracle.svm.hosted.snippets;
2626

2727
import com.oracle.graal.pointsto.meta.AnalysisMethod;
28+
import com.oracle.svm.core.SubstrateOptions;
2829
import com.oracle.svm.core.annotate.AutomaticFeature;
2930
import com.oracle.svm.core.graal.GraalFeature;
3031
import com.oracle.svm.core.graal.meta.SubstrateForeignCallsProvider;
32+
import com.oracle.svm.core.graal.snippets.NonSnippetLowerings;
3133
import com.oracle.svm.core.snippets.ExceptionUnwind;
3234
import com.oracle.svm.core.snippets.ImplicitExceptions;
3335
import com.oracle.svm.core.snippets.SnippetRuntime.SubstrateForeignCallDescriptor;
@@ -46,11 +48,17 @@ public void beforeAnalysis(BeforeAnalysisAccess a) {
4648
for (SubstrateForeignCallDescriptor descriptor : ExceptionUnwind.FOREIGN_CALLS) {
4749
access.getBigBang().addRootMethod((AnalysisMethod) descriptor.findMethod(access.getMetaAccess()));
4850
}
51+
if (SubstrateOptions.VerifyTypes.getValue()) {
52+
access.getBigBang().addRootMethod((AnalysisMethod) NonSnippetLowerings.REPORT_VERIFY_TYPES_ERROR.findMethod(access.getMetaAccess()));
53+
}
4954
}
5055

5156
@Override
5257
public void registerForeignCalls(SubstrateForeignCallsProvider foreignCalls) {
5358
foreignCalls.register(ImplicitExceptions.FOREIGN_CALLS);
5459
foreignCalls.register(ExceptionUnwind.FOREIGN_CALLS);
60+
if (SubstrateOptions.VerifyTypes.getValue()) {
61+
foreignCalls.register(NonSnippetLowerings.REPORT_VERIFY_TYPES_ERROR);
62+
}
5563
}
5664
}

0 commit comments

Comments
 (0)