diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/DynamicAccessDetectionFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/DynamicAccessDetectionFeature.java index 8556aa0a8aa9..53c18f0191b0 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/DynamicAccessDetectionFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/DynamicAccessDetectionFeature.java @@ -105,7 +105,8 @@ public ConcurrentLinkedQueue getMethodCallLocations(String methodName) { "java.io.ObjectInputStream.readObject", "java.io.ObjectStreamClass.lookup", "java.lang.reflect.Array.newInstance", - "java.lang.ClassLoader.loadClass"); + "java.lang.ClassLoader.loadClass", + "java.lang.foreign.Linker.nativeLinker"); public static final String GRAAL_SUBPATH = File.separator + "graal" + File.separator; public static final String TRACK_ALL = "all"; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/DynamicAccessDetectionPhase.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/DynamicAccessDetectionPhase.java index 6b0a95dfc04e..562c386a37d3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/DynamicAccessDetectionPhase.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/phases/DynamicAccessDetectionPhase.java @@ -42,6 +42,10 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemorySegment; import java.lang.invoke.ConstantBootstraps; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandleProxies; @@ -75,7 +79,8 @@ public class DynamicAccessDetectionPhase extends BasePhase { public enum DynamicAccessKind { Reflection("reflection-calls.json"), - Resource("resource-calls.json"); + Resource("resource-calls.json"), + Foreign("foreign-calls.json"); public final String fileName; @@ -89,6 +94,7 @@ public record MethodInfo(DynamicAccessKind accessKind, String signature) { private static final EconomicMap, Set> reflectionMethodSignatures = EconomicMap.create(); private static final EconomicMap, Set> resourceMethodSignatures = EconomicMap.create(); + private static final EconomicMap, Set> foreignMethodSignatures = EconomicMap.create(); private final DynamicAccessDetectionFeature dynamicAccessDetectionFeature; @@ -184,6 +190,11 @@ public record MethodInfo(DynamicAccessKind accessKind, String signature) { resourceMethodSignatures.put(Class.class, Set.of( new MethodSignature("getResource", String.class), new MethodSignature("getResourceAsStream", String.class))); + + foreignMethodSignatures.put(Linker.class, Set.of( + new MethodSignature("downcallHandle", MemorySegment.class, FunctionDescriptor.class, Linker.Option[].class), + new MethodSignature("downcallHandle", FunctionDescriptor.class, Linker.Option[].class), + new MethodSignature("upcallStub", MethodHandle.class, FunctionDescriptor.class, Arena.class, Linker.Option[].class))); } public DynamicAccessDetectionPhase() { @@ -216,7 +227,8 @@ protected void run(StructuredGraph graph, CoreProviders context) { private static MethodInfo getMethodInfo(ResolvedJavaMethod method) { Class declaringClass = OriginalClassProvider.getJavaClass(method.getDeclaringClass()); if (!reflectionMethodSignatures.containsKey(declaringClass) && - !resourceMethodSignatures.containsKey(declaringClass)) { + !resourceMethodSignatures.containsKey(declaringClass) && + !foreignMethodSignatures.containsKey(declaringClass)) { return null; } @@ -236,6 +248,9 @@ private static MethodInfo getMethodInfo(ResolvedJavaMethod method) { } else if (resourceMethodSignatures.containsKey(declaringClass) && resourceMethodSignatures.get(declaringClass).contains(methodSignature)) { return new MethodInfo(DynamicAccessKind.Resource, declaringClass.getName() + "#" + methodSignature); + } else if (foreignMethodSignatures.containsKey(declaringClass) && + foreignMethodSignatures.get(declaringClass).contains(methodSignature)) { + return new MethodInfo(DynamicAccessKind.Foreign, declaringClass.getName() + "#" + methodSignature); } return null; @@ -288,6 +303,7 @@ private static NodeSourcePosition getRootSourcePosition(NodeSourcePosition nodeS public static void clearMethodSignatures() { reflectionMethodSignatures.clear(); resourceMethodSignatures.clear(); + foreignMethodSignatures.clear(); } private static class MethodSignature {