Skip to content

Commit 0cb893c

Browse files
committed
[GR-65764] Add FFM method detection to the dynamic access analysis
PullRequest: graal/21193
2 parents 0211318 + 591062d commit 0cb893c

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ public ConcurrentLinkedQueue<String> getMethodCallLocations(String methodName) {
105105
"java.io.ObjectInputStream.readObject",
106106
"java.io.ObjectStreamClass.lookup",
107107
"java.lang.reflect.Array.newInstance",
108-
"java.lang.ClassLoader.loadClass");
108+
"java.lang.ClassLoader.loadClass",
109+
"java.lang.foreign.Linker.nativeLinker");
109110

110111
public static final String GRAAL_SUBPATH = File.separator + "graal" + File.separator;
111112
public static final String TRACK_ALL = "all";

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
import java.io.ObjectInputStream;
4343
import java.io.ObjectOutputStream;
4444
import java.io.ObjectStreamClass;
45+
import java.lang.foreign.Arena;
46+
import java.lang.foreign.FunctionDescriptor;
47+
import java.lang.foreign.Linker;
48+
import java.lang.foreign.MemorySegment;
4549
import java.lang.invoke.ConstantBootstraps;
4650
import java.lang.invoke.MethodHandle;
4751
import java.lang.invoke.MethodHandleProxies;
@@ -75,7 +79,8 @@
7579
public class DynamicAccessDetectionPhase extends BasePhase<CoreProviders> {
7680
public enum DynamicAccessKind {
7781
Reflection("reflection-calls.json"),
78-
Resource("resource-calls.json");
82+
Resource("resource-calls.json"),
83+
Foreign("foreign-calls.json");
7984

8085
public final String fileName;
8186

@@ -89,6 +94,7 @@ public record MethodInfo(DynamicAccessKind accessKind, String signature) {
8994

9095
private static final EconomicMap<Class<?>, Set<MethodSignature>> reflectionMethodSignatures = EconomicMap.create();
9196
private static final EconomicMap<Class<?>, Set<MethodSignature>> resourceMethodSignatures = EconomicMap.create();
97+
private static final EconomicMap<Class<?>, Set<MethodSignature>> foreignMethodSignatures = EconomicMap.create();
9298

9399
private final DynamicAccessDetectionFeature dynamicAccessDetectionFeature;
94100

@@ -184,6 +190,11 @@ public record MethodInfo(DynamicAccessKind accessKind, String signature) {
184190
resourceMethodSignatures.put(Class.class, Set.of(
185191
new MethodSignature("getResource", String.class),
186192
new MethodSignature("getResourceAsStream", String.class)));
193+
194+
foreignMethodSignatures.put(Linker.class, Set.of(
195+
new MethodSignature("downcallHandle", MemorySegment.class, FunctionDescriptor.class, Linker.Option[].class),
196+
new MethodSignature("downcallHandle", FunctionDescriptor.class, Linker.Option[].class),
197+
new MethodSignature("upcallStub", MethodHandle.class, FunctionDescriptor.class, Arena.class, Linker.Option[].class)));
187198
}
188199

189200
public DynamicAccessDetectionPhase() {
@@ -216,7 +227,8 @@ protected void run(StructuredGraph graph, CoreProviders context) {
216227
private static MethodInfo getMethodInfo(ResolvedJavaMethod method) {
217228
Class<?> declaringClass = OriginalClassProvider.getJavaClass(method.getDeclaringClass());
218229
if (!reflectionMethodSignatures.containsKey(declaringClass) &&
219-
!resourceMethodSignatures.containsKey(declaringClass)) {
230+
!resourceMethodSignatures.containsKey(declaringClass) &&
231+
!foreignMethodSignatures.containsKey(declaringClass)) {
220232
return null;
221233
}
222234

@@ -236,6 +248,9 @@ private static MethodInfo getMethodInfo(ResolvedJavaMethod method) {
236248
} else if (resourceMethodSignatures.containsKey(declaringClass) &&
237249
resourceMethodSignatures.get(declaringClass).contains(methodSignature)) {
238250
return new MethodInfo(DynamicAccessKind.Resource, declaringClass.getName() + "#" + methodSignature);
251+
} else if (foreignMethodSignatures.containsKey(declaringClass) &&
252+
foreignMethodSignatures.get(declaringClass).contains(methodSignature)) {
253+
return new MethodInfo(DynamicAccessKind.Foreign, declaringClass.getName() + "#" + methodSignature);
239254
}
240255

241256
return null;
@@ -288,6 +303,7 @@ private static NodeSourcePosition getRootSourcePosition(NodeSourcePosition nodeS
288303
public static void clearMethodSignatures() {
289304
reflectionMethodSignatures.clear();
290305
resourceMethodSignatures.clear();
306+
foreignMethodSignatures.clear();
291307
}
292308

293309
private static class MethodSignature {

0 commit comments

Comments
 (0)