Skip to content

Commit 9acd1b0

Browse files
committed
Trace JNI accesses
1 parent 76a34cc commit 9acd1b0

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/access/JNIAccessibleMethodDescriptor.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,19 @@ public boolean isClassInitializer() {
9898
return WRAPPED_CSTRING_EQUIVALENCE.equals(name, INITIALIZER_NAME);
9999
}
100100

101+
/**
102+
* Returns the method name as a String. Can be used if the descriptor is known to be a String
103+
* (i.e., it does not come from a JNI call); otherwise, use {@link #getNameConvertToString()}.
104+
*/
101105
public String getName() {
102106
return (String) name;
103107
}
104108

109+
/**
110+
* Returns the method signature as a String. Can be used if the descriptor is known to be a
111+
* String (i.e., it does not come from a JNI call); otherwise, use
112+
* {@link #getSignatureConvertToString()}.
113+
*/
105114
public String getSignature() {
106115
return (String) signature;
107116
}
@@ -113,6 +122,13 @@ public String getNameConvertToString() {
113122
return name.toString();
114123
}
115124

125+
/**
126+
* Performs a potentially costly conversion to string, only for slow paths.
127+
*/
128+
public String getSignatureConvertToString() {
129+
return signature.toString();
130+
}
131+
116132
public String getSignatureWithoutReturnType() {
117133
String signatureString = signature.toString();
118134
int parametersEnd = signatureString.lastIndexOf(')');

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/access/JNIReflectionDictionary.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import org.graalvm.nativeimage.Platforms;
4242
import org.graalvm.word.Pointer;
4343

44+
import com.oracle.svm.configure.config.ConfigurationMemberInfo;
45+
import com.oracle.svm.configure.config.ConfigurationType;
4446
import com.oracle.svm.core.SubstrateOptions;
4547
import com.oracle.svm.core.Uninterruptible;
4648
import com.oracle.svm.core.heap.Heap;
@@ -52,6 +54,7 @@
5254
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
5355
import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton;
5456
import com.oracle.svm.core.log.Log;
57+
import com.oracle.svm.core.metadata.MetadataTracer;
5558
import com.oracle.svm.core.snippets.KnownIntrinsics;
5659
import com.oracle.svm.core.util.ImageHeapMap;
5760
import com.oracle.svm.core.util.Utf8.WrappedAsciiCString;
@@ -185,6 +188,9 @@ public Iterable<JNIAccessibleClass> getClasses() {
185188
public static Class<?> getClassObjectByName(CharSequence name) {
186189
for (var dictionary : layeredSingletons()) {
187190
JNIAccessibleClass clazz = dictionary.classesByName.get(name);
191+
if (MetadataTracer.Options.MetadataTracingSupport.getValue() && clazz != null && MetadataTracer.singleton().enabled()) {
192+
MetadataTracer.singleton().traceJNIType(convertFindClassNameToBinaryName(name.toString()));
193+
}
188194
clazz = checkClass(clazz, name);
189195
if (clazz != null) {
190196
return clazz.getClassObject();
@@ -194,6 +200,16 @@ public static Class<?> getClassObjectByName(CharSequence name) {
194200
return null;
195201
}
196202

203+
/**
204+
* FindClass's argument is either an internal class name (e.g., {@code pkg/sub/Class}) or an
205+
* array type signature (e.g., {@code [Lpkg/sub/Class;}). Converts the argument to a regular
206+
* binary name (e.g., {@code pkg.sub.Class}.
207+
*/
208+
private static String convertFindClassNameToBinaryName(String name) {
209+
String internalName = (name.charAt(0) != '[') ? ('L' + name + ';') : name;
210+
return MetaUtil.internalNameToJava(internalName, true, true);
211+
}
212+
197213
private static JNIAccessibleClass checkClass(JNIAccessibleClass clazz, CharSequence name) {
198214
if (throwMissingRegistrationErrors() && clazz == null) {
199215
MissingJNIRegistrationUtils.forClass(name.toString());
@@ -277,6 +293,10 @@ private static JNIAccessibleMethod getDeclaredMethod(Class<?> classObject, JNIAc
277293
foundClass = true;
278294
JNIAccessibleMethod method = clazz.getMethod(descriptor);
279295
if (method != null) {
296+
if (MetadataTracer.Options.MetadataTracingSupport.getValue() && MetadataTracer.singleton().enabled()) {
297+
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
298+
clazzType.addMethod(descriptor.getNameConvertToString(), descriptor.getSignatureConvertToString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
299+
}
280300
return method;
281301
}
282302
}
@@ -332,6 +352,10 @@ private static JNIAccessibleField getDeclaredField(Class<?> classObject, CharSeq
332352
foundClass = true;
333353
JNIAccessibleField field = clazz.getField(name);
334354
if (field != null && (field.isStatic() == isStatic || field.isNegative())) {
355+
if (MetadataTracer.Options.MetadataTracingSupport.getValue() && MetadataTracer.singleton().enabled()) {
356+
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
357+
clazzType.addField(name.toString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED, false);
358+
}
335359
return field;
336360
}
337361
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/metadata/MetadataTracer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition;
3737

3838
import com.oracle.svm.configure.config.ConfigurationSet;
39+
import com.oracle.svm.configure.config.ConfigurationType;
3940
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
4041
import com.oracle.svm.core.feature.InternalFeature;
4142
import com.oracle.svm.core.jdk.RuntimeSupport;
@@ -79,6 +80,11 @@ public boolean enabled() {
7980
return config != null;
8081
}
8182

83+
public ConfigurationType traceJNIType(String className) {
84+
assert enabled();
85+
return config.getJniConfiguration().getOrCreateType(UnresolvedConfigurationCondition.alwaysTrue(), className);
86+
}
87+
8288
public void traceResource(String resourceName, String moduleName) {
8389
assert enabled();
8490
config.getResourceConfiguration().addGlobPattern(UnresolvedConfigurationCondition.alwaysTrue(), resourceName, moduleName);

0 commit comments

Comments
 (0)