Skip to content

Commit 75fd53a

Browse files
committed
Trace JNI accesses
1 parent e9a1174 commit 75fd53a

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-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: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import org.graalvm.word.Pointer;
4343

4444
import com.oracle.svm.configure.ClassNameSupport;
45+
import com.oracle.svm.configure.config.ConfigurationMemberInfo;
46+
import com.oracle.svm.configure.config.ConfigurationType;
4547
import com.oracle.svm.core.SubstrateOptions;
4648
import com.oracle.svm.core.Uninterruptible;
4749
import com.oracle.svm.core.heap.Heap;
@@ -53,6 +55,7 @@
5355
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
5456
import com.oracle.svm.core.layeredimagesingleton.UnsavedSingleton;
5557
import com.oracle.svm.core.log.Log;
58+
import com.oracle.svm.core.metadata.MetadataTracer;
5659
import com.oracle.svm.core.snippets.KnownIntrinsics;
5760
import com.oracle.svm.core.util.ImageHeapMap;
5861
import com.oracle.svm.core.util.Utf8.WrappedAsciiCString;
@@ -181,6 +184,9 @@ public static Class<?> getClassObjectByName(CharSequence name) {
181184
JNIAccessibleClass clazz = dictionary.classesByName.get(name);
182185
if (clazz == null && !ClassNameSupport.isValidJNIName(name.toString())) {
183186
clazz = NEGATIVE_CLASS_LOOKUP;
187+
} else if (MetadataTracer.Options.MetadataTracingSupport.getValue() && MetadataTracer.singleton().enabled()) {
188+
// trace if class exists (positive query) or name is valid (negative query)
189+
MetadataTracer.singleton().traceJNIType(ClassNameSupport.jniNameToTypeName(name.toString()));
184190
}
185191
clazz = checkClass(clazz, name.toString());
186192
if (clazz != null) {
@@ -274,6 +280,10 @@ private static JNIAccessibleMethod getDeclaredMethod(Class<?> classObject, JNIAc
274280
foundClass = true;
275281
JNIAccessibleMethod method = clazz.getMethod(descriptor);
276282
if (method != null) {
283+
if (MetadataTracer.Options.MetadataTracingSupport.getValue() && MetadataTracer.singleton().enabled()) {
284+
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
285+
clazzType.addMethod(descriptor.getNameConvertToString(), descriptor.getSignatureConvertToString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
286+
}
277287
return method;
278288
}
279289
}
@@ -329,6 +339,10 @@ private static JNIAccessibleField getDeclaredField(Class<?> classObject, CharSeq
329339
foundClass = true;
330340
JNIAccessibleField field = clazz.getField(name);
331341
if (field != null && (field.isStatic() == isStatic || field.isNegative())) {
342+
if (MetadataTracer.Options.MetadataTracingSupport.getValue() && MetadataTracer.singleton().enabled()) {
343+
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
344+
clazzType.addField(name.toString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED, false);
345+
}
332346
return field;
333347
}
334348
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ private ConfigurationType traceReflectionTypeImpl(ConfigurationTypeDescriptor ty
9898
return config.getReflectionConfiguration().getOrCreateType(UnresolvedConfigurationCondition.alwaysTrue(), new NamedConfigurationTypeDescriptor(className));
9999
}
100100

101+
public ConfigurationType traceJNIType(String className) {
102+
assert enabled();
103+
ConfigurationType result = traceReflectionType(className);
104+
result.setJniAccessible();
105+
return result;
106+
}
107+
101108
public void traceResource(String resourceName, String moduleName) {
102109
assert enabled();
103110
config.getResourceConfiguration().addGlobPattern(UnresolvedConfigurationCondition.alwaysTrue(), resourceName, moduleName);

0 commit comments

Comments
 (0)