# HG changeset patch # User coleenp # Date 1542371440 18000 # Node ID 74109912c7383b2c7fca3d43cae844f575d1326c # Parent f7f90fddce02bf79ad4e5e69fd5f4bedfd25334e 8213751: ClassLoaderDataGraph::cld_do() should sometimes require CLDG_lock Summary: Add version of loaded_cld_do for runtime calls. Reviewed-by: eosterlund, rehn diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/classfile/classLoaderDataGraph.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. diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/classfile/classLoaderDataGraph.hpp --- 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 diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp --- 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) { diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/classfile/classLoaderStats.cpp --- 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(); } diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp --- 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); } diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/jfr/periodic/jfrPeriodic.cpp --- 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(); } }; diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp --- 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, diff -r f7f90fddce02 -r 74109912c738 src/hotspot/share/memory/metaspace.cpp --- 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) {