diff --git a/src/share/vm/oops/klassVtable.cpp b/src/share/vm/oops/klassVtable.cpp index 315d97f3e1e3f03215260e94e6da4bf46502694a..61dd4c21db6530d2d1604a9158c067659c18ff71 100644 --- a/src/share/vm/oops/klassVtable.cpp +++ b/src/share/vm/oops/klassVtable.cpp @@ -663,6 +663,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, 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); @@ -684,12 +685,31 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, 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 k = superk->super(); // haven't found an override match yet; continue to look } + // 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 @@ -697,7 +717,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, 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 diff --git a/test/runtime/VtableTests/VTableTest.java b/test/runtime/VtableTests/VTableTest.java new file mode 100644 index 0000000000000000000000000000000000000000..2ca32e43f06bb8d1360d8f380a246a491bad023f --- /dev/null +++ b/test/runtime/VtableTests/VTableTest.java @@ -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(); + } +} diff --git a/test/runtime/VtableTests/pkg/A.java b/test/runtime/VtableTests/pkg/A.java new file mode 100644 index 0000000000000000000000000000000000000000..a4b7f49e715f949c5ee80cecc4d375586c1b1435 --- /dev/null +++ b/test/runtime/VtableTests/pkg/A.java @@ -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() { } +}