Skip to content

Commit d031227

Browse files
committed
[GR-65387] [GR-65921] [GR-67442] [GR-64765] Tracing & registration fixes: fix tracing bugs, rename runtime tracing option, support debug-log, add missing MissingRegistrationError checks.
PullRequest: graal/21403
2 parents dc94a20 + 0cda565 commit d031227

21 files changed

+461
-198
lines changed

substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/tracing/TraceFileWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
import com.oracle.svm.agent.tracing.core.Tracer;
3333
import com.oracle.svm.agent.tracing.core.TracingResultWriter;
34-
import com.oracle.svm.configure.trace.JsonFileWriter;
34+
import com.oracle.svm.configure.JsonFileWriter;
3535

3636
public class TraceFileWriter extends Tracer implements TracingResultWriter {
3737
private final JsonFileWriter jsonFileWriter;
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package com.oracle.svm.configure.trace;
25+
package com.oracle.svm.configure;
2626

2727
import java.io.BufferedWriter;
2828
import java.io.Closeable;
@@ -97,6 +97,10 @@ private static void printArray(JsonWriter json, Object[] array) throws IOExcepti
9797
}
9898

9999
private static void printValue(JsonWriter json, Object value) throws IOException {
100+
if (value instanceof JsonPrintable printable) {
101+
printable.printJson(json);
102+
return;
103+
}
100104
Object s = null;
101105
if (value instanceof byte[]) {
102106
s = Base64.getEncoder().encodeToString((byte[]) value);

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationType.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,10 +465,18 @@ public synchronized void setAllPublicConstructors(ConfigurationMemberAccessibili
465465
}
466466
}
467467

468+
public synchronized boolean isSerializable() {
469+
return serializable;
470+
}
471+
468472
public synchronized void setSerializable() {
469473
serializable = true;
470474
}
471475

476+
public synchronized boolean isJniAccessible() {
477+
return typeJniAccessible;
478+
}
479+
472480
public synchronized void setJniAccessible() {
473481
typeJniAccessible = true;
474482
}

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SignatureUtil.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ public static String toInternalSignature(List<?> parameterTypes) {
8080
return sb.append(')').toString();
8181
}
8282

83+
public static String toInternalSignature(Class<?>[] parameters) {
84+
List<String> names;
85+
if (parameters == null) {
86+
names = List.of();
87+
} else {
88+
names = new ArrayList<>(parameters.length);
89+
for (Class<?> parameter : parameters) {
90+
names.add(parameter.getName());
91+
}
92+
}
93+
return toInternalSignature(names);
94+
}
95+
8396
public static String toInternalClassName(String qualifiedForNameString) {
8497
assert qualifiedForNameString.indexOf('/') == -1 : "Requires qualified Java name, not internal representation";
8598
assert !qualifiedForNameString.endsWith("[]") : "Requires Class.forName syntax, for example '[Ljava.lang.String;'";

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/AccessAdvisor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
import org.graalvm.collections.EconomicMap;
3333

34+
import com.oracle.svm.configure.JsonFileWriter;
3435
import com.oracle.svm.configure.filters.ConfigurationFilter;
3536
import com.oracle.svm.configure.filters.HierarchyFilterNode;
3637

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import org.graalvm.nativeimage.impl.ConfigurationCondition;
4848

4949
import com.oracle.svm.configure.ClassNameSupport;
50-
import com.oracle.svm.configure.config.ConfigurationType;
5150
import com.oracle.svm.core.configure.ConditionalRuntimeValue;
5251
import com.oracle.svm.core.configure.RuntimeConditionSet;
5352
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
@@ -414,7 +413,7 @@ private Object forName0(String className, ClassLoader classLoader) {
414413
}
415414
if (MetadataTracer.enabled()) {
416415
// NB: the early returns above ensure we do not trace calls with bad type args.
417-
MetadataTracer.singleton().traceReflectionType(className);
416+
MetadataTracer.singleton().traceReflectionType(ClassNameSupport.reflectionNameToTypeName(className));
418417
}
419418
return result == NEGATIVE_QUERY ? new ClassNotFoundException(className) : result;
420419
}
@@ -502,10 +501,7 @@ public static Throwable getSavedException(String className) {
502501
public static boolean canUnsafeInstantiateAsInstance(DynamicHub hub) {
503502
Class<?> clazz = DynamicHub.toClass(hub);
504503
if (MetadataTracer.enabled()) {
505-
ConfigurationType type = MetadataTracer.singleton().traceReflectionType(clazz.getName());
506-
if (type != null) {
507-
type.setUnsafeAllocated();
508-
}
504+
MetadataTracer.singleton().traceUnsafeAllocatedType(clazz);
509505
}
510506
RuntimeConditionSet conditionSet = null;
511507
for (var singleton : layeredSingletons()) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java

Lines changed: 11 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.hub;
2626

27-
import static com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberAccessibility;
2827
import static com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberDeclaration;
2928
import static com.oracle.svm.core.MissingRegistrationUtils.throwMissingRegistrationErrors;
3029
import static com.oracle.svm.core.Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE;
@@ -91,7 +90,6 @@
9190
import org.graalvm.nativeimage.Platform;
9291
import org.graalvm.nativeimage.Platforms;
9392

94-
import com.oracle.svm.configure.config.ConfigurationType;
9593
import com.oracle.svm.configure.config.SignatureUtil;
9694
import com.oracle.svm.core.BuildPhaseProvider.AfterHostedUniverse;
9795
import com.oracle.svm.core.BuildPhaseProvider.CompileQueueFinished;
@@ -761,7 +759,7 @@ private ReflectionMetadata reflectionMetadata() {
761759

762760
private void checkClassFlag(int mask, String methodName) {
763761
if (MetadataTracer.enabled()) {
764-
traceClassFlagQuery(mask);
762+
MetadataTracer.singleton().traceReflectionType(toClass(this));
765763
}
766764
if (throwMissingRegistrationErrors() && !(isClassFlagSet(mask) && getConditions().satisfied())) {
767765
MissingReflectionRegistrationUtils.reportClassQuery(DynamicHub.toClass(this), methodName);
@@ -785,30 +783,6 @@ private static boolean isClassFlagSet(int mask, ReflectionMetadata reflectionMet
785783
return reflectionMetadata != null && (reflectionMetadata.classFlags & mask) != 0;
786784
}
787785

788-
private void traceClassFlagQuery(int mask) {
789-
ConfigurationType type = MetadataTracer.singleton().traceReflectionType(getName());
790-
if (type == null) {
791-
return;
792-
}
793-
// TODO (GR-64765): We over-approximate member accessibility here because we don't trace
794-
// accesses. Once we trace accesses, it will suffice to register the class for reflection.
795-
switch (mask) {
796-
case ALL_FIELDS_FLAG -> type.setAllPublicFields(ConfigurationMemberAccessibility.ACCESSED);
797-
case ALL_DECLARED_FIELDS_FLAG -> type.setAllDeclaredFields(ConfigurationMemberAccessibility.ACCESSED);
798-
case ALL_METHODS_FLAG -> type.setAllPublicMethods(ConfigurationMemberAccessibility.ACCESSED);
799-
case ALL_DECLARED_METHODS_FLAG -> type.setAllDeclaredMethods(ConfigurationMemberAccessibility.ACCESSED);
800-
case ALL_CONSTRUCTORS_FLAG -> type.setAllPublicConstructors(ConfigurationMemberAccessibility.ACCESSED);
801-
case ALL_DECLARED_CONSTRUCTORS_FLAG -> type.setAllDeclaredConstructors(ConfigurationMemberAccessibility.ACCESSED);
802-
case ALL_CLASSES_FLAG -> type.setAllPublicClasses();
803-
case ALL_DECLARED_CLASSES_FLAG -> type.setAllDeclaredClasses();
804-
case ALL_RECORD_COMPONENTS_FLAG -> type.setAllRecordComponents();
805-
case ALL_PERMITTED_SUBCLASSES_FLAG -> type.setAllPermittedSubclasses();
806-
case ALL_NEST_MEMBERS_FLAG -> type.setAllNestMembers();
807-
case ALL_SIGNERS_FLAG -> type.setAllSigners();
808-
default -> throw VMError.shouldNotReachHere("unknown class flag " + mask);
809-
}
810-
}
811-
812786
/** Executed at runtime. */
813787
private static Object initEnumConstantsAtRuntime(Method values) {
814788
try {
@@ -1396,19 +1370,13 @@ private void checkField(String fieldName, Field field, boolean publicOnly) throw
13961370
private void traceFieldLookup(String fieldName, Field field, boolean publicOnly) {
13971371
ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration.PRESENT : ConfigurationMemberDeclaration.DECLARED;
13981372
if (field != null) {
1399-
// register declaring type and field
1400-
ConfigurationType declaringType = MetadataTracer.singleton().traceReflectionType(field.getDeclaringClass().getName());
1401-
if (declaringType != null) {
1402-
declaringType.addField(fieldName, declaration, false);
1403-
}
1373+
// register declaring type (registers all fields for lookup)
1374+
MetadataTracer.singleton().traceReflectionType(field.getDeclaringClass());
14041375
// register receiver type
1405-
MetadataTracer.singleton().traceReflectionType(getName());
1376+
MetadataTracer.singleton().traceReflectionType(toClass(this));
14061377
} else {
14071378
// register receiver type and negative field query
1408-
ConfigurationType receiverType = MetadataTracer.singleton().traceReflectionType(getName());
1409-
if (receiverType != null) {
1410-
receiverType.addField(fieldName, declaration, false);
1411-
}
1379+
MetadataTracer.singleton().traceFieldAccess(toClass(this), fieldName, declaration);
14121380
}
14131381
}
14141382

@@ -1481,35 +1449,16 @@ private boolean checkExecutableExists(String methodName, Class<?>[] parameterTyp
14811449
private void traceMethodLookup(String methodName, Class<?>[] parameterTypes, Executable method, boolean publicOnly) {
14821450
ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration.PRESENT : ConfigurationMemberDeclaration.DECLARED;
14831451
if (method != null) {
1484-
// register declaring type and method
1485-
ConfigurationType declaringType = MetadataTracer.singleton().traceReflectionType(method.getDeclaringClass().getName());
1486-
if (declaringType != null) {
1487-
declaringType.addMethod(methodName, toInternalSignature(parameterTypes), declaration);
1488-
}
1452+
// register declaring type (registers all methods for lookup)
1453+
MetadataTracer.singleton().traceReflectionType(method.getDeclaringClass());
14891454
// register receiver type
1490-
MetadataTracer.singleton().traceReflectionType(getName());
1455+
MetadataTracer.singleton().traceReflectionType(toClass(this));
14911456
} else {
14921457
// register receiver type and negative method query
1493-
ConfigurationType receiverType = MetadataTracer.singleton().traceReflectionType(getName());
1494-
if (receiverType != null) {
1495-
receiverType.addMethod(methodName, toInternalSignature(parameterTypes), declaration, ConfigurationMemberAccessibility.QUERIED);
1496-
}
1458+
MetadataTracer.singleton().traceMethodAccess(toClass(this), methodName, SignatureUtil.toInternalSignature(parameterTypes), declaration);
14971459
}
14981460
}
14991461

1500-
private static String toInternalSignature(Class<?>[] classes) {
1501-
List<String> names;
1502-
if (classes == null) {
1503-
names = List.of();
1504-
} else {
1505-
names = new ArrayList<>(classes.length);
1506-
for (Class<?> aClass : classes) {
1507-
names.add(aClass.getName());
1508-
}
1509-
}
1510-
return SignatureUtil.toInternalSignature(names);
1511-
}
1512-
15131462
private boolean allElementsRegistered(boolean publicOnly, int allDeclaredElementsFlag, int allPublicElementsFlag) {
15141463
return isClassFlagSet(allDeclaredElementsFlag) || (publicOnly && isClassFlagSet(allPublicElementsFlag));
15151464
}
@@ -2025,18 +1974,14 @@ public DynamicHub arrayType() {
20251974
throw new UnsupportedOperationException(new IllegalArgumentException());
20261975
}
20271976
if (MetadataTracer.enabled()) {
2028-
MetadataTracer.singleton().traceReflectionType(arrayTypeName());
1977+
MetadataTracer.singleton().traceReflectionArrayType(toClass(this));
20291978
}
20301979
if (companion.arrayHub == null) {
2031-
MissingReflectionRegistrationUtils.reportClassAccess(arrayTypeName());
1980+
MissingReflectionRegistrationUtils.reportClassAccess(getTypeName() + "[]");
20321981
}
20331982
return companion.arrayHub;
20341983
}
20351984

2036-
private String arrayTypeName() {
2037-
return getTypeName() + "[]";
2038-
}
2039-
20401985
@KeepOriginal
20411986
private native Class<?> elementType();
20421987

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaIOSubstitutions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static ObjectStreamClass lookup(Class<?> cl, boolean all) {
6666

6767
if (Serializable.class.isAssignableFrom(cl) && !cl.isArray()) {
6868
if (MetadataTracer.enabled()) {
69-
MetadataTracer.singleton().traceSerializationType(cl.getName());
69+
MetadataTracer.singleton().traceSerializationType(cl);
7070
}
7171
if (!DynamicHub.fromClass(cl).isRegisteredForSerialization()) {
7272
MissingSerializationRegistrationUtils.reportSerialization(cl);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaLangReflectSubstitutions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ private static void set(Object a, int index, Object value) {
388388
private static Object newArray(Class<?> componentType, int length)
389389
throws NegativeArraySizeException {
390390
if (MetadataTracer.enabled()) {
391-
MetadataTracer.singleton().traceReflectionType(componentType.arrayType().getName());
391+
MetadataTracer.singleton().traceReflectionArrayType(componentType);
392392
}
393393
return KnownIntrinsics.unvalidatedNewArray(componentType, length);
394394
}

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343

4444
import com.oracle.svm.configure.ClassNameSupport;
4545
import com.oracle.svm.configure.config.ConfigurationMemberInfo;
46-
import com.oracle.svm.configure.config.ConfigurationType;
4746
import com.oracle.svm.core.SubstrateOptions;
4847
import com.oracle.svm.core.Uninterruptible;
4948
import com.oracle.svm.core.heap.Heap;
@@ -274,10 +273,9 @@ public static JNIMethodId getDeclaredMethodID(Class<?> classObject, JNIAccessibl
274273

275274
private static JNIAccessibleMethod getDeclaredMethod(Class<?> classObject, JNIAccessibleMethodDescriptor descriptor, String dumpLabel) {
276275
if (MetadataTracer.enabled()) {
277-
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
278-
if (clazzType != null) {
279-
clazzType.addMethod(descriptor.getNameConvertToString(), descriptor.getSignatureConvertToString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
280-
}
276+
MetadataTracer.singleton().traceJNIType(classObject);
277+
MetadataTracer.singleton().traceMethodAccess(classObject, descriptor.getNameConvertToString(), descriptor.getSignatureConvertToString(),
278+
ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
281279
}
282280
boolean foundClass = false;
283281
for (var dictionary : layeredSingletons()) {
@@ -335,10 +333,8 @@ private static JNIAccessibleMethod checkMethod(JNIAccessibleMethod method, Class
335333

336334
private static JNIAccessibleField getDeclaredField(Class<?> classObject, CharSequence name, boolean isStatic, String dumpLabel) {
337335
if (MetadataTracer.enabled()) {
338-
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
339-
if (clazzType != null) {
340-
clazzType.addField(name.toString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED, false);
341-
}
336+
MetadataTracer.singleton().traceJNIType(classObject);
337+
MetadataTracer.singleton().traceFieldAccess(classObject, name.toString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
342338
}
343339
boolean foundClass = false;
344340
for (var dictionary : layeredSingletons()) {

0 commit comments

Comments
 (0)