Nestmates JVMS changes to selection and behavior implications

Karen Kinnear karen.kinnear at oracle.com
Wed Jan 3 16:16:06 UTC 2018


After discussions with David Holmes, I have updated the description to note that there were three changes
to invokeinterface selection - so we can discuss which ones we actually want.

.pdf copied below since it was stripped in earlier emails. Focus of the discussion on potential changes is
on invokeinterface selection changes.

thanks,
Karen

=======

Invocation changes due to the December 2017 Nestmates JVMS proposal: http://cr.openjdk.java.net/~dlsmith/nestmates.html <http://cr.openjdk.java.net/~dlsmith/nestmates.html> are described below.
In studying the details of these changes, there are three sets of changes that change the behavior of invokeinterface.
Invokeinterface is allowed to resolve to a private member of the reference class, and the resolved method becomes the selected method. 
The removal of the invokeinterface selection runtime access check, allows selection of a package-private or protected method, since they can override a public method from the resolution step.
The combining of the invokeinterface selection and invokevirtual selection (and equivalent preparation modifications) add the concept of "overrides" to the invokeinterface selection lookup steps. Note that private methods never override and are never overridden. The consequence of this change is that the invokeinterface selection lookup will now SKIP private methods as invokevirtual does, where before it would find the private method and throw an IllegalAccessError.
I am proposing that for nestmates we do not need the second change, and that we could continue to have invokeinterface and invokevirtual selection be aligned, while keeping the restriction that if the selection lookup procedure selects a method that is not public, invokeinterface throws an IllegalAccessError. (This would continue to allow resolution to a private member, select the same private member). This prevents adding additional cases in which the caller is able to invoke a method it can not directly access.
For the 3rd change we have two ways to approach this. We can leave the existing invokeinterface selection/preparation alone, find private methods in the receiver and its superclasses, and throw an IllegalAccessError, or we can make the proposed changes and skip private methods as we do for invokevirtual (because of the term "overrides") and potentially find a public method that overrides the resolved method.

Invokeinterface Selection Changes:
JVMS 6.5 Invokeinterface changes
Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure: The selected method (5.4.5 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.5>) for class C of an invocation of the referenced method is the actual method to be invoked.
If C contains a declaration for an instance method with the same name and descriptor as the resolved method, then it is the method to be invoked.
Otherwise, if C has a superclass, a search for a declaration of an instance method with the same name and descriptor as the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until a match is found or no further superclasses exist. If a match is found, then it is the method to be invoked.
Otherwise, if there is exactly one maximally-specific method (5.4.3.3 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.3.1>) in the superinterfaces of C that matches the resolved method's name and descriptor and is not abstract, then it is the method to be invoked...
Linking Exceptions
Otherwise, if the resolved method is static or private, the invokeinterface instruction throws an IncompatibleClassChangeError.
Run-time Exceptions
Otherwise, if step 1 or step 2 of the lookup procedure selects a method that is not public, invokeinterface throws an IllegalAccessError.
This is the line that we believe could be restored, slightly modified to apply to the selection lookup procedure steps in 5.4.5, so that the only non-public selected method would be a private method which is the referenced method as well as the selected method.
5.4.5 Selection new section:
Where an invokevirtual or an invokeinterface invocation refers to a resolved method mR, the selected method of the invocation for an instance of a class or interface C is determined as follows:
If mR is marked ACC_PRIVATE, then it is the selected method.
Otherwise, the selected method is determined by the following lookup procedure:
If C contains a declaration for an instance method m that can override the resolved method, then m is the selected method.
Otherwise, if C has a superclass, a search for a declaration of an instance method that can override the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until a method is found or no further superclasses exist. If a method is found, it is the selected method.
Otherwise, if there is exactly one maximally-specific method (5.4.3.3 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.3.1>) in the superinterfaces of C that matches the resolved method's name and descriptor and is not abstract, then it is the selected method.
Note that any maximally-specific method selected in this step can override mR; there is no need to check this explicitly.
While C will typically be a class, it may be an interface when these rules are applied during preparation (5.4.2 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.2>).
Beyond improving presentation, this change has the following effects:
Addresses JDK-8098577 <https://bugs.openjdk.java.net/browse/JDK-8098577>: if an invokevirtual resolves to an interface method, C or one of its superclasses may override the interface method.
Prevents private methods from being selected by invokeinterface, unless the private method is also the referenced method.

InvokeInterface Selection Table
Summary: Current nestmates JVMS proposal: Invokeinterface has been modified to support private members as well as to be more consistent with invoke virtual by defining selection based on overriding, which does not change any success cases, and does change some IAE cases to become success cases.

Color coding: The current proposal makes both the green and the red changes. 
The proposed modification would only make the green changes, i.e. only change behavior relative to private methods
support for referenced method is private -> == selected method
support for selection lookup skipping private methods in 

 
 
Resolved Method
X Selected Method
selected:
local
C.m
public
local
C.m
Prot/PP
C.m
private
SuperC.m
(includes Object.m)
public
SuperC.m
(includes Object.m)
Prot/PP
SuperC.m
Object.m
private
SuperJ.m
Pub/def
resolved:
local I.m private
old: IAE check, then ICCE
new: I.m
old:N/A
new:I.m
-	-	-	-	-	-	-
local I.m public	-	C.m	
old:IAE
new: C.m
old: IAE
new: skip
SuperC.m
old: IAE
new: SuperC.m
old: IAE
new: skip
max-specific
Object public m	-	C.m	
old: IAE
new: C.m
old: IAE
new: skip
SuperC.m	
old: IAE
new: SuperC.m
old: IAE
new: skip
-
SuperI: public default	-	C.m	
old: IAE
new: C.m
old: IAE
new: skip
SuperC.m	
old: IAE
new: SuperC.m
old: IAE
new: skip
max-specific
SuperI: public (abstract)	-	C.m	
old: IAE
new: C.m
old: IAE
new: skip
SuperC.m	
old: IAE
new: SuperC.m
old: IAE
new: skip
max-specific
 
Key:
Rows are Resolved Method, Columns are available methods for selection
SuperC is a super class, SuperI is a super interface of I, SuperJ is a super interface of C
Not in this table:
If the selected method in local, SuperC, Object or SuperJ is Abstract -> AME unchanged.
If there is more than one maximally-specific method -> ICCE unchanged
If there are zero maximally-specific methods -> AME unchanged
If there are private methods in SuperI at resolution time, they are skipped -> unchanged
If there are private methods in SuperJ at selection time, they are skipped -> unchanged

Additional checks performed on source:
double-check all the AME error handling
I do not believe these cases have changed
are there any error cases in which we change what error we throw?
I do not believe so
are there cases in preparation in which we check loader constraints, which actually throw exceptions?
Hotspot does not check loader constraints for exception throwing cases
Invokevirtual Selection Changes (8098577)
6.5 Invokevirtual
Let C be the class of objectref. The actual method to be invoked is selected by the following lookup procedure: The selected method (5.4.5 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.5>) for class C of an invocation of the referenced method is the actual method to be invoked.
If C contains a declaration for an instance method m that overrides (5.4.5 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.5>) the resolved method, then m is the method to be invoked.
Otherwise, if C has a superclass, a search for a declaration of an instance method that overrides the resolved method is performed, starting with the direct superclass of C and continuing with the direct superclass of that class, and so forth, until an overriding method is found or no further superclasses exist. If an overriding method is found, it is the method to be invoked.
Otherwise, if there is exactly one maximally-specific method (5.4.3.3 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.3.1>) in the superinterfaces of C that matches the resolved method's name and descriptor and is not abstract, then it is the method to be invoked.
JVMS 5.4.5 Overriding new section on common selection rules 
Addresses JDK-8098577 <https://bugs.openjdk.java.net/browse/JDK-8098577>: if an invokevirtual resolves to an interface method, C or one of its superclasses may override the interface method.
Invokevirtual behavior changes
If a resolved method was private and in the same class as the caller, prior to this change, I do not see a clear selection definition since overriding does not apply to private methods. Implementation kept resolved == selected which is now clearly spelled out in the specification.
Clarification: SuperC.m private, C extends SuperC. SuperC invoke virtual C.m, resolves to SuperC.m private
Old and new specification should continue to allow invokevirtual of SuperC.m via C.m. New specification would extend this for nestmates.
Addresses JDK-8098577 <https://bugs.openjdk.java.net/browse/JDK-8098577>: if an invokevirtual resolves to an interface method, C or one of its superclasses may override the interface method.
update from Dan H - this is not a behavioral change, this is a clarification in the specification.
Preparation Changes:
5.4.2 Preparation (changes)
During preparation of a class or interface C, the Java Virtual Machine also imposes loading constraints (5.3.4 <https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-5.html#jvms-5.3.4>). Let L1 be the defining loader of C. For each instance method m declared in C that overrides can override (5.4.5 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.5>) a an instance method declared in a superclass or superinterface <D, L2>, the Java Virtual Machine imposes the following loading constraints: ...
Furthermore, if C implements a for each instance method m declared in a superinterface <I, L3> of C, but if C does not itself declare the method an instance method that can override m, then let <D, L2> be the superclass of C that declares the implementation of method m inherited by C. The if the selected method (5.4.5 <http://cr.openjdk.java.net/~dlsmith/nestmates.html#jep181-5.4.5>) for class or interface C of an invocation of m is declared in a class or interface <D, L2>, the Java Virtual Machine imposes the following constraints: ...
Changes in Preparation relative to Selection Behavior:
Summary: New specification is more accurate than the old one. It is still challenging to map to the implementation.
One example, prior to nestmates, the hotspot implementation treated the second paragraph as if it said "if C implements an ACC_PUBLIC method". We did not perform loader constraints for cases in which the selected method would throw an exception, since the intention of preparation is loader constraint checking when creating a selection cache.
With nestmates, and the modification to use the term override to match the common selection description, this would also allow ACC_PROTECTED and package private methods to be selected, and therefore have their loader constraints checked.
All agreed that an interface method never overrides a class method (even for the java.lang.Object case).
An interface method can override another interface method





> On Dec 20, 2017, at 10:45 AM, Karen Kinnear <karen.kinnear at oracle.com> wrote:
> 
> David Holmes and I were studying the JVMS changes for nestmates - in particular the selection and preparation changes which
> are designed to make invoke interface more like invoke virtual (JDK-8024806).
> 
> I wanted to ensure that the behavior changes were all either error -> success, or error 1 -> error 2.
> 
> As I went through this again, I had a couple more questions on the JVMS changes for selection preparation to sanity check.
> 
> thanks,
> Karen
> 
> <Nestmates Invocation Changes - Java Platform Group - wiki.se.pdf>
> 
> 
> 



More information about the valhalla-spec-observers mailing list