8330734: JFR: Re-engineer mirror class mechanism

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2024-04-26 17:15:09 +00:00
parent 0bf516f7ba
commit 07facd0420
26 changed files with 128 additions and 160 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,9 +36,8 @@ import jdk.jfr.internal.RemoveFields;
@Label("Deserialization") @Label("Deserialization")
@Name("jdk.Deserialization") @Name("jdk.Deserialization")
@Description("Results of deserialization and ObjectInputFilter checks") @Description("Results of deserialization and ObjectInputFilter checks")
@MirrorEvent(className = "jdk.internal.event.DeserializationEvent")
@RemoveFields("duration") @RemoveFields("duration")
public final class DeserializationEvent extends AbstractJDKEvent { public final class DeserializationEvent extends MirrorEvent {
@Label("Filter Configured") @Label("Filter Configured")
public boolean filterConfigured; public boolean filterConfigured;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,9 +36,8 @@ import jdk.jfr.internal.Type;
@Label("Java Error") @Label("Java Error")
@Category("Java Application") @Category("Java Application")
@Description("An object derived from java.lang.Error has been created. OutOfMemoryErrors are ignored") @Description("An object derived from java.lang.Error has been created. OutOfMemoryErrors are ignored")
@MirrorEvent(className = "jdk.internal.event.ErrorThrownEvent")
@RemoveFields("duration") @RemoveFields("duration")
public final class ErrorThrownEvent extends AbstractJDKEvent { public final class ErrorThrownEvent extends MirrorEvent {
@Label("Message") @Label("Message")
public String message; public String message;

View File

@ -31,14 +31,15 @@ import jdk.jfr.Label;
import jdk.jfr.Name; import jdk.jfr.Name;
import jdk.jfr.StackTrace; import jdk.jfr.StackTrace;
import jdk.jfr.internal.MirrorEvent; import jdk.jfr.internal.MirrorEvent;
import jdk.jfr.internal.RemoveFields;
import jdk.jfr.internal.Type; import jdk.jfr.internal.Type;
@Name(Type.EVENT_NAME_PREFIX + "ExceptionStatistics") @Name(Type.EVENT_NAME_PREFIX + "ExceptionStatistics")
@Label("Exception Statistics") @Label("Exception Statistics")
@Category({ "Java Application", "Statistics" }) @Category({ "Java Application", "Statistics" })
@Description("Number of objects derived from java.lang.Throwable that have been created") @Description("Number of objects derived from java.lang.Throwable that have been created")
@MirrorEvent(className = "jdk.internal.event.ExceptionStatisticsEvent") @RemoveFields({"duration", "eventThread", "stackTrace"})
public final class ExceptionStatisticsEvent extends AbstractPeriodicEvent { public final class ExceptionStatisticsEvent extends MirrorEvent {
@Label("Exceptions Created") @Label("Exceptions Created")
public long throwables; public long throwables;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,9 +37,8 @@ import jdk.jfr.internal.Type;
@Label("Java Exception") @Label("Java Exception")
@Category("Java Application") @Category("Java Application")
@Description("An object derived from java.lang.Exception has been created") @Description("An object derived from java.lang.Exception has been created")
@MirrorEvent(className = "jdk.internal.event.ExceptionThrownEvent")
@RemoveFields("duration") @RemoveFields("duration")
public final class ExceptionThrownEvent extends AbstractJDKEvent { public final class ExceptionThrownEvent extends MirrorEvent {
@Label("Message") @Label("Message")
public String message; public String message;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,10 +36,9 @@ import jdk.jfr.internal.RemoveFields;
@Label("Process Start") @Label("Process Start")
@Name("jdk.ProcessStart") @Name("jdk.ProcessStart")
@Description("Operating system process started") @Description("Operating system process started")
@MirrorEvent(className = "jdk.internal.event.ProcessStartEvent")
@RemoveFields("duration") @RemoveFields("duration")
@StackFilter({"java.lang.ProcessBuilder", "java.lang.Runtime::exec"}) @StackFilter({"java.lang.ProcessBuilder", "java.lang.Runtime::exec"})
public final class ProcessStartEvent extends AbstractJDKEvent { public final class ProcessStartEvent extends MirrorEvent {
@Label("Process Id") @Label("Process Id")
public long pid; public long pid;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,10 +33,9 @@ import jdk.jfr.internal.RemoveFields;
@Label("Security Property Modification") @Label("Security Property Modification")
@Name("jdk.SecurityPropertyModification") @Name("jdk.SecurityPropertyModification")
@Description("Modification of Security property") @Description("Modification of Security property")
@MirrorEvent(className = "jdk.internal.event.SecurityPropertyModificationEvent")
@RemoveFields("duration") @RemoveFields("duration")
@StackFilter({"java.security.Security::setProperty"}) @StackFilter({"java.security.Security::setProperty"})
public final class SecurityPropertyModificationEvent extends AbstractJDKEvent { public final class SecurityPropertyModificationEvent extends MirrorEvent {
@Label("Key") @Label("Key")
public String key; public String key;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,10 +36,9 @@ import jdk.jfr.internal.RemoveFields;
@Label("Security Provider Instance Request") @Label("Security Provider Instance Request")
@Name("jdk.SecurityProviderService") @Name("jdk.SecurityProviderService")
@Description("Details of Provider.getInstance(String type, String algorithm) calls") @Description("Details of Provider.getInstance(String type, String algorithm) calls")
@MirrorEvent(className = "jdk.internal.event.SecurityProviderServiceEvent")
@RemoveFields("duration") @RemoveFields("duration")
@StackFilter({"java.security.Provider::getService"}) @StackFilter({"java.security.Provider::getService"})
public final class SecurityProviderServiceEvent extends AbstractJDKEvent { public final class SecurityProviderServiceEvent extends MirrorEvent {
@Label("Type of Service") @Label("Type of Service")
public String type; public String type;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -40,9 +40,8 @@ import jdk.jfr.internal.Type;
" The checks are usually performed just once per serializable class," + " The checks are usually performed just once per serializable class," +
" the first time it is used by serialization." + " the first time it is used by serialization." +
" Under high memory pressure, a class might be re-checked again.") " Under high memory pressure, a class might be re-checked again.")
@MirrorEvent(className = "jdk.internal.event.SerializationMisdeclarationEvent")
@RemoveFields({"duration", "stackTrace", "eventThread"}) @RemoveFields({"duration", "stackTrace", "eventThread"})
public final class SerializationMisdeclarationEvent extends AbstractJDKEvent { public final class SerializationMisdeclarationEvent extends MirrorEvent {
@Label("Misdeclared Class") @Label("Misdeclared Class")
public Class<?> misdeclaredClass; public Class<?> misdeclaredClass;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -38,8 +38,7 @@ import jdk.jfr.internal.Type;
@Label("Socket Read") @Label("Socket Read")
@Category("Java Application") @Category("Java Application")
@Description("Reading data from a socket") @Description("Reading data from a socket")
@MirrorEvent(className = "jdk.internal.event.SocketReadEvent") public final class SocketReadEvent extends MirrorEvent {
public final class SocketReadEvent extends AbstractJDKEvent {
@Label("Remote Host") @Label("Remote Host")
public String host; public String host;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,8 +37,7 @@ import jdk.jfr.internal.Type;
@Label("Socket Write") @Label("Socket Write")
@Category("Java Application") @Category("Java Application")
@Description("Writing data to a socket") @Description("Writing data to a socket")
@MirrorEvent(className = "jdk.internal.event.SocketWriteEvent") public final class SocketWriteEvent extends MirrorEvent {
public final class SocketWriteEvent extends AbstractJDKEvent {
@Label("Remote Host") @Label("Remote Host")
public String host; public String host;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,10 +37,9 @@ import jdk.jfr.internal.RemoveFields;
@Label("TLS Handshake") @Label("TLS Handshake")
@Name("jdk.TLSHandshake") @Name("jdk.TLSHandshake")
@Description("Parameters used in TLS Handshake") @Description("Parameters used in TLS Handshake")
@MirrorEvent(className = "jdk.internal.event.TLSHandshakeEvent")
@RemoveFields("duration") @RemoveFields("duration")
@StackFilter("sun.security.ssl.Finished::recordEvent") @StackFilter("sun.security.ssl.Finished::recordEvent")
public final class TLSHandshakeEvent extends AbstractJDKEvent { public final class TLSHandshakeEvent extends MirrorEvent {
@Label("Peer Host") @Label("Peer Host")
public String peerHost; public String peerHost;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,11 +34,10 @@ import jdk.jfr.internal.MirrorEvent;
@Category("Java Application") @Category("Java Application")
@Label("Java Thread Sleep") @Label("Java Thread Sleep")
@Name("jdk.ThreadSleep") @Name("jdk.ThreadSleep")
@MirrorEvent(className = "jdk.internal.event.ThreadSleepEvent")
@StackFilter({"java.lang.Thread::afterSleep", @StackFilter({"java.lang.Thread::afterSleep",
"java.lang.Thread::sleepNanos", "java.lang.Thread::sleepNanos",
"java.lang.Thread::sleep"}) "java.lang.Thread::sleep"})
public final class ThreadSleepEvent extends AbstractJDKEvent { public final class ThreadSleepEvent extends MirrorEvent {
@Label("Sleep Time") @Label("Sleep Time")
@Timespan(Timespan.NANOSECONDS) @Timespan(Timespan.NANOSECONDS)
public long time; public long time;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,9 +34,8 @@ import jdk.jfr.internal.RemoveFields;
@Category("Java Application") @Category("Java Application")
@Label("Virtual Thread End") @Label("Virtual Thread End")
@Name("jdk.VirtualThreadEnd") @Name("jdk.VirtualThreadEnd")
@MirrorEvent(className = "jdk.internal.event.VirtualThreadEndEvent")
@RemoveFields({"duration", "stackTrace"}) @RemoveFields({"duration", "stackTrace"})
public final class VirtualThreadEndEvent extends AbstractJDKEvent { public final class VirtualThreadEndEvent extends MirrorEvent {
@Label("Thread Id") @Label("Thread Id")
public long javaThreadId; public long javaThreadId;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,5 @@ import jdk.jfr.internal.MirrorEvent;
@Category("Java Application") @Category("Java Application")
@Label("Virtual Thread Pinned") @Label("Virtual Thread Pinned")
@Name("jdk.VirtualThreadPinned") @Name("jdk.VirtualThreadPinned")
@MirrorEvent(className = "jdk.internal.event.VirtualThreadPinnedEvent") public final class VirtualThreadPinnedEvent extends MirrorEvent {
public final class VirtualThreadPinnedEvent extends AbstractJDKEvent {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,9 +34,8 @@ import jdk.jfr.internal.RemoveFields;
@Category("Java Application") @Category("Java Application")
@Label("Virtual Thread Start") @Label("Virtual Thread Start")
@Name("jdk.VirtualThreadStart") @Name("jdk.VirtualThreadStart")
@MirrorEvent(className = "jdk.internal.event.VirtualThreadStartEvent")
@RemoveFields("duration") @RemoveFields("duration")
public final class VirtualThreadStartEvent extends AbstractJDKEvent { public final class VirtualThreadStartEvent extends MirrorEvent {
@Label("Thread Id") @Label("Thread Id")
public long javaThreadId; public long javaThreadId;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,9 +36,8 @@ import jdk.jfr.internal.RemoveFields;
@Label("Virtual Thread Submit Failed") @Label("Virtual Thread Submit Failed")
@Name("jdk.VirtualThreadSubmitFailed") @Name("jdk.VirtualThreadSubmitFailed")
@Description("Submit of task for virtual thread failed") @Description("Submit of task for virtual thread failed")
@MirrorEvent(className = "jdk.internal.event.VirtualThreadSubmitFailedEvent")
@RemoveFields("duration") @RemoveFields("duration")
public final class VirtualThreadSubmitFailedEvent extends AbstractJDKEvent { public final class VirtualThreadSubmitFailedEvent extends MirrorEvent {
@Label("Thread Id") @Label("Thread Id")
public long javaThreadId; public long javaThreadId;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,9 +33,8 @@ import jdk.jfr.internal.RemoveFields;
@Label("X509 Certificate") @Label("X509 Certificate")
@Name("jdk.X509Certificate") @Name("jdk.X509Certificate")
@Description("Details of X.509 Certificate parsed by JDK") @Description("Details of X.509 Certificate parsed by JDK")
@MirrorEvent(className = "jdk.internal.event.X509CertificateEvent")
@RemoveFields("duration") @RemoveFields("duration")
public final class X509CertificateEvent extends AbstractJDKEvent { public final class X509CertificateEvent extends MirrorEvent {
@Label("Signature Algorithm") @Label("Signature Algorithm")
public String algorithm; public String algorithm;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,9 +33,8 @@ import jdk.jfr.internal.RemoveFields;
@Label("X509 Validation") @Label("X509 Validation")
@Name("jdk.X509Validation") @Name("jdk.X509Validation")
@Description("Serial numbers from X.509 Certificates forming chain of trust") @Description("Serial numbers from X.509 Certificates forming chain of trust")
@MirrorEvent(className = "jdk.internal.event.X509ValidationEvent")
@RemoveFields("duration") @RemoveFields("duration")
public final class X509ValidationEvent extends AbstractJDKEvent { public final class X509ValidationEvent extends MirrorEvent {
@CertificateId @CertificateId
@Label("Certificate Id") @Label("Certificate Id")
@Unsigned @Unsigned

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -90,7 +90,6 @@ final class EventInstrumentation {
private static final ClassDesc TYPE_ISE = Bytecode.classDesc(IllegalStateException.class); private static final ClassDesc TYPE_ISE = Bytecode.classDesc(IllegalStateException.class);
private static final ClassDesc TYPE_EVENT_WRITER = classDesc(EventWriter.class); private static final ClassDesc TYPE_EVENT_WRITER = classDesc(EventWriter.class);
private static final ClassDesc TYPE_EVENT_WRITER_FACTORY = ClassDesc.of("jdk.jfr.internal.event.EventWriterFactory"); private static final ClassDesc TYPE_EVENT_WRITER_FACTORY = ClassDesc.of("jdk.jfr.internal.event.EventWriterFactory");
private static final ClassDesc TYPE_MIRROR_EVENT = Bytecode.classDesc(MirrorEvent.class);
private static final ClassDesc TYPE_OBJECT = Bytecode.classDesc(Object.class); private static final ClassDesc TYPE_OBJECT = Bytecode.classDesc(Object.class);
private static final ClassDesc TYPE_SETTING_DEFINITION = Bytecode.classDesc(SettingDefinition.class); private static final ClassDesc TYPE_SETTING_DEFINITION = Bytecode.classDesc(SettingDefinition.class);
private static final MethodDesc METHOD_BEGIN = MethodDesc.of("begin", "()V"); private static final MethodDesc METHOD_BEGIN = MethodDesc.of("begin", "()V");
@ -144,9 +143,7 @@ final class EventInstrumentation {
private ImplicitFields determineImplicitFields() { private ImplicitFields determineImplicitFields() {
if (isJDK) { if (isJDK) {
// For now, only support mirror events in java.base Class<?> eventClass = MirrorEvents.find(isJDK, className);
String fullName = "java.base:" + className;
Class<?> eventClass = MirrorEvents.find(fullName);
if (eventClass != null) { if (eventClass != null) {
return new ImplicitFields(eventClass); return new ImplicitFields(eventClass);
} }
@ -221,20 +218,6 @@ final class EventInstrumentation {
return true; return true;
} }
boolean isMirrorEvent() {
String typeDescriptor = TYPE_MIRROR_EVENT.descriptorString();
for (ClassElement ce : classModel.elements()) {
if (ce instanceof RuntimeVisibleAnnotationsAttribute rvaa) {
for (var annotation : rvaa.annotations()) {
if (annotation.className().equalsString(typeDescriptor)) {
return true;
}
}
}
}
return false;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
// Only supports String, String[] and Boolean values // Only supports String, String[] and Boolean values
private static <T> T annotationValue(ClassModel classModel, ClassDesc classDesc, Class<T> type) { private static <T> T annotationValue(ClassModel classModel, ClassDesc classDesc, Class<T> type) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -112,9 +112,6 @@ final class JVMUpcalls {
Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Skipping instrumentation for " + eventName + " since container support is missing"); Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Skipping instrumentation for " + eventName + " since container support is missing");
return oldBytes; return oldBytes;
} }
if (ei.isMirrorEvent()) {
return oldBytes;
}
if (!forceInstrumentation) { if (!forceInstrumentation) {
// Assume we are recording // Assume we are recording

View File

@ -144,10 +144,6 @@ public final class MetadataRepository {
} }
EventConfiguration configuration = getConfiguration(eventClass, true); EventConfiguration configuration = getConfiguration(eventClass, true);
if (configuration == null) { if (configuration == null) {
if (eventClass.getAnnotation(MirrorEvent.class) != null) {
// Don't register mirror classes.
return null;
}
PlatformEventType pe = findMirrorType(eventClass); PlatformEventType pe = findMirrorType(eventClass);
configuration = makeConfiguration(eventClass, pe, dynamicAnnotations, dynamicFields); configuration = makeConfiguration(eventClass, pe, dynamicAnnotations, dynamicFields);
} }
@ -162,8 +158,7 @@ public final class MetadataRepository {
} }
private PlatformEventType findMirrorType(Class<? extends jdk.internal.event.Event> eventClass) throws InternalError { private PlatformEventType findMirrorType(Class<? extends jdk.internal.event.Event> eventClass) throws InternalError {
String fullName = eventClass.getModule().getName() + ":" + eventClass.getName(); Class<? extends MirrorEvent> mirrorClass = MirrorEvents.find(eventClass);
Class<? extends Event> mirrorClass = MirrorEvents.find(fullName);
if (mirrorClass == null) { if (mirrorClass == null) {
return null; // not a mirror return null; // not a mirror
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,32 +22,28 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package jdk.jfr.internal; package jdk.jfr.internal;
import java.lang.annotation.Retention; import jdk.jfr.Enabled;
import java.lang.annotation.Target; import jdk.jfr.Registered;
import java.lang.annotation.RetentionPolicy; import jdk.jfr.StackTrace;
import java.lang.annotation.ElementType;
/**
* Any event class annotated with this annotation must be added
* to the {@link MirrorEvents) class for it to take effect.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface MirrorEvent {
/**
* Fully qualified name of the class to mirror metadata for (for example,
* {@code "jdk.internal.event.Example"})
*
* @return the fully qualified class name of the event
*/
String className();
/** /**
* The module where the event is located, by default {@code "java.base"}. * A mirror event is a fictitious event class that contains metadata about an
* * event, but not the implementation to write the event data to buffers.
* @return the module name * <p>
* A mirror event should be used when an event class is in a module where a
* dependency on the jdk.jfr module is not possible, for example, due to a
* circular dependency.
* <p>
* Subclass the MirrorEvent class and add the exact same fields as the actual
* event, but with labels, descriptions etc.
* <p>
* For the mirror mechanism to work, the mirror class must be registered in the
* jdk.jfr.internal.MirrorEvents class.
*/ */
String module() default "java.base"; @Registered(false)
@Enabled(false)
@StackTrace(false)
public abstract class MirrorEvent {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,10 +24,9 @@
*/ */
package jdk.jfr.internal; package jdk.jfr.internal;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import jdk.jfr.Event;
import jdk.jfr.events.DeserializationEvent; import jdk.jfr.events.DeserializationEvent;
import jdk.jfr.events.ErrorThrownEvent; import jdk.jfr.events.ErrorThrownEvent;
import jdk.jfr.events.ExceptionStatisticsEvent; import jdk.jfr.events.ExceptionStatisticsEvent;
@ -47,52 +46,46 @@ import jdk.jfr.events.VirtualThreadSubmitFailedEvent;
import jdk.jfr.events.X509CertificateEvent; import jdk.jfr.events.X509CertificateEvent;
import jdk.jfr.events.X509ValidationEvent; import jdk.jfr.events.X509ValidationEvent;
public final class MirrorEvents { /**
private static final Class<?>[] mirrorEventClasses = { * This class registers all mirror events.
DeserializationEvent.class, */
ProcessStartEvent.class, final class MirrorEvents {
SecurityPropertyModificationEvent.class, private static final Map<String, Class<? extends MirrorEvent>> mirrorLookup = new ConcurrentHashMap<>();
SecurityProviderServiceEvent.class,
SerializationMisdeclarationEvent.class, // Add mirror event mapping here. See MirrorEvent class for details.
SocketReadEvent.class, static {
SocketWriteEvent.class, register("jdk.internal.event.DeserializationEvent", DeserializationEvent.class);
ThreadSleepEvent.class, register("jdk.internal.event.ProcessStartEvent", ProcessStartEvent.class);
TLSHandshakeEvent.class, register("jdk.internal.event.SecurityPropertyModificationEvent", SecurityPropertyModificationEvent.class);
VirtualThreadStartEvent.class, register("jdk.internal.event.SecurityProviderServiceEvent", SecurityProviderServiceEvent.class);
VirtualThreadEndEvent.class, register("jdk.internal.event.SerializationMisdeclarationEvent", SerializationMisdeclarationEvent.class);
VirtualThreadPinnedEvent.class, register("jdk.internal.event.SocketReadEvent", SocketReadEvent.class);
VirtualThreadSubmitFailedEvent.class, register("jdk.internal.event.SocketWriteEvent", SocketWriteEvent.class);
X509CertificateEvent.class, register("jdk.internal.event.ThreadSleepEvent", ThreadSleepEvent.class);
X509ValidationEvent.class, register("jdk.internal.event.TLSHandshakeEvent", TLSHandshakeEvent.class);
ErrorThrownEvent.class, register("jdk.internal.event.VirtualThreadStartEvent", VirtualThreadStartEvent.class);
ExceptionStatisticsEvent.class, register("jdk.internal.event.VirtualThreadEndEvent", VirtualThreadEndEvent.class);
ExceptionThrownEvent.class, register("jdk.internal.event.VirtualThreadPinnedEvent", VirtualThreadPinnedEvent.class);
register("jdk.internal.event.VirtualThreadSubmitFailedEvent", VirtualThreadSubmitFailedEvent.class);
register("jdk.internal.event.X509CertificateEvent", X509CertificateEvent.class);
register("jdk.internal.event.X509ValidationEvent", X509ValidationEvent.class);
register("jdk.internal.event.ErrorThrownEvent", ErrorThrownEvent.class);
register("jdk.internal.event.ExceptionStatisticsEvent", ExceptionStatisticsEvent.class);
register("jdk.internal.event.ExceptionThrownEvent", ExceptionThrownEvent.class);
}; };
private static final Map<String, Class<? extends Event>> mirrorLookup = createLookup(); private static void register(String eventClassName, Class<? extends MirrorEvent> mirrorClass) {
mirrorLookup.put(eventClassName, mirrorClass);
}
public static Class<? extends Event> find(String name) { static Class<? extends MirrorEvent> find(Class<? extends jdk.internal.event.Event> eventClass) {
// When <clinit> of this class is executed it may lead return find(eventClass.getClassLoader() == null, eventClass.getName());
// to a JVM up call and invocation of this method before }
// the mirrorLookup field has been set. This is fine,
// mirrors should not be instrumented. static Class<? extends MirrorEvent> find(boolean bootClassLoader, String name) {
if (mirrorLookup != null) { if (bootClassLoader) {
return mirrorLookup.get(name); return mirrorLookup.get(name);
} }
return null; return null;
} }
@SuppressWarnings("unchecked")
private static Map<String, Class<? extends Event>> createLookup() {
Map<String, Class<? extends Event>> mirrors = new HashMap<>();
for (Class<?> eventClass : mirrorEventClasses) {
MirrorEvent me = eventClass.getAnnotation(MirrorEvent.class);
if (me == null) {
throw new InternalError("Mirror class must have annotation " + MirrorEvent.class.getName());
}
String fullName = me.module() + ":" + me.className();
mirrors.put(fullName, (Class<? extends Event>) eventClass);
}
return mirrors;
}
} }

View File

@ -263,7 +263,7 @@ public final class TypeLibrary {
// STRUCT // STRUCT
String superType = null; String superType = null;
boolean eventType = false; boolean eventType = false;
if (jdk.internal.event.Event.class.isAssignableFrom(clazz)) { if (isEventClass(clazz)) {
superType = Type.SUPER_TYPE_EVENT; superType = Type.SUPER_TYPE_EVENT;
eventType= true; eventType= true;
} }
@ -291,6 +291,16 @@ public final class TypeLibrary {
return type; return type;
} }
private static boolean isEventClass(Class<?> clazz) {
if (jdk.internal.event.Event.class.isAssignableFrom(clazz)) {
return true;
}
if (MirrorEvent.class.isAssignableFrom(clazz)) {
return true;
}
return false;
}
private static void addAnnotations(Class<?> clazz, Type type, List<AnnotationElement> dynamicAnnotations) { private static void addAnnotations(Class<?> clazz, Type type, List<AnnotationElement> dynamicAnnotations) {
ArrayList<AnnotationElement> aes = new ArrayList<>(); ArrayList<AnnotationElement> aes = new ArrayList<>();
if (dynamicAnnotations.isEmpty()) { if (dynamicAnnotations.isEmpty()) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,11 +41,11 @@ public final class ImplicitFields {
private final List<String> fields = new ArrayList<>(4); private final List<String> fields = new ArrayList<>(4);
public ImplicitFields(Class<?> eventClass) { public ImplicitFields(Class<?> eventClass) {
fields.add(START_TIME); // for completeness, not really needed fields.add(START_TIME);
fields.add(DURATION); fields.add(DURATION);
fields.add(STACK_TRACE); fields.add(STACK_TRACE);
fields.add(EVENT_THREAD); fields.add(EVENT_THREAD);
for (Class<?> c = eventClass; jdk.internal.event.Event.class != c; c = c.getSuperclass()) { for (Class<?> c = eventClass; !Utils.isEventBaseClass(c); c = c.getSuperclass()) {
RemoveFields rf = c.getAnnotation(RemoveFields.class); RemoveFields rf = c.getAnnotation(RemoveFields.class);
if (rf != null) { if (rf != null) {
for (String value : rf.value()) { for (String value : rf.value()) {

View File

@ -51,6 +51,7 @@ import jdk.jfr.RecordingState;
import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogLevel;
import jdk.jfr.internal.LogTag; import jdk.jfr.internal.LogTag;
import jdk.jfr.internal.Logger; import jdk.jfr.internal.Logger;
import jdk.jfr.internal.MirrorEvent;
import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.SecuritySupport;
import jdk.jfr.internal.Type; import jdk.jfr.internal.Type;
import jdk.jfr.internal.settings.PeriodSetting; import jdk.jfr.internal.settings.PeriodSetting;
@ -206,9 +207,8 @@ public final class Utils {
} }
public static List<Field> getVisibleEventFields(Class<?> clazz) { public static List<Field> getVisibleEventFields(Class<?> clazz) {
Utils.ensureValidEventSubclass(clazz);
List<Field> fields = new ArrayList<>(); List<Field> fields = new ArrayList<>();
for (Class<?> c = clazz; c != jdk.internal.event.Event.class; c = c.getSuperclass()) { for (Class<?> c = clazz; !Utils.isEventBaseClass(c); c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) { for (Field field : c.getDeclaredFields()) {
// skip private field in base classes // skip private field in base classes
if (c == clazz || !Modifier.isPrivate(field.getModifiers())) { if (c == clazz || !Modifier.isPrivate(field.getModifiers())) {
@ -219,6 +219,16 @@ public final class Utils {
return fields; return fields;
} }
public static boolean isEventBaseClass(Class<?> clazz) {
if (jdk.internal.event.Event.class == clazz) {
return true;
}
if (jdk.jfr.internal.MirrorEvent.class == clazz) {
return true;
}
return false;
}
public static void ensureValidEventSubclass(Class<?> eventClass) { public static void ensureValidEventSubclass(Class<?> eventClass) {
if (jdk.internal.event.Event.class.isAssignableFrom(eventClass) && Modifier.isAbstract(eventClass.getModifiers())) { if (jdk.internal.event.Event.class.isAssignableFrom(eventClass) && Modifier.isAbstract(eventClass.getModifiers())) {
throw new IllegalArgumentException("Abstract event classes are not allowed"); throw new IllegalArgumentException("Abstract event classes are not allowed");
@ -338,7 +348,7 @@ public final class Utils {
return eventName; return eventName;
} }
public static void verifyMirror(Class<?> mirror, Class<?> real) { public static void verifyMirror(Class<? extends MirrorEvent> mirror, Class<?> real) {
Class<?> cMirror = Objects.requireNonNull(mirror); Class<?> cMirror = Objects.requireNonNull(mirror);
Class<?> cReal = Objects.requireNonNull(real); Class<?> cReal = Objects.requireNonNull(real);
@ -353,7 +363,7 @@ public final class Utils {
} }
while (cReal != null) { while (cReal != null) {
for (Field realField : cReal.getDeclaredFields()) { for (Field realField : cReal.getDeclaredFields()) {
if (isSupportedType(realField.getType())) { if (isSupportedType(realField.getType()) && !realField.isSynthetic()) {
String fieldName = realField.getName(); String fieldName = realField.getName();
Field mirrorField = mirrorFields.get(fieldName); Field mirrorField = mirrorFields.get(fieldName);
if (mirrorField == null) { if (mirrorField == null) {