Sharing the markword (aka Valhalla's markword use)
John Rose
john.r.rose at oracle.com
Sun Mar 10 03:38:35 UTC 2024
What Dan said. Here’s more color commentary:
The larval state of a value object can be viewed as an analog of the locked state of an identity object. In both cases, one specific thread is doing something exclusive to the object. For values, this larval state is indeed highly exclusive: The thread that made the value object is also filling in its fields, protected either by the verifier (if it is constructor code) or by some other means (if the fields are being set by privileged non-constructor code). Unlike a locked identity object, once a value exits the larval state, it is forever an adult; an identity object can be relocked many times.
All that said, the lifecycles are different, but they are similar enough that we can envision using some of the same bit-patterns in parallel. I am pretty sure that whatever locked state indicator (a bit pattern) that we invent for the object header of an identity object is more than adequate for a value object in its larval state.
So, just have each GC process larvae very much like locked objects, and arrange the header bit patterns to make this easy, by making them be similar.
And, as an aside, in the future the GC or JIT may perform deduplication (or, say, NUMA-sensitive duplication) of values, or any other reorganization that reassigns varying pointers which alias equivalent copies of the same value state. In such a case, please be sure to treat every larval value object as unique and never aliased to any other value object, however similar. A larval value is likely to be side-effected to a new state before it becomes adult, which would cause bad failures if it were accidentally treated as aliased to some unrelated value. Only adult values are legitimate subjects for alias-based optimizations, whether in the JIT or GC.
Regarding the other bits (is-value, is-flat-array, is-null-free-array), those can all be re-hoisted from the Klass object, if for some reason the header needs to be restored or reset. After all, those bits are just optimized copies (hoisted into a convenient place in the header), copied from the original information in the Klass object itself. This hoisting is a performance hack. We are discussing it at length here because the Valhalla team has determined, at least provisionally, that acceptable product performance requires such a “hoisting hack”.
I suggest adding, to Klass itself, a field which is a prototype header for the object, with all the right bits in place. The GC can use that as a starting point when repairing headers that it had to reset. (I thought we already had something like this somewhere, but a quick check came up empty…) Currently, it appears we reset object headers from markWord::prototype which is an absolute constant. Perhaps this function should be refactored to a query to non-static Klass::prototype_mark_word. That’s just my $0.02; probably stuff like this has been discussed several times.
A final suggestion, which I’ve mentioned elsewhere, but it’s worth repeating: If we don’t choose to burn whole a bit on the is-value test, we can use a joint bit encoding. (Similar point for an is-array test, in fact, or for particular subkinds of arrays.) In either the klass or IHC subfield of the header, we might be able to get away with stating something like, “if there 10 or more zeroes at the high end of the subfield, then the object is a value, and otherwise it’s not”. That would steal dynamic range from the subfield for values, but would leave the non-values unscathed (except for the responsibility to avoid that 1/1024 fraction of reserved encodings). For more details, please see: https://cr.openjdk.org/~jrose/jvm/joint-bit-encodings.html
On 6 Mar 2024, at 7:20, Dan Heidinga wrote:
> Values lack identity so it’s possible for them to be deduplicated (or even duplicated!) at any point when they are not in the larval state. That would mean we’d need the is_larval bit to be stable to any process (gc?) that may be responsible for (de)duplication.
>
>
>
> The other three bits shouldn’t be required during GC and can be re-derived from the klass metadata.
More information about the valhalla-dev
mailing list