On Tue, 22 Oct 2024 16:19:24 GMT, Roman Kennke <rken...@openjdk.org> wrote:

>> This is the main body of the JEP 450: Compact Object Headers (Experimental).
>> 
>> It is also a follow-up to #20640, which now also includes (and supersedes) 
>> #20603 and #20605, plus the Tiny Class-Pointers parts that have been 
>> previously missing.
>> 
>> Main changes:
>>  - Introduction of the (experimental) flag UseCompactObjectHeaders. All 
>> changes in this PR are protected by this flag. The purpose of the flag is to 
>> provide a fallback, in case that users unexpectedly observe problems with 
>> the new implementation. The intention is that this flag will remain 
>> experimental and opt-in for at least one release, then make it on-by-default 
>> and diagnostic (?), and eventually deprecate and obsolete it. However, there 
>> are a few unknowns in that plan, specifically, we may want to further 
>> improve compact headers to 4 bytes, we are planning to enhance the Klass* 
>> encoding to support virtually unlimited number of Klasses, at which point we 
>> could also obsolete UseCompressedClassPointers.
>>  - The compressed Klass* can now be stored in the mark-word of objects. In 
>> order to be able to do this, we are add some changes to GC forwarding (see 
>> below) to protect the relevant (upper 22) bits of the mark-word. Significant 
>> parts of this PR deal with loading the compressed Klass* from the mark-word. 
>> This PR also changes some code paths (mostly in GCs) to be more careful when 
>> accessing Klass* (or mark-word or size) to be able to fetch it from the 
>> forwardee in case the object is forwarded.
>>  - Self-forwarding in GCs (which is used to deal with promotion failure) now 
>> uses a bit to indicate 'self-forwarding'. This is needed to preserve the 
>> crucial Klass* bits in the header. This also allows to get rid of 
>> preserved-header machinery in SerialGC and G1 (Parallel GC abuses 
>> preserved-marks to also find all other relevant oops).
>>  - Full GC forwarding now uses an encoding similar to compressed-oops. We 
>> have 40 bits for that, and can encode up to 8TB of heap. When exceeding 8TB, 
>> we turn off UseCompressedClassPointers (except in ZGC, which doesn't use the 
>> GC forwarding at all).
>>  - Instances can now have their base-offset (the offset where the field 
>> layouter starts to place fields) at offset 8 (instead of 12 or 16).
>>  - Arrays will now store their length at offset 8.
>>  - CDS can now write and read archives with the compressed header. However, 
>> it is not possible to read an archive that has been written with an opposite 
>> setting of UseCompactObjectHeaders. Some build machinery is added so that 
>> _co...
>
> Roman Kennke has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - Update copyright
>  - Avoid assert/endless-loop in JFR code

Our testing has found a failure in 
serviceability/sa/ClhsdbJstackWithConcurrentLock.java when we run C1-only.

I've narrowed it down to be a stale, but seemingly working, implementation of 
the TLAB data structure. When Lilliput changes the header size this 
implementation doesn't work anymore and needs to be fixed.

The reproducer for this problem is:

make -C ../build/fastdebug test 
TEST=serviceability/sa/ClhsdbJstackWithConcurrentLock.java 
JTREG="JAVA_OPTIONS=-XX:TieredStopAtLevel=2 -XX:+UnlockExperimentalVMOptions 
-XX:+UseCompactObjectHeaders"


See how the thread reports that the frame holds an AOS, but the list of "Locked 
ownable synchronizers" is (incorrectly) empty:

"Thread-0" #31 prio=5 tid=0x00007a708c259ad0 nid=1480533 waiting on condition 
[0x00007a706fefe000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
   JavaThread state: _thread_blocked
 - java.lang.Thread.sleepNanos0(long) @bci=0 (Interpreted frame)
 - java.lang.Thread.sleepNanos(long) @bci=33, line=497 (Interpreted frame)
 - java.lang.Thread.sleep(long) @bci=25, line=528 (Interpreted frame)
 - LingeredAppWithConcurrentLock.lockMethod(java.util.concurrent.locks.Lock) 
@bci=13, line=38 (Interpreted frame)
        - locked <0x00000000ffd32d88> (a 
java.util.concurrent.locks.ReentrantLock)
 - LingeredAppWithConcurrentLock.lambda$main$0() @bci=3, line=46 (Interpreted 
frame)
 - LingeredAppWithConcurrentLock$$Lambda+0x00007a7023001000.run() @bci=0 
(Interpreted frame)
 - java.lang.Thread.runWith(java.lang.Object, java.lang.Runnable) @bci=5, 
line=1589 (Interpreted frame)
 - java.lang.Thread.run() @bci=19, line=1576 (Interpreted frame)

Locked ownable synchronizers:
    - None


This happens because the TLAB ranges become overlapped and that confuses the 
rest of the SA code that looks for objects in the heap.

I've created a fix for this, which I intend to try to get pushed to openjdk/jdk:
https://github.com/openjdk/jdk/compare/pr/20677...stefank:jdk:8342857_SA_heap_iterator_fix
https://github.com/stefank/jdk/tree/8342857_SA_heap_iterator_fix

-------------

PR Comment: https://git.openjdk.org/jdk/pull/20677#issuecomment-2430157348

Reply via email to