JDK-8159215 : Tighten checks for final field updates
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • Submitted: 2016-06-10
  • Updated: 2017-11-06
  • Resolved: 2016-07-21
Related Reports
Blocks :  
Blocks :  
Relates :  
Description
In Java SE 5.0, the JVM Specification tightened up checks for putfield and putstatic bytecodes targeting final fields. For example, putfield changed in the following way:

- JVMS Second Edition (1999, prior to Java SE 5.0) [1]: "Otherwise, if the field is final, it must be declared in the current class. Otherwise, an IllegalAccessError is thrown."

- JVMS updates for Java SE 5.0 (2004) [2]: "Otherwise, if the field is final, it must be declared in the current class, and the instruction must occur in an instance initialization method (<init>) of the current class. Otherwise, an IllegalAccessError is thrown."

The HotSpot VM did not implement the new checks until JDK-8157181. However, the changes by JDK-8157181 have introduced the checks only for class files with version 9 and onwards.

The goal of the current bug is to investigate if the new checks should be tightened up to Java 7 and/or 8.

[1] JVMS Second Edition, section 6.4: https://docs.oracle.com/javase/specs/jvms/se6/html/Instructions2.doc11.html
[2] JVMS updates for Java SE 5.0: https://jcp.org/aboutJava/communityprocess/maintenance/jsr924/index.html -> open "The Java Virtual Machine Instruction Set" -> jump to putfield.
Comments
Can you open bugs for the testbase changes and notify Jython? We can fix testbase in advance of this change going in.
01-07-2016

Thank you, Alex, for the clarification!
01-07-2016

My understanding was that the new verifier was written because the old verifier was so full of holes you could drive a bytecode truck through it. However, if old classes failed with the new verifier we would allow them to be checked by the old verifier instead. The only difference I see is that this case is about a single rule the VM was not enforcing, while the new verifier patched many rules. But it is Alex's call. I waved the compatibility flag and the majority vote seems to be to ignore it. So be it.
01-07-2016

JDK-8157181 is the same issue as this, though for the JIT rather than the interpreter. What I wrote there applies here as well: "I recommend the HotSpot fix in this bug does NOT inspect class file version." The failover-to-old-verifier rule is not a good comparison. It involved a major new mechanism for which old class files were not prepared, despite nothing being "wrong" with those old class files per se. Gating the new mechanism by class file version made sense. In the case of final fields, an old class file that assigns to one outside the appropriate initialization method is very much in the wrong, so gating the putfield/putstatic logic by class file version is unnecessary.
30-06-2016

My recollection is that we have several times added classfile version checks when enforcing JVMS rules. Just consider the failover-to-old-verifier case!
30-06-2016

Hi Alex ([~abuckley]), could you please tell us your opinion about implementing the checks introduced by JVMS-7 also for class files with version 7 and 8 (and not only 9, as it was implemented by JDK-8157181)? Thank you very much in advance! Best regards, Zoltan
30-06-2016

Adding [~abuckley] - we'd decided not to have a classfile version check for JDK-8145148. We should probably make the same decision here. As part of the query for that bug, it was noted that there weren't any existing classfile version checks to selectively enforce rules in the jvm specification.
29-06-2016