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

Frederic Parain frederic.parain at oracle.com
Wed Jan 31 19:08:24 UTC 2018


Here’s an update of the JVMS draft which includes the semantic
proposed below.

http://cr.openjdk.java.net/~fparain/L-world/L-World-JVMS-3.pdf

Feedback and comments are welcome.

Fred


> On Jan 31, 2018, at 05:54, Remi Forax <forax at univ-mlv.fr> wrote:
> 
> 
> 
> ----- Mail original -----
>> De: "Frederic Parain" <frederic.parain at oracle.com>
>> À: "John Rose" <john.r.rose at oracle.com>
>> Cc: "valhalla-dev" <valhalla-dev at openjdk.java.net>
>> Envoyé: Lundi 29 Janvier 2018 20:31:56
>> Objet: Re: Moving from VVT to the L-world value types (LWVT)
> 
>> John,
>> 
>> Silently transforming null into the default value in case 2-B was
>> just in case it could ease the handling of migrated case. If throwing
>> NPE is OK here, it makes the semantic much cleaner. It also solves
>> some problems we had while trying to add support for the null
>> value in the value class’ equals() method.
>> 
>> During a brainstorming session with Karen this morning, we realized
>> that case 2-A (ACC_FLAT flag set for an object class) should be in
>> fact treated as an error, instead of just ignoring the flag.
> 
> Which means that changing a value type to a reference type is not a backward compatible change,
> i'm Ok with that.
> 
>> 
>> These two modifications makes the semantic mucho simpler and
>> cleaner with only two cases: one where null is always valid, and
>> one where null is never valid.
>> 
>> So here’s a re-write of the semantic:
>> 
>> Fields have a new access flag called ACC_NON_NULLABLE.
>> 
>> The type of a field with the ACC_NON_NULLABLE flag set must
>> be a value class type, otherwise an ICCE is thrown.
>> 
>> 1 - If a field is declared without the ACC_NON_NULLABLE flag set:
>>    - this field is initialized with the null reference
>>    - it is valid to write null to this field
>>    - note: JVMs are unlikely to flatten such field
>> 
>> 2 - If a field is declared with the ACC_NON_NULLABLE flag set:
>>    - this field is initialized with the default value of this field’s value class
>>    - writing null to this field causes a NPE
>>    - JVMs are encouraged to flatten such field
>> 
>> This semantic makes much more sense because being non-nullable
>> is a property of the container more than a property of the field’s type.
>> 
>> Fred
> 
> I agree about the semantics,
> the name of the flag is wrong, it should be ACC_FLAT_THUS_NON_NULLABLE :)
> 
> Rémi
> 
>> 
>>> On Jan 25, 2018, at 17:48, John Rose <john.r.rose at oracle.com> wrote:
>>> 
>>> On Jan 25, 2018, at 1:51 PM, Frederic Parain <frederic.parain at oracle.com> 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
>>> 
>>> Yes.
>>> 
>>>>  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.
>>> 
>>> Exactly.
>>> 
>>>> 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.
>>> 
>>> Yes.
>>> 
>>> — John



More information about the valhalla-dev mailing list