RFR: 8279016: JFR Leak Profiler is broken with Shenandoah [v3]
Roman Kennke
rkennke at openjdk.org
Mon Jul 29 14:54:51 UTC 2024
On Fri, 26 Jul 2024 18:26:51 GMT, Aleksey Shipilev <shade at openjdk.org> wrote:
>> While testing unrelated Shenandoah patch, I caught a GC assert when Leak Profiler was running ([JDK-8337194](https://bugs.openjdk.org/browse/JDK-8337194)).
>>
>> Leak Profiler is notorious in using the mark words for its own needs. We have been trying to mitigate its impact on GCs by moving to separate bitsets for tracking marked objects, or by treating "marked without fwdptr" as "JFR marked" and handling it. But this is not reliable, since things like [putting indexes in mark word](https://github.com/openjdk/jdk/blob/3baff2af6a30cc6cb2e0d4391db1cf7e61c33f64/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp#L275-L280) sneak in. This is okay for Leak Profiler alone, since it restores the mark words after the operation completes, but that is still not enough when GC is already running.
>>
>> I say we side-step this whack-a-mole by cleanly bailing from JFR op, when we know it is unsafe to do. I thought to use `VM_Operation::doit_prologue`, but I think GC start may sneak in between checking in prologue and op start.
>>
>> This realistically only affects Shenandoah. All other STW collectors would never see what Leak Profiler did with mark words. ZGC would not see it, since it does not care about mark words for its own operation.
>>
>> Additional testing:
>> - [x] `jdk/jfr/event/oldobject/` pass by default (100x times)
>> - [x] `jdk/jfr/event/oldobject/` pass with `-XX:+UseShenandoah` (1000x)
>
> Aleksey Shipilev has updated the pull request incrementally with one additional commit since the last revision:
>
> Referencing INCLUDE_SHENANDOAHGC nominally requires macro.hpp
Changes requested by rkennke (Reviewer).
src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp line 147:
> 145: // mark word uses by Shenandoah itself, if we hit the op during the concurrent
> 146: // GC cycle.
> 147: return ShenandoahHeap::heap()->is_idle();
I think you need to include shenandoahHeap.inline.hpp for this? Also, do we need to block this during all of GC, even marking? Would it make sense to only block during evac/updaterefs?
-------------
PR Review: https://git.openjdk.org/jdk/pull/20328#pullrequestreview-2205204781
PR Review Comment: https://git.openjdk.org/jdk/pull/20328#discussion_r1695377835
More information about the hotspot-jfr-dev
mailing list