mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 09:34:38 +02:00
8268364: jmethod clearing should be done during unloading
Reviewed-by: dcubed, eosterlund
This commit is contained in:
parent
53ad903a82
commit
3d84398d12
2 changed files with 23 additions and 16 deletions
|
@ -550,6 +550,21 @@ void ClassLoaderData::unload() {
|
||||||
// after erroneous classes are released.
|
// after erroneous classes are released.
|
||||||
classes_do(InstanceKlass::unload_class);
|
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
|
// Clean up global class iterator for compiler
|
||||||
ClassLoaderDataGraph::adjust_saved_class(this);
|
ClassLoaderDataGraph::adjust_saved_class(this);
|
||||||
}
|
}
|
||||||
|
@ -694,20 +709,7 @@ ClassLoaderData::~ClassLoaderData() {
|
||||||
_metaspace = NULL;
|
_metaspace = NULL;
|
||||||
delete m;
|
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 lock
|
||||||
delete _metaspace_lock;
|
delete _metaspace_lock;
|
||||||
|
|
||||||
|
|
|
@ -2254,10 +2254,15 @@ bool Method::is_method_id(jmethodID mid) {
|
||||||
Method* Method::checked_resolve_jmethod_id(jmethodID mid) {
|
Method* Method::checked_resolve_jmethod_id(jmethodID mid) {
|
||||||
if (mid == NULL) return NULL;
|
if (mid == NULL) return NULL;
|
||||||
Method* o = resolve_jmethod_id(mid);
|
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 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) {
|
void Method::set_on_stack(const bool value) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue