8360287: JFR: PlatformTracer class should be loaded lazily

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2025-06-26 22:18:56 +00:00
parent 334683e634
commit 8ea544c33f
4 changed files with 64 additions and 13 deletions

View File

@ -45,6 +45,7 @@ import jdk.jfr.events.InitialSecurityPropertyEvent;
import jdk.jfr.events.MethodTimingEvent;
import jdk.jfr.events.MethodTraceEvent;
import jdk.jfr.internal.periodic.PeriodicEvents;
import jdk.jfr.internal.settings.MethodSetting;
import jdk.jfr.internal.tracing.PlatformTracer;
import jdk.jfr.tracing.MethodTracer;
@ -235,7 +236,7 @@ public final class JDKEvents {
}
private static void emitMethodTiming() {
if (MethodTimingEvent.enabled()) {
if (MethodSetting.isInitialized() && MethodTimingEvent.enabled()) {
PlatformTracer.emitTiming();
}
}

View File

@ -42,6 +42,7 @@ import jdk.jfr.internal.tracing.PlatformTracer;
@Name(Type.SETTINGS_PREFIX + "Filter")
public final class MethodSetting extends FilterSetting {
private final Modification modification;
private volatile static boolean initialized;
public MethodSetting(PlatformEventType eventType, Modification modification, String defaultValue) {
super(eventType, defaultValue);
@ -55,6 +56,20 @@ public final class MethodSetting extends FilterSetting {
@Override
protected void apply(PlatformEventType eventType, List<String> filters) {
ensureInitialized();
PlatformTracer.setFilters(modification, filters);
}
// Expected to be called when holding external lock, so no extra
// synchronization is required here.
private static void ensureInitialized() {
if (!initialized) {
PlatformTracer.initialize();
initialized = true;
}
}
public static boolean isInitialized() {
return initialized;
}
}

View File

@ -53,8 +53,6 @@ public final class PlatformTracer {
private static List<Filter> timingFilters = List.of();
private static TimedMethod OBJECT;
private static boolean initialized;
public static byte[] onMethodTrace(Module module, ClassLoader classLoader, String className,
byte[] oldBytecode, long[] ids, String[] names, String[] signatures,
int[] modifications) {
@ -159,7 +157,6 @@ public final class PlatformTracer {
}
public static void setFilters(Modification modification, List<String> filters) {
ensureInitialized();
publishClasses(applyFilter(modification, filters));
}
@ -252,14 +249,6 @@ public final class PlatformTracer {
timedClasses.clear();
}
// Expected to be called when holding external lock, so no extra
// synchronization is required here.
private static void ensureInitialized() {
if (!initialized) {
initialize();
initialized = true;
}
}
// This method has three purposes:
//
@ -274,7 +263,7 @@ public final class PlatformTracer {
// This method takes 1-10 milliseconds to run and is only executed once,
// provided a user has specified a non-empty filter for the MethodTrace or
// MethodTiming event.
private static void initialize() {
public static void initialize() {
try {
Logger.log(LogTag.JFR_METHODTRACE, LogLevel.DEBUG, "Method tracer initialization started.");
Thread current = Thread.currentThread();

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2025, 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.
*
* 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.event.tracing;
import jdk.internal.misc.Unsafe;
import jdk.jfr.FlightRecorder;
import jdk.jfr.Recording;
/**
* @test
* @summary Tests that PlatformTracer is not initialized if a method filter has not been set.
* @requires vm.flagless
* @requires vm.hasJFR
* @modules java.base/jdk.internal.misc jdk.jfr/jdk.jfr.internal.tracing
* @library /test/lib
* @run main/othervm -XX:StartFlightRecording jdk.jfr.event.tracing.TestLazyPlatformTracer
*/
public class TestLazyPlatformTracer {
public static void main(String... args) throws Exception {
// Stop recording so end chunk events are emitted
FlightRecorder.getFlightRecorder().getRecordings().getFirst().stop();
if (!Unsafe.getUnsafe().shouldBeInitialized(jdk.jfr.internal.tracing.PlatformTracer.class)) {
throw new AssertionError("PlatformTracer should not have been initialized");
}
}
}