mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8256640: assert(!m->is_old() || ik()->is_being_redefined()) failed: old methods should not be in vtable
Reviewed-by: lfoltan, dcubed, dholmes
This commit is contained in:
parent
c1407733c5
commit
fae68ff016
2 changed files with 24 additions and 5 deletions
|
@ -2571,15 +2571,21 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
|
||||||
for (int index = 0; index < num_methods; ++index) {
|
for (int index = 0; index < num_methods; ++index) {
|
||||||
methods->at(index)->restore_unshareable_info(CHECK);
|
methods->at(index)->restore_unshareable_info(CHECK);
|
||||||
}
|
}
|
||||||
|
#if INCLUDE_JVMTI
|
||||||
if (JvmtiExport::has_redefined_a_class()) {
|
if (JvmtiExport::has_redefined_a_class()) {
|
||||||
// Reinitialize vtable because RedefineClasses may have changed some
|
// Reinitialize vtable because RedefineClasses may have changed some
|
||||||
// entries in this vtable for super classes so the CDS vtable might
|
// entries in this vtable for super classes so the CDS vtable might
|
||||||
// point to old or obsolete entries. RedefineClasses doesn't fix up
|
// point to old or obsolete entries. RedefineClasses doesn't fix up
|
||||||
// vtables in the shared system dictionary, only the main one.
|
// vtables in the shared system dictionary, only the main one.
|
||||||
// It also redefines the itable too so fix that too.
|
// It also redefines the itable too so fix that too.
|
||||||
|
// First fix any default methods that point to a super class that may
|
||||||
|
// have been redefined.
|
||||||
|
bool trace_name_printed = false;
|
||||||
|
adjust_default_methods(&trace_name_printed);
|
||||||
vtable().initialize_vtable(false, CHECK);
|
vtable().initialize_vtable(false, CHECK);
|
||||||
itable().initialize_itable(false, CHECK);
|
itable().initialize_itable(false, CHECK);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// restore constant pool resolved references
|
// restore constant pool resolved references
|
||||||
constants()->restore_unshareable_info(CHECK);
|
constants()->restore_unshareable_info(CHECK);
|
||||||
|
|
|
@ -222,13 +222,22 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
|
||||||
assert(def_vtable_indices->length() == len, "reinit vtable len?");
|
assert(def_vtable_indices->length() == len, "reinit vtable len?");
|
||||||
}
|
}
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
|
bool needs_new_entry;
|
||||||
|
{
|
||||||
|
// Reduce the scope of this handle so that it is fetched again.
|
||||||
|
// The methodHandle keeps it from being deleted by RedefineClasses while
|
||||||
|
// we're using it.
|
||||||
methodHandle mh(THREAD, default_methods->at(i));
|
methodHandle mh(THREAD, default_methods->at(i));
|
||||||
assert(!mh->is_private(), "private interface method in the default method list");
|
assert(!mh->is_private(), "private interface method in the default method list");
|
||||||
bool needs_new_entry = update_inherited_vtable(mh, super_vtable_len, i, checkconstraints, CHECK);
|
needs_new_entry = update_inherited_vtable(mh, super_vtable_len, i, checkconstraints, CHECK);
|
||||||
|
}
|
||||||
|
|
||||||
// needs new entry
|
// needs new entry
|
||||||
if (needs_new_entry) {
|
if (needs_new_entry) {
|
||||||
put_method_at(mh(), initialized);
|
// Refetch this default method in case of redefinition that might
|
||||||
|
// happen during constraint checking in the update_inherited_vtable call above.
|
||||||
|
Method* method = default_methods->at(i);
|
||||||
|
put_method_at(method, initialized);
|
||||||
if (is_preinitialized_vtable()) {
|
if (is_preinitialized_vtable()) {
|
||||||
// At runtime initialize_vtable is rerun for a shared class
|
// At runtime initialize_vtable is rerun for a shared class
|
||||||
// (loaded by the non-boot loader) as part of link_class_impl().
|
// (loaded by the non-boot loader) as part of link_class_impl().
|
||||||
|
@ -494,6 +503,11 @@ bool klassVtable::update_inherited_vtable(const methodHandle& target_method,
|
||||||
allocate_new = false;
|
allocate_new = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the vtable index before the constraint check safepoint, which potentially
|
||||||
|
// redefines this method if this method is a default method belonging to a
|
||||||
|
// super class or interface.
|
||||||
|
put_method_at(target_method(), i);
|
||||||
|
|
||||||
// Do not check loader constraints for overpass methods because overpass
|
// Do not check loader constraints for overpass methods because overpass
|
||||||
// methods are created by the jvm to throw exceptions.
|
// methods are created by the jvm to throw exceptions.
|
||||||
if (checkconstraints && !target_method->is_overpass()) {
|
if (checkconstraints && !target_method->is_overpass()) {
|
||||||
|
@ -531,7 +545,6 @@ bool klassVtable::update_inherited_vtable(const methodHandle& target_method,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
put_method_at(target_method(), i);
|
|
||||||
overrides = true;
|
overrides = true;
|
||||||
if (!is_default) {
|
if (!is_default) {
|
||||||
target_method->set_vtable_index(i);
|
target_method->set_vtable_index(i);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue