8232112: MDO extra_data_lock leaks during class unloading
authorcoleenp
Thu, 17 Oct 2019 07:35:22 -0400
changeset 58668 eda750f21308
parent 58664 e3618c902d17
child 58669 931ec3339786
8232112: MDO extra_data_lock leaks during class unloading Summary: call the MDO destructor during class unloading. Reviewed-by: dholmes, eosterlund
src/hotspot/share/oops/instanceKlass.cpp
src/hotspot/share/oops/method.cpp
src/hotspot/share/oops/method.hpp
src/hotspot/share/oops/methodData.hpp
--- a/src/hotspot/share/oops/instanceKlass.cpp	Mon Oct 14 11:36:17 2019 +0200
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Thu Oct 17 07:35:22 2019 -0400
@@ -2497,10 +2497,18 @@
 #endif
 }
 
+static void method_release_C_heap_structures(Method* m) {
+  m->release_C_heap_structures();
+}
+
 void InstanceKlass::release_C_heap_structures(InstanceKlass* ik) {
   // Clean up C heap
   ik->release_C_heap_structures();
   ik->constants()->release_C_heap_structures();
+
+  // Deallocate and call destructors for MDO mutexes
+  ik->methods_do(method_release_C_heap_structures);
+
 }
 
 void InstanceKlass::release_C_heap_structures() {
--- a/src/hotspot/share/oops/method.cpp	Mon Oct 14 11:36:17 2019 +0200
+++ b/src/hotspot/share/oops/method.cpp	Thu Oct 17 07:35:22 2019 -0400
@@ -118,11 +118,6 @@
 void Method::deallocate_contents(ClassLoaderData* loader_data) {
   MetadataFactory::free_metadata(loader_data, constMethod());
   set_constMethod(NULL);
-#if INCLUDE_JVMCI
-  if (method_data()) {
-    FailedSpeculation::free_failed_speculations(method_data()->get_failed_speculations_address());
-  }
-#endif
   MetadataFactory::free_metadata(loader_data, method_data());
   set_method_data(NULL);
   MetadataFactory::free_metadata(loader_data, method_counters());
@@ -131,6 +126,16 @@
   if (code() != NULL) _code = NULL;
 }
 
+void Method::release_C_heap_structures() {
+  if (method_data()) {
+#if INCLUDE_JVMCI
+    FailedSpeculation::free_failed_speculations(method_data()->get_failed_speculations_address());
+#endif
+    // Destroy MethodData
+    method_data()->~MethodData();
+  }
+}
+
 address Method::get_i2c_entry() {
   assert(adapter() != NULL, "must have");
   return adapter()->get_i2c_entry();
--- a/src/hotspot/share/oops/method.hpp	Mon Oct 14 11:36:17 2019 +0200
+++ b/src/hotspot/share/oops/method.hpp	Thu Oct 17 07:35:22 2019 -0400
@@ -1006,6 +1006,8 @@
   // Deallocation function for redefine classes or if an error occurs
   void deallocate_contents(ClassLoaderData* loader_data);
 
+  void release_C_heap_structures();
+
   Method* get_new_method() const {
     InstanceKlass* holder = method_holder();
     Method* new_method = holder->method_with_idnum(orig_method_idnum());
--- a/src/hotspot/share/oops/methodData.hpp	Mon Oct 14 11:36:17 2019 +0200
+++ b/src/hotspot/share/oops/methodData.hpp	Thu Oct 17 07:35:22 2019 -0400
@@ -2445,7 +2445,7 @@
   virtual void metaspace_pointers_do(MetaspaceClosure* iter);
   virtual MetaspaceObj::Type type() const { return MethodDataType; }
 
-  // Deallocation support - no pointer fields to deallocate
+  // Deallocation support - no metaspace pointer fields to deallocate
   void deallocate_contents(ClassLoaderData* loader_data) {}
 
   // GC support