8330734: JFR: Re-engineer mirror class mechanism
Reviewed-by: mgronlun
This commit is contained in:
parent
0bf516f7ba
commit
07facd0420
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,9 +36,8 @@ import jdk.jfr.internal.RemoveFields;
|
||||
@Label("Deserialization")
|
||||
@Name("jdk.Deserialization")
|
||||
@Description("Results of deserialization and ObjectInputFilter checks")
|
||||
@MirrorEvent(className = "jdk.internal.event.DeserializationEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class DeserializationEvent extends AbstractJDKEvent {
|
||||
public final class DeserializationEvent extends MirrorEvent {
|
||||
|
||||
@Label("Filter Configured")
|
||||
public boolean filterConfigured;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Category("Java Application")
|
||||
@Description("An object derived from java.lang.Error has been created. OutOfMemoryErrors are ignored")
|
||||
@MirrorEvent(className = "jdk.internal.event.ErrorThrownEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class ErrorThrownEvent extends AbstractJDKEvent {
|
||||
public final class ErrorThrownEvent extends MirrorEvent {
|
||||
|
||||
@Label("Message")
|
||||
public String message;
|
||||
|
@ -31,14 +31,15 @@ import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.StackTrace;
|
||||
import jdk.jfr.internal.MirrorEvent;
|
||||
import jdk.jfr.internal.RemoveFields;
|
||||
import jdk.jfr.internal.Type;
|
||||
|
||||
@Name(Type.EVENT_NAME_PREFIX + "ExceptionStatistics")
|
||||
@Label("Exception Statistics")
|
||||
@Category({ "Java Application", "Statistics" })
|
||||
@Description("Number of objects derived from java.lang.Throwable that have been created")
|
||||
@MirrorEvent(className = "jdk.internal.event.ExceptionStatisticsEvent")
|
||||
public final class ExceptionStatisticsEvent extends AbstractPeriodicEvent {
|
||||
@RemoveFields({"duration", "eventThread", "stackTrace"})
|
||||
public final class ExceptionStatisticsEvent extends MirrorEvent {
|
||||
|
||||
@Label("Exceptions Created")
|
||||
public long throwables;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Category("Java Application")
|
||||
@Description("An object derived from java.lang.Exception has been created")
|
||||
@MirrorEvent(className = "jdk.internal.event.ExceptionThrownEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class ExceptionThrownEvent extends AbstractJDKEvent {
|
||||
public final class ExceptionThrownEvent extends MirrorEvent {
|
||||
|
||||
@Label("Message")
|
||||
public String message;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Name("jdk.ProcessStart")
|
||||
@Description("Operating system process started")
|
||||
@MirrorEvent(className = "jdk.internal.event.ProcessStartEvent")
|
||||
@RemoveFields("duration")
|
||||
@StackFilter({"java.lang.ProcessBuilder", "java.lang.Runtime::exec"})
|
||||
public final class ProcessStartEvent extends AbstractJDKEvent {
|
||||
public final class ProcessStartEvent extends MirrorEvent {
|
||||
@Label("Process Id")
|
||||
public long pid;
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Name("jdk.SecurityPropertyModification")
|
||||
@Description("Modification of Security property")
|
||||
@MirrorEvent(className = "jdk.internal.event.SecurityPropertyModificationEvent")
|
||||
@RemoveFields("duration")
|
||||
@StackFilter({"java.security.Security::setProperty"})
|
||||
public final class SecurityPropertyModificationEvent extends AbstractJDKEvent {
|
||||
public final class SecurityPropertyModificationEvent extends MirrorEvent {
|
||||
@Label("Key")
|
||||
public String key;
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Name("jdk.SecurityProviderService")
|
||||
@Description("Details of Provider.getInstance(String type, String algorithm) calls")
|
||||
@MirrorEvent(className = "jdk.internal.event.SecurityProviderServiceEvent")
|
||||
@RemoveFields("duration")
|
||||
@StackFilter({"java.security.Provider::getService"})
|
||||
public final class SecurityProviderServiceEvent extends AbstractJDKEvent {
|
||||
public final class SecurityProviderServiceEvent extends MirrorEvent {
|
||||
@Label("Type of Service")
|
||||
public String type;
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* 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 first time it is used by serialization." +
|
||||
" Under high memory pressure, a class might be re-checked again.")
|
||||
@MirrorEvent(className = "jdk.internal.event.SerializationMisdeclarationEvent")
|
||||
@RemoveFields({"duration", "stackTrace", "eventThread"})
|
||||
public final class SerializationMisdeclarationEvent extends AbstractJDKEvent {
|
||||
public final class SerializationMisdeclarationEvent extends MirrorEvent {
|
||||
|
||||
@Label("Misdeclared Class")
|
||||
public Class<?> misdeclaredClass;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Category("Java Application")
|
||||
@Description("Reading data from a socket")
|
||||
@MirrorEvent(className = "jdk.internal.event.SocketReadEvent")
|
||||
public final class SocketReadEvent extends AbstractJDKEvent {
|
||||
public final class SocketReadEvent extends MirrorEvent {
|
||||
|
||||
@Label("Remote Host")
|
||||
public String host;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Category("Java Application")
|
||||
@Description("Writing data to a socket")
|
||||
@MirrorEvent(className = "jdk.internal.event.SocketWriteEvent")
|
||||
public final class SocketWriteEvent extends AbstractJDKEvent {
|
||||
public final class SocketWriteEvent extends MirrorEvent {
|
||||
|
||||
@Label("Remote Host")
|
||||
public String host;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Name("jdk.TLSHandshake")
|
||||
@Description("Parameters used in TLS Handshake")
|
||||
@MirrorEvent(className = "jdk.internal.event.TLSHandshakeEvent")
|
||||
@RemoveFields("duration")
|
||||
@StackFilter("sun.security.ssl.Finished::recordEvent")
|
||||
public final class TLSHandshakeEvent extends AbstractJDKEvent {
|
||||
public final class TLSHandshakeEvent extends MirrorEvent {
|
||||
@Label("Peer Host")
|
||||
public String peerHost;
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Label("Java Thread Sleep")
|
||||
@Name("jdk.ThreadSleep")
|
||||
@MirrorEvent(className = "jdk.internal.event.ThreadSleepEvent")
|
||||
@StackFilter({"java.lang.Thread::afterSleep",
|
||||
"java.lang.Thread::sleepNanos",
|
||||
"java.lang.Thread::sleep"})
|
||||
public final class ThreadSleepEvent extends AbstractJDKEvent {
|
||||
public final class ThreadSleepEvent extends MirrorEvent {
|
||||
@Label("Sleep Time")
|
||||
@Timespan(Timespan.NANOSECONDS)
|
||||
public long time;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Label("Virtual Thread End")
|
||||
@Name("jdk.VirtualThreadEnd")
|
||||
@MirrorEvent(className = "jdk.internal.event.VirtualThreadEndEvent")
|
||||
@RemoveFields({"duration", "stackTrace"})
|
||||
public final class VirtualThreadEndEvent extends AbstractJDKEvent {
|
||||
public final class VirtualThreadEndEvent extends MirrorEvent {
|
||||
|
||||
@Label("Thread Id")
|
||||
public long javaThreadId;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Label("Virtual Thread Pinned")
|
||||
@Name("jdk.VirtualThreadPinned")
|
||||
@MirrorEvent(className = "jdk.internal.event.VirtualThreadPinnedEvent")
|
||||
public final class VirtualThreadPinnedEvent extends AbstractJDKEvent {
|
||||
public final class VirtualThreadPinnedEvent extends MirrorEvent {
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Label("Virtual Thread Start")
|
||||
@Name("jdk.VirtualThreadStart")
|
||||
@MirrorEvent(className = "jdk.internal.event.VirtualThreadStartEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class VirtualThreadStartEvent extends AbstractJDKEvent {
|
||||
public final class VirtualThreadStartEvent extends MirrorEvent {
|
||||
|
||||
@Label("Thread Id")
|
||||
public long javaThreadId;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Name("jdk.VirtualThreadSubmitFailed")
|
||||
@Description("Submit of task for virtual thread failed")
|
||||
@MirrorEvent(className = "jdk.internal.event.VirtualThreadSubmitFailedEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class VirtualThreadSubmitFailedEvent extends AbstractJDKEvent {
|
||||
public final class VirtualThreadSubmitFailedEvent extends MirrorEvent {
|
||||
|
||||
@Label("Thread Id")
|
||||
public long javaThreadId;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Name("jdk.X509Certificate")
|
||||
@Description("Details of X.509 Certificate parsed by JDK")
|
||||
@MirrorEvent(className = "jdk.internal.event.X509CertificateEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class X509CertificateEvent extends AbstractJDKEvent {
|
||||
public final class X509CertificateEvent extends MirrorEvent {
|
||||
@Label("Signature Algorithm")
|
||||
public String algorithm;
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
* 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")
|
||||
@Name("jdk.X509Validation")
|
||||
@Description("Serial numbers from X.509 Certificates forming chain of trust")
|
||||
@MirrorEvent(className = "jdk.internal.event.X509ValidationEvent")
|
||||
@RemoveFields("duration")
|
||||
public final class X509ValidationEvent extends AbstractJDKEvent {
|
||||
public final class X509ValidationEvent extends MirrorEvent {
|
||||
@CertificateId
|
||||
@Label("Certificate Id")
|
||||
@Unsigned
|
||||
|
@ -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.
|
||||
*
|
||||
* 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_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_MIRROR_EVENT = Bytecode.classDesc(MirrorEvent.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 MethodDesc METHOD_BEGIN = MethodDesc.of("begin", "()V");
|
||||
@ -144,9 +143,7 @@ final class EventInstrumentation {
|
||||
|
||||
private ImplicitFields determineImplicitFields() {
|
||||
if (isJDK) {
|
||||
// For now, only support mirror events in java.base
|
||||
String fullName = "java.base:" + className;
|
||||
Class<?> eventClass = MirrorEvents.find(fullName);
|
||||
Class<?> eventClass = MirrorEvents.find(isJDK, className);
|
||||
if (eventClass != null) {
|
||||
return new ImplicitFields(eventClass);
|
||||
}
|
||||
@ -221,20 +218,6 @@ final class EventInstrumentation {
|
||||
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")
|
||||
// Only supports String, String[] and Boolean values
|
||||
private static <T> T annotationValue(ClassModel classModel, ClassDesc classDesc, Class<T> type) {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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");
|
||||
return oldBytes;
|
||||
}
|
||||
if (ei.isMirrorEvent()) {
|
||||
return oldBytes;
|
||||
}
|
||||
|
||||
if (!forceInstrumentation) {
|
||||
// Assume we are recording
|
||||
|
@ -144,10 +144,6 @@ public final class MetadataRepository {
|
||||
}
|
||||
EventConfiguration configuration = getConfiguration(eventClass, true);
|
||||
if (configuration == null) {
|
||||
if (eventClass.getAnnotation(MirrorEvent.class) != null) {
|
||||
// Don't register mirror classes.
|
||||
return null;
|
||||
}
|
||||
PlatformEventType pe = findMirrorType(eventClass);
|
||||
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 {
|
||||
String fullName = eventClass.getModule().getName() + ":" + eventClass.getName();
|
||||
Class<? extends Event> mirrorClass = MirrorEvents.find(fullName);
|
||||
Class<? extends MirrorEvent> mirrorClass = MirrorEvents.find(eventClass);
|
||||
if (mirrorClass == null) {
|
||||
return null; // not a mirror
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.jfr.internal;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
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();
|
||||
import jdk.jfr.Enabled;
|
||||
import jdk.jfr.Registered;
|
||||
import jdk.jfr.StackTrace;
|
||||
|
||||
/**
|
||||
* The module where the event is located, by default {@code "java.base"}.
|
||||
*
|
||||
* @return the module name
|
||||
*/
|
||||
String module() default "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.
|
||||
* <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.
|
||||
*/
|
||||
@Registered(false)
|
||||
@Enabled(false)
|
||||
@StackTrace(false)
|
||||
public abstract class MirrorEvent {
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,10 +24,9 @@
|
||||
*/
|
||||
package jdk.jfr.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.events.DeserializationEvent;
|
||||
import jdk.jfr.events.ErrorThrownEvent;
|
||||
import jdk.jfr.events.ExceptionStatisticsEvent;
|
||||
@ -47,52 +46,46 @@ import jdk.jfr.events.VirtualThreadSubmitFailedEvent;
|
||||
import jdk.jfr.events.X509CertificateEvent;
|
||||
import jdk.jfr.events.X509ValidationEvent;
|
||||
|
||||
public final class MirrorEvents {
|
||||
private static final Class<?>[] mirrorEventClasses = {
|
||||
DeserializationEvent.class,
|
||||
ProcessStartEvent.class,
|
||||
SecurityPropertyModificationEvent.class,
|
||||
SecurityProviderServiceEvent.class,
|
||||
SerializationMisdeclarationEvent.class,
|
||||
SocketReadEvent.class,
|
||||
SocketWriteEvent.class,
|
||||
ThreadSleepEvent.class,
|
||||
TLSHandshakeEvent.class,
|
||||
VirtualThreadStartEvent.class,
|
||||
VirtualThreadEndEvent.class,
|
||||
VirtualThreadPinnedEvent.class,
|
||||
VirtualThreadSubmitFailedEvent.class,
|
||||
X509CertificateEvent.class,
|
||||
X509ValidationEvent.class,
|
||||
ErrorThrownEvent.class,
|
||||
ExceptionStatisticsEvent.class,
|
||||
ExceptionThrownEvent.class,
|
||||
/**
|
||||
* This class registers all mirror events.
|
||||
*/
|
||||
final class MirrorEvents {
|
||||
private static final Map<String, Class<? extends MirrorEvent>> mirrorLookup = new ConcurrentHashMap<>();
|
||||
|
||||
// Add mirror event mapping here. See MirrorEvent class for details.
|
||||
static {
|
||||
register("jdk.internal.event.DeserializationEvent", DeserializationEvent.class);
|
||||
register("jdk.internal.event.ProcessStartEvent", ProcessStartEvent.class);
|
||||
register("jdk.internal.event.SecurityPropertyModificationEvent", SecurityPropertyModificationEvent.class);
|
||||
register("jdk.internal.event.SecurityProviderServiceEvent", SecurityProviderServiceEvent.class);
|
||||
register("jdk.internal.event.SerializationMisdeclarationEvent", SerializationMisdeclarationEvent.class);
|
||||
register("jdk.internal.event.SocketReadEvent", SocketReadEvent.class);
|
||||
register("jdk.internal.event.SocketWriteEvent", SocketWriteEvent.class);
|
||||
register("jdk.internal.event.ThreadSleepEvent", ThreadSleepEvent.class);
|
||||
register("jdk.internal.event.TLSHandshakeEvent", TLSHandshakeEvent.class);
|
||||
register("jdk.internal.event.VirtualThreadStartEvent", VirtualThreadStartEvent.class);
|
||||
register("jdk.internal.event.VirtualThreadEndEvent", VirtualThreadEndEvent.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) {
|
||||
// When <clinit> of this class is executed it may lead
|
||||
// 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.
|
||||
if (mirrorLookup != null) {
|
||||
static Class<? extends MirrorEvent> find(Class<? extends jdk.internal.event.Event> eventClass) {
|
||||
return find(eventClass.getClassLoader() == null, eventClass.getName());
|
||||
}
|
||||
|
||||
static Class<? extends MirrorEvent> find(boolean bootClassLoader, String name) {
|
||||
if (bootClassLoader) {
|
||||
return mirrorLookup.get(name);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ public final class TypeLibrary {
|
||||
// STRUCT
|
||||
String superType = null;
|
||||
boolean eventType = false;
|
||||
if (jdk.internal.event.Event.class.isAssignableFrom(clazz)) {
|
||||
if (isEventClass(clazz)) {
|
||||
superType = Type.SUPER_TYPE_EVENT;
|
||||
eventType= true;
|
||||
}
|
||||
@ -291,6 +291,16 @@ public final class TypeLibrary {
|
||||
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) {
|
||||
ArrayList<AnnotationElement> aes = new ArrayList<>();
|
||||
if (dynamicAnnotations.isEmpty()) {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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);
|
||||
|
||||
public ImplicitFields(Class<?> eventClass) {
|
||||
fields.add(START_TIME); // for completeness, not really needed
|
||||
fields.add(START_TIME);
|
||||
fields.add(DURATION);
|
||||
fields.add(STACK_TRACE);
|
||||
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);
|
||||
if (rf != null) {
|
||||
for (String value : rf.value()) {
|
||||
|
@ -51,6 +51,7 @@ import jdk.jfr.RecordingState;
|
||||
import jdk.jfr.internal.LogLevel;
|
||||
import jdk.jfr.internal.LogTag;
|
||||
import jdk.jfr.internal.Logger;
|
||||
import jdk.jfr.internal.MirrorEvent;
|
||||
import jdk.jfr.internal.SecuritySupport;
|
||||
import jdk.jfr.internal.Type;
|
||||
import jdk.jfr.internal.settings.PeriodSetting;
|
||||
@ -206,9 +207,8 @@ public final class Utils {
|
||||
}
|
||||
|
||||
public static List<Field> getVisibleEventFields(Class<?> clazz) {
|
||||
Utils.ensureValidEventSubclass(clazz);
|
||||
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()) {
|
||||
// skip private field in base classes
|
||||
if (c == clazz || !Modifier.isPrivate(field.getModifiers())) {
|
||||
@ -219,6 +219,16 @@ public final class Utils {
|
||||
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) {
|
||||
if (jdk.internal.event.Event.class.isAssignableFrom(eventClass) && Modifier.isAbstract(eventClass.getModifiers())) {
|
||||
throw new IllegalArgumentException("Abstract event classes are not allowed");
|
||||
@ -338,7 +348,7 @@ public final class Utils {
|
||||
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<?> cReal = Objects.requireNonNull(real);
|
||||
|
||||
@ -353,7 +363,7 @@ public final class Utils {
|
||||
}
|
||||
while (cReal != null) {
|
||||
for (Field realField : cReal.getDeclaredFields()) {
|
||||
if (isSupportedType(realField.getType())) {
|
||||
if (isSupportedType(realField.getType()) && !realField.isSynthetic()) {
|
||||
String fieldName = realField.getName();
|
||||
Field mirrorField = mirrorFields.get(fieldName);
|
||||
if (mirrorField == null) {
|
||||
|
Loading…
Reference in New Issue
Block a user