Fri, 05 Aug 2016 10:47:35 +0000
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
src/share/vm/oops/method.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/oops/method.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/oops/method.cpp Mon Aug 08 13:17:49 2016 -0700 1.2 +++ b/src/share/vm/oops/method.cpp Fri Aug 05 10:47:35 2016 +0000 1.3 @@ -111,6 +111,7 @@ 1.4 // Release Method*. The nmethod will be gone when we get here because 1.5 // we've walked the code cache. 1.6 void Method::deallocate_contents(ClassLoaderData* loader_data) { 1.7 + clear_jmethod_id(loader_data); 1.8 MetadataFactory::free_metadata(loader_data, constMethod()); 1.9 set_constMethod(NULL); 1.10 MetadataFactory::free_metadata(loader_data, method_data()); 1.11 @@ -1800,6 +1801,17 @@ 1.12 #endif // ASSERT 1.13 *m = _free_method; 1.14 } 1.15 + void clear_method(Method* m) { 1.16 + for (JNIMethodBlock* b = this; b != NULL; b = b->_next) { 1.17 + for (int i = 0; i < number_of_methods; i++) { 1.18 + if (b->_methods[i] == m) { 1.19 + b->_methods[i] = NULL; 1.20 + return; 1.21 + } 1.22 + } 1.23 + } 1.24 + // not found 1.25 + } 1.26 1.27 // During class unloading the methods are cleared, which is different 1.28 // than freed. 1.29 @@ -1872,7 +1884,9 @@ 1.30 1.31 bool Method::is_method_id(jmethodID mid) { 1.32 Method* m = resolve_jmethod_id(mid); 1.33 - assert(m != NULL, "should be called with non-null method"); 1.34 + if (m == NULL) { 1.35 + return false; 1.36 + } 1.37 InstanceKlass* ik = m->method_holder(); 1.38 if (ik == NULL) { 1.39 return false; 1.40 @@ -1905,6 +1919,10 @@ 1.41 } 1.42 } 1.43 1.44 +void Method::clear_jmethod_id(ClassLoaderData* loader_data) { 1.45 + loader_data->jmethod_ids()->clear_method(this); 1.46 +} 1.47 + 1.48 // Called when the class loader is unloaded to make all methods weak. 1.49 void Method::clear_jmethod_ids(ClassLoaderData* loader_data) { 1.50 loader_data->jmethod_ids()->clear_all_methods();
2.1 --- a/src/share/vm/oops/method.hpp Mon Aug 08 13:17:49 2016 -0700 2.2 +++ b/src/share/vm/oops/method.hpp Fri Aug 05 10:47:35 2016 +0000 2.3 @@ -768,6 +768,8 @@ 2.4 2.5 // Helper routines for intrinsic_id() and vmIntrinsics::method(). 2.6 void init_intrinsic_id(); // updates from _none if a match 2.7 + void clear_jmethod_id(ClassLoaderData* loader_data); 2.8 + 2.9 static vmSymbols::SID klass_id_for_intrinsics(Klass* holder); 2.10 2.11 bool jfr_towrite() { return _jfr_towrite; }