8226798: JVM crash in klassItable::initialize_itable_for_interface(int, InstanceKlass*, bool, Thread*)
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
This commit is contained in:
parent
5cb091693d
commit
5e24afc868
@ -638,6 +638,7 @@ bool klassVtable::needs_new_vtable_entry(const methodHandle& target_method,
|
|||||||
Method* super_method = NULL;
|
Method* super_method = NULL;
|
||||||
InstanceKlass *holder = NULL;
|
InstanceKlass *holder = NULL;
|
||||||
Method* recheck_method = NULL;
|
Method* recheck_method = NULL;
|
||||||
|
bool found_pkg_prvt_method = false;
|
||||||
while (k != NULL) {
|
while (k != NULL) {
|
||||||
// lookup through the hierarchy for a method with matching name and sign.
|
// lookup through the hierarchy for a method with matching name and sign.
|
||||||
super_method = InstanceKlass::cast(k)->lookup_method(name, signature);
|
super_method = InstanceKlass::cast(k)->lookup_method(name, signature);
|
||||||
@ -659,6 +660,16 @@ bool klassVtable::needs_new_vtable_entry(const methodHandle& target_method,
|
|||||||
return false;
|
return false;
|
||||||
// else keep looking for transitive overrides
|
// 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
|
// Start with lookup result and continue to search up, for versions supporting transitive override
|
||||||
@ -669,6 +680,15 @@ bool klassVtable::needs_new_vtable_entry(const methodHandle& target_method,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
// if the target method is public or protected it may have a matching
|
||||||
// miranda method in the super, whose entry it should re-use.
|
// miranda method in the super, whose entry it should re-use.
|
||||||
// Actually, to handle cases that javac would not generate, we need
|
// Actually, to handle cases that javac would not generate, we need
|
||||||
|
50
test/hotspot/jtreg/runtime/VtableTests/VTableTest.java
Normal file
50
test/hotspot/jtreg/runtime/VtableTests/VTableTest.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
28
test/hotspot/jtreg/runtime/VtableTests/pkg/A.java
Normal file
28
test/hotspot/jtreg/runtime/VtableTests/pkg/A.java
Normal file
@ -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() { }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user