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

Srikanth srikanth.adayapalam at oracle.com
Mon Feb 12 16:53:10 UTC 2018


Hi Frederic,

A couple of follow up questions below:

On Monday 12 February 2018 10:02 PM, Frederic Parain wrote:

[...]
> The current design allows null references for value types, as long as they are not stored
> in a container (field or array) declared as flattenable. This is a significant change from
> previous design. So, casting null to a value class type is now legal.

OK.  This does not call for any change to the specification of checkcast 
in JVMS ?
(I don't know that it does - Just double checking)

>> (10) withfield, Linking exceptions:
>>
>> "The field must be final, it must be declared in the current value class, and the
>> instruction must occur in a method of the current value class. Otherwise,
>> an IllegalAccessError is thrown."
>>
>> Per point made above, javac would emit withfield only from (a) static value factory method(s) and not any method of the current value class.
>>
> Thinking more about this, it might be time to drop __ValueFactory and allow
> all methods from a value class to use withfield. I cannot remember the argument
> in favor of stricter rules for this bytecode.

Problem in allowing all methods to use withfield is that it will make 
the final keyword meaningless as it is defined now. It is one thing to 
say a specially privileged method that is really a factory and so works 
with nascent values is allowed to update instance fields that are marked 
final and that it really results in copy-on-write semantics. There is 
precedence for such - a constructor is privileged to set blank final 
fields. (indeed it must), quite another to open the floodgates.

I am not saying it cannot be done, but we need to redefine finality for 
fields of a value type in order to be able to do that. In that case, 
should we even require them to be final ? Why won't we simply state that 
all updates to instance field would result in a copy ?

Thanks!
Srikanth


>
> An updated version of the draft is now available here:
> http://cr.openjdk.java.net/~fparain/L-world/L-World-JVMS-4b.pdf
>
> Thank you this very useful feedback,
>
> Fred
>
>
>>   
>>   
>>
>>   
>> On Thursday 01 February 2018 12:38 AM, Frederic Parain wrote:
>>> 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