Value types design decisions

John Rose john.r.rose at oracle.com
Sun Jan 21 06:10:08 UTC 2024


On 20 Jan 2024, at 21:20, - wrote:

> Hi Brian, from your description of LocalDate![] comes a contingent question:
> Can (non-implicitly constructable) classes now have null-restricted
> (inlined) fields of types that are not implicitly constructable, given
> these fields will be initialized by the constructors to valid values? I
> assume any assignment of invalid values (notably, null) will simply result
> in exceptions such as NPE.
>
> If yes, how will such fields be represented in heap as:
> 1. identity object's final fields?
> 2. identity object's mutable fields?
> 3. non-implicitly constructable value object's final fields?
>
> Given these fields can have their proper states visible no later than their
> owner objects are visible.
>
> I think this is a new aspect of inlining that hasn't yet been discussed,
> but is probably worth discussing.
>

That is well spotted.  As Brian said, “Stay tuned”.  Here is a teaser:

https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-December/002400.html

You are right to imply that the implementation options are likely to differ for immutable and mutable fields (and sub-fields of values).

As a result of certain conversations last summer at JMVLS, our design for Valhalla got simpler, because value and identity objects use more similar code shapes for their construction.  That gave us a better logical framework for thinking about problems and requirements of guaranteed field initialization, the results of which will come out shortly.

The basic insight is, if you can prove a field is initialized, you can tolerate an abstraction-breaking initial value.  The fun problem is building out the framework for making the necessary proofs, at the right levels in the stack.

For mutable fields there is an additional problem, of course, of ensuring that races (on a field of type V! or V) cannot expose values that the author of V has deemed private to V.  (Allowing V to opt out of atomicity makes the VM’s job easier.)  Once the initialization problem is solved, it is easier to attack the “safe mutation” problem, with or without an atomicity requirement.  All of this stuff will happen “under the hood”.

As Brian says, once the semantics are nailed down, then the optimizations can start to show up.  Once the rules are set properly, the games can begin.  (I’m talking about the VM implementation games, the kind of games I like best.)

I expect to see a long line of VM optimizations arise in the future after Valhalla, to flatten more and more value types, as optimizations get more clever and hardware gets more capable.  My concern for this year is to get the semantic rules into the right shape (for both language and VM).  That way the best optimizations are possible in the future.

Examples of possible future stuff:  Research on STM and HTM might be “mined” for potential candidates to optimize flat, mutable data.  There are clever “cache friendly” and “lock free” algorithms that might be applicable.  I have a handful of pet ideas…  One is doubly-periodic arrays, where each array “card” has N payloads and N null bits (or N big fields and N little fields; N might be 7) but they are allocated column-style (within the card) instead of row-style (which is what we do to day in the Valhalla prototype).  The card size is tuned to the cache line size, of course.  The indexing arithmetic is surprisingly clean, once you work it out.

— John



More information about the valhalla-dev mailing list