RFR: 8376822: UseCompactObjectHeaders: fill Klass alignment gaps in AOT cache [v3]
Ashutosh Mehra
asmehra at openjdk.org
Thu Feb 26 17:01:44 UTC 2026
On Wed, 25 Feb 2026 18:24:37 GMT, Ioi Lam <iklam at openjdk.org> wrote:
>> When `UseCompactObjectHeaders` is enabled, `Klass` objects must be aligned by 1024 bytes. This leaves many gaps in the "rw" region of the AOT cache.
>>
>> This PR manages the gaps using an `RBTree`. The gaps are sorted in ascending sizes. Gaps of the same size are sorted in ascending addresses. When allocating a small object, we try to find a suitable gap with the lowest address.
>>
>> Because we have lots of small metaspace objects in the AOT cache, the gaps are always filled. We save abuot 5% of footprint with the JDK's default CDS archive (777KB out of 15.7MB):
>>
>>
>> $ java -Xshare:dump -XX:+UseCompactObjectHeaders -Xlog:aot,aot+alloc=trace | grep -i gap | tail -2
>> [0.407s][trace][aot,alloc] 8 bytes @ 0x716e804623f0 in a gap of 8 bytes (used gaps 10293 times, remain gap = 0 bytes in 0 blocks)
>> [0.443s][info ][aot ] Allocated 10293 objects of 777264 bytes in gaps
>> $ ls -l images/jdk/lib/server/classes_coh.jsa
>> -rw-rw-r-- 1 iklam iklam 15704064 Feb 22 16:17 images/jdk/lib/server/classes_coh.jsa
>>
>>
>> Related changes
>>
>> - Address sorting added to AOTMapLogger
>> - The null assertion in `ArchivePtrMarker::mark_pointer()` was wrong for the dynamic archive (`ptr_base()` points to the bottom of the dynamic archive, not the bottom of the AOT metaspace).
>
> Ioi Lam has updated the pull request incrementally with two additional commits since the last revision:
>
> - @lmesnik comment: added test case
> - @johan-sjolen comments
src/hotspot/share/cds/archiveBuilder.cpp line 641:
> 639: void ArchiveBuilder::make_shallow_copy(DumpRegion *dump_region, SourceObjInfo* src_info) {
> 640: address src = src_info->source_addr();
> 641: int bytes = src_info->size_in_bytes();
Earlier code had special handling for `SymbolType`:
```
// Symbols may be allocated by using AllocateHeap, so their sizes
// may be less than size_in_bytes() indicates.
bytes = ((Symbol*)src)->byte_size();
Is that not needed now? I guess it shouldn't matter because `src_info->size_in_bytes()` for SymbolType returns bytes aligned to HeapWordSize which is same as `SharedSpaceObjectAlignment`. So the earlier code was passing the actual size of Symbol in bytes and `DumpRegion::allocate` would align it to `SharedSpaceObjectAlignment` but now the `bytes` should already by aligned to `HeapWordSize` or `SharedSpaceObjectAlignment`. It would probably result in memory wastage if ever `HeapWordSize` is more `SharedSpaceObjectAlignment`. Right?
src/hotspot/share/cds/archiveUtils.cpp line 371:
> 369: #endif
> 370:
> 371: if (alignment == SharedSpaceObjectAlignment && type != MetaspaceClosureType::SymbolType) {
Since the gaps are in rw region only, shouldn't we use the gaps only when `read_only` is false?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/29869#discussion_r2860187250
PR Review Comment: https://git.openjdk.org/jdk/pull/29869#discussion_r2860188233
More information about the hotspot-dev
mailing list