Skip to content

Commit b5cd103

Browse files
committed
Use strict constant analysis for automatically inferring invocations with dynamic access.
1 parent 646b9db commit b5cd103

File tree

4 files changed

+356
-161
lines changed

4 files changed

+356
-161
lines changed

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

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,14 @@
5252
import java.util.concurrent.ScheduledExecutorService;
5353
import java.util.concurrent.TimeUnit;
5454
import java.util.concurrent.atomic.LongAdder;
55+
import java.util.function.BooleanSupplier;
56+
import java.util.function.Predicate;
5557
import java.util.regex.Pattern;
5658
import java.util.stream.Collectors;
5759

60+
import com.oracle.svm.hosted.strictconstantanalysis.ConstantExpressionRegistry;
61+
import com.oracle.svm.hosted.strictconstantanalysis.InferredDynamicAccessLoggingFeature;
62+
import com.oracle.svm.hosted.strictconstantanalysis.StrictConstantAnalysisFeature;
5863
import org.graalvm.nativeimage.ImageSingletons;
5964
import org.graalvm.nativeimage.hosted.RuntimeResourceAccess;
6065
import org.graalvm.nativeimage.impl.ConfigurationCondition;
@@ -702,20 +707,33 @@ public boolean isDecorator() {
702707
@Override
703708
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
704709
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);
713-
}
714-
b.add(ReachabilityRegistrationNode.create(() -> RuntimeResourceAccess.addResource(clazz.getModule(), resourceName), reason));
715-
return true;
716-
}
717-
return false;
710+
Predicate<ConstantExpressionRegistry> strictModeRoutine = (registry) -> {
711+
Class<?> clazz = registry.getReceiver(b.getMethod(), b.bci(), targetMethod, Class.class);
712+
String resource = registry.getArgument(b.getMethod(), b.bci(), targetMethod, 0, String.class);
713+
return processInferredResourceAccess(b, targetMethod, reason, resolveResourceName, clazz, resource);
714+
};
715+
BooleanSupplier graphModeRoutine = () -> {
716+
Class<?> clazz = SubstrateGraphBuilderPlugins.asConstantObject(b, Class.class, receiver.get(false));
717+
String resource = SubstrateGraphBuilderPlugins.asConstantObject(b, String.class, arg);
718+
return processInferredResourceAccess(b, targetMethod, reason, resolveResourceName, clazz, resource);
719+
};
720+
return StrictConstantAnalysisFeature.tryToInfer(strictModeRoutine, graphModeRoutine);
718721
}
719722
});
720723
}
724+
725+
private static boolean processInferredResourceAccess(GraphBuilderContext b, ResolvedJavaMethod targetMethod, ParsingReason reason, Method resolveResourceName, Class<?> clazz, String resource) {
726+
if (clazz != null && resource != null) {
727+
String resourceName;
728+
try {
729+
resourceName = (String) resolveResourceName.invoke(clazz, resource);
730+
} catch (ReflectiveOperationException e) {
731+
throw VMError.shouldNotReachHere(e);
732+
}
733+
b.add(ReachabilityRegistrationNode.create(() -> RuntimeResourceAccess.addResource(clazz.getModule(), resourceName), reason));
734+
InferredDynamicAccessLoggingFeature.logRegistration(b, reason, targetMethod, clazz, new Object[]{resource});
735+
return true;
736+
}
737+
return false;
738+
}
721739
}

0 commit comments

Comments
 (0)