Draft JVMS changes for Nestmates
daniel.smith at oracle.com
Wed Apr 19 22:58:20 UTC 2017
One other topic to add to this thread, which I forgot to mention: compatibility.
Sometimes JVMS changes need to be guarded by rules that preserve old behavior for old class file version numbers, in order to prevent changes in behavior when an old class is run on a new JVM. My hope is that there's no need for such logic here.
Here's my analysis. Let me know if you can think of any other cases, or if you feel that any of these changes are concerning.
- The MemberOfNest and NestMembers attributes are illegal prior to 54.0. So well-formed older classes always belong to singleton nests—they can't claim membership in a different nest, and can't act as hosts.
- Access control for private members declared in or called from old class files then degenerates to the old rule: the private member must be declared by the calling class.
- The verification-time checks on the referenced class of an invokespecial have been moved to resolution time. Some cases:
- Referencing a public method in a disallowed class used to be a VerifyError*; now it's a IAE at resolution time
- Referencing a private method in a disallowed class used to be a VerifyError; now it's an IAE at resolution time
- Referencing a private method in a subclass that resolves to a member of the current class used to be a VerifyError; now it's allowed.
- Referencing a nonexistent method in a disallowed class used to be a VerifyError; now it's a NSME at resolution time
- Referencing a static method in a disallowed class used to be a VerifyError; now it's a ICCE at resolution time
(*Confirmed with some testing, although I found that referencing an indirect superinterface caused an ICCE, apparently at resolution time.)
- The verification-time restriction on the target reference stack type of an invokespecial is only enforced if the referenced class is a superclass and the resolved method is non-private. Only change here (besides those outlined above due to a reference to a non-superclass) is that a private method referenced in a superclass that used to get a VerifyError (due to a disallowed stack type) will now get an IAE at resolution time.
- Verification is more eager to resolve classes and methods referenced by `invokespecial`. The change in class loading only affects programs that would have had VerifyErrors before (for a reference to a disallowed class—superclasses are already loaded). The change in method resolution may be visible, depending on how the implementation chooses to handle errors. But flexibility for these sorts of changes is granted by 5.4.
- As described in the comment in 5.4.4, tweaking the applicability of the `protected` access referenced class restriction causes some IAEs to become ICCEs or NSMEs.
- The runtime checks added to `invokespecial` introduce some new ICCEs when the current class or referenced class are interfaces.
Summary: almost all of these are simply changes in the error produced, and perhaps in the timing of errors being reported, depending on when resolution happens. There's one case where the new rules for private invokespecial allow something that was an error before (fine). There's also one case where new errors are introduced, but that would be a deliberate choice in response to a bug report.
More information about the valhalla-spec-observers