Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

import com.oracle.svm.agent.tracing.core.Tracer;
import com.oracle.svm.agent.tracing.core.TracingResultWriter;
import com.oracle.svm.configure.trace.JsonFileWriter;
import com.oracle.svm.configure.JsonFileWriter;

public class TraceFileWriter extends Tracer implements TracingResultWriter {
private final JsonFileWriter jsonFileWriter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.configure.trace;
package com.oracle.svm.configure;

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

private static void printValue(JsonWriter json, Object value) throws IOException {
if (value instanceof JsonPrintable printable) {
printable.printJson(json);
return;
}
Object s = null;
if (value instanceof byte[]) {
s = Base64.getEncoder().encodeToString((byte[]) value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,18 @@ public synchronized void setAllPublicConstructors(ConfigurationMemberAccessibili
}
}

public synchronized boolean isSerializable() {
return serializable;
}

public synchronized void setSerializable() {
serializable = true;
}

public synchronized boolean isJniAccessible() {
return typeJniAccessible;
}

public synchronized void setJniAccessible() {
typeJniAccessible = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ public static String toInternalSignature(List<?> parameterTypes) {
return sb.append(')').toString();
}

public static String toInternalSignature(Class<?>[] parameters) {
List<String> names;
if (parameters == null) {
names = List.of();
} else {
names = new ArrayList<>(parameters.length);
for (Class<?> parameter : parameters) {
names.add(parameter.getName());
}
}
return toInternalSignature(names);
}

public static String toInternalClassName(String qualifiedForNameString) {
assert qualifiedForNameString.indexOf('/') == -1 : "Requires qualified Java name, not internal representation";
assert !qualifiedForNameString.endsWith("[]") : "Requires Class.forName syntax, for example '[Ljava.lang.String;'";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import org.graalvm.collections.EconomicMap;

import com.oracle.svm.configure.JsonFileWriter;
import com.oracle.svm.configure.filters.ConfigurationFilter;
import com.oracle.svm.configure.filters.HierarchyFilterNode;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import org.graalvm.nativeimage.impl.ConfigurationCondition;

import com.oracle.svm.configure.ClassNameSupport;
import com.oracle.svm.configure.config.ConfigurationType;
import com.oracle.svm.core.configure.ConditionalRuntimeValue;
import com.oracle.svm.core.configure.RuntimeConditionSet;
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
Expand Down Expand Up @@ -414,7 +413,7 @@ private Object forName0(String className, ClassLoader classLoader) {
}
if (MetadataTracer.enabled()) {
// NB: the early returns above ensure we do not trace calls with bad type args.
MetadataTracer.singleton().traceReflectionType(className);
MetadataTracer.singleton().traceReflectionType(ClassNameSupport.reflectionNameToTypeName(className));
}
return result == NEGATIVE_QUERY ? new ClassNotFoundException(className) : result;
}
Expand Down Expand Up @@ -502,10 +501,7 @@ public static Throwable getSavedException(String className) {
public static boolean canUnsafeInstantiateAsInstance(DynamicHub hub) {
Class<?> clazz = DynamicHub.toClass(hub);
if (MetadataTracer.enabled()) {
ConfigurationType type = MetadataTracer.singleton().traceReflectionType(clazz.getName());
if (type != null) {
type.setUnsafeAllocated();
}
MetadataTracer.singleton().traceUnsafeAllocatedType(clazz);
}
RuntimeConditionSet conditionSet = null;
for (var singleton : layeredSingletons()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/
package com.oracle.svm.core.hub;

import static com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberAccessibility;
import static com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberDeclaration;
import static com.oracle.svm.core.MissingRegistrationUtils.throwMissingRegistrationErrors;
import static com.oracle.svm.core.Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE;
Expand Down Expand Up @@ -91,7 +90,6 @@
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.configure.config.ConfigurationType;
import com.oracle.svm.configure.config.SignatureUtil;
import com.oracle.svm.core.BuildPhaseProvider.AfterHostedUniverse;
import com.oracle.svm.core.BuildPhaseProvider.CompileQueueFinished;
Expand Down Expand Up @@ -761,7 +759,7 @@ private ReflectionMetadata reflectionMetadata() {

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

private void traceClassFlagQuery(int mask) {
ConfigurationType type = MetadataTracer.singleton().traceReflectionType(getName());
if (type == null) {
return;
}
// TODO (GR-64765): We over-approximate member accessibility here because we don't trace
// accesses. Once we trace accesses, it will suffice to register the class for reflection.
switch (mask) {
case ALL_FIELDS_FLAG -> type.setAllPublicFields(ConfigurationMemberAccessibility.ACCESSED);
case ALL_DECLARED_FIELDS_FLAG -> type.setAllDeclaredFields(ConfigurationMemberAccessibility.ACCESSED);
case ALL_METHODS_FLAG -> type.setAllPublicMethods(ConfigurationMemberAccessibility.ACCESSED);
case ALL_DECLARED_METHODS_FLAG -> type.setAllDeclaredMethods(ConfigurationMemberAccessibility.ACCESSED);
case ALL_CONSTRUCTORS_FLAG -> type.setAllPublicConstructors(ConfigurationMemberAccessibility.ACCESSED);
case ALL_DECLARED_CONSTRUCTORS_FLAG -> type.setAllDeclaredConstructors(ConfigurationMemberAccessibility.ACCESSED);
case ALL_CLASSES_FLAG -> type.setAllPublicClasses();
case ALL_DECLARED_CLASSES_FLAG -> type.setAllDeclaredClasses();
case ALL_RECORD_COMPONENTS_FLAG -> type.setAllRecordComponents();
case ALL_PERMITTED_SUBCLASSES_FLAG -> type.setAllPermittedSubclasses();
case ALL_NEST_MEMBERS_FLAG -> type.setAllNestMembers();
case ALL_SIGNERS_FLAG -> type.setAllSigners();
default -> throw VMError.shouldNotReachHere("unknown class flag " + mask);
}
}

/** Executed at runtime. */
private static Object initEnumConstantsAtRuntime(Method values) {
try {
Expand Down Expand Up @@ -1396,19 +1370,13 @@ private void checkField(String fieldName, Field field, boolean publicOnly) throw
private void traceFieldLookup(String fieldName, Field field, boolean publicOnly) {
ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration.PRESENT : ConfigurationMemberDeclaration.DECLARED;
if (field != null) {
// register declaring type and field
ConfigurationType declaringType = MetadataTracer.singleton().traceReflectionType(field.getDeclaringClass().getName());
if (declaringType != null) {
declaringType.addField(fieldName, declaration, false);
}
// register declaring type (registers all fields for lookup)
MetadataTracer.singleton().traceReflectionType(field.getDeclaringClass());
// register receiver type
MetadataTracer.singleton().traceReflectionType(getName());
MetadataTracer.singleton().traceReflectionType(toClass(this));
} else {
// register receiver type and negative field query
ConfigurationType receiverType = MetadataTracer.singleton().traceReflectionType(getName());
if (receiverType != null) {
receiverType.addField(fieldName, declaration, false);
}
MetadataTracer.singleton().traceFieldAccess(toClass(this), fieldName, declaration);
}
}

Expand Down Expand Up @@ -1481,35 +1449,16 @@ private boolean checkExecutableExists(String methodName, Class<?>[] parameterTyp
private void traceMethodLookup(String methodName, Class<?>[] parameterTypes, Executable method, boolean publicOnly) {
ConfigurationMemberDeclaration declaration = publicOnly ? ConfigurationMemberDeclaration.PRESENT : ConfigurationMemberDeclaration.DECLARED;
if (method != null) {
// register declaring type and method
ConfigurationType declaringType = MetadataTracer.singleton().traceReflectionType(method.getDeclaringClass().getName());
if (declaringType != null) {
declaringType.addMethod(methodName, toInternalSignature(parameterTypes), declaration);
}
// register declaring type (registers all methods for lookup)
MetadataTracer.singleton().traceReflectionType(method.getDeclaringClass());
// register receiver type
MetadataTracer.singleton().traceReflectionType(getName());
MetadataTracer.singleton().traceReflectionType(toClass(this));
} else {
// register receiver type and negative method query
ConfigurationType receiverType = MetadataTracer.singleton().traceReflectionType(getName());
if (receiverType != null) {
receiverType.addMethod(methodName, toInternalSignature(parameterTypes), declaration, ConfigurationMemberAccessibility.QUERIED);
}
MetadataTracer.singleton().traceMethodAccess(toClass(this), methodName, SignatureUtil.toInternalSignature(parameterTypes), declaration);
}
}

private static String toInternalSignature(Class<?>[] classes) {
List<String> names;
if (classes == null) {
names = List.of();
} else {
names = new ArrayList<>(classes.length);
for (Class<?> aClass : classes) {
names.add(aClass.getName());
}
}
return SignatureUtil.toInternalSignature(names);
}

private boolean allElementsRegistered(boolean publicOnly, int allDeclaredElementsFlag, int allPublicElementsFlag) {
return isClassFlagSet(allDeclaredElementsFlag) || (publicOnly && isClassFlagSet(allPublicElementsFlag));
}
Expand Down Expand Up @@ -2025,18 +1974,14 @@ public DynamicHub arrayType() {
throw new UnsupportedOperationException(new IllegalArgumentException());
}
if (MetadataTracer.enabled()) {
MetadataTracer.singleton().traceReflectionType(arrayTypeName());
MetadataTracer.singleton().traceReflectionArrayType(toClass(this));
}
if (companion.arrayHub == null) {
MissingReflectionRegistrationUtils.reportClassAccess(arrayTypeName());
MissingReflectionRegistrationUtils.reportClassAccess(getTypeName() + "[]");
}
return companion.arrayHub;
}

private String arrayTypeName() {
return getTypeName() + "[]";
}

@KeepOriginal
private native Class<?> elementType();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static ObjectStreamClass lookup(Class<?> cl, boolean all) {

if (Serializable.class.isAssignableFrom(cl) && !cl.isArray()) {
if (MetadataTracer.enabled()) {
MetadataTracer.singleton().traceSerializationType(cl.getName());
MetadataTracer.singleton().traceSerializationType(cl);
}
if (!DynamicHub.fromClass(cl).isRegisteredForSerialization()) {
MissingSerializationRegistrationUtils.reportSerialization(cl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ private static void set(Object a, int index, Object value) {
private static Object newArray(Class<?> componentType, int length)
throws NegativeArraySizeException {
if (MetadataTracer.enabled()) {
MetadataTracer.singleton().traceReflectionType(componentType.arrayType().getName());
MetadataTracer.singleton().traceReflectionArrayType(componentType);
}
return KnownIntrinsics.unvalidatedNewArray(componentType, length);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@

import com.oracle.svm.configure.ClassNameSupport;
import com.oracle.svm.configure.config.ConfigurationMemberInfo;
import com.oracle.svm.configure.config.ConfigurationType;
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.heap.Heap;
Expand Down Expand Up @@ -274,10 +273,9 @@ public static JNIMethodId getDeclaredMethodID(Class<?> classObject, JNIAccessibl

private static JNIAccessibleMethod getDeclaredMethod(Class<?> classObject, JNIAccessibleMethodDescriptor descriptor, String dumpLabel) {
if (MetadataTracer.enabled()) {
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
if (clazzType != null) {
clazzType.addMethod(descriptor.getNameConvertToString(), descriptor.getSignatureConvertToString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
}
MetadataTracer.singleton().traceJNIType(classObject);
MetadataTracer.singleton().traceMethodAccess(classObject, descriptor.getNameConvertToString(), descriptor.getSignatureConvertToString(),
ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
}
boolean foundClass = false;
for (var dictionary : layeredSingletons()) {
Expand Down Expand Up @@ -335,10 +333,8 @@ private static JNIAccessibleMethod checkMethod(JNIAccessibleMethod method, Class

private static JNIAccessibleField getDeclaredField(Class<?> classObject, CharSequence name, boolean isStatic, String dumpLabel) {
if (MetadataTracer.enabled()) {
ConfigurationType clazzType = MetadataTracer.singleton().traceJNIType(classObject.getName());
if (clazzType != null) {
clazzType.addField(name.toString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED, false);
}
MetadataTracer.singleton().traceJNIType(classObject);
MetadataTracer.singleton().traceFieldAccess(classObject, name.toString(), ConfigurationMemberInfo.ConfigurationMemberDeclaration.DECLARED);
}
boolean foundClass = false;
for (var dictionary : layeredSingletons()) {
Expand Down
Loading