8307298: JFR: Ensure jdk.jfr.internal.TypeLibrary is initialized only once

Reviewed-by: sgehwolf, egahlin
This commit is contained in:
Robert Toyonaga 2023-05-11 18:05:58 +00:00 committed by Severin Gehwolf
parent 51b8f3cfb9
commit 5d6cce0f85

@ -62,7 +62,7 @@ import jdk.jfr.ValueDescriptor;
public final class TypeLibrary {
private static boolean implicitFieldTypes;
private static final Map<Long, Type> types = LinkedHashMap.newLinkedHashMap(350);
private static volatile boolean initialized;
static final ValueDescriptor DURATION_FIELD = createDurationField();
static final ValueDescriptor THREAD_FIELD = createThreadField();
static final ValueDescriptor STACK_TRACE_FIELD = createStackTraceField();
@ -98,6 +98,11 @@ public final class TypeLibrary {
}
public static synchronized void initialize() {
// The usual case is that TypeLibrary is initialized only once by the MetadataRepository singleton.
// However, this check is needed to ensure some tools (ie. GraalVM Native Image) do not perform the initialization routine twice.
if (initialized) {
return;
}
List<Type> jvmTypes;
try {
jvmTypes = MetadataLoader.createTypes();
@ -106,6 +111,7 @@ public final class TypeLibrary {
throw new Error("JFR: Could not read metadata");
}
visitReachable(jvmTypes, t -> !types.containsKey(t.getId()), t -> types.put(t.getId(), t));
initialized = true;
if (Logger.shouldLog(LogTag.JFR_SYSTEM_METADATA, LogLevel.INFO)) {
Stream<Type> s = types.values().stream().sorted((x, y) -> Long.compare(x.getId(), y.getId()));
s.forEach(t -> t.log("Added", LogTag.JFR_SYSTEM_METADATA, LogLevel.INFO));