From 78af0c17547eab5d2d61794d806b8b63a02770db Mon Sep 17 00:00:00 2001 From: prithvi Date: Sat, 25 Apr 2026 03:17:46 +0530 Subject: [PATCH 1/6] GITHUB#15926: Support jdk.CPUTimeSample in ProfileResults for Java 25+ (JEP 509) --- .../gradle/plugins/java/ProfileResults.java | 35 +++++++++++++++++-- gradle/testing/profiling.jfc | 5 +++ lucene/CHANGES.txt | 5 +++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java index 802cef5f6d55..656d9057a0e2 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java @@ -101,10 +101,16 @@ public static void main(String[] args) throws IOException { } /** true if we care about this event */ - static boolean isInteresting(String mode, RecordedEvent event) { + static boolean isInteresting(String mode, RecordedEvent event, boolean hasCPUTimeSamples) { String name = event.getEventType().getName(); switch (mode) { case "cpu": + if (hasCPUTimeSamples) { + // Prefer jdk.CPUTimeSample (Java 25+, JEP 509): samples by CPU time, not wall-clock + // time, so idle threads (like gradle epoll) are inherently excluded — no filtering + // needed. When available, we skip legacy execution samples to avoid double-counting. + return name.equals("jdk.CPUTimeSample"); + } return (name.equals("jdk.ExecutionSample") || name.equals("jdk.NativeMethodSample")) && !isGradlePollThread(event.getThread("sampledThread")); case "heap": @@ -121,6 +127,24 @@ static boolean isGradlePollThread(RecordedThread thread) { return (thread != null && thread.getJavaName().startsWith("/127.0.0.1")); } + /** + * Pre-scan recording files to detect if any jdk.CPUTimeSample events are present. When they are, + * we prefer them over legacy jdk.ExecutionSample/jdk.NativeMethodSample to avoid double-counting. + */ + static boolean detectCPUTimeSamples(List files) throws IOException { + for (String file : files) { + try (RecordingFile recording = new RecordingFile(Paths.get(file))) { + while (recording.hasMoreEvents()) { + RecordedEvent event = recording.readEvent(); + if (event.getEventType().getName().equals("jdk.CPUTimeSample")) { + return true; + } + } + } + } + return false; + } + /** value we accumulate for this event */ static long getValue(RecordedEvent event) { switch (event.getEventType().getName()) { @@ -132,6 +156,8 @@ static long getValue(RecordedEvent event) { return 1L; case "jdk.NativeMethodSample": return 1L; + case "jdk.CPUTimeSample": + return 1L; default: throw new UnsupportedOperationException(event.toString()); } @@ -173,6 +199,11 @@ public static void printReport( if (count < 1) { throw new IllegalArgumentException("tests.profile.count must be positive"); } + + // Pre-scan to detect if CPU-time samples (Java 25+, JEP 509) are available. + // If so, prefer them over legacy execution samples to avoid double-counting. + boolean hasCPUTimeSamples = "cpu".equals(mode) && detectCPUTimeSamples(files); + Map> histogram = new HashMap<>(); int totalEvents = 0; long sumValues = 0; @@ -181,7 +212,7 @@ public static void printReport( try (RecordingFile recording = new RecordingFile(Paths.get(file))) { while (recording.hasMoreEvents()) { RecordedEvent event = recording.readEvent(); - if (!isInteresting(mode, event)) { + if (!isInteresting(mode, event, hasCPUTimeSamples)) { continue; } RecordedStackTrace trace = event.getStackTrace(); diff --git a/gradle/testing/profiling.jfc b/gradle/testing/profiling.jfc index d2b95b26d60f..5fb86a0f2ecd 100644 --- a/gradle/testing/profiling.jfc +++ b/gradle/testing/profiling.jfc @@ -29,6 +29,11 @@ Collects only execution and method samples at a low interval 1 ms + + true + 10 ms + + true true diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 278a4ae28b79..e6155f0afdb5 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -187,6 +187,11 @@ Changes in Runtime Behavior Build --------------------- +* GITHUB#15926: Support jdk.CPUTimeSample event (Java 25+, JEP 509) in ProfileResults. + CPU-time profiling produces more accurate profiles by sampling CPU instructions instead + of wall-clock time. When CPUTimeSample events are present, they are preferred over legacy + ExecutionSample events to avoid double-counting. (Prithvi) + * GITHUB#15327: New low-level build options to detect abuse of LuceneTestCase.random(): tests.random.maxacquires and tests.random.maxcalls (Robert Muir, Dawid Weiss) From 254196da6d4d14103d08a7267f2520202d4e7ac9 Mon Sep 17 00:00:00 2001 From: prithvi Date: Sat, 25 Apr 2026 03:30:05 +0530 Subject: [PATCH 2/6] Updated CHANGES.txt --- lucene/CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index b432fdf5d227..dc139eca2999 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -188,7 +188,7 @@ Build * GITHUB#15926: Support jdk.CPUTimeSample event (Java 25+, JEP 509) in ProfileResults. CPU-time profiling produces more accurate profiles by sampling CPU instructions instead of wall-clock time. When CPUTimeSample events are present, they are preferred over legacy - ExecutionSample events to avoid double-counting. (Prithvi) + ExecutionSample events to avoid double-counting. (Prithvi S) * GITHUB#15327: New low-level build options to detect abuse of LuceneTestCase.random(): tests.random.maxacquires and tests.random.maxcalls (Robert Muir, Dawid Weiss) From 5125d0e95f84da8e544f15ab7a660eb5f739f6ee Mon Sep 17 00:00:00 2001 From: prithvi Date: Tue, 28 Apr 2026 02:44:07 +0530 Subject: [PATCH 3/6] review changes Signed-off-by: prithvi --- .../plugins/java/CodeProfilingPlugin.java | 15 +++++++- .../gradle/plugins/java/ProfileResults.java | 35 +++++++++++++------ gradle/testing/profiling.jfc | 9 ++--- lucene/CHANGES.txt | 6 ++-- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java index 8c428d167fe2..46df74b69a10 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.util.List; +import java.util.Locale; import org.apache.lucene.gradle.plugins.LuceneGradlePlugin; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; @@ -91,6 +92,8 @@ public void run() { getCount().get(), getLineNumbers().get(), getFrametypes().get()); + } catch (IllegalStateException e) { + throw new GradleException(e.getMessage(), e); } catch (IOException e) { throw new GradleException("Error when generating jfr profile summaries.", e); } @@ -189,7 +192,7 @@ public void apply(Project project) { task.jvmArgs( List.of( "-XX:StartFlightRecording=dumponexit=true,maxsize=250M,settings=" - + gradlePluginResource(project, "testing/profiling.jfc"), + + gradlePluginResource(project, profilingSettingsPath()), "-XX:+UnlockDiagnosticVMOptions", "-XX:+DebugNonSafepoints")); task.dependsOn(cleanPreviousProfiles); @@ -254,4 +257,14 @@ private record ProfilingOptions( Provider countOption, Provider lineNumbersOption, Provider frametypesOption) {} + + /** + * JEP 509 CPU-time sampling ({@code jdk.CPUTimeSample}) is implemented on Linux. Use a Linux-only + * JFR template with CPU-time sampling only; other hosts keep wall-clock execution sampling for + * short tests. + */ + private static String profilingSettingsPath() { + String os = System.getProperty("os.name", "").toLowerCase(Locale.ROOT); + return os.contains("linux") ? "testing/profiling.linux.jfc" : "testing/profiling.jfc"; + } } diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java index 656d9057a0e2..b6fafe62b282 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java @@ -107,8 +107,9 @@ static boolean isInteresting(String mode, RecordedEvent event, boolean hasCPUTim case "cpu": if (hasCPUTimeSamples) { // Prefer jdk.CPUTimeSample (Java 25+, JEP 509): samples by CPU time, not wall-clock - // time, so idle threads (like gradle epoll) are inherently excluded — no filtering - // needed. When available, we skip legacy execution samples to avoid double-counting. + // time, so idle threads (like gradle epoll) are inherently excluded; no filtering + // needed. When present, we ignore jdk.ExecutionSample and jdk.NativeMethodSample + // (wall-clock / JNI execution sampling) so the same hot code is not double-counted. return name.equals("jdk.CPUTimeSample"); } return (name.equals("jdk.ExecutionSample") || name.equals("jdk.NativeMethodSample")) @@ -128,21 +129,34 @@ static boolean isGradlePollThread(RecordedThread thread) { } /** - * Pre-scan recording files to detect if any jdk.CPUTimeSample events are present. When they are, - * we prefer them over legacy jdk.ExecutionSample/jdk.NativeMethodSample to avoid double-counting. + * Pre-scan recording files for CPU sampling strategy. Returns whether any {@code + * jdk.CPUTimeSample} events appear in the inputs. Throws if recordings mix those with legacy + * wall-clock samples ({@code jdk.ExecutionSample} / {@code jdk.NativeMethodSample}); only one + * CPU sampler should be enabled in JFR settings. */ - static boolean detectCPUTimeSamples(List files) throws IOException { + static boolean resolveCpuTimeSampling(List files) throws IOException { + boolean hasCpuTime = false; + boolean hasLegacy = false; for (String file : files) { try (RecordingFile recording = new RecordingFile(Paths.get(file))) { while (recording.hasMoreEvents()) { RecordedEvent event = recording.readEvent(); - if (event.getEventType().getName().equals("jdk.CPUTimeSample")) { - return true; + String n = event.getEventType().getName(); + if (n.equals("jdk.CPUTimeSample")) { + hasCpuTime = true; + } else if (n.equals("jdk.ExecutionSample") || n.equals("jdk.NativeMethodSample")) { + hasLegacy = true; + } + if (hasCpuTime && hasLegacy) { + throw new IllegalStateException( + "Mixed CPU profiling events: found both jdk.CPUTimeSample and legacy wall-clock " + + "samples (jdk.ExecutionSample / jdk.NativeMethodSample). Use a single sampler " + + "in JFR settings (see gradle/testing/profiling*.jfc)."); } } } } - return false; + return hasCpuTime; } /** value we accumulate for this event */ @@ -200,9 +214,8 @@ public static void printReport( throw new IllegalArgumentException("tests.profile.count must be positive"); } - // Pre-scan to detect if CPU-time samples (Java 25+, JEP 509) are available. - // If so, prefer them over legacy execution samples to avoid double-counting. - boolean hasCPUTimeSamples = "cpu".equals(mode) && detectCPUTimeSamples(files); + // Pre-scan recordings: decide CPU-time vs legacy sampling and reject mixed configurations. + boolean hasCPUTimeSamples = "cpu".equals(mode) && resolveCpuTimeSampling(files); Map> histogram = new HashMap<>(); int totalEvents = 0; diff --git a/gradle/testing/profiling.jfc b/gradle/testing/profiling.jfc index 5fb86a0f2ecd..565457d385b7 100644 --- a/gradle/testing/profiling.jfc +++ b/gradle/testing/profiling.jfc @@ -16,7 +16,9 @@ limitations under the License. --> @@ -29,11 +31,6 @@ Collects only execution and method samples at a low interval 1 ms - - true - 10 ms - - true true diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index dc139eca2999..65dfe628f865 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -186,9 +186,9 @@ Changes in Runtime Behavior Build --------------------- * GITHUB#15926: Support jdk.CPUTimeSample event (Java 25+, JEP 509) in ProfileResults. - CPU-time profiling produces more accurate profiles by sampling CPU instructions instead - of wall-clock time. When CPUTimeSample events are present, they are preferred over legacy - ExecutionSample events to avoid double-counting. (Prithvi S) + Linux test JVMs use gradle/testing/profiling.linux.jfc (CPU-time sampling only); other hosts + keep wall-clock jdk.ExecutionSample/jdk.NativeMethodSample. ProfileResults rejects recordings + that mix CPU-time and legacy execution samples. (Prithvi S) * GITHUB#15327: New low-level build options to detect abuse of LuceneTestCase.random(): tests.random.maxacquires and tests.random.maxcalls (Robert Muir, Dawid Weiss) From d076437a420c798832488fd8677f1a89fc8834ec Mon Sep 17 00:00:00 2001 From: prithvi Date: Tue, 28 Apr 2026 12:04:52 +0530 Subject: [PATCH 4/6] review changes Signed-off-by: prithvi --- .../plugins/java/CodeProfilingPlugin.java | 2 - .../gradle/plugins/java/ProfileResults.java | 55 ++++--------------- gradle/testing/profiling.linux.jfc | 46 ++++++++++++++++ lucene/CHANGES.txt | 4 +- 4 files changed, 59 insertions(+), 48 deletions(-) create mode 100644 gradle/testing/profiling.linux.jfc diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java index 46df74b69a10..7505613d3671 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java @@ -92,8 +92,6 @@ public void run() { getCount().get(), getLineNumbers().get(), getFrametypes().get()); - } catch (IllegalStateException e) { - throw new GradleException(e.getMessage(), e); } catch (IOException e) { throw new GradleException("Error when generating jfr profile summaries.", e); } diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java index b6fafe62b282..cf16432b4b30 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java @@ -101,19 +101,20 @@ public static void main(String[] args) throws IOException { } /** true if we care about this event */ - static boolean isInteresting(String mode, RecordedEvent event, boolean hasCPUTimeSamples) { + static boolean isInteresting(String mode, RecordedEvent event) { String name = event.getEventType().getName(); switch (mode) { case "cpu": - if (hasCPUTimeSamples) { - // Prefer jdk.CPUTimeSample (Java 25+, JEP 509): samples by CPU time, not wall-clock - // time, so idle threads (like gradle epoll) are inherently excluded; no filtering - // needed. When present, we ignore jdk.ExecutionSample and jdk.NativeMethodSample - // (wall-clock / JNI execution sampling) so the same hot code is not double-counted. - return name.equals("jdk.CPUTimeSample"); + // jdk.CPUTimeSample: JEP 509 (e.g. gradle/testing/profiling.linux.jfc). Legacy samples: + // jdk.ExecutionSample / jdk.NativeMethodSample (e.g. profiling.jfc). Stock Lucene configs + // enable one family; filter gradle poll thread for legacy samples only. + if (name.equals("jdk.CPUTimeSample")) { + return true; } - return (name.equals("jdk.ExecutionSample") || name.equals("jdk.NativeMethodSample")) - && !isGradlePollThread(event.getThread("sampledThread")); + if (name.equals("jdk.ExecutionSample") || name.equals("jdk.NativeMethodSample")) { + return !isGradlePollThread(event.getThread("sampledThread")); + } + return false; case "heap": return (name.equals("jdk.ObjectAllocationInNewTLAB") || name.equals("jdk.ObjectAllocationOutsideTLAB")) @@ -128,37 +129,6 @@ static boolean isGradlePollThread(RecordedThread thread) { return (thread != null && thread.getJavaName().startsWith("/127.0.0.1")); } - /** - * Pre-scan recording files for CPU sampling strategy. Returns whether any {@code - * jdk.CPUTimeSample} events appear in the inputs. Throws if recordings mix those with legacy - * wall-clock samples ({@code jdk.ExecutionSample} / {@code jdk.NativeMethodSample}); only one - * CPU sampler should be enabled in JFR settings. - */ - static boolean resolveCpuTimeSampling(List files) throws IOException { - boolean hasCpuTime = false; - boolean hasLegacy = false; - for (String file : files) { - try (RecordingFile recording = new RecordingFile(Paths.get(file))) { - while (recording.hasMoreEvents()) { - RecordedEvent event = recording.readEvent(); - String n = event.getEventType().getName(); - if (n.equals("jdk.CPUTimeSample")) { - hasCpuTime = true; - } else if (n.equals("jdk.ExecutionSample") || n.equals("jdk.NativeMethodSample")) { - hasLegacy = true; - } - if (hasCpuTime && hasLegacy) { - throw new IllegalStateException( - "Mixed CPU profiling events: found both jdk.CPUTimeSample and legacy wall-clock " - + "samples (jdk.ExecutionSample / jdk.NativeMethodSample). Use a single sampler " - + "in JFR settings (see gradle/testing/profiling*.jfc)."); - } - } - } - } - return hasCpuTime; - } - /** value we accumulate for this event */ static long getValue(RecordedEvent event) { switch (event.getEventType().getName()) { @@ -214,9 +184,6 @@ public static void printReport( throw new IllegalArgumentException("tests.profile.count must be positive"); } - // Pre-scan recordings: decide CPU-time vs legacy sampling and reject mixed configurations. - boolean hasCPUTimeSamples = "cpu".equals(mode) && resolveCpuTimeSampling(files); - Map> histogram = new HashMap<>(); int totalEvents = 0; long sumValues = 0; @@ -225,7 +192,7 @@ public static void printReport( try (RecordingFile recording = new RecordingFile(Paths.get(file))) { while (recording.hasMoreEvents()) { RecordedEvent event = recording.readEvent(); - if (!isInteresting(mode, event, hasCPUTimeSamples)) { + if (!isInteresting(mode, event)) { continue; } RecordedStackTrace trace = event.getStackTrace(); diff --git a/gradle/testing/profiling.linux.jfc b/gradle/testing/profiling.linux.jfc new file mode 100644 index 000000000000..9190eb9771b7 --- /dev/null +++ b/gradle/testing/profiling.linux.jfc @@ -0,0 +1,46 @@ + + + + + + false + + + + false + + + + true + 1 ms + + + + true + true + + + + true + true + + diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index b45566c78a80..98892486bdc7 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -187,8 +187,8 @@ Build --------------------- * GITHUB#15926: Support jdk.CPUTimeSample event (Java 25+, JEP 509) in ProfileResults. Linux test JVMs use gradle/testing/profiling.linux.jfc (CPU-time sampling only); other hosts - keep wall-clock jdk.ExecutionSample/jdk.NativeMethodSample. ProfileResults rejects recordings - that mix CPU-time and legacy execution samples. (Prithvi S) + keep wall-clock jdk.ExecutionSample/jdk.NativeMethodSample. CodeProfilingPlugin selects the + JFR settings file by host OS. (Prithvi S) * GITHUB#15327: New low-level build options to detect abuse of LuceneTestCase.random(): tests.random.maxacquires and tests.random.maxcalls (Robert Muir, Dawid Weiss) From 30d45102aae561903b1ce0139d2d74350b732d72 Mon Sep 17 00:00:00 2001 From: prithvi Date: Tue, 28 Apr 2026 20:03:13 +0530 Subject: [PATCH 5/6] review changes Signed-off-by: prithvi --- .../gradle/plugins/java/CodeProfilingPlugin.java | 9 +++++---- .../lucene/gradle/plugins/java/ProfileResults.java | 2 +- .../{profiling.linux.jfc => profiling.cputime.jfc} | 13 +++++++++---- gradle/testing/profiling.jfc | 4 ++-- lucene/CHANGES.txt | 8 ++++---- 5 files changed, 21 insertions(+), 15 deletions(-) rename gradle/testing/{profiling.linux.jfc => profiling.cputime.jfc} (70%) diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java index 7505613d3671..33b25b289ea1 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/CodeProfilingPlugin.java @@ -257,12 +257,13 @@ private record ProfilingOptions( Provider frametypesOption) {} /** - * JEP 509 CPU-time sampling ({@code jdk.CPUTimeSample}) is implemented on Linux. Use a Linux-only - * JFR template with CPU-time sampling only; other hosts keep wall-clock execution sampling for - * short tests. + * Java 25+ JEP 509 ({@code jdk.CPUTimeSample}) is currently implemented only on Linux in the JDK. + * When the Gradle host is Linux, use {@code testing/profiling.cputime.jfc} (CPU-time sampling + * only). Otherwise use {@code testing/profiling.jfc} (legacy wall-clock execution sampling). Host + * selection may broaden if CPU-time sampling is supported on other OS releases later. */ private static String profilingSettingsPath() { String os = System.getProperty("os.name", "").toLowerCase(Locale.ROOT); - return os.contains("linux") ? "testing/profiling.linux.jfc" : "testing/profiling.jfc"; + return os.contains("linux") ? "testing/profiling.cputime.jfc" : "testing/profiling.jfc"; } } diff --git a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java index cf16432b4b30..0acdb48df636 100644 --- a/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java +++ b/build-tools/build-infra/src/main/java/org/apache/lucene/gradle/plugins/java/ProfileResults.java @@ -105,7 +105,7 @@ static boolean isInteresting(String mode, RecordedEvent event) { String name = event.getEventType().getName(); switch (mode) { case "cpu": - // jdk.CPUTimeSample: JEP 509 (e.g. gradle/testing/profiling.linux.jfc). Legacy samples: + // jdk.CPUTimeSample: JEP 509 (e.g. gradle/testing/profiling.cputime.jfc). Legacy samples: // jdk.ExecutionSample / jdk.NativeMethodSample (e.g. profiling.jfc). Stock Lucene configs // enable one family; filter gradle poll thread for legacy samples only. if (name.equals("jdk.CPUTimeSample")) { diff --git a/gradle/testing/profiling.linux.jfc b/gradle/testing/profiling.cputime.jfc similarity index 70% rename from gradle/testing/profiling.linux.jfc rename to gradle/testing/profiling.cputime.jfc index 9190eb9771b7..6aa33f55b4d1 100644 --- a/gradle/testing/profiling.linux.jfc +++ b/gradle/testing/profiling.cputime.jfc @@ -16,11 +16,16 @@ limitations under the License. --> - + false diff --git a/gradle/testing/profiling.jfc b/gradle/testing/profiling.jfc index 565457d385b7..84f0c2db3e32 100644 --- a/gradle/testing/profiling.jfc +++ b/gradle/testing/profiling.jfc @@ -16,8 +16,8 @@ limitations under the License. --> diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 98892486bdc7..4f745a3881a9 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -185,10 +185,10 @@ Changes in Runtime Behavior Build --------------------- -* GITHUB#15926: Support jdk.CPUTimeSample event (Java 25+, JEP 509) in ProfileResults. - Linux test JVMs use gradle/testing/profiling.linux.jfc (CPU-time sampling only); other hosts - keep wall-clock jdk.ExecutionSample/jdk.NativeMethodSample. CodeProfilingPlugin selects the - JFR settings file by host OS. (Prithvi S) +* GITHUB#15926: Use the Java 25+ (JEP 509) CPU-time sampling profiler when available (currently + only on Linux), and fall back to legacy wall-clock execution sampling elsewhere. ProfileResults + recognizes jdk.CPUTimeSample; CodeProfilingPlugin picks gradle/testing/profiling.cputime.jfc or + profiling.jfc by host OS. (Prithvi S) * GITHUB#15327: New low-level build options to detect abuse of LuceneTestCase.random(): tests.random.maxacquires and tests.random.maxcalls (Robert Muir, Dawid Weiss) From 6f2c12fabe7ce42f53abcfc78d71ab89fbd29b6d Mon Sep 17 00:00:00 2001 From: prithvi Date: Tue, 28 Apr 2026 20:17:15 +0530 Subject: [PATCH 6/6] review changes Signed-off-by: prithvi --- gradle/testing/profiling.cputime.jfc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/gradle/testing/profiling.cputime.jfc b/gradle/testing/profiling.cputime.jfc index 6aa33f55b4d1..a632754b35fa 100644 --- a/gradle/testing/profiling.cputime.jfc +++ b/gradle/testing/profiling.cputime.jfc @@ -19,21 +19,9 @@ CPU-time method sampling (Java 25+, JEP 509, jdk.CPUTimeSample). Used when CPU-time profiling is available for the test JVM (currently only on Linux for this JDK). - jdk.ExecutionSample and jdk.NativeMethodSample are listed with enabled=false so wall-clock - sampling stays off: defaults vary by JDK/template, and we want an explicit single CPU sampler - without stacking overhead from legacy execution sampling. - Object allocation events match profiling.jfc for heap profiling mode. --> - - false - - - - false - - true 1 ms