[master] RFR: Implement self-forwarding of objects that preserves header bits [v3]

Thomas Schatzl tschatzl at openjdk.java.net
Mon Jul 12 09:02:44 UTC 2021


On Fri, 9 Jul 2021 12:12:37 GMT, Roman Kennke <rkennke at openjdk.org> wrote:

>> In a few places in GCs we self-forward objects to indicate promotion failures. This is problematic with Lilliput because it irreversably overrides header bits.
>> 
>> I propose to address this problem by using the recently-free'd biased-locking bit to indicate self-forwarding, without actually writing the ptr-to-self in the header.
>> 
>> A few notes:
>>  - The code in g1FullGCCompactionPoint.cpp keeps degenerating into ugly mess. This certainly warrants some rewriting.
>>  - We have some naked header-decodings, which get tidied-up. This could also be brought upstream.
>>  - cas_forward_to() kinda duplicates forward_to_atomic(), and has been replaced by the new forward_to_self_atomic(). It could be unduplicated upstream, too.
>> 
>> An alternative *may be* to preserve the header of self-forwarded objects in a side-table (like PreservedMarksStack) instead. This may be possible but hairy: we could not access the compressed-klass* in the upper bits until the header gets restored. (This also affects calls to size(), etc).
>> 
>> The ex-biased-locking-bit may still be used in regular operation. It only acts as self-forwarding-indicator when the lower two bits are also set. It requires the usual marks-preservation if we do this.
>> 
>> We might want to have a discussion which project would need header bits, and how to realistically allocate them. #4522 mentions Valhalla as possible taker of the BL header bit. We may be able to free one or two bits when we compress the klass* even more. For example, we currently use 25 bits for i-hash, and 32 bits for nklass*. We usually want 32bits for i-hash instead. This would leave 25bits for nklass, which can address 268MB of Klass*-space (usual compression scheme), or 32million classes (table-lookup), or something in-between if we use fixed-size Klass (seems unrealistic though). Taking away another bit mean halving the addressable space.
>> 
>> (It would be kinda-nice to have the BL-bit for Shenandoah, too, and for a similar purpose: indicate evacuation failure. But we do have a working solution, however that is ugly and affects performance a little.)
>> 
>> Testing:
>>  - [x] tier1
>>  - [x] hotspot_gc
>>  - [x] hotspot_gc_shenandoah
>
> Roman Kennke has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains four commits:
> 
>  - Increase sliding forwarding base shift to 3, to leave room for self-forwarding
>  - Merge
>  - Alekey's comments
>  - Implement self-forwarding of objects that preserves header bits

Sorry, I'm late, but I only now got the time to look into this.

src/hotspot/share/gc/g1/g1OopClosures.inline.hpp line 237:

> 235:     markWord m = obj->mark();
> 236:     if (m.is_marked()) {
> 237:       forwardee = obj->forwardee(m);

The original code has been done that way intentionally: the changed code reloads the value from the header from memory (from what I can tell from generated code), while the original code does not, just reusing the value in the register.

Even if this is a nano-nano-optimization I would prefer to keep it as is. Some of the other changes seem to cause very similar "regressions".

(Yeah, I'm late, sorry).

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

PR: https://git.openjdk.java.net/lilliput/pull/10


More information about the lilliput-dev mailing list