--- old/src/hotspot/share/oops/klassVtable.cpp 2019-07-10 14:02:01.003787219 -0400 +++ new/src/hotspot/share/oops/klassVtable.cpp 2019-07-10 14:02:00.862458525 -0400 @@ -638,6 +638,7 @@ Method* super_method = NULL; InstanceKlass *holder = NULL; Method* recheck_method = NULL; + bool found_pkg_prvt_method = false; while (k != NULL) { // lookup through the hierarchy for a method with matching name and sign. super_method = InstanceKlass::cast(k)->lookup_method(name, signature); @@ -659,6 +660,16 @@ return false; // else keep looking for transitive overrides } + // If we get here then one of the super classes has a package private method + // that will not get overridden because it is in a different package. But, + // that package private method does "override" any matching methods in super + // interfaces, so there will be no miranda vtable entry created. So, set flag + // to TRUE for use below, in case there are no methods in super classes that + // this target method overrides. + assert(super_method->is_package_private(), "super_method must be package private"); + assert(!superk->is_same_class_package(classloader(), classname), + "Must be different packages"); + found_pkg_prvt_method = true; } // Start with lookup result and continue to search up, for versions supporting transitive override @@ -669,6 +680,15 @@ } } + // If found_pkg_prvt_method is set, then the ONLY matching method in the + // superclasses is package private in another package. That matching method will + // prevent a miranda vtable entry from being created. Because the target method can not + // override the package private method in another package, then it needs to be the root + // for its own vtable entry. + if (found_pkg_prvt_method) { + return true; + } + // if the target method is public or protected it may have a matching // miranda method in the super, whose entry it should re-use. // Actually, to handle cases that javac would not generate, we need @@ -676,7 +696,7 @@ const InstanceKlass *sk = InstanceKlass::cast(super); if (sk->has_miranda_methods()) { if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) { - return false; // found a matching miranda; we do not need a new entry + return false; // found a matching miranda; we do not need a new entry } } return true; // found no match; we need a new entry --- /dev/null 2019-07-07 00:27:35.580000035 -0400 +++ new/test/hotspot/jtreg/runtime/VtableTests/VTableTest.java 2019-07-10 14:02:01.358015147 -0400 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8226798 + * @summary Check that the vTable for class C gets set up without causing + * an assertion failure. + * @compile pkg/A.java + * @run main VTableTest + */ + +public class VTableTest { + + interface Intf { + public default void m() { } + public default void unusedButNeededToReproduceIssue() { } + } + + static class B extends pkg.A implements Intf { + } + + static class C extends B { + public void m() { System.out.println("In C.m()"); } + } + + public static void main(String[] args) { + new C().m(); + } +} --- /dev/null 2019-07-07 00:27:35.580000035 -0400 +++ new/test/hotspot/jtreg/runtime/VtableTests/pkg/A.java 2019-07-10 14:02:01.795082097 -0400 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +public class A { + void m() { } +}