From 339b0c677b406ae247a2e33a7e49b65e8b3c874e Mon Sep 17 00:00:00 2001 From: hseigel Date: Thu, 11 Jul 2019 09:26:04 -0400 Subject: [PATCH] 8226798: JVM crash in klassItable::initialize_itable_for_interface(int, InstanceKlass*, bool, Thread*) Summary: When calculating vtable size at class load time, do not look for miranda method if matching package private method is found in a super class. Reviewed-by: acorn, lfoltan --- src/share/vm/oops/klassVtable.cpp | 22 ++++++++++- test/runtime/VtableTests/VTableTest.java | 50 ++++++++++++++++++++++++ test/runtime/VtableTests/pkg/A.java | 28 +++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 test/runtime/VtableTests/VTableTest.java create mode 100644 test/runtime/VtableTests/pkg/A.java diff --git a/src/share/vm/oops/klassVtable.cpp b/src/share/vm/oops/klassVtable.cpp index 315d97f3e..61dd4c21d 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 000000000..2ca32e43f --- /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 000000000..a4b7f49e7 --- /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() { } +} -- GitLab