Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8275800: Redefinition leaks MethodData::_extra_data_lock #6105

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1638,7 +1638,8 @@ bool InstanceKlass::find_field_from_offset(int offset, bool is_static, fieldDesc
void InstanceKlass::methods_do(void f(Method* method)) {
// Methods aren't stable until they are loaded. This can be read outside
// a lock through the ClassLoaderData for profiling
if (!is_loaded()) {
// Redefined scratch classes are on the list and need to be cleaned
if (!is_loaded() && !is_scratch_class()) {
return;
}

@@ -2682,22 +2683,22 @@ static void method_release_C_heap_structures(Method* m) {
}

void InstanceKlass::release_C_heap_structures() {

// Clean up C heap
release_C_heap_structures_internal();
constants()->release_C_heap_structures();

// Deallocate and call destructors for MDO mutexes
methods_do(method_release_C_heap_structures);
}

// Called also by InstanceKlass::deallocate_contents
void InstanceKlass::release_C_heap_structures_internal() {
coleenp marked this conversation as resolved.
Show resolved Hide resolved
Klass::release_C_heap_structures();

// Can't release the constant pool here because the constant pool can be
// deallocated separately from the InstanceKlass for default methods and
// redefine classes.

// Deallocate and call destructors for MDO mutexes
methods_do(method_release_C_heap_structures);

// Deallocate oop map cache
if (_oop_map_cache != NULL) {
delete _oop_map_cache;
@@ -3988,8 +3989,6 @@ void InstanceKlass::purge_previous_version_list() {
// so will be deallocated during the next phase of class unloading.
log_trace(redefine, class, iklass, purge)
("previous version " INTPTR_FORMAT " is dead.", p2i(pv_node));
// For debugging purposes.
pv_node->set_is_scratch_class();
// Unlink from previous version list.
assert(pv_node->class_loader_data() == loader_data, "wrong loader_data");
InstanceKlass* next = pv_node->previous_versions();
@@ -4104,8 +4103,6 @@ void InstanceKlass::add_previous_version(InstanceKlass* scratch_class,
ConstantPool* cp_ref = scratch_class->constants();
if (!cp_ref->on_stack()) {
log_trace(redefine, class, iklass, add)("scratch class not added; no methods are running");
// For debugging purposes.
scratch_class->set_is_scratch_class();
scratch_class->class_loader_data()->add_to_deallocate_list(scratch_class);
return;
}
@@ -4404,6 +4404,9 @@ void VM_RedefineClasses::redefine_single_class(Thread* current, jclass the_jclas

the_class->set_has_been_redefined();

// Scratch class is unloaded but still needs cleaning, and skipping for CDS.
scratch_class->set_is_scratch_class();

// keep track of previous versions of this class
the_class->add_previous_version(scratch_class, emcp_method_count);