To sanity check the JVMS changes relative to “transitive” overriding in the 
JVMS update for JEP 181: nestmates: 
http://cr.openjdk.java.net/~dlsmith/nestmates.html 
<http://cr.openjdk.java.net/~dlsmith/nestmates.html>

The first goal here is to ensure that we are all in agreement on the intended 
behavior of invoke virtual relative
to transitive overriding. Once we are sure about that - then we can 
double-check that the new wording of 5.4.4.
Overriding works for all of us. While I agree that the transitive overriding 
only applies in cases where there
is a package private method in the hierarchy, it is not the case that it only 
applies if the resolved method is
package private.

I went back to the pre-default method changes in JDK7 when the transitive 
overriding was added to find the
reasoning, examples, and in particular to find the test cases which 
demonstrated a change in behavior in invoke virtual
due to the JVMS change from JVMS 2nd edition to JVMS 3rd edition based on the 
JVMS Clarifications and Addenda
to 2nd edition. I have appended first my notes at the time, then the explicit 
list of tests that had behavioral changes
due to the JVMS change for us.

In practice, we create a virtual method table, or vtable, at preparation time, 
as an invoke virtual selection cache.
The conceptual model is that each potential resolved class creates a new index 
in the vtable which will be overridden
for each potential receiver to contain the selected method based on the search 
and overriding rules.
To save space we actually don’t always create a new index - if A.m is public 
and B extends A has public m as well,
they can share an index. We are extremely careful that any package private 
method does create a new index
because even if it overrides a superclass’s public method, a subclass may not 
override it.

So the theory is that we are testing overriding on the root of the index. In 
practice we are testing overriding
of the latest overrider. I think that is where we have a translation from the 
JVMS and need to make sure
we are all saying the same thing.

The set of tests that changed behavior when we added the transitive overriding 
all look like:
 
class A public or protected m()
class B extends A package private m()
class C extends B public or protected or package private m()

call: invoke virtual A.m object ref C

The old result was B.m or AME (if B.m is abstract), the new result was C.m 
(unless IAE due to caller access of A.m protected)

I am appending my notes from the change at the time.
Below that is the test matrix reporting the tests that changed and the results 
are listed as : 1.6 results/1.7 expected results.

We are internally in the process of cleaning up the tests and making them open 
jtreg tests. They currently use a very old ASM.
However you can find them in JDK-8163974. Give a shout if you need help 
figuring out how to run them.
If you run them on our jvm - you might need to run -Xint -Xverify:none right 
now.

thanks,
Karen


Here are my notes from the change at the time:
Changes in Invoke-Virtual behavior due to specification changes 
With classfile version 51, which will be introduced in JDK7, the invokevirtual 
behavior will be fixed to match the clarifications in the JVMS which were made 
to handle the following test case: 

Sample test case from: Why the Definition of Method Override was Revised 
<http://java.sun.com/docs/books/jls/method-override-rationale.html>
package P1;

class A {
  void m(){System.out.println("A.m");}
  public void callM(){ m();}
}

public class B extends A {
   protected void m() { System.out.println("B.m");}
}

package P2;

class C extends P1.B {
  protected void m(){ System.out.println("C.m");}

  public static void main(String[] args) {
    C c = new C();
    c.callM();
}

Given the original definition of override, we find that the method m() declared 
in C overrides the method m() declared in B(), since it has the same name and 
signature and is accessible from class C. However, we a lso find that the 
method m() declared in C does not override the method m() declared in A(), 
since it is pr ivate to package P1 and therefore not accessible from class C.

In this case, invoking callM() on an instance of C causes a call of m() where 
the target of the method invocation is an instance of C as well. However, this 
call is in the class P1.A, and is attempting to invoke a package private method 
of A. Since this method is not overridden by C, the code will not print "C.m" 
as expected. Instead, it prints "B.m".

This is quite unintuitive, and also incompatible with the behavior of the 
classic VM.

We believe that this interpretation, while literally accurate, is undesirable. 
It prevents a package private method from ever being overridden outside its 
package, even if a subclass within the package has increased the method's 
accessibility.
* Invokevirtual modifications: * Invokevirtual, JVMS Clarifications and Addenda 
to 2nd edition
Let C be the class of objectref. The actual method to be invoked is selected by 
the following lookup procedure:
If C contains a declaration for an instance method M with the same name and 
descriptor as the resolved method, and M overrides the resolved method, then M 
is the method to be invoked, and the lookup procedure terminates.
Otherwise, if C has a superclass, this same lookup procedure is performed 
recursively using the direct superclass of C ; the method to be invoked is the 
result of the recursive invocation of this lookup procedure.
Otherwise, an AbstractMethodError? 
<http://j2se.us.oracle.com/web/bin/edit/HotspotRuntime/AbstractMethodError?topicparent=HotspotRuntime.VtableAccess>
 is raised.

JVMS 2nd edition invokevirtual:
Let C be the class of objectref. The actual method to be invoked is selected by 
the following lookup procedure:
If C contains a declaration for an instance method with the same name and 
descriptor as the resolved method, and the resolved method is accessible from 
C, then this is the method to be invoked, and the lookup procedure terminates.
Otherwise, if C has a superclass, this same lookup procedure is performed 
recursively using the direct superclass of C ; the method to be invoked is the 
result of the recursive invocation of this lookup procedure.
Otherwise, an AbstractMethodError? 
<http://j2se.us.oracle.com/web/bin/edit/HotspotRuntime/AbstractMethodError?topicparent=HotspotRuntime.VtableAccess>
 is raised.
Note: the key difference here is the phrase: "the resolved method is accessible 
from C" which in the Clarifications and Addenda has been replaced with "M 
overrides the resolved method”
Inheritance rules: JLS 3rd edition, 8.4.8 Inheritance, Overriding, and Hiding
A class C inherits from its direct superclass and direct superinterfaces all 
non-private methods (whether abstract or not) of the superclass and 
superinterfaces that are public, protected or declared with default access in 
the same package as C and are neither overridden ('8.4.8.1) nor hidden 
('8.4.8.2) by a declaration in the class.

JLS 3rd edition 8.4.8.1 Overriding (by Instance Methods)
An instance method m1 declared in a class C overrides another instance method, 
m2, declared in class A iff all of the following are true:
      1. C is a subclass of A.
      2. The signature of m1 is a subsignature (§8.4.2) of the signature of m2.
      3. Either
         o m2 is public, protected or declared with default access in the same 
package as C, or
         o m1 overrides a method m3, m3 distinct from m1, m3 distinct from m2, 
such that m3 overrides m2.
Moreover, if m1 is not abstract, then m1 is said to implement any and all 
declarations of abstract methods that it overrides.

Note that based on the JVMS 3rd edition transitive overriding rules, we need to 
do an override check first for the direct superclass and if the current class 
does not override the direct superclass, recursively for the superclass' 
superclass.
Thanks to Alex Buckley and Vladimir V. Ivanov for help understanding this.

========

Invokevirtual behavior differences between JDK 1.6 and upcoming 1.7.
Changes in behavior due to clarification of overriding behavior as transitive,
clarified Invokevirtual JVMS 3rd edition and JLS 3rd edition: 8.4.8.1 
Overriding (by Instance Methods)

This test represents a run of a 1.6 JDK relative to 1.7 expected results.
The 1.6 results are listed/expected results are listed. In all of these 
examples,
B.m was the old expected result (sometimes resulting in AME),
but with the clarification of overriding behavior as transitive, C.m is now the 
expected result.

       Method access modifiers                            Call site location    
           Status
  #   A.m()        B.m()        C.m()              A     pkgA      B      pkgB  
   C     pkgC
-------------------------------------------------------------------------------------------------
 841|   A PUB        a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
 842| ! A PUB        a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
 843|   A PUB      ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
 844| ! A PUB      ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
 845|   A PUB        a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
 846| ! A PUB        a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
 847|   A PUB      ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
 848| ! A PUB      ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
 849|   A PUB        a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
 850| ! A PUB        a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
 851|   A PUB      ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
 852| ! A PUB      ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
 941|   A PROT       a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m     IAE |   FAILED
 942| ! A PROT       a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m     IAE |   FAILED
 943|   A PROT     ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m     IAE |   FAILED
 944| ! A PROT     ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m     IAE |   FAILED
 945|   A PROT       a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m     IAE |   FAILED
 946| ! A PROT       a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m     IAE |   FAILED
 947|   A PROT     ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m     IAE |   FAILED
 948| ! A PROT     ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m     IAE |   FAILED
 949|   A PROT       a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m     IAE |   FAILED
 950| ! A PROT       a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m     IAE |   FAILED
 951|   A PROT     ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m     IAE |   FAILED
 952| ! A PROT     ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m     IAE |   FAILED
1641|   a.A PUB      a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
1642| ! a.A PUB      a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
1643|   a.A PUB    ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
1644| ! a.A PUB    ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
1645|   a.A PUB      a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
1646| ! a.A PUB      a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
1647|   a.A PUB    ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
1648| ! a.A PUB    ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
1649|   a.A PUB      a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
1650| ! a.A PUB      a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
1651|   a.A PUB    ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
1652| ! a.A PUB    ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
1741|   a.A PROT     a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m     IAE |   FAILED
1742| ! a.A PROT     a.B PP     b.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m     IAE |   FAILED
1743|   a.A PROT   ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m     IAE |   FAILED
1744| ! a.A PROT   ! a.B PP     b.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m     IAE |   FAILED
1745|   a.A PROT     a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m     IAE |   FAILED
1746| ! a.A PROT     a.B PP     b.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m     IAE |   FAILED
1747|   a.A PROT   ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m     IAE |   FAILED
1748| ! a.A PROT   ! a.B PP     b.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m     IAE |   FAILED
1749|   a.A PROT     a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m     IAE |   FAILED
1750| ! a.A PROT     a.B PP     b.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m     IAE |   FAILED
1751|   a.A PROT   ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m     IAE |   FAILED
1752| ! a.A PROT   ! a.B PP     b.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m     IAE |   FAILED
2041|   a.A PUB      b.B PP     a.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
2042| ! a.A PUB      b.B PP     a.C PUB     |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
2043|   a.A PUB    ! b.B PP     a.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
2044| ! a.A PUB    ! b.B PP     a.C PUB     |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
2045|   a.A PUB      b.B PP     a.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
2046| ! a.A PUB      b.B PP     a.C PROT    |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
2047|   a.A PUB    ! b.B PP     a.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
2048| ! a.A PUB    ! b.B PP     a.C PROT    |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
2049|   a.A PUB      b.B PP     a.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
2050| ! a.A PUB      b.B PP     a.C PP      |  B.m/C.m B.m/C.m B.m/C.m B.m/C.m 
B.m/C.m B.m/C.m |   FAILED
2051|   a.A PUB    ! b.B PP     a.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
2052| ! a.A PUB    ! b.B PP     a.C PP      |  AME/C.m AME/C.m AME/C.m AME/C.m 
AME/C.m AME/C.m |   FAILED
2141|   a.A PROT     b.B PP     a.C PUB     |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m B.m/C.m |   FAILED
2142| ! a.A PROT     b.B PP     a.C PUB     |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m B.m/C.m |   FAILED
2143|   a.A PROT   ! b.B PP     a.C PUB     |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m AME/C.m |   FAILED
2144| ! a.A PROT   ! b.B PP     a.C PUB     |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m AME/C.m |   FAILED
2145|   a.A PROT     b.B PP     a.C PROT    |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m B.m/C.m |   FAILED
2146| ! a.A PROT     b.B PP     a.C PROT    |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m B.m/C.m |   FAILED
2147|   a.A PROT   ! b.B PP     a.C PROT    |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m AME/C.m |   FAILED
2148| ! a.A PROT   ! b.B PP     a.C PROT    |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m AME/C.m |   FAILED
2149|   a.A PROT     b.B PP     a.C PP      |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m B.m/C.m |   FAILED
2150| ! a.A PROT     b.B PP     a.C PP      |  B.m/C.m B.m/C.m B.m/C.m     IAE 
B.m/C.m B.m/C.m |   FAILED
2151|   a.A PROT   ! b.B PP     a.C PP      |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m AME/C.m |   FAILED
2152| ! a.A PROT   ! b.B PP     a.C PP      |  AME/C.m AME/C.m AME/C.m     IAE 
AME/C.m AME/C.m |   FAILED




Reply via email to