The Record Attribute - What does it mean to be a record at runtime?

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Nov 10 19:36:17 UTC 2020


> De: "Chris Hegarty" <chris.hegarty at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Mardi 10 Novembre 2020 15:23:22
> Objet: Re: The Record Attribute - What does it mean to be a record at runtime?

> Thanks for your reply Remi, comments inline.

>> On 5 Nov 2020, at 23:59, Remi Forax < [ mailto:forax at univ-mlv.fr |
>> forax at univ-mlv.fr ] > wrote:

>>> ..
>>> A recent change, 8255342 [2], laxifies the JVM checking of the Record

>> ...
>> What a record is, is defined by the JLS but not by the JVMS (like enums),
>> so the JVM should not know what a record is given that it's an artifact of the
>> language not an artifact of the VM.

> Agreed.

>> We are also trying to enforce more unmodifiability of the final fields in the
>> VM, Reflection, Unsafe, VarHandle, etc.

> Yes. And this is a good move.

>> Because of backward compatibility, we can not just make all final fields
>> unmodifiable, because some libraries (or worst some Jakarta EE specs) relies on
>> the fact that a final field can be changed after construction.
>> So we are selectively enabling a more stronger stance on the modifiability of
>> final field only for new constructs, VM anonymous class, VM hidden class and
>> record class.

> Yes, this is my understanding also.

>> Here the VM doesn't really need to know what a record is but only that this is a
>> new construct so the rules around final fields are stronger, stricter.
>> So for me, we do not need to do more in the VM.

> I agree that The Abstract JVM does not need to concern itself with the
> details of a record beyond the currently specified checks for the Record
> Attribute in the JVMS.

>> Now, for the reflection part, the reflection is mostly the Java view of the
>> world, it's not stricto sensu true because you can see the desugaring done by
>> the compiler.
>> The reflection knows what a record is, it has to directly inherits from
>> java.lang.Record, be final and have a RecordComponents attribute (gently
>> provided by the VM).
>> So both isRecord and getRecordComponents should checks these properties.

> Currently the core Java Reflection implementations determine whether a
> field is a trusted final based on information served up by the VM. One
> of the criteria that the VM uses to determine this is whether, or not,
> the field's containing class is a record. The VM asserts that a class is
> a record if it has a parsable Record attribute.

> Core reflection, however, determines a class to be a record class if the
> class is 1) a direct subclass of j.l.Record, and 2) contains a Record
> attribute.

> One option is to just update Class::isRecord to ensure, along with the
> above #1 and #2 checks, that the class is also 3) final, and
> 4) non-abstract. But this leaves a kind of impedance mismatch between
> both the VM and the libraries, and would require Core Reflection,
> MethodHandles, and VarHandles to also be updated, since their
> implementation is based on the VM's trusted final determination, whereas
> their specification is built atop Class::isRecord.

> A better option would be to update the VM implementation to only assert
> that the fields of a record-like class are trusted if that class
> contains 1) a structurally sound Record attribute, 2) is a direct
> subclass of j.l.Record, 3) is final, and 4) is non-abstract. This would
> align Core Reflection and the VM in this respect, while the JVMS would
> remain unchanged - it's an implementation detail.

No, it's pushing the JLS semantics into the JVM. 

What you want to know is if a field is trusted final or not, to disallow the creation of VarHandle, the use Unsafe, etc. 
So the JDK API should ask the VM if a field is trusted final or not instead of asking if the class is a record. 

It will also be easier to update each time you introduce a new kind of classes, by example when primitive objects will be introduced, you have only to update isTrustedFinalField and not at each place you test if a field is trusted. 

> -Chris.
Rémi 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20201110/efcfee7b/attachment-0001.htm>


More information about the amber-spec-experts mailing list