8275800: Redefinition leaks MethodData::_extra_data_lock

Reviewed-by: sspitsyn, dholmes
This commit is contained in:
Coleen Phillimore 2021-10-27 12:09:46 +00:00
parent 485d65865e
commit 40606021ee
5 changed files with 19 additions and 24 deletions

View file

@ -583,7 +583,10 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
// Release C heap allocated data that this points to, which includes
// reference counting symbol names.
release_C_heap_structures_internal();
// Can't release the constant pool here because the constant pool can be
// deallocated separately from the InstanceKlass for default methods and
// redefine classes.
release_C_heap_structures(/* release_constant_pool */ false);
deallocate_methods(loader_data, methods());
set_methods(NULL);
@ -1638,7 +1641,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;
}
@ -2681,22 +2685,13 @@ static void method_release_C_heap_structures(Method* m) {
m->release_C_heap_structures();
}
void InstanceKlass::release_C_heap_structures() {
// Called also by InstanceKlass::deallocate_contents, with false for release_constant_pool.
void InstanceKlass::release_C_heap_structures(bool release_constant_pool) {
// Clean up C heap
release_C_heap_structures_internal();
constants()->release_C_heap_structures();
Klass::release_C_heap_structures();
// Deallocate and call destructors for MDO mutexes
methods_do(method_release_C_heap_structures);
}
void InstanceKlass::release_C_heap_structures_internal() {
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 oop map cache
if (_oop_map_cache != NULL) {
@ -2732,6 +2727,10 @@ void InstanceKlass::release_C_heap_structures_internal() {
#endif
FREE_C_HEAP_ARRAY(char, _source_debug_extension);
if (release_constant_pool) {
constants()->release_C_heap_structures();
}
}
void InstanceKlass::set_source_debug_extension(const char* array, int length) {
@ -3988,8 +3987,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 +4101,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;
}