Inline Record vs JLS / Reflection

forax at univ-mlv.fr forax at univ-mlv.fr
Wed Dec 16 19:39:30 UTC 2020


> De: "John Rose" <john.r.rose at oracle.com>
> À: "daniel smith" <daniel.smith at oracle.com>
> Cc: "Remi Forax" <forax at univ-mlv.fr>, "valhalla-spec-experts"
> <valhalla-spec-experts at openjdk.java.net>
> Envoyé: Mercredi 16 Décembre 2020 20:09:44
> Objet: Re: Inline Record vs JLS / Reflection

> On Dec 16, 2020, at 11:07 AM, Dan Smith < [ mailto:daniel.smith at oracle.com |
> daniel.smith at oracle.com ] > wrote:

>> I don't think we have a good answer right now, but it's something we will want
>> to address at some point. A solution would have to look like one of:

>> - Ask clients (e.g., "is this a record?" code) to adapt to the presence of the
>> '$ref' class
>> - Modify reflection to hide the '$ref' superclass somehow
>> - Change the translation strategy to not disrupt the superclass hierarchy

I will add that we also have the same issue with enums, should a primitive enum extends java.lang.Enum ? 

> The last is cleanest; the cost is resolving some technical
> debt in Valhalla, which is allowing more kinds of supers
> for primitive classes. There’s no firm reason, IMO, why
> Record could not be a super of both primitive and identity
> classes, all of which are proper records. Basically we need
> to make interfaces and abstract classes look a little more
> similar, with respect to the requirements of primitive
> classes.

yes, in the case of enum it's more difficult because ordinal and name are fields in java.lang.Enum. 

> Spoiler alert: I think the final solution will endow
> abstract classes with *both* abstract and concrete
> constructors. The former will serve primitive
> classes and the latter will serve identity classes.
> Record will be such an abstract class.

By abstract constructors, i suppose you mean empty constructors so they can be bypassed when creating a primitive type. 
It will not work with java.lang.Enum. 
For enums, we need have both constructors and factory methods and a way to ensure that they are semantically equivalent. 
One possibility is to have the VM generating the factory methods code only inside the primitive type from the chain of superclasses, doing the transformation that is currently done by the compiler at runtime. 

It can works that way, if i want a primitive enum, the constructor of java.lang.Enum has to be marked as transformable to a factory method, same thing for the constructor of the primitive enum itself. 
For java.lang.Enum an for any classes of a primitive enum, an empty factory method is generated with a descriptor, an empty body, and an attribute pointing to the corresponding constructor. 
At runtime, when the class is loaded, the VM insert the correct code in the factory method of the non abstract class. 

If the VM generates the code, we are sure that the constructor and the factory method are both equivalent. 
Another solution is to have a special verifying pass that verify that the constructor and the factory method are both equivalent, but it seems harder to me. 

[...] 

> — John

Rémi 


More information about the valhalla-spec-observers mailing list