Moving from VVT to the L-world value types (LWVT)

John Rose john.r.rose at
Thu Jan 25 22:48:13 UTC 2018

On Jan 25, 2018, at 1:51 PM, Frederic Parain <frederic.parain at> wrote:
> Simply allowing non-flattened field to be null is not a viable
> solution because a consequence would be  that the result of
> reading  a non-initialized field would depend on wether or not
> the field has been flattened.

As you note below, it is possible to make the details
of null processing depend on whether the *field* was
declared flat or not.

> With Valhalla Value Types, we were able to use the null
> value internally for non-initialized non-flattened field because
> the JVM always knew if a field were a value type or not.

Nice trick.

> Unfortunately, this cannot be done in the L-world because
> when a non-initialized field is read, there’s no guarantee that
> the class of this field has been loaded yet.
> So, here’s a proposal that provides a semantic for null value
> fields that do not depend on the implementation, and without
> additional runtime checks for non-value fields:
> 1 - If a field is declared without the ACC_FLAT flag set:
>   -> it is never flattened (even if the class is already loaded
>      and it is a value class)
>   -> it is OK to write null on this field
>   -> reading the default value of this field returns null

Yes, that's what I had in mind too.

> 2 - If a field is declared wit the ACC_FLAT_flag set:
>   -> the class of this field is loaded before computing the layout
>      of the declaring class
>   A - If the field's class is an object class
>       -> same semantic as in 1 is applied


>   B - If the field's class is a value class
>       -> writing null to this field results in setting this field
>          to the default value of its value class

We have a choice here:  We can also throw NPE on
such writes.  I think we should.  There's no legitimate
need for writing a null value to a flat field, I think.

(But maybe there's a translation strategy, that I'm not
noticing, that could use this behavior?)

>       -> reading the default value of this field (uninitialized)
>          returns the default value of its value class

If you can't write null w/o NPE, then the JVM can
still use the internal trick of allowing null as a
sentinel for the default value.

> Case 1 is the object world as we know it today, no changes, no
> additional runtime checks, values will be handled like objects.
> Case 2-A is the case where the ACC_FLAT has been mis-used
> on an object class.
> Case 2-B is the interesting value type case, and its semantic
> relies only on the presence of the ACC_FLAT flag, not on the
> decision of the JVM to flatten the field or not.


> Checks to intercept
> the null value are easy to implement, all information they need
> are in the field descriptor and on the execution stack. 

I agree.  Resolving the CONSTANT_Fieldref to the descriptor
will determine whether the *field* was declared ACC_FLAT.
In that case null writes will fail and null reads (if any) can be
handled in some manner convenient to the JVM.

> Bytecode quickening or JIT compilation will help avoiding the ACC_FLAT
> test completely for cases 1 and 2-A.


— John

More information about the valhalla-dev mailing list