8213751: ClassLoaderDataGraph::cld_do() should sometimes require CLDG_lock
Summary: Add version of loaded_cld_do for runtime calls.
Reviewed-by: eosterlund, rehn
--- 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) {