changeset 8155:d18eb5b5a3d6

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
author shshahma
date Fri, 05 Aug 2016 10:47:35 +0000
parents 56ff16dd9b8c
children 1ccd27199595
files src/share/vm/oops/method.cpp src/share/vm/oops/method.hpp
diffstat 2 files changed, 21 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/oops/method.cpp	Mon Aug 08 13:17:49 2016 -0700
+++ b/src/share/vm/oops/method.cpp	Fri Aug 05 10:47:35 2016 +0000
@@ -111,6 +111,7 @@
 // Release Method*.  The nmethod will be gone when we get here because
 // we've walked the code cache.
 void Method::deallocate_contents(ClassLoaderData* loader_data) {
+  clear_jmethod_id(loader_data);
   MetadataFactory::free_metadata(loader_data, constMethod());
   set_constMethod(NULL);
   MetadataFactory::free_metadata(loader_data, method_data());
@@ -1800,6 +1801,17 @@
 #endif // ASSERT
     *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
   // than freed.
@@ -1872,7 +1884,9 @@
 
 bool Method::is_method_id(jmethodID 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();
   if (ik == NULL) {
     return false;
@@ -1905,6 +1919,10 @@
   }
 }
 
+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.
 void Method::clear_jmethod_ids(ClassLoaderData* loader_data) {
   loader_data->jmethod_ids()->clear_all_methods();
--- a/src/share/vm/oops/method.hpp	Mon Aug 08 13:17:49 2016 -0700
+++ b/src/share/vm/oops/method.hpp	Fri Aug 05 10:47:35 2016 +0000
@@ -768,6 +768,8 @@
 
   // Helper routines for intrinsic_id() and vmIntrinsics::method().
   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);
 
   bool     jfr_towrite()                { return _jfr_towrite;              }