From 4e8a235e35adfd4f43a4af5ee6cded7891ebc05b Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Sun, 29 Oct 2023 18:33:55 +0100 Subject: [PATCH] Initial --- .../jdk/jfr/consumer/RecordedEvent.java | 6 +- .../events/AbstractBufferStatisticsEvent.java | 4 +- .../jdk/jfr/events/AbstractPeriodicEvent.java | 31 +++ .../jdk/jfr/events/ActiveRecordingEvent.java | 4 +- .../jdk/jfr/events/ActiveSettingEvent.java | 6 +- .../events/ContainerCPUThrottlingEvent.java | 4 +- .../jfr/events/ContainerCPUUsageEvent.java | 4 +- .../events/ContainerConfigurationEvent.java | 4 +- .../jdk/jfr/events/ContainerIOUsageEvent.java | 4 +- .../jfr/events/ContainerMemoryUsageEvent.java | 4 +- .../jdk/jfr/events/DeserializationEvent.java | 4 +- .../jdk/jfr/events/ErrorThrownEvent.java | 6 +- .../jfr/events/ExceptionStatisticsEvent.java | 4 +- .../jdk/jfr/events/ExceptionThrownEvent.java | 6 +- .../events/InitialSecurityPropertyEvent.java | 4 +- .../jdk/jfr/events/ProcessStartEvent.java | 4 +- .../SecurityPropertyModificationEvent.java | 4 +- .../events/SecurityProviderServiceEvent.java | 4 +- .../jdk/jfr/events/TLSHandshakeEvent.java | 4 +- .../jdk/jfr/events/VirtualThreadEndEvent.java | 4 +- .../jfr/events/VirtualThreadStartEvent.java | 4 +- .../VirtualThreadSubmitFailedEvent.java | 4 +- .../jdk/jfr/events/X509CertificateEvent.java | 4 +- .../jdk/jfr/events/X509ValidationEvent.java | 4 +- .../jdk/jfr/internal/EventControl.java | 4 +- .../jfr/internal/EventInstrumentation.java | 182 +++++++++++++----- .../jdk/jfr/internal/EventWriterMethod.java | 6 +- .../classes/jdk/jfr/internal/JVMUpcalls.java | 4 + .../jdk/jfr/internal/MetadataRepository.java | 16 +- .../classes/jdk/jfr/internal/MirrorEvent.java | 7 +- .../jdk/jfr/internal/MirrorEvents.java | 90 +++++++++ .../jdk/jfr/internal/PlatformEventType.java | 21 +- .../jdk/jfr/internal/PlatformRecorder.java | 1 - .../jdk/jfr/internal/RemoveFields.java | 53 +++++ .../jdk/jfr/internal/SecuritySupport.java | 4 - .../classes/jdk/jfr/internal/TypeLibrary.java | 18 +- .../jfr/internal/consumer/EventParser.java | 6 +- .../jfr/internal/instrument/JDKEvents.java | 35 +--- .../internal/instrument/ThrowableTracer.java | 8 +- .../jdk/jfr/internal/util/ImplicitFields.java | 74 +++++++ .../classes/jdk/jfr/internal/util/Utils.java | 5 - .../settings/TestSettingsAvailability.java | 8 +- .../metadata/TestDefaultConfigurations.java | 37 +--- 43 files changed, 491 insertions(+), 219 deletions(-) create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/events/AbstractPeriodicEvent.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/RemoveFields.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/util/ImplicitFields.java diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java index 7ffcaabd57cf1..d91e688005946 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java @@ -31,8 +31,8 @@ import jdk.jfr.EventType; import jdk.jfr.ValueDescriptor; -import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.consumer.ObjectContext; +import jdk.jfr.internal.util.ImplicitFields; /** * A recorded event. @@ -57,7 +57,7 @@ public final class RecordedEvent extends RecordedObject { * @return stack trace, or {@code null} if doesn't exist for the event */ public RecordedStackTrace getStackTrace() { - return getTyped(Utils.FIELD_STACK_TRACE, RecordedStackTrace.class, null); + return getTyped(ImplicitFields.STACK_TRACE, RecordedStackTrace.class, null); } /** @@ -67,7 +67,7 @@ public RecordedStackTrace getStackTrace() { * @return thread, or {@code null} if doesn't exist for the event */ public RecordedThread getThread() { - return getTyped(Utils.FIELD_EVENT_THREAD, RecordedThread.class, null); + return getTyped(ImplicitFields.EVENT_THREAD, RecordedThread.class, null); } /** diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java index 50f77c79eafb5..d436b32db83e3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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 @@ -30,7 +30,7 @@ import jdk.jfr.*; @Category({ "Java Application", "Statistics" }) -public abstract class AbstractBufferStatisticsEvent extends AbstractJDKEvent { +public abstract class AbstractBufferStatisticsEvent extends AbstractPeriodicEvent { protected AbstractBufferStatisticsEvent(BufferPool bufferPool) { count = bufferPool.getCount(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractPeriodicEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractPeriodicEvent.java new file mode 100644 index 0000000000000..9893b9ce3da55 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractPeriodicEvent.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.events; + +import jdk.jfr.internal.RemoveFields; + +@RemoveFields({"duration", "eventThread", "stackTrace"}) +abstract class AbstractPeriodicEvent extends AbstractJDKEvent { +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java index bb2ad9a1ad815..985b5c61fb579 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java @@ -32,12 +32,14 @@ import jdk.jfr.StackTrace; import jdk.jfr.Timespan; import jdk.jfr.Timestamp; +import jdk.jfr.internal.RemoveFields; import jdk.jfr.internal.Type; @Name(Type.EVENT_NAME_PREFIX + "ActiveRecording") @Label("Flight Recording") @Category("Flight Recorder") @StackTrace(false) +@RemoveFields({"duration", "eventThread", "stackTrace"}) public final class ActiveRecordingEvent extends AbstractJDKEvent { // The order of these fields must be the same as the parameters in @@ -79,7 +81,7 @@ public static boolean enabled() { return false; // Generated } - public static void commit(long timestamp, long duration, long id, String name, + public static void commit(long timestamp, long id, String name, String destination, boolean disk, long maxAge, long flushInterval, long maxSize, long recordingStart, long recordingDuration) { // Generated diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java index 7bef015007739..d751580fa3aa1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -29,12 +29,14 @@ import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.StackTrace; +import jdk.jfr.internal.RemoveFields; import jdk.jfr.internal.Type; @Name(Type.EVENT_NAME_PREFIX + "ActiveSetting") @Label("Recording Setting") @Category("Flight Recorder") @StackTrace(false) +@RemoveFields({"duration", "eventThread", "stackTrace"}) public final class ActiveSettingEvent extends AbstractJDKEvent { // The order of these fields must be the same as the parameters in @@ -49,7 +51,7 @@ public final class ActiveSettingEvent extends AbstractJDKEvent { @Label("Setting Value") public String value; - public static void commit(long startTime, long duration, long id, String name, String value) { + public static void commit(long startTime, long id, String name, String value) { // Generated } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUThrottlingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUThrottlingEvent.java index bb87d0f5f00fc..40856ace7009c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUThrottlingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUThrottlingEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, DataDog. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,7 +36,7 @@ @Label("CPU Throttling") @Category({"Operating System", "Processor"}) @Description("Container CPU throttling related information") -public class ContainerCPUThrottlingEvent extends AbstractJDKEvent { +public class ContainerCPUThrottlingEvent extends AbstractPeriodicEvent { @Label("CPU Elapsed Slices") @Description("Number of time-slice periods that have elapsed if a CPU quota has been setup for the container") public long cpuElapsedSlices; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUUsageEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUUsageEvent.java index b6ed9667db4e6..f9a0ce280edbd 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUUsageEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerCPUUsageEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, DataDog. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,7 +36,7 @@ @Label("CPU Usage") @Category({"Operating System", "Processor"}) @Description("Container CPU usage related information") -public class ContainerCPUUsageEvent extends AbstractJDKEvent { +public class ContainerCPUUsageEvent extends AbstractPeriodicEvent { @Label("CPU Time") @Description("Aggregate time consumed by all tasks in the container") @Timespan diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerConfigurationEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerConfigurationEvent.java index 3ea198164e295..333b734c1c10a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerConfigurationEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerConfigurationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, DataDog. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -37,7 +37,7 @@ @Label("Container Configuration") @Category({"Operating System"}) @Description("A set of container specific attributes") -public final class ContainerConfigurationEvent extends AbstractJDKEvent { +public final class ContainerConfigurationEvent extends AbstractPeriodicEvent { @Label("Container Type") @Description("Container type information") public String containerType; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerIOUsageEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerIOUsageEvent.java index 23afd84879c3f..7c92da3f8dbd1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerIOUsageEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerIOUsageEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, DataDog. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -37,7 +37,7 @@ @Label("Container IO Usage") @Category({"Operating System", "File System"}) @Description("Container IO usage related information") -public class ContainerIOUsageEvent extends AbstractJDKEvent { +public class ContainerIOUsageEvent extends AbstractPeriodicEvent { @Label("Block IO Request Count") @Description("Number of block IO requests to the disk that have been issued by the container") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerMemoryUsageEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerMemoryUsageEvent.java index c023b066f4afd..285952d0c66c9 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerMemoryUsageEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ContainerMemoryUsageEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, DataDog. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -36,7 +36,7 @@ @Label("Container Memory Usage") @Category({"Operating System", "Memory"}) @Description("Container memory usage related information") -public final class ContainerMemoryUsageEvent extends AbstractJDKEvent { +public final class ContainerMemoryUsageEvent extends AbstractPeriodicEvent { @Label("Memory Fail Count") @Description("Number of times that user memory requests in the container have exceeded the memory limit") public long memoryFailCount; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java index 8d58e4cd0affd..66c376e9022dc 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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 @@ -30,12 +30,14 @@ import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Java Development Kit", "Serialization"}) @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 { @Label("Filter Configured") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.java index 3f467256dd2c2..43f17d6ee62a3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ErrorThrownEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -28,12 +28,14 @@ import jdk.jfr.Description; import jdk.jfr.Label; import jdk.jfr.Name; +import jdk.jfr.internal.RemoveFields; import jdk.jfr.internal.Type; @Name(Type.EVENT_NAME_PREFIX + "JavaErrorThrow") @Label("Java Error") @Category("Java Application") @Description("An object derived from java.lang.Error has been created. OutOfMemoryErrors are ignored") +@RemoveFields("duration") public final class ErrorThrownEvent extends AbstractJDKEvent { // The order of these fields must be the same as the parameters in @@ -45,7 +47,7 @@ public final class ErrorThrownEvent extends AbstractJDKEvent { @Label("Class") public Class thrownClass; - public static void commit(long start, long duration, String message, Class thrownClass) { + public static void commit(long start, String message, Class thrownClass) { // Generated } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java index 1a63019a469b6..0c33bcac81bdf 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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,7 +37,7 @@ @Category({ "Java Application", "Statistics" }) @Description("Number of objects derived from java.lang.Throwable that have been created") @StackTrace(false) -public final class ExceptionStatisticsEvent extends AbstractJDKEvent { +public final class ExceptionStatisticsEvent extends AbstractPeriodicEvent { @Label("Exceptions Created") public long throwables; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java index 033586a8fe9d8..719206c8133ff 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionThrownEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -29,12 +29,14 @@ import jdk.jfr.Description; import jdk.jfr.Label; import jdk.jfr.Name; +import jdk.jfr.internal.RemoveFields; import jdk.jfr.internal.Type; @Name(Type.EVENT_NAME_PREFIX + "JavaExceptionThrow") @Label("Java Exception") @Category("Java Application") @Description("An object derived from java.lang.Exception has been created") +@RemoveFields("duration") public final class ExceptionThrownEvent extends AbstractJDKEvent { // The order of these fields must be the same as the parameters in @@ -46,7 +48,7 @@ public final class ExceptionThrownEvent extends AbstractJDKEvent { @Label("Class") public Class thrownClass; - public static void commit(long start, long duration, String message, Class thrownClass) { + public static void commit(long start, String message, Class thrownClass) { // Generated } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/InitialSecurityPropertyEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/InitialSecurityPropertyEvent.java index 28b6e2f92c733..af4a01b0bfe9d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/InitialSecurityPropertyEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/InitialSecurityPropertyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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,7 +34,7 @@ @Label("Initial Security Property") @Name("jdk.InitialSecurityProperty") @Description("Initial Security Properties") -public final class InitialSecurityPropertyEvent extends AbstractJDKEvent { +public final class InitialSecurityPropertyEvent extends AbstractPeriodicEvent { @Label("Key") public String key; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ProcessStartEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ProcessStartEvent.java index f3e1cf314785d..b936099aa743a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ProcessStartEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ProcessStartEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, 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 @@ -30,12 +30,14 @@ import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Operating System"}) @Label("Process Start") @Name("jdk.ProcessStart") @Description("Operating system process started") @MirrorEvent(className = "jdk.internal.event.ProcessStartEvent") +@RemoveFields("duration") public final class ProcessStartEvent extends AbstractJDKEvent { @Label("Process Id") public long pid; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityPropertyModificationEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityPropertyModificationEvent.java index e56310210dee8..df2e9c241de06 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityPropertyModificationEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityPropertyModificationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -27,12 +27,14 @@ import jdk.jfr.*; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Java Development Kit", "Security"}) @Label("Security Property Modification") @Name("jdk.SecurityPropertyModification") @Description("Modification of Security property") @MirrorEvent(className = "jdk.internal.event.SecurityPropertyModificationEvent") +@RemoveFields("duration") public final class SecurityPropertyModificationEvent extends AbstractJDKEvent { @Label("Key") public String key; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java index 97a5150561ca8..193bfa54ae255 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/SecurityProviderServiceEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, 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 @@ -30,12 +30,14 @@ import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Java Development Kit", "Security"}) @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") public final class SecurityProviderServiceEvent extends AbstractJDKEvent { @Label("Type of Service") public String type; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/TLSHandshakeEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/TLSHandshakeEvent.java index 6bcbe9ab39385..ce5e8c8576804 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/TLSHandshakeEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/TLSHandshakeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -31,12 +31,14 @@ import jdk.jfr.Name; import jdk.jfr.Unsigned; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Java Development Kit", "Security"}) @Label("TLS Handshake") @Name("jdk.TLSHandshake") @Description("Parameters used in TLS Handshake") @MirrorEvent(className = "jdk.internal.event.TLSHandshakeEvent") +@RemoveFields("duration") public final class TLSHandshakeEvent extends AbstractJDKEvent { @Label("Peer Host") public String peerHost; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadEndEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadEndEvent.java index 2c504fca4a8ac..8ad64abf1bfd6 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadEndEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadEndEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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 @@ -29,11 +29,13 @@ import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.internal.MirrorEvent; +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 { @Label("Thread Id") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadStartEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadStartEvent.java index e109aefb3bb2f..646c2379178a9 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadStartEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadStartEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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 @@ -29,11 +29,13 @@ import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.internal.MirrorEvent; +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 { @Label("Thread Id") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadSubmitFailedEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadSubmitFailedEvent.java index 292b90c378bb6..d59fbe2931e98 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadSubmitFailedEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/VirtualThreadSubmitFailedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, 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 @@ -30,12 +30,14 @@ import jdk.jfr.Label; import jdk.jfr.Name; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Java Development Kit", "Threading"}) @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 { @Label("Thread Id") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/X509CertificateEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/X509CertificateEvent.java index bebff12c32d73..7ec9c04360579 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/X509CertificateEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/X509CertificateEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -27,12 +27,14 @@ import jdk.jfr.*; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Java Development Kit", "Security"}) @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 { @Label("Signature Algorithm") public String algorithm; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/X509ValidationEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/X509ValidationEvent.java index a17c90d1f7481..c4a73d2ffe841 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/X509ValidationEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/X509ValidationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -27,12 +27,14 @@ import jdk.jfr.*; import jdk.jfr.internal.MirrorEvent; +import jdk.jfr.internal.RemoveFields; @Category({"Java Development Kit", "Security"}) @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 { @CertificateId @Label("Certificate Id") diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index 4f54aba79858b..d2327a189b54e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -72,7 +72,7 @@ record NamedControl(String name, Control control) { private final String idName; EventControl(PlatformEventType eventType) { - if (eventType.hasDuration()) { + if (eventType.hasThreshold()) { addControl(Threshold.NAME, defineThreshold(eventType)); } if (eventType.hasStackTrace()) { @@ -289,7 +289,7 @@ void writeActiveSettingEvent(long timestamp) { value = nc.control.getDefaultValue(); } if (ActiveSettingEvent.enabled()) { - ActiveSettingEvent.commit(timestamp, 0L, type.getId(), nc.name(), value); + ActiveSettingEvent.commit(timestamp, type.getId(), nc.name(), value); } } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java index fcf00a7db9b3b..e9acf7b17093e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventInstrumentation.java @@ -54,12 +54,14 @@ import jdk.jfr.internal.event.EventConfiguration; import jdk.jfr.internal.event.EventWriter; import jdk.jfr.Enabled; +import jdk.jfr.Event; import jdk.jfr.Name; import jdk.jfr.Registered; import jdk.jfr.SettingControl; import jdk.jfr.SettingDefinition; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.util.Bytecode; +import jdk.jfr.internal.util.ImplicitFields; import jdk.jfr.internal.util.Bytecode.FieldDesc; import jdk.jfr.internal.util.Bytecode.MethodDesc; import static jdk.jfr.internal.util.Bytecode.invokevirtual; @@ -77,15 +79,18 @@ final class EventInstrumentation { private record SettingDesc(ClassDesc paramType, String methodName) { } - private static final FieldDesc FIELD_DURATION = FieldDesc.of(long.class, Utils.FIELD_DURATION); + private static final FieldDesc FIELD_DURATION = FieldDesc.of(long.class, ImplicitFields.DURATION); private static final FieldDesc FIELD_EVENT_CONFIGURATION = FieldDesc.of(Object.class, "eventConfiguration");; - private static final FieldDesc FIELD_START_TIME = FieldDesc.of(long.class, Utils.FIELD_START_TIME); + private static final FieldDesc FIELD_START_TIME = FieldDesc.of(long.class, ImplicitFields.START_TIME); private static final ClassDesc ANNOTATION_ENABLED = classDesc(Enabled.class); private static final ClassDesc ANNOTATION_NAME = classDesc(Name.class); private static final ClassDesc ANNOTATION_REGISTERED = classDesc(Registered.class); + private static final ClassDesc ANNOTATION_REMOVE_FIELDS = classDesc(RemoveFields.class); private static final ClassDesc TYPE_EVENT_CONFIGURATION = classDesc(EventConfiguration.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_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"); @@ -106,6 +111,7 @@ private record SettingDesc(ClassDesc paramType, String methodName) { private final List settingDescs; private final List fieldDescs;; private final String eventName; + private final String className; private final Class superClass; private final boolean untypedEventConfiguration; private final MethodDesc staticCommitMethod; @@ -113,15 +119,19 @@ private record SettingDesc(ClassDesc paramType, String methodName) { private final boolean guardEventConfiguration; private final boolean isJDK; private final Map> methodUpdates = new LinkedHashMap<>(); + private final ImplicitFields implicitFields; EventInstrumentation(Class superClass, byte[] bytes, long id, boolean isJDK, boolean guardEventConfiguration) { this.eventTypeId = id; this.superClass = superClass; + this.isJDK = isJDK; this.classModel = createClassModel(bytes); + this.className = classModel.thisClass().asInternalName().replace("/", "."); + String name = annotationValue(classModel, ANNOTATION_NAME, String.class); + this.eventName = name == null ? className : name; + this.implicitFields = determineImplicitFields(); this.settingDescs = buildSettingDescs(superClass, classModel); this.fieldDescs = buildFieldDescs(superClass, classModel); - String n = annotationValue(classModel, ANNOTATION_NAME, String.class); - this.eventName = n == null ? classModel.thisClass().asInternalName().replace("/", ".") : n; this.staticCommitMethod = isJDK ? findStaticCommitMethod(classModel, fieldDescs) : null; this.untypedEventConfiguration = hasUntypedConfiguration(); // Corner case when we are forced to generate bytecode @@ -130,7 +140,23 @@ private record SettingDesc(ClassDesc paramType, String methodName) { // been registered, // so we add a guard against a null reference. this.guardEventConfiguration = guardEventConfiguration; - this.isJDK = isJDK; + } + + private ImplicitFields determineImplicitFields() { + if (isJDK) { + // For now, only support mirror events in java.base + String fullName = "java.base:" + className; + Class eventClass = MirrorEvents.find(fullName); + if (eventClass != null) { + return new ImplicitFields(eventClass); + } + } + ImplicitFields ifs = new ImplicitFields(superClass); + String[] value = annotationValue(classModel, ANNOTATION_REMOVE_FIELDS, String[].class); + if (value != null) { + ifs.removeFields(value); + } + return ifs; } static MethodDesc findStaticCommitMethod(ClassModel classModel, List fields) { @@ -195,8 +221,22 @@ boolean isEnabled() { 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 and Boolean values + // Only supports String, String[] and Boolean values private static T annotationValue(ClassModel classModel, ClassDesc classDesc, Class type) { String typeDescriptor = classDesc.descriptorString(); for (ClassElement ce : classModel.elements()) { @@ -214,6 +254,16 @@ private static T annotationValue(ClassModel classModel, ClassDesc classDesc, String s = ofs.stringValue(); return (T)s; } + if (ae.value() instanceof AnnotationValue.OfArray ofa && type.equals(String[].class)) { + List list = ofa.values(); + String[] array = new String[list.size()]; + int index = 0; + for (AnnotationValue av : list) { + var avs = (AnnotationValue.OfString)av; + array[index++] = avs.stringValue(); + } + return (T)array; + } } } } @@ -287,7 +337,7 @@ private static List buildSettingDescs(Class superClass, ClassMod return settingDescs; } - private static List buildFieldDescs(Class superClass, ClassModel classModel) { + private List buildFieldDescs(Class superClass, ClassModel classModel) { Set fieldSet = new HashSet<>(); List fieldDescs = new ArrayList<>(classModel.fields().size()); // These two fields are added by native as 'transient' so they will be @@ -297,7 +347,9 @@ private static List buildFieldDescs(Class superClass, ClassModel c // in Java, instead of in native. It also means code for adding implicit // fields for native can be reused by Java. fieldDescs.add(FIELD_START_TIME); - fieldDescs.add(FIELD_DURATION); + if (implicitFields.hasDuration()) { + fieldDescs.add(FIELD_DURATION); + } for (FieldModel field : classModel.fields()) { if (!fieldSet.contains(field.fieldName().stringValue()) && isValidField(field.flags().flagsMask(), field.fieldTypeSymbol())) { FieldDesc fi = FieldDesc.of(field.fieldTypeSymbol(), field.fieldName().stringValue()); @@ -368,26 +420,39 @@ public byte[] buildUninstrumented() { return toByteArray(); } + private void throwMissingDuration(CodeBuilder codeBuilder, String method) { + String message = "Cannot use method " + method + " when event lacks duration field"; + Bytecode.throwException(codeBuilder, TYPE_ISE, message); + } + private void makeInstrumented() { // MyEvent#isEnabled() updateEnabledMethod(METHOD_IS_ENABLED); // MyEvent#begin() updateMethod(METHOD_BEGIN, codeBuilder -> { - codeBuilder.aload(0); - invokestatic(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_TIME_STAMP); - putfield(codeBuilder, getEventClassDesc(), FIELD_START_TIME); - codeBuilder.return_(); + if (!implicitFields.hasDuration()) { + throwMissingDuration(codeBuilder, "begin"); + } else { + codeBuilder.aload(0); + invokestatic(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_TIME_STAMP); + putfield(codeBuilder, getEventClassDesc(), FIELD_START_TIME); + codeBuilder.return_(); + } }); // MyEvent#end() updateMethod(METHOD_END, codeBuilder -> { - codeBuilder.aload(0); - codeBuilder.aload(0); - getfield(codeBuilder, getEventClassDesc(), FIELD_START_TIME); - invokestatic(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_DURATION); - putfield(codeBuilder, getEventClassDesc(), FIELD_DURATION); - codeBuilder.return_(); + if (!implicitFields.hasDuration()) { + throwMissingDuration(codeBuilder, "end"); + } else { + codeBuilder.aload(0); + codeBuilder.aload(0); + getfield(codeBuilder, getEventClassDesc(), FIELD_START_TIME); + invokestatic(codeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_DURATION); + putfield(codeBuilder, getEventClassDesc(), FIELD_DURATION); + codeBuilder.return_(); + } }); // MyEvent#commit() or static MyEvent#commit(...) @@ -529,27 +594,33 @@ void updateStaticCommit(BlockCodeBuilder blockCodeBuilder, Label excluded) { // stack: [EW], [EW], [long] slotIndex += tk.slotSize(); invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_LONG.method()); - // stack: [EW] fieldIndex++; - // write duration - blockCodeBuilder.dup(); - // stack: [EW], [EW] - tk = TypeKind.from(argumentTypes[argIndex++]); - blockCodeBuilder.loadInstruction(tk, slotIndex); - // stack: [EW], [EW], [long] - slotIndex += tk.slotSize(); - invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_LONG.method()); // stack: [EW] - fieldIndex++; - // write eventThread - blockCodeBuilder.dup(); - // stack: [EW], [EW] - invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_EVENT_THREAD.method()); + if (implicitFields.hasDuration()) { + // write duration + blockCodeBuilder.dup(); + // stack: [EW], [EW] + tk = TypeKind.from(argumentTypes[argIndex++]); + blockCodeBuilder.loadInstruction(tk, slotIndex); + // stack: [EW], [EW], [long] + slotIndex += tk.slotSize(); + invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_LONG.method()); + fieldIndex++; + } // stack: [EW] - // write stackTrace - blockCodeBuilder.dup(); - // stack: [EW], [EW] - invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_STACK_TRACE.method()); + if (implicitFields.hasEventThread()) { + // write eventThread + blockCodeBuilder.dup(); + // stack: [EW], [EW] + invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_EVENT_THREAD.method()); + } + // stack: [EW] + if (implicitFields.hasStackTrace()) { + // write stackTrace + blockCodeBuilder.dup(); + // stack: [EW], [EW] + invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_STACK_TRACE.method()); + } // stack: [EW] // write custom fields while (fieldIndex < fieldDescs.size()) { @@ -634,24 +705,33 @@ void updateInstanceCommit(BlockCodeBuilder blockCodeBuilder, Label end, Label ex blockCodeBuilder.lload(1); // stack: [EW] [EW] [long] invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_LONG.method()); - // stack: [EW] fieldIndex++; - blockCodeBuilder.dup(); - // stack: [EW] [EW] - blockCodeBuilder.aload(0); - // stack: [EW] [EW] [this] - getfield(blockCodeBuilder, getEventClassDesc(), FIELD_DURATION); - // stack: [EW] [EW] [long] - invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_LONG.method()); // stack: [EW] - fieldIndex++; - blockCodeBuilder.dup(); - // stack: [EW] [EW] - invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_EVENT_THREAD.method()); + if (implicitFields.hasDuration()) { + // write duration + blockCodeBuilder.dup(); + // stack: [EW] [EW] + blockCodeBuilder.aload(0); + // stack: [EW] [EW] [this] + getfield(blockCodeBuilder, getEventClassDesc(), FIELD_DURATION); + // stack: [EW] [EW] [long] + invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_LONG.method()); + fieldIndex++; + } // stack: [EW] - blockCodeBuilder.dup(); - // stack: [EW] [EW] - invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_STACK_TRACE.method()); + if (implicitFields.hasEventThread()) { + // write eventThread + blockCodeBuilder.dup(); + // stack: [EW] [EW] + invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_EVENT_THREAD.method()); + } + // stack: [EW] + if (implicitFields.hasStackTrace()) { + // write stack trace + blockCodeBuilder.dup(); + // stack: [EW] [EW] + invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_STACK_TRACE.method()); + } // stack: [EW] while (fieldIndex < fieldDescs.size()) { FieldDesc field = fieldDescs.get(fieldIndex); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriterMethod.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriterMethod.java index e1cbbb99d5661..530b25573b45b 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriterMethod.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriterMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, 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 @@ -27,7 +27,7 @@ import jdk.jfr.internal.util.Bytecode.FieldDesc; import jdk.jfr.internal.util.Bytecode.MethodDesc; -import jdk.jfr.internal.util.Utils; +import jdk.jfr.internal.util.ImplicitFields; public enum EventWriterMethod { @@ -69,7 +69,7 @@ public MethodDesc method() { */ public static EventWriterMethod lookupMethod(FieldDesc field) { // event thread - if (field.name().equals(Utils.FIELD_EVENT_THREAD)) { + if (field.name().equals(ImplicitFields.EVENT_THREAD)) { return EventWriterMethod.PUT_EVENT_THREAD; } for (EventWriterMethod m : EventWriterMethod.values()) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java index 38ac6a680bf78..25d0e0418f1ac 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMUpcalls.java @@ -112,6 +112,10 @@ static byte[] bytesForEagerInstrumentation(long traceId, boolean forceInstrument 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 MetadataRepository mr = MetadataRepository.getInstance(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index b554fb1aa9223..417238c06f8af 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -34,7 +34,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -58,7 +57,6 @@ public final class MetadataRepository { private final List nativeEventTypes = new ArrayList<>(150); private final List nativeControls = new ArrayList(nativeEventTypes.size()); private final SettingsManager settingsManager = new SettingsManager(); - private final Map> mirrors = new HashMap<>(); private Constructor cachedEventConfigurationConstructor; private boolean staleMetadata = true; private boolean unregistered; @@ -73,8 +71,6 @@ private void initializeJVMEventTypes() { for (Type type : TypeLibrary.getTypes()) { if (type instanceof PlatformEventType pEventType) { EventType eventType = PrivateAccess.getInstance().newEventType(pEventType); - pEventType.setHasDuration(eventType.getAnnotation(Threshold.class) != null); - pEventType.setHasStackTrace(eventType.getAnnotation(StackTrace.class) != null); pEventType.setHasCutoff(eventType.getAnnotation(Cutoff.class) != null); pEventType.setHasThrottle(eventType.getAnnotation(Throttle.class) != null); pEventType.setHasPeriod(eventType.getAnnotation(Period.class) != null); @@ -163,7 +159,7 @@ public synchronized EventType register(Class private PlatformEventType findMirrorType(Class eventClass) throws InternalError { String fullName = eventClass.getModule().getName() + ":" + eventClass.getName(); - Class mirrorClass = mirrors.get(fullName); + Class mirrorClass = MirrorEvents.find(fullName); if (mirrorClass == null) { return null; // not a mirror } @@ -336,16 +332,6 @@ synchronized void setUnregistered() { unregistered = true; } - public synchronized void registerMirror(Class eventClass) { - MirrorEvent me = eventClass.getAnnotation(MirrorEvent.class); - if (me != null) { - String fullName = me.module() + ":" + me.className(); - mirrors.put(fullName, eventClass); - return; - } - throw new InternalError("Mirror class must have annotation " + MirrorEvent.class.getName()); - } - public synchronized void flush() { if (staleMetadata) { storeDescriptorInJVM(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvent.java index eaf3d9b8fcd60..ce5126e3afe6a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, 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 @@ -29,7 +29,10 @@ 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 { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java new file mode 100644 index 0000000000000..9da55247d628c --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MirrorEvents.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016, 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal; + +import java.util.HashMap; +import java.util.Map; + +import jdk.jfr.Event; +import jdk.jfr.events.DeserializationEvent; +import jdk.jfr.events.ProcessStartEvent; +import jdk.jfr.events.SecurityPropertyModificationEvent; +import jdk.jfr.events.SecurityProviderServiceEvent; +import jdk.jfr.events.SocketReadEvent; +import jdk.jfr.events.SocketWriteEvent; +import jdk.jfr.events.TLSHandshakeEvent; +import jdk.jfr.events.ThreadSleepEvent; +import jdk.jfr.events.VirtualThreadEndEvent; +import jdk.jfr.events.VirtualThreadPinnedEvent; +import jdk.jfr.events.VirtualThreadStartEvent; +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, + SocketReadEvent.class, + SocketWriteEvent.class, + ThreadSleepEvent.class, + TLSHandshakeEvent.class, + VirtualThreadStartEvent.class, + VirtualThreadEndEvent.class, + VirtualThreadPinnedEvent.class, + VirtualThreadSubmitFailedEvent.class, + X509CertificateEvent.class, + X509ValidationEvent.class + }; + + private static final Map> mirrorLookup = createLookup(); + + public static Class find(String name) { + // When 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) { + return mirrorLookup.get(name); + } + return null; + } + + @SuppressWarnings("unchecked") + private static Map> createLookup() { + Map> 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) eventClass); + } + return mirrors; + } +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java index 8c087de474fec..e600a0c70fe0c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java @@ -31,6 +31,7 @@ import jdk.jfr.SettingDescriptor; import jdk.jfr.internal.periodic.PeriodicEvents; +import jdk.jfr.internal.util.ImplicitFields; import jdk.jfr.internal.util.Utils; /** * Implementation of event type. @@ -56,8 +57,6 @@ public final class PlatformEventType extends Type { private boolean beginChunk; private boolean endChunk; - private boolean hasStackTrace = true; - private boolean hasDuration = true; private boolean hasPeriod = true; private boolean hasCutoff = false; private boolean hasThrottle = false; @@ -131,14 +130,6 @@ public List getAllSettings() { return settings; } - public void setHasStackTrace(boolean hasStackTrace) { - this.hasStackTrace = hasStackTrace; - } - - public void setHasDuration(boolean hasDuration) { - this.hasDuration = hasDuration; - } - public void setHasCutoff(boolean hasCutoff) { this.hasCutoff = hasCutoff; } @@ -165,11 +156,15 @@ public void setHasPeriod(boolean hasPeriod) { } public boolean hasStackTrace() { - return this.hasStackTrace; + return getField(ImplicitFields.STACK_TRACE) != null; } - public boolean hasDuration() { - return this.hasDuration; + public boolean hasThreshold() { + if (hasCutoff) { + // Event has a duration, but not a threshold. Used by OldObjectSample + return false; + } + return getField(ImplicitFields.DURATION) != null; } public boolean hasPeriod() { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java index 1215cfa29dbac..1cd7297928630 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java @@ -482,7 +482,6 @@ private void writeMetaEvents() { Duration rDuration = r.getDuration(); ActiveRecordingEvent.commit( timestamp, - 0L, r.getId(), r.getName(), path == null ? null : path.getRealPathText(), diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/RemoveFields.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/RemoveFields.java new file mode 100644 index 0000000000000..92086f6734ce3 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/RemoveFields.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation that can remove the fields "duration", "eventThread" and + * "stackTrace". + *

+ * Example usage: + * {@snippet : + * @RemoveFields({{"duration", "stackTrace"} + * class NonThreadEvent extends Event { + * } + * } + * + *

+ * Calling Event::begin() or Event:end() on an event without a duration field + * will result in an {@code IllegalStateException} + **/ +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface RemoveFields { + String[] value() default {}; +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java index 2866646b1d60a..68888967899b5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/SecuritySupport.java @@ -334,10 +334,6 @@ public static void registerEvent(Class event doPrivileged(() -> MetadataRepository.getInstance().register(eventClass), new FlightRecorderPermission(REGISTER_EVENT)); } - public static void registerMirror(Class eventClass) { - doPrivileged(() -> MetadataRepository.getInstance().registerMirror(eventClass), new FlightRecorderPermission(REGISTER_EVENT)); - } - public static void setProperty(String propertyName, String value) { doPrivileged(() -> System.setProperty(propertyName, value), new PropertyPermission(propertyName, "write")); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java index d858c56354e60..0a1f1c05dee57 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/TypeLibrary.java @@ -59,6 +59,7 @@ import jdk.jfr.Timestamp; import jdk.jfr.ValueDescriptor; import jdk.jfr.internal.util.Utils; +import jdk.jfr.internal.util.ImplicitFields; public final class TypeLibrary { private static boolean implicitFieldTypes; @@ -76,26 +77,26 @@ private TypeLibrary() { private static ValueDescriptor createStartTimeField() { var annos = createStandardAnnotations("Start Time", null); annos.add(new jdk.jfr.AnnotationElement(Timestamp.class, Timestamp.TICKS)); - return PrivateAccess.getInstance().newValueDescriptor(Utils.FIELD_START_TIME, Type.LONG, annos, 0, false, - Utils.FIELD_START_TIME); + return PrivateAccess.getInstance().newValueDescriptor(ImplicitFields.START_TIME, Type.LONG, annos, 0, false, + ImplicitFields.START_TIME); } private static ValueDescriptor createStackTraceField() { var annos = createStandardAnnotations("Stack Trace", "Stack Trace starting from the method the event was committed in"); - return PrivateAccess.getInstance().newValueDescriptor(Utils.FIELD_STACK_TRACE, Type.STACK_TRACE, annos, 0, true, - Utils.FIELD_STACK_TRACE); + return PrivateAccess.getInstance().newValueDescriptor(ImplicitFields.STACK_TRACE, Type.STACK_TRACE, annos, 0, true, + ImplicitFields.STACK_TRACE); } private static ValueDescriptor createThreadField() { var annos = createStandardAnnotations("Event Thread", "Thread in which event was committed in"); - return PrivateAccess.getInstance().newValueDescriptor(Utils.FIELD_EVENT_THREAD, Type.THREAD, annos, 0, true, - Utils.FIELD_EVENT_THREAD); + return PrivateAccess.getInstance().newValueDescriptor(ImplicitFields.EVENT_THREAD, Type.THREAD, annos, 0, true, + ImplicitFields.EVENT_THREAD); } private static ValueDescriptor createDurationField() { var annos = createStandardAnnotations("Duration", null); annos.add(new jdk.jfr.AnnotationElement(Timespan.class, Timespan.TICKS)); - return PrivateAccess.getInstance().newValueDescriptor(Utils.FIELD_DURATION, Type.LONG, annos, 0, false, Utils.FIELD_DURATION); + return PrivateAccess.getInstance().newValueDescriptor(ImplicitFields.DURATION, Type.LONG, annos, 0, false, ImplicitFields.DURATION); } public static synchronized void initialize() { @@ -266,7 +267,8 @@ public static synchronized Type createType(Class clazz, List[] mirrorEventClasses = { - DeserializationEvent.class, - ProcessStartEvent.class, - SecurityPropertyModificationEvent.class, - SecurityProviderServiceEvent.class, - SocketReadEvent.class, - SocketWriteEvent.class, - ThreadSleepEvent.class, - TLSHandshakeEvent.class, - VirtualThreadStartEvent.class, - VirtualThreadEndEvent.class, - VirtualThreadPinnedEvent.class, - VirtualThreadSubmitFailedEvent.class, - X509CertificateEvent.class, - X509ValidationEvent.class - }; private static final Class[] eventClasses = { FileForceEvent.class, @@ -98,6 +71,8 @@ public final class JDKEvents { ErrorThrownEvent.class, ActiveSettingEvent.class, ActiveRecordingEvent.class, + // jdk.internal.event.* classes need their mirror + // event class to be listed in the MirrorEvents class. jdk.internal.event.DeserializationEvent.class, jdk.internal.event.ProcessStartEvent.class, jdk.internal.event.SecurityPropertyModificationEvent.class, @@ -112,7 +87,6 @@ public final class JDKEvents { jdk.internal.event.VirtualThreadSubmitFailedEvent.class, jdk.internal.event.X509CertificateEvent.class, jdk.internal.event.X509ValidationEvent.class, - DirectBufferStatisticsEvent.class, InitialSecurityPropertyEvent.class, }; @@ -141,9 +115,6 @@ public final class JDKEvents { public static synchronized void initialize() { try { if (initializationTriggered == false) { - for (Class mirrorEventClass : mirrorEventClasses) { - SecuritySupport.registerMirror(((Class)mirrorEventClass)); - } for (Class eventClass : eventClasses) { SecuritySupport.registerEvent((Class) eventClass); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.java index 7a4c6273978d1..94a4543693873 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/ThrowableTracer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, 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 @@ -44,11 +44,11 @@ public static void traceError(Error e, String message) { EventConfiguration eventConfiguration1 = EventConfigurations.ERROR_THROWN; if (eventConfiguration1.isEnabled()) { - ErrorThrownEvent.commit(timestamp, 0L, message, e.getClass()); + ErrorThrownEvent.commit(timestamp, message, e.getClass()); } EventConfiguration eventConfiguration2 = EventConfigurations.EXCEPTION_THROWN; if (eventConfiguration2.isEnabled()) { - ExceptionThrownEvent.commit(timestamp, 0L, message, e.getClass()); + ExceptionThrownEvent.commit(timestamp, message, e.getClass()); } numThrowables.incrementAndGet(); } @@ -57,7 +57,7 @@ public static void traceThrowable(Throwable t, String message) { EventConfiguration eventConfiguration = EventConfigurations.EXCEPTION_THROWN; if (eventConfiguration.isEnabled()) { long timestamp = EventConfiguration.timestamp(); - ExceptionThrownEvent.commit(timestamp, 0L, message, t.getClass()); + ExceptionThrownEvent.commit(timestamp, message, t.getClass()); } numThrowables.incrementAndGet(); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ImplicitFields.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ImplicitFields.java new file mode 100644 index 0000000000000..8e302f8542f60 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ImplicitFields.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.internal.util; + +import java.util.ArrayList; +import java.util.List; + +import jdk.jfr.internal.RemoveFields; +/** + * Class that describes fields that was not directly named + * in the event definition. + */ +public final class ImplicitFields { + public static final String START_TIME = "startTime"; + public static final String DURATION = "duration"; + public static final String EVENT_THREAD = "eventThread"; + public static final String STACK_TRACE = "stackTrace"; + + private final List fields = new ArrayList<>(4); + + public ImplicitFields(Class eventClass) { + fields.add(START_TIME); // for completeness, not really needed + fields.add(DURATION); + fields.add(STACK_TRACE); + fields.add(EVENT_THREAD); + for (Class c = eventClass; jdk.internal.event.Event.class != c; c = c.getSuperclass()) { + RemoveFields rf = c.getAnnotation(RemoveFields.class); + if (rf != null) { + for (String value : rf.value()) { + fields.remove(value); + } + } + } + } + public void removeFields(String... fieldNames) { + for (String fieldName : fieldNames) { + fields.remove(fieldName); + } + } + + public boolean hasDuration() { + return fields.contains(DURATION); + } + + public boolean hasEventThread() { + return fields.contains(EVENT_THREAD); + } + + public boolean hasStackTrace() { + return fields.contains(STACK_TRACE); + } +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java index 4be05abca08a0..1b73971298579 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java @@ -56,11 +56,6 @@ import jdk.jfr.internal.settings.ThresholdSetting; public final class Utils { - public static final String FIELD_DURATION = "duration"; - public static final String FIELD_STACK_TRACE = "stackTrace"; - public static final String FIELD_START_TIME = "startTime"; - public static final String FIELD_EVENT_THREAD = "eventThread"; - private static final Object flushObject = new Object(); private static final String LEGACY_EVENT_NAME_PREFIX = "com.oracle.jdk."; diff --git a/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java b/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java index dd160881d2edd..e5d90e4b80bca 100644 --- a/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java +++ b/test/jdk/jdk/jfr/api/recording/settings/TestSettingsAvailability.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, 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 @@ -94,9 +94,9 @@ private static void testKnownSettings() throws Exception { testSetting(EventNames.ExceptionStatistics, "enabled", "period"); testSetting(EventNames.SocketRead, "enabled", "threshold", "stackTrace"); testSetting(EventNames.SocketWrite, "enabled", "threshold", "stackTrace"); - testSetting(EventNames.ActiveRecording, "enabled", "threshold", "stackTrace"); - testSetting(EventNames.ActiveSetting, "enabled", "threshold", "stackTrace"); - testSetting(EventNames.JavaExceptionThrow, "enabled", "threshold", "stackTrace"); + testSetting(EventNames.ActiveRecording, "enabled"); + testSetting(EventNames.ActiveSetting, "enabled"); + testSetting(EventNames.JavaExceptionThrow, "enabled", "stackTrace"); } private static void testSetting(String eventName, String... settingNames) throws Exception { diff --git a/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java b/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java index 57b63316da75a..3b8b0d975eb6f 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java +++ b/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, 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 @@ -162,44 +162,9 @@ private static Document createDocument(String content) throws ParserConfiguratio DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(new InputSource(new StringReader(content))); doc.getDocumentElement().normalize(); - // Don't want to add these settings to the jfc-files we ship since they - // are not useful to configure. They are however needed to make the test - // pass. - insertSetting(doc, EventNames.ActiveSetting, "stackTrace", "false"); - insertSetting(doc, EventNames.ActiveSetting, "threshold", "0 ns"); - insertSetting(doc, EventNames.ActiveRecording, "stackTrace", "false"); - insertSetting(doc, EventNames.ActiveRecording, "threshold", "0 ns"); - insertSetting(doc, EventNames.JavaExceptionThrow, "threshold", "0 ns"); - insertSetting(doc, EventNames.JavaErrorThrow, "threshold", "0 ns"); - insertSetting(doc, EventNames.SecurityProperty, "threshold", "0 ns"); - insertSetting(doc, EventNames.SecurityProviderService, "threshold", "0 ns"); - insertSetting(doc, EventNames.TLSHandshake, "threshold", "0 ns"); - insertSetting(doc, EventNames.X509Certificate, "threshold", "0 ns"); - insertSetting(doc, EventNames.X509Validation, "threshold", "0 ns"); - insertSetting(doc, EventNames.ProcessStart, "threshold", "0 ns"); - insertSetting(doc, EventNames.Deserialization, "threshold", "0 ns"); - insertSetting(doc, EventNames.VirtualThreadStart, "threshold", "0 ns"); - insertSetting(doc, EventNames.VirtualThreadEnd, "threshold", "0 ns"); - insertSetting(doc, EventNames.VirtualThreadEnd, "stackTrace", "false"); - insertSetting(doc, EventNames.VirtualThreadSubmitFailed, "threshold", "0 ns"); - return doc; } - private static void insertSetting(Document doc, String eventName, String settingName, String settingValue) { - for (Element event : getChildElements(doc.getDocumentElement(), "event")) { - Attr attribute = event.getAttributeNode("name"); - if (attribute != null) { - if (eventName.equals(attribute.getValue())) { - Element setting = doc.createElement("setting"); - setting.setAttribute("name", settingName); - setting.setTextContent(settingValue); - event.appendChild(setting); - } - } - } - } - private static Collection getChildElements(Element parent, String name) { NodeList elementsByTagName = parent.getElementsByTagName(name); List elements = new ArrayList<>();