--- old/src/hotspot/share/classfile/classLoaderDataGraph.cpp 2018-11-14 07:09:54.256154104 -0500 +++ new/src/hotspot/share/classfile/classLoaderDataGraph.cpp 2018-11-14 07:09:53.976154113 -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_oops_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) { @@ -257,12 +259,12 @@ } } -void ClassLoaderDataGraph::always_strong_cld_do(CLDClosure* cl) { +void ClassLoaderDataGraph::always_strong_cld_oops_do(CLDClosure* cl) { assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock); if (ClassUnloading) { roots_cld_do(cl, NULL); } else { - cld_do(cl); + cld_oops_do(cl); } } @@ -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,25 @@ } return cld; } +}; +void ClassLoaderDataGraph::cld_do(CLDClosure* cl) { + ClassLoaderDataGraphIterator iter; + while (ClassLoaderData* cld = iter.get_next()) { + cl->do_cld(cld); + } +} -}; +void ClassLoaderDataGraph::always_strong_cld_do(CLDClosure* cl) { + assert_locked_or_safepoint(ClassLoaderDataGraph_lock); + if (ClassUnloading) { + // The keep_alive bits are only so GC doesn't unload the classes prematurely, + // not for tools to find. + cl->do_cld(ClassLoaderData::the_null_class_loader_data()); + } else { + cld_do(cl); + } +} // These functions assume that the caller has locked the ClassLoaderDataGraph_lock // if they are not calling the function from a safepoint. --- old/src/hotspot/share/classfile/classLoaderDataGraph.hpp 2018-11-14 07:09:54.624154091 -0500 +++ new/src/hotspot/share/classfile/classLoaderDataGraph.hpp 2018-11-14 07:09:54.356154100 -0500 @@ -69,9 +69,12 @@ static void purge(); static void clear_claimed_marks(); // Iteration through CLDG inside a safepoint; GC support - static void cld_do(CLDClosure* cl); + static void cld_oops_do(CLDClosure* cl); static void cld_unloading_do(CLDClosure* cl); static void roots_cld_do(CLDClosure* strong, CLDClosure* weak); + static void always_strong_cld_oops_do(CLDClosure* cl); + // Iteration through CLDG not by GC. + static void cld_do(CLDClosure* cl); static void always_strong_cld_do(CLDClosure* cl); // klass do // Walking classes through the ClassLoaderDataGraph include array classes. It also includes --- old/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp 2018-11-14 07:09:55.004154078 -0500 +++ new/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp 2018-11-14 07:09:54.724154087 -0500 @@ -2445,7 +2445,7 @@ verify_work_stacks_empty(); VerifyCLDOopsCLDClosure verify_cld_oops(verification_mark_bm()); - ClassLoaderDataGraph::cld_do(&verify_cld_oops); + ClassLoaderDataGraph::cld_oops_do(&verify_cld_oops); // Marking completed -- now verify that each bit marked in // verification_mark_bm() is also marked in markBitMap(); flag all @@ -4084,7 +4084,7 @@ // SSS: Add equivalent to ScanMarkedObjectsAgainCarefullyClosure::do_yield_check and should_abort_preclean? // SSS: We should probably check if precleaning should be aborted, at suitable intervals? PrecleanCLDClosure preclean_closure(cl); - ClassLoaderDataGraph::cld_do(&preclean_closure); + ClassLoaderDataGraph::cld_oops_do(&preclean_closure); verify_work_stacks_empty(); verify_overflow_empty(); @@ -4448,7 +4448,7 @@ // Scan all classes that was dirtied during the concurrent marking phase. RemarkCLDClosure remark_closure(&par_mrias_cl); - ClassLoaderDataGraph::cld_do(&remark_closure); + ClassLoaderDataGraph::cld_oops_do(&remark_closure); _timer.stop(); log_trace(gc, task)("Finished dirty CLD scanning work in %dth thread: %3.3f sec", worker_id, _timer.seconds()); @@ -4985,7 +4985,7 @@ verify_work_stacks_empty(); RemarkCLDClosure remark_closure(&mrias_cl); - ClassLoaderDataGraph::cld_do(&remark_closure); + ClassLoaderDataGraph::cld_oops_do(&remark_closure); verify_work_stacks_empty(); } --- old/src/hotspot/share/gc/parallel/pcTasks.cpp 2018-11-14 07:09:55.516154060 -0500 +++ new/src/hotspot/share/gc/parallel/pcTasks.cpp 2018-11-14 07:09:55.228154070 -0500 @@ -111,7 +111,7 @@ case class_loader_data: { CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong); - ClassLoaderDataGraph::always_strong_cld_do(&cld_closure); + ClassLoaderDataGraph::always_strong_cld_oops_do(&cld_closure); } break; --- old/src/hotspot/share/gc/parallel/psMarkSweep.cpp 2018-11-14 07:09:55.900154046 -0500 +++ new/src/hotspot/share/gc/parallel/psMarkSweep.cpp 2018-11-14 07:09:55.620154056 -0500 @@ -523,7 +523,7 @@ Management::oops_do(mark_and_push_closure()); JvmtiExport::oops_do(mark_and_push_closure()); SystemDictionary::oops_do(mark_and_push_closure()); - ClassLoaderDataGraph::always_strong_cld_do(follow_cld_closure()); + ClassLoaderDataGraph::always_strong_cld_oops_do(follow_cld_closure()); // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure())); AOTLoader::oops_do(mark_and_push_closure()); @@ -620,7 +620,7 @@ Management::oops_do(adjust_pointer_closure()); JvmtiExport::oops_do(adjust_pointer_closure()); SystemDictionary::oops_do(adjust_pointer_closure()); - ClassLoaderDataGraph::cld_do(adjust_cld_closure()); + ClassLoaderDataGraph::cld_oops_do(adjust_cld_closure()); // Now adjust pointers in remaining weak roots. (All of which should // have been cleared if they pointed to non-surviving objects.) --- old/src/hotspot/share/gc/parallel/psParallelCompact.cpp 2018-11-14 07:09:56.292154033 -0500 +++ new/src/hotspot/share/gc/parallel/psParallelCompact.cpp 2018-11-14 07:09:56.004154043 -0500 @@ -2214,7 +2214,7 @@ JvmtiExport::oops_do(&oop_closure); SystemDictionary::oops_do(&oop_closure); CLDToOopClosure cld_closure(&oop_closure, ClassLoaderData::_claim_strong); - ClassLoaderDataGraph::cld_do(&cld_closure); + ClassLoaderDataGraph::cld_oops_do(&cld_closure); // Now adjust pointers in remaining weak roots. (All of which should // have been cleared if they pointed to non-surviving objects.) --- old/src/hotspot/share/gc/parallel/psTasks.cpp 2018-11-14 07:09:56.716154018 -0500 +++ new/src/hotspot/share/gc/parallel/psTasks.cpp 2018-11-14 07:09:56.436154028 -0500 @@ -81,7 +81,7 @@ case class_loader_data: { PSScavengeCLDClosure cld_closure(pm); - ClassLoaderDataGraph::cld_do(&cld_closure); + ClassLoaderDataGraph::cld_oops_do(&cld_closure); } break; --- old/src/hotspot/share/gc/shared/cardTableRS.cpp 2018-11-14 07:09:57.084154005 -0500 +++ new/src/hotspot/share/gc/shared/cardTableRS.cpp 2018-11-14 07:09:56.812154015 -0500 @@ -58,7 +58,7 @@ bool CLDRemSet::mod_union_is_clear() { HasAccumulatedModifiedOopsClosure closure; - ClassLoaderDataGraph::cld_do(&closure); + ClassLoaderDataGraph::cld_oops_do(&closure); return !closure.found(); } @@ -75,7 +75,7 @@ void CLDRemSet::clear_mod_union() { ClearCLDModUnionClosure closure; - ClassLoaderDataGraph::cld_do(&closure); + ClassLoaderDataGraph::cld_oops_do(&closure); } --- old/src/hotspot/share/gc/z/zRootsIterator.cpp 2018-11-14 07:09:57.480153991 -0500 +++ new/src/hotspot/share/gc/z/zRootsIterator.cpp 2018-11-14 07:09:57.204154001 -0500 @@ -243,7 +243,7 @@ void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) { ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph); CLDToOopClosure cld_cl(cl, _marking ? ClassLoaderData::_claim_strong : ClassLoaderData::_claim_none); - ClassLoaderDataGraph::cld_do(&cld_cl); + ClassLoaderDataGraph::cld_oops_do(&cld_cl); } void ZConcurrentRootsIterator::oops_do(ZRootsIteratorClosure* cl) { --- old/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp 2018-11-14 07:09:57.860153978 -0500 +++ new/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp 2018-11-14 07:09:57.584153988 -0500 @@ -103,7 +103,8 @@ } SaveRestoreCLDClaimBits::SaveRestoreCLDClaimBits() : _claim_state_closure() { - ClassLoaderDataGraph::cld_do(&_claim_state_closure); + // interferes with GC, so walk all oops that GC would. + ClassLoaderDataGraph::cld_oops_do(&_claim_state_closure); } SaveRestoreCLDClaimBits::~SaveRestoreCLDClaimBits() {