> De: "Chris Hegarty" <[email protected]> > À: "Remi Forax" <[email protected]> > Cc: "amber-spec-experts" <[email protected]> > 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:[email protected] | >> [email protected] ] > 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
