提交 6d0adddb 编写于 作者: S shshahma

8161144: Fix for JDK-8147451 failed: Crash in Method::checked_resolve_jmethod_id(_jmethodID*)

Summary: Method::deallocate_contents() should clear 'this' from list of Methods in JNIMethodBlock, when class is unloaded.
Reviewed-by: coleenp, dholmes
上级 3c449145
...@@ -111,6 +111,7 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) { ...@@ -111,6 +111,7 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
// Release Method*. The nmethod will be gone when we get here because // Release Method*. The nmethod will be gone when we get here because
// we've walked the code cache. // we've walked the code cache.
void Method::deallocate_contents(ClassLoaderData* loader_data) { void Method::deallocate_contents(ClassLoaderData* loader_data) {
clear_jmethod_id(loader_data);
MetadataFactory::free_metadata(loader_data, constMethod()); MetadataFactory::free_metadata(loader_data, constMethod());
set_constMethod(NULL); set_constMethod(NULL);
MetadataFactory::free_metadata(loader_data, method_data()); MetadataFactory::free_metadata(loader_data, method_data());
...@@ -1800,6 +1801,17 @@ class JNIMethodBlock : public CHeapObj<mtClass> { ...@@ -1800,6 +1801,17 @@ class JNIMethodBlock : public CHeapObj<mtClass> {
#endif // ASSERT #endif // ASSERT
*m = _free_method; *m = _free_method;
} }
void clear_method(Method* m) {
for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
for (int i = 0; i < number_of_methods; i++) {
if (b->_methods[i] == m) {
b->_methods[i] = NULL;
return;
}
}
}
// not found
}
// During class unloading the methods are cleared, which is different // During class unloading the methods are cleared, which is different
// than freed. // than freed.
...@@ -1872,7 +1884,9 @@ void Method::change_method_associated_with_jmethod_id(jmethodID jmid, Method* ne ...@@ -1872,7 +1884,9 @@ void Method::change_method_associated_with_jmethod_id(jmethodID jmid, Method* ne
bool Method::is_method_id(jmethodID mid) { bool Method::is_method_id(jmethodID mid) {
Method* m = resolve_jmethod_id(mid); Method* m = resolve_jmethod_id(mid);
assert(m != NULL, "should be called with non-null method"); if (m == NULL) {
return false;
}
InstanceKlass* ik = m->method_holder(); InstanceKlass* ik = m->method_holder();
if (ik == NULL) { if (ik == NULL) {
return false; return false;
...@@ -1905,6 +1919,10 @@ void Method::set_on_stack(const bool value) { ...@@ -1905,6 +1919,10 @@ void Method::set_on_stack(const bool value) {
} }
} }
void Method::clear_jmethod_id(ClassLoaderData* loader_data) {
loader_data->jmethod_ids()->clear_method(this);
}
// Called when the class loader is unloaded to make all methods weak. // Called when the class loader is unloaded to make all methods weak.
void Method::clear_jmethod_ids(ClassLoaderData* loader_data) { void Method::clear_jmethod_ids(ClassLoaderData* loader_data) {
loader_data->jmethod_ids()->clear_all_methods(); loader_data->jmethod_ids()->clear_all_methods();
......
...@@ -768,6 +768,8 @@ class Method : public Metadata { ...@@ -768,6 +768,8 @@ class Method : public Metadata {
// Helper routines for intrinsic_id() and vmIntrinsics::method(). // Helper routines for intrinsic_id() and vmIntrinsics::method().
void init_intrinsic_id(); // updates from _none if a match void init_intrinsic_id(); // updates from _none if a match
void clear_jmethod_id(ClassLoaderData* loader_data);
static vmSymbols::SID klass_id_for_intrinsics(Klass* holder); static vmSymbols::SID klass_id_for_intrinsics(Klass* holder);
bool jfr_towrite() { return _jfr_towrite; } bool jfr_towrite() { return _jfr_towrite; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册