Moving from VVT to the L-world value types (LWVT) (original) (raw)
Frederic Parain frederic.parain at oracle.com
Thu Jan 25 21:51:49 UTC 2018
- Previous message (by thread): Moving from VVT to the L-world value types (LWVT)
- Next message (by thread): Moving from VVT to the L-world value types (LWVT)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Jan 24, 2018, at 16:53, John Rose <john.r.rose at oracle.com> wrote:
On Jan 24, 2018, at 12:24 PM, Frederic Parain <frederic.parain at oracle.com> wrote:
... Do we want to describe the default value of a value class type? Perhaps we can leave these changes for Dan. The default value for the reference type is null. Which is different from the default value of an instance of a value class. The content of the default value for value class is define with the defaultvalue bytecode: "All instance variables of the instance must have their default initial values (§2.3, §2.4)." This a “pointer" vs “instance designed by the pointer” distinction. But it could be confusing. I’m open to better suggestions. Nullability is the confusing bit. Variables which are not primitives or flattened values are inherently nullable, and default to null, they are references. Even though their class is a value class. We are convincing ourselves that this is OK for variables which are JVM stack or local variables. It may also be true for fields, in some corner cases. Basically, if classfiles get out of sync, you can witness polluting nulls in variables which are not flattened. Including fields. We could restrict the confusing pollution if we could somehow ensure that field variables whose classes are value classes are always flattened, even if the class defining the field "forgot" to ask for the flattening. The practicalities of classfile evolution make this hard to enforce, so I think we are stuck with nullable value fields as a corner case: Exactly when the class "forgets" to say ACCVALUETYPE.
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.
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.
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
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 -> reading the default value of this field (uninitialized) returns the default value of its value class
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.
Bytecode quickening or JIT compilation will help avoiding the ACC_FLAT test completely for cases 1 and 2-A.
Fred
(BTW, maybe it should be ACCFLAT. So a class defined as ACCFLAT is a value class, and a field defined ACCFLAT loads the field class and inlines that class's layout, if it's a value class. Flatness is a linked but distinct property of classes and fields.)
4.1/ 4.5 From our discussion today, it sounds as though we can try Remi’s original/John’s proposal for just tracking knowledge of a value type in the class file at two places: 1) when declaring a class, the class accessflags would add ACCVALUETYPE 2) when declaring a field, the field accessflags would add ACCVALUETYPE (small note - can we use 0x100?) Fixed +100 ... 6 invoke special Where do we throw an exception if we have an method in a value class? Would that be verifier? Just in case they skip verification, might it be worth throwing an exception if the resolved method is an instance initialization method and the class is a value class - would that be an ICCE? or a NoSuchMethodError? Eventually we need to forbid object-style methods in value classes, as a local structural constraint. We can be lax to start with, since such methods will never run. Alternatively, we could allow value types to define methods but require them to be static factories. That is, they must be ACCSTATIC and must return the value type. They must also have at least one parameter, since the nullary constructor should be reserved, to denote the default value. There's no advantage to this at the JVM level, compared with regular factory methods. But such a could provide a translation strategy for the value-type version of a "new" expression. var x = Complex(0.0, -1.0); // invokestatic Complex.(DD)Complex This is a point we should discuss with the langtools team. Yes; if they want to repurpose , we can do it. Or if they want to make a new token , or some some standard string, it's up to them, I think. Today, even Valhalla Value Types have an method because javac refuses to compile a class with final fields that are not initialized in a constructor. That's why we want to be lax today, until we can tighten up the rules. It makes sense to forbid the method for value class, but there might be consequences I cannot see yet. I think it's safe to remove . I suggest we start by removing , and let the langtools people tell us what to put back in its place. — John
- Previous message (by thread): Moving from VVT to the L-world value types (LWVT)
- Next message (by thread): Moving from VVT to the L-world value types (LWVT)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]