Skip to content

Commit 238bd7e

Browse files
committed
[GR-45250][GR-45734] Use strict constant analysis for automatic registration for Class.getResource and Class.getResourceAsStream invocations.
1 parent 52d865b commit 238bd7e

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
import java.util.regex.Pattern;
5656
import java.util.stream.Collectors;
5757

58+
import com.oracle.svm.hosted.strictconstantanalysis.ConstantExpressionRegistry;
59+
import com.oracle.svm.hosted.strictconstantanalysis.InferredDynamicAccessLoggingFeature;
60+
import com.oracle.svm.hosted.strictconstantanalysis.StrictConstantAnalysisFeature;
5861
import org.graalvm.nativeimage.ImageSingletons;
5962
import org.graalvm.nativeimage.hosted.RuntimeResourceAccess;
6063
import org.graalvm.nativeimage.impl.ConfigurationCondition;
@@ -693,6 +696,10 @@ private void registerResourceRegistrationPlugin(InvocationPlugins plugins, Metho
693696
parameterTypes.add(InvocationPlugin.Receiver.class);
694697
parameterTypes.addAll(Arrays.asList(method.getParameterTypes()));
695698

699+
ConstantExpressionRegistry registry = ImageSingletons.contains(ConstantExpressionRegistry.class)
700+
? ImageSingletons.lookup(ConstantExpressionRegistry.class)
701+
: null;
702+
696703
plugins.register(method.getDeclaringClass(), new InvocationPlugin.RequiredInvocationPlugin(method.getName(), parameterTypes.toArray(new Class<?>[0])) {
697704
@Override
698705
public boolean isDecorator() {
@@ -702,20 +709,38 @@ public boolean isDecorator() {
702709
@Override
703710
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
704711
VMError.guarantee(!sealed, "All bytecode parsing happens before the analysis, i.e., before the registry is sealed");
705-
Class<?> clazz = SubstrateGraphBuilderPlugins.asConstantObject(b, Class.class, receiver.get(false));
706-
String resource = SubstrateGraphBuilderPlugins.asConstantObject(b, String.class, arg);
707-
if (clazz != null && resource != null) {
708-
String resourceName;
709-
try {
710-
resourceName = (String) resolveResourceName.invoke(clazz, resource);
711-
} catch (ReflectiveOperationException e) {
712-
throw VMError.shouldNotReachHere(e);
712+
StrictConstantAnalysisFeature.Options.Mode analysisMode = StrictConstantAnalysisFeature.Options.StrictConstantAnalysis.getValue();
713+
if (analysisMode != StrictConstantAnalysisFeature.Options.Mode.Disable) {
714+
assert registry != null;
715+
Class<?> clazz = registry.getReceiver(b.getMethod(), b.bci(), targetMethod, Class.class);
716+
String resource = registry.getArgument(b.getMethod(), b.bci(), targetMethod, 0, String.class);
717+
boolean inferredInStrictMode = processInferredResourceAccess(b, targetMethod, reason, resolveResourceName, clazz, resource);
718+
if (inferredInStrictMode) {
719+
return true;
713720
}
714-
b.add(ReachabilityRegistrationNode.create(() -> RuntimeResourceAccess.addResource(clazz.getModule(), resourceName), reason));
715-
return true;
721+
}
722+
if (analysisMode != StrictConstantAnalysisFeature.Options.Mode.Enforce) {
723+
Class<?> clazz = SubstrateGraphBuilderPlugins.asConstantObject(b, Class.class, receiver.get(false));
724+
String resource = SubstrateGraphBuilderPlugins.asConstantObject(b, String.class, arg);
725+
return processInferredResourceAccess(b, targetMethod, reason, resolveResourceName, clazz, resource);
716726
}
717727
return false;
718728
}
719729
});
720730
}
731+
732+
private static boolean processInferredResourceAccess(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ParsingReason reason, Method resolveResourceName, Class<?> clazz, String resource) {
733+
if (clazz != null && resource != null) {
734+
String resourceName;
735+
try {
736+
resourceName = (String) resolveResourceName.invoke(clazz, resource);
737+
} catch (ReflectiveOperationException e) {
738+
throw VMError.shouldNotReachHere(e);
739+
}
740+
b.add(ReachabilityRegistrationNode.create(() -> RuntimeResourceAccess.addResource(clazz.getModule(), resourceName), reason));
741+
InferredDynamicAccessLoggingFeature.logRegistration(b, reason, targetMethod, clazz, new Object[]{resource});
742+
return true;
743+
}
744+
return false;
745+
}
721746
}

0 commit comments

Comments
 (0)