[master] RFR: Implement self-forwarding of objects that preserves header bits
Roman Kennke
rkennke at openjdk.java.net
Wed Jun 30 09:25:41 UTC 2021
On Tue, 29 Jun 2021 18:42:45 GMT, John R Rose <jrose at openjdk.org> wrote:
> The Valhalla project has a strong requirement for very fast detection of references to primitive objects (the term was previously inline objects), because the behavior of the very frequent `acmp` operation differs between references to primitives and to regular identity objects. After much experiment, the prototype has settled on testing the biased-lock bit in the mark word to see if the reference points to a primitive object instead of a regular one. An extra indirection through the `klass` pointer would be too slow.
>
> Valhalla defines three additional object header bits, for more limited purposes. (H/T to Fred Parain for reminding me of these.) For primitive objects only, there is a "larval" state which sometimes needs to be marked, on an unpublished object which is under construction. This bit is related to the "always locked" bit; it is a stronger condition. It seems likely to me that whatever provision there is for short-circuiting attempted lock operations on primitive objects will easily expand to another provision for marking larval objects, by using related state bits in the header (assuming header locking consumes more than one bit).
>
> For arrays, there are two bits which accelerate slow paths relating to arrays whose elements are restricted to primitive classes (aka inline objects). The two bits encode whether (a) the array elements are stored as null-free references (internally boxed primitives) or (b) the array elements are stored flat as inline primitive objects (the preferred case). These bits accelerate array access operations. They are present only on 64-bit VMs; when bits are scarce they are loaded via the `klass` pointer. This would seem to be a reasonable tactic for Lilliput also, if bits are scarce. Another tactic for Lilliput might be to pack such array-specific flags into an extra field just for arrays, adjacent to the `length` field.
>
> The relevant declarations are in `markOop.hpp`:
>
> https://github.com/openjdk/valhalla/blob/b62a66e379fda00a5ba4622da7661c89b380ecdf/src/hotspot/share/oops/markWord.hpp#L97
>
> (As a completely separate technique, header bits could be migrated to pointer-color bits on a 64-bit VM. If Lilliput explores this territory, three out of the above four bits could be moved to the pointer, since they are immutable object properties. The larval bit is slightly stateful, undergoing a single state transition just before the object is published.)
Thanks, John, for the detailed explanations!
For this PR, I'd like to take the BL bit. But I believe it should be ok, because it's only relevant during GC and only if the lowest two bits are also set, when doing self-forwarding in case of a promotion failure. In this scenario, the header bits would be overwritten anyway, and GC would have to ensure that the header (including the BL bit) is preserved if there is anything interesting in the lower header bits.
Roman
-------------
PR: https://git.openjdk.java.net/lilliput/pull/10
More information about the lilliput-dev
mailing list