Moving from VVT to the L-world value types (LWVT)
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
Feedback and comments are welcome.
> 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)
>> 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.
> I agree about the semantics,
> the name of the flag is wrong, it should be ACC_FLAT_THUS_NON_NULLABLE :)
>>> 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
>>>> 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