RFR: 8373595: A new ObjectMonitorTable implementation [v2]
Fei Yang
fyang at openjdk.org
Fri Feb 13 14:59:06 UTC 2026
On Wed, 4 Feb 2026 14:57:39 GMT, Fredrik Bredberg <fbredberg at openjdk.org> wrote:
>> Me and Anton Artemov (@toxaart) investigated a quite large regression that occurred in Pet Clinic that happened if you turned on Compact Object Headers. It was found that a large portion of that regression could be attributed to not finding the monitor in the Object Monitor Cache, and because we couldn't access the Object Monitor Table from C2 generated code, we often had to take the slow path.
>>
>> By making the object monitor cache larger and make it use the object's hash value as a key, we managed to mitigate the regression.
>>
>> Erik Österlund (@fisk) took that idea and elevated it to the next level, which means that he rewrote the object monitor table code so that we can now search for an object in the global object monitor table from C2 generated code. I.e. from `C2_MacroAssembler::fast_lock()`. As in my and Anton's version, the key is the hash value from the object.
>>
>> Erik also provided new barrier code needed for ZGC for x86 and aarch64. Roman Kennke (@rkennke) provided the same for Shenandoah, also for x86 and aarch64.
>>
>> We decided to keep the Object Monitor Cache, since we found that for most programs (but not Pet Clinic) the monitor you are looking for is likely found in the first positions of the cache (it's sorted in most recently used order). However we decresed the size from 8 to 2 elements.
>>
>> After running extensive performance tests we can say that this has improved the performance in many of them, not only mitigated the regression in Pet Clinic.
>>
>> Tests are running okay tier1-7 on supported platforms.
>>
>> The rest of the platforms (`ppc`, `riscv` and `s390`) have been smoke tested using QEMU.
>> I mainly used this test for smoke testing with QEMU: `-XX:+UnlockDiagnosticVMOptions -XX:+UseObjectMonitorTable ./test/hotspot/jtreg/runtime/Monitor/UseObjectMonitorTableTest.java `
>
> Fredrik Bredberg has updated the pull request incrementally with one additional commit since the last revision:
>
> Updated all platforms after review comments
src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp line 480:
> 478: __ beqz(obj, done);
> 479:
> 480: assert(obj != tmp, "need tmp");
Seems better if we move this `assert` to entry of this assembler routine and replace it with: `assert_different_registers(obj, tmp);`. Also `ZBarrierSetAssembler::try_resolve_weak_handle_in_c2` could be improved. So I am suggesting following add-on changes:
diff --git a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp
index fcb5fa512ec..8d530d15ee5 100644
--- a/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/gc/shenandoah/shenandoahBarrierSetAssembler_riscv.cpp
@@ -465,6 +465,8 @@ void ShenandoahBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler
#ifdef COMPILER2
void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler *masm, Register obj,
Register tmp, Label& slow_path) {
+ assert_different_registers(obj, tmp);
+
Label done;
// Resolve weak handle using the standard implementation.
@@ -473,7 +475,6 @@ void ShenandoahBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler
// Check if the reference is null, and if it is, take the fast path.
__ beqz(obj, done);
- assert(obj != tmp, "need tmp");
Address gc_state(xthread, ShenandoahThreadLocalData::gc_state_offset());
__ lbu(tmp, gc_state);
diff --git a/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp
index f2453af19d7..163271a2f11 100644
--- a/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/gc/z/zBarrierSetAssembler_riscv.cpp
@@ -610,7 +610,9 @@ void ZBarrierSetAssembler::try_resolve_weak_handle_in_c2(MacroAssembler* masm, R
BarrierSetAssembler::try_resolve_weak_handle_in_c2(masm, obj, tmp, slow_path);
// Check if the oop is bad, in which case we need to take the slow path.
- __ ld(tmp, mark_bad_mask_from_thread(xthread));
+ __ relocate(barrier_Relocation::spec(), [&] {
+ __ li16u(tmp, barrier_Relocation::unpatched);
+ }, ZBarrierRelocationFormatMarkBadMask);
__ andr(tmp, obj, tmp);
__ bnez(tmp, slow_path);
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/29383#discussion_r2776966104
More information about the shenandoah-dev
mailing list