8213751: ClassLoaderDataGraph::cld_do() should sometimes require CLDG_lock
authorcoleenp
Fri, 16 Nov 2018 07:30:40 -0500
changeset 52586 74109912c738
parent 52585 f7f90fddce02
child 52587 6cd56deebb0d
8213751: ClassLoaderDataGraph::cld_do() should sometimes require CLDG_lock Summary: Add version of loaded_cld_do for runtime calls. Reviewed-by: eosterlund, rehn
src/hotspot/share/classfile/classLoaderDataGraph.cpp
src/hotspot/share/classfile/classLoaderDataGraph.hpp
src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp
src/hotspot/share/classfile/classLoaderStats.cpp
src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp
src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp
src/hotspot/share/memory/metaspace.cpp
--- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Fri Nov 16 07:30:40 2018 -0500
@@ -230,13 +230,6 @@
   return loader_data;
 }
 
-void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
-  assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
-  for (ClassLoaderData* cld = _head;  cld != NULL; cld = cld->_next) {
-    cl->do_cld(cld);
-  }
-}
-
 void ClassLoaderDataGraph::cld_unloading_do(CLDClosure* cl) {
   assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
   // Only walk the head until any clds not purged from prior unloading
@@ -247,6 +240,15 @@
   }
 }
 
+// These are functions called by the GC, which require all of the CLDs, including the
+// unloading ones.
+void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
+  assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
+  for (ClassLoaderData* cld = _head;  cld != NULL; cld = cld->_next) {
+    cl->do_cld(cld);
+  }
+}
+
 void ClassLoaderDataGraph::roots_cld_do(CLDClosure* strong, CLDClosure* weak) {
   assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
   for (ClassLoaderData* cld = _head;  cld != NULL; cld = cld->_next) {
@@ -286,9 +288,12 @@
   HandleMark       _hm;  // clean up handles when this is done.
   Handle           _holder;
   Thread*          _thread;
+  NoSafepointVerifier _nsv; // No safepoints allowed in this scope
+                            // unless verifying at a safepoint.
 
 public:
-  ClassLoaderDataGraphIterator() : _next(ClassLoaderDataGraph::_head) {
+  ClassLoaderDataGraphIterator() : _next(ClassLoaderDataGraph::_head),
+     _nsv(true, !SafepointSynchronize::is_at_safepoint()) {
     _thread = Thread::current();
     assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
   }
@@ -308,9 +313,14 @@
     }
     return cld;
   }
-
+};
 
-};
+void ClassLoaderDataGraph::loaded_cld_do(CLDClosure* cl) {
+  ClassLoaderDataGraphIterator iter;
+  while (ClassLoaderData* cld = iter.get_next()) {
+    cl->do_cld(cld);
+  }
+}
 
 // These functions assume that the caller has locked the ClassLoaderDataGraph_lock
 // if they are not calling the function from a safepoint.
--- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Fri Nov 16 07:30:40 2018 -0500
@@ -73,6 +73,8 @@
   static void cld_unloading_do(CLDClosure* cl);
   static void roots_cld_do(CLDClosure* strong, CLDClosure* weak);
   static void always_strong_cld_do(CLDClosure* cl);
+  // Iteration through CLDG not by GC.
+  static void loaded_cld_do(CLDClosure* cl);
   // klass do
   // Walking classes through the ClassLoaderDataGraph include array classes.  It also includes
   // classes that are allocated but not loaded, classes that have errors, and scratch classes
--- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp	Fri Nov 16 07:30:40 2018 -0500
@@ -515,7 +515,7 @@
     assert(SafepointSynchronize::is_at_safepoint(), "must be a safepoint");
     ResourceMark rm;
     LoaderInfoScanClosure cl (_show_classes, _verbose);
-    ClassLoaderDataGraph::cld_do(&cl);
+    ClassLoaderDataGraph::loaded_cld_do(&cl);
     // In non-verbose and non-show-classes mode, attempt to fold the tree.
     if (_fold) {
       if (!_verbose && !_show_classes) {
--- a/src/hotspot/share/classfile/classLoaderStats.cpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/classfile/classLoaderStats.cpp	Fri Nov 16 07:30:40 2018 -0500
@@ -159,7 +159,7 @@
 
 void ClassLoaderStatsVMOperation::doit() {
   ClassLoaderStatsClosure clsc (_out);
-  ClassLoaderDataGraph::cld_do(&clsc);
+  ClassLoaderDataGraph::loaded_cld_do(&clsc);
   clsc.print();
 }
 
--- a/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp	Fri Nov 16 07:30:40 2018 -0500
@@ -103,6 +103,7 @@
 }
 
 SaveRestoreCLDClaimBits::SaveRestoreCLDClaimBits() : _claim_state_closure() {
+  // interferes with GC, so walk all oops that GC would.
   ClassLoaderDataGraph::cld_do(&_claim_state_closure);
 }
 
--- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Fri Nov 16 07:30:40 2018 -0500
@@ -495,7 +495,7 @@
 
   void doit() {
     JfrClassLoaderStatsClosure clsc;
-    ClassLoaderDataGraph::cld_do(&clsc);
+    ClassLoaderDataGraph::loaded_cld_do(&clsc);
     clsc.createEvents();
   }
 };
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Fri Nov 16 07:30:40 2018 -0500
@@ -939,7 +939,7 @@
     ClassLoaderDataGraph::cld_unloading_do(&cld_cb);
     return;
   }
-  ClassLoaderDataGraph::cld_do(&cld_cb);
+  ClassLoaderDataGraph::loaded_cld_do(&cld_cb);
 }
 
 static void clear_artifacts(JfrArtifactSet* artifacts,
--- a/src/hotspot/share/memory/metaspace.cpp	Thu Nov 15 17:08:59 2018 +0100
+++ b/src/hotspot/share/memory/metaspace.cpp	Fri Nov 16 07:30:40 2018 -0500
@@ -616,7 +616,7 @@
     out->cr();
   }
 
-  ClassLoaderDataGraph::cld_do(&cl); // collect data and optionally print
+  ClassLoaderDataGraph::loaded_cld_do(&cl); // collect data and optionally print
 
   // Print totals, broken up by space type.
   if (print_by_spacetype) {