Skip to content
Permalink
Browse files
8268364: jmethod clearing should be done during unloading
Reviewed-by: dcubed, eosterlund
  • Loading branch information
coleenp committed Jul 2, 2021
1 parent 53ad903 commit 3d84398d128bb2eed6280ebbc3f57afb3b89908f
Showing 2 changed files with 23 additions and 16 deletions.
@@ -550,6 +550,21 @@ void ClassLoaderData::unload() {
// after erroneous classes are released.
classes_do(InstanceKlass::unload_class);

// Method::clear_jmethod_ids only sets the jmethod_ids to NULL without
// releasing the memory for related JNIMethodBlocks and JNIMethodBlockNodes.
// This is done intentionally because native code (e.g. JVMTI agent) holding
// jmethod_ids may access them after the associated classes and class loader
// are unloaded. The Java Native Interface Specification says "method ID
// does not prevent the VM from unloading the class from which the ID has
// been derived. After the class is unloaded, the method or field ID becomes
// invalid". In real world usages, the native code may rely on jmethod_ids
// being NULL after class unloading. Hence, it is unsafe to free the memory
// from the VM side without knowing when native code is going to stop using
// them.
if (_jmethod_ids != NULL) {
Method::clear_jmethod_ids(this);
}

// Clean up global class iterator for compiler
ClassLoaderDataGraph::adjust_saved_class(this);
}
@@ -694,20 +709,7 @@ ClassLoaderData::~ClassLoaderData() {
_metaspace = NULL;
delete m;
}
// Method::clear_jmethod_ids only sets the jmethod_ids to NULL without
// releasing the memory for related JNIMethodBlocks and JNIMethodBlockNodes.
// This is done intentionally because native code (e.g. JVMTI agent) holding
// jmethod_ids may access them after the associated classes and class loader
// are unloaded. The Java Native Interface Specification says "method ID
// does not prevent the VM from unloading the class from which the ID has
// been derived. After the class is unloaded, the method or field ID becomes
// invalid". In real world usages, the native code may rely on jmethod_ids
// being NULL after class unloading. Hence, it is unsafe to free the memory
// from the VM side without knowing when native code is going to stop using
// them.
if (_jmethod_ids != NULL) {
Method::clear_jmethod_ids(this);
}

// Delete lock
delete _metaspace_lock;

@@ -2254,10 +2254,15 @@ bool Method::is_method_id(jmethodID mid) {
Method* Method::checked_resolve_jmethod_id(jmethodID mid) {
if (mid == NULL) return NULL;
Method* o = resolve_jmethod_id(mid);
if (o == NULL || o == JNIMethodBlock::_free_method || !((Metadata*)o)->is_method()) {
if (o == NULL || o == JNIMethodBlock::_free_method) {
return NULL;
}
return o;
// Method should otherwise be valid. Assert for testing.
assert(is_valid_method(o), "should be valid jmethodid");
// If the method's class holder object is unreferenced, but not yet marked as
// unloaded, we need to return NULL here too because after a safepoint, its memory
// will be reclaimed.
return o->method_holder()->is_loader_alive() ? o : NULL;
};

void Method::set_on_stack(const bool value) {

1 comment on commit 3d84398

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 3d84398 Jul 2, 2021

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.