提交 339b0c67 编写于 作者: H hseigel

8226798: JVM crash in klassItable::initialize_itable_for_interface(int,...

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
上级 2e08558e
......@@ -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
......
/*
* 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();
}
}
/*
* 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() { }
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册