RFR: 8342818: Implement JEP 509: JFR CPU-Time Profiling [v50]
Patricio Chilano Mateo
pchilanomate at openjdk.org
Wed Jun 4 14:15:53 UTC 2025
On Wed, 4 Jun 2025 12:56:22 GMT, Johannes Bechberger <jbechberger at openjdk.org> wrote:
>> This is the code for the [JEP 509: CPU Time based profiling for JFR](https://openjdk.org/jeps/509).
>>
>> Currently tested using [this test suite](https://github.com/parttimenerd/basic-profiler-tests). This runs profiles the [Renaissance](https://renaissance.dev/) benchmark with
>> - ... different heap sizes
>> - ... different GCs
>> - ... different samplers (the standard JFR and the new CPU Time Sampler and both)
>> - ... different JFR recording durations
>> - ... different chunk-sizes
>
> Johannes Bechberger has updated the pull request incrementally with one additional commit since the last revision:
>
> Fix build
I took a look at this. I only found one issue that needs fixing before integration and then a few comments. Thanks.
src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 59:
> 57: Thread* raw_thread = Thread::current_or_null_safe();
> 58: if (raw_thread == nullptr) {
> 59: // probably while shutting down
Do you remember which test fail because of this? It would be interesting to know, since I don’t see how it could be null here.
src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 330:
> 328: void JfrCPUSamplerThread::stackwalk_threads_in_native() {
> 329: ResourceMark rm;
> 330: MutexLocker tlock(Threads_lock);
What exactly are we guarding against by holding the `Threads_lock`? Seems `ThreadsListHandle` should be enough.
src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 430:
> 428: void JfrCPUTimeThreadSampling::create_sampler(double rate, bool auto_adapt) {
> 429: assert(_sampler == nullptr, "invariant");
> 430: _sampler = new JfrCPUSamplerThread(rate, auto_adapt);
If we start a recording on an already running process we have a race here where a new thread can create and set its timer before we call init_timers() where the signal handler is installed. In that case the program will terminate with message “Profiling timer expired" (default action for SIGPROF). It can be easily reproduced by adding a delay here and starting a recording on a simple test that just creates new threads. We need to add some extra check in create_timer_for_thread() or install the signal handler earlier.
src/hotspot/share/jfr/periodic/sampling/jfrCPUTimeThreadSampler.cpp line 584:
> 582: sev.sigev_notify = SIGEV_THREAD_ID;
> 583: sev.sigev_signo = SIG;
> 584: sev.sigev_value.sival_ptr = &t;
Why setting the address of `t` which is a local variable here?
-------------
PR Review: https://git.openjdk.org/jdk/pull/25302#pullrequestreview-2896813404
PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126661443
PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126670024
PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126651264
PR Review Comment: https://git.openjdk.org/jdk/pull/25302#discussion_r2126666505
More information about the hotspot-dev
mailing list