RFR: 8305895: Implement JEP 450: Compact Object Headers (Experimental) [v7]
Thomas Schatzl
tschatzl at openjdk.org
Mon Sep 9 12:40:13 UTC 2024
On Mon, 9 Sep 2024 10:29:55 GMT, Roman Kennke <rkennke at 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 with a new target base due to a merge or a rebase. The pull request now contains 26 commits:
>
> - Fix compiler/c2/irTests/TestPadding.java for +COH
> - Simplify arrayOopDesc::length_offset_in_bytes and oopDesc::base_offset_in_bytes
> - Nit in header_size
> - GC code tweaks
> - Fix runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java
> - Fix jdk/tools/jlink/plugins/CDSPluginTest.java
> - Cleanup markWord bits and comments
> - x86_64: Fix loadNKlassCompactHeaders
> - aarch64: Fix loadNKlassCompactHeaders
> - Use FLAG_SET_ERGO when turning off UseCompactObjectHeaders
> - ... and 16 more: https://git.openjdk.org/jdk/compare/b45fe174...49126383
src/hotspot/share/gc/g1/g1ParScanThreadState.cpp line 481:
> 479: Klass* klass = UseCompactObjectHeaders
> 480: ? old_mark.klass()
> 481: : old->klass();
To be exact "promotion" only refers to copying to an older generation, so this comment does not cover objects copied within the generation.
Suggestion:
// NOTE: With compact headers, it is not safe to load the Klass* from old, because
// that would access the mark-word, that might change at any time by concurrent
// workers.
// This mark word would refer to a forwardee, which may not yet have completed
// copying. Therefore we must load the Klass* from the mark-word that we already
// loaded. This is safe, because we only enter here if not yet forwarded.
src/hotspot/share/gc/parallel/mutableSpace.cpp line 225:
> 223: // header-based forwarding during promotion. Full GC doesn't
> 224: // use the object header for forwarding at all.
> 225: p += obj->forwardee()->size();
Better use `!obj->is_self_forwarded()` here.
src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp line 174:
> 172: // may not yet have completed copying. Therefore we must load the Klass* from
> 173: // the mark-word that we have already loaded. This is safe, because we have checked
> 174: // that this is not yet forwarded in the caller.)
Same adjustment needed as for G1.
src/hotspot/share/gc/shared/c2/barrierSetC2.cpp line 711:
> 709: // 8 - 32-bit VM
> 710: // 12 - 64-bit VM, compressed klass
> 711: // 16 - 64-bit VM, normal klass
The comment needs to be adapted to include the case for compact object headers.
src/hotspot/share/oops/arrayOop.hpp line 83:
> 81: // The _length field is not declared in C++. It is allocated after the
> 82: // declared nonstatic fields in arrayOopDesc if not compressed, otherwise
> 83: // it occupies the second half of the _klass field in oopDesc.
Needs update.
src/hotspot/share/oops/instanceOop.hpp line 36:
> 34: class instanceOopDesc : public oopDesc {
> 35: public:
> 36: // If compressed, the offset of the fields of the instance may not be aligned.
Needs fixing (or removal) wrt to compact object headers, or move to the particular case.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/20677#discussion_r1750046114
PR Review Comment: https://git.openjdk.org/jdk/pull/20677#discussion_r1750056160
PR Review Comment: https://git.openjdk.org/jdk/pull/20677#discussion_r1750074607
PR Review Comment: https://git.openjdk.org/jdk/pull/20677#discussion_r1750080552
PR Review Comment: https://git.openjdk.org/jdk/pull/20677#discussion_r1750027009
PR Review Comment: https://git.openjdk.org/jdk/pull/20677#discussion_r1750116336
More information about the serviceability-dev
mailing list