-
Notifications
You must be signed in to change notification settings - Fork 5.8k
8257596: Clarify trusted final fields for record classes #1706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back mchung! A progress list of the required criteria for merging this PR into |
/label add hotspot-runtime |
@mlchung |
@mlchung |
Mailing list message from Remi Forax on hotspot-dev: ----- Mail original -----
Hi Mandy,
It's not an issue, the JVM view of what a record is and the JLS view of what a record is doesn't have to be identical, We already had this discussion on amber-spec-expert list, We already know that the JLS definition of a record will have to be changed for inline record (an inline record is not direct subclass of j.l.Record because you have the reference projection in the middle). The real issue is that the JIT optimisation and Field.set() should be aligned, VarHandle deosn't let you change a final field and Unsafe is unsafe, so the current problem is that Field.set() relies on the reflection api by calling Class.isRecord() which is not good because Classs.isRecord() returns the JLS view of the world not the JVM view of the world. As said in the mail chain above, for the JIT optimization, instead of listing all the new constructs, record, inline, etc, i propose to check the other way, only allow to set a final field is only allowed for plain old java class, so the VM should not have a method InstanceKlass::is_record but a method that return if a class is a plain class or not and this method should be called by the JIT and by Field.set (through a JVM entry point) The more we inject the Java (the language) semantics in the JVM the less it is useful for other languages that run one the JVM. R?mi
R?mi |
Hi Remi,
What is the conclusion (sorry it was unclear to me)? Drop TNSFF for records? This issue is to fix the regression introduced by JDK-8255342. I expect someone else will file a new JBS issue and implement what amber-spec-experts decided.
Yes I saw that. I updated JDK-8251041 to follow up.
I agree the current situation is not ideal which requires to declare all the new constructs explicitly for TNSFF. However, it's a reasonable tradeoff to get the JIT optimization for records in time while waiting for true TNSFF investigation like JMM and other relevant specs. I see this just a stop-gap solution. When the long-term TNSFF is in place, the spec can be updated to drop the explicit list of record, inline, etc. A related issue is JDK-8233873. I'm happy if we can do TNSFF in a different solution. Again this PR intends to fix the regression. Two options:
I expect Chris and/or others will follow up the decision made by the amber-spec-experts w.r.t. trusting finals in records. I'm okay with either option. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Mandy,
Could you regression test this change against the JCK lang and vm test suites and Mach5 tiers 1 and 2?
Thanks, Harold
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Mandy,
Could you replace the comment starting at line 1854 in jvm.cpp with:
// A class is a record if and only if it is final and a direct subclass
// of java.lang.Record and the presence of Record
attribute;
// otherwise, it is not a record.
Also, replace the comment starting at line 1872 in jvm.cpp with:
// Returns an array containing the components of the Record attribute,
// or NULL if the attribute is not present.
//
// Note that this function returns the components of the Record
// attribute even if the class is not a Record.
Also, please change the name of the attribute in the comments added
to Class.java from RecordComponent to Record.
Thanks, Harold
@mlchung This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 44 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
Mailing list message from Remi Forax on core-libs-dev: ----- Mail original -----
For me, it's backout JDK-8247444, as i said on the amber-spec-expert, i prefer VM to be oblivious about java.lang.Record. And there are also a related issue with the validation of the InnerClass/Enclosing attribute were the VM does a handshake between the inner class attribute and the enclosing class attribute when calling Class.getSimpleName(), again using the JLS definition of what an inner class is instead of using the VM definition, the content of the InnerClass attribute with no validation. R?mi |
Hi Remi,
This reply was before you realized that records are are permanent Java SE 16 feature :-) If the future ended up requiring/desiring to allow final fields of a record class be modifiable reflectively (I double that!),
It's the implementation details of the core reflection how to determine if a class is a member of another class. The |
I have created a new branch off jdk16: https://github.com/mlchung/jdk16/tree/8257596. It fixed the attribute name as Harold pointed out. @hseigel tier1-tier3 and jck-runtime:vm and jck-runtime:lang tests all passed. |
Target this fix for jdk16 (openjdk/jdk16#14). |
This is a follow-up on JDK-8255342 that removes non-specified JVM checks on classes with
RecordComponents
attributes. That introduces a regression inInstanceKlass::is_record
that returns true on a non-record class which hasRecordComponents
attribute present. This causes unexpected semantics inJVM_IsRecord
andJVM_GetRecordComponents
and also a regression to trust final fields for non-record classes.I propose to change
InstanceKlass::is_record
to match the JLS semantic of a record class, i.e. final direct subclass ofjava.lang.Record
with the presence ofRecordComponents
attribute. There is no change to JVM class file validation. Also I propose clearly define:-
JVM_IsRecord
returns true if the given class is a record i.e. final and direct subclass ofjava.lang.Record
withRecordComponents
attribute-
JVM_GetRecordComponents
returns anRecordComponents
array ifRecordComponents
attribute is present; otherwise, returns NULL. This does not check if it's a record class or not. So it may return non-null on a non-record class if it hasRecordComponents
attribute. SoJVM_GetRecordComponents
returns the content of the classfile.Progress
Issue
Reviewers
Download
$ git fetch https://git.openjdk.java.net/jdk pull/1706/head:pull/1706
$ git checkout pull/1706