Skip to content

Commit

Permalink
8256640: assert(!m->is_old() || ik()->is_being_redefined()) failed: o…
Browse files Browse the repository at this point in the history
…ld methods should not be in vtable

Reviewed-by: lfoltan, dcubed, dholmes
  • Loading branch information
coleenp committed Nov 19, 2020
1 parent c140773 commit fae68ff
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
6 changes: 6 additions & 0 deletions src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2571,15 +2571,21 @@ void InstanceKlass::restore_unshareable_info(ClassLoaderData* loader_data, Handl
for (int index = 0; index < num_methods; ++index) {
methods->at(index)->restore_unshareable_info(CHECK);
}
#if INCLUDE_JVMTI
if (JvmtiExport::has_redefined_a_class()) {
// Reinitialize vtable because RedefineClasses may have changed some
// entries in this vtable for super classes so the CDS vtable might
// point to old or obsolete entries. RedefineClasses doesn't fix up
// vtables in the shared system dictionary, only the main one.
// 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);
itable().initialize_itable(false, CHECK);
}
#endif

// restore constant pool resolved references
constants()->restore_unshareable_info(CHECK);
Expand Down
23 changes: 18 additions & 5 deletions src/hotspot/share/oops/klassVtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,22 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
assert(def_vtable_indices->length() == len, "reinit vtable len?");
}
for (int i = 0; i < len; i++) {
methodHandle mh(THREAD, default_methods->at(i));
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);
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));
assert(!mh->is_private(), "private interface method in the default method list");
needs_new_entry = update_inherited_vtable(mh, super_vtable_len, i, checkconstraints, CHECK);
}

// 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()) {
// At runtime initialize_vtable is rerun for a shared class
// (loaded by the non-boot loader) as part of link_class_impl().
Expand Down Expand Up @@ -494,6 +503,11 @@ bool klassVtable::update_inherited_vtable(const methodHandle& target_method,
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
// methods are created by the jvm to throw exceptions.
if (checkconstraints && !target_method->is_overpass()) {
Expand Down Expand Up @@ -531,7 +545,6 @@ bool klassVtable::update_inherited_vtable(const methodHandle& target_method,
}
}

put_method_at(target_method(), i);
overrides = true;
if (!is_default) {
target_method->set_vtable_index(i);
Expand Down

1 comment on commit fae68ff

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.