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

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 (ACCFLAT 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 ACCNONNULLABLE. The type of a field with the ACCNONNULLABLE flag set must be a value class type, otherwise an ICCE is thrown. 1 - If a field is declared without the ACCNONNULLABLE 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 ACCNONNULLABLE 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 ACCFLATTHUSNONNULLABLE :) 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 ACCFLAT 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 ACCFLATflag 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 ACCFLAT 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 ACCFLAT 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 CONSTANTFieldref to the descriptor will determine whether the field was declared ACCFLAT. 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 ACCFLAT test completely for cases 1 and 2-A. Yes. — John



More information about the valhalla-dev mailing list