8213751: ClassLoaderDataGraph::cld_do() should sometimes require CLDG_lock

Add version of loaded_cld_do for runtime calls.

Reviewed-by: eosterlund, rehn
This commit is contained in:
Coleen Phillimore 2018-11-16 07:30:40 -05:00
parent 93a6b7e355
commit dce8ff4dba
8 changed files with 28 additions and 15 deletions

View File

@ -230,13 +230,6 @@ ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_unsafe_anonymo
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 @@ void ClassLoaderDataGraph::cld_unloading_do(CLDClosure* cl) {
}
}
// 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 @@ class ClassLoaderDataGraphIterator : public StackObj {
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,10 +313,15 @@ public:
}
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.
void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {

View File

@ -73,6 +73,8 @@ class ClassLoaderDataGraph : public AllStatic {
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

View File

@ -515,7 +515,7 @@ public:
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) {

View File

@ -159,7 +159,7 @@ void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
void ClassLoaderStatsVMOperation::doit() {
ClassLoaderStatsClosure clsc (_out);
ClassLoaderDataGraph::cld_do(&clsc);
ClassLoaderDataGraph::loaded_cld_do(&clsc);
clsc.print();
}

View File

@ -103,6 +103,7 @@ void CLDClaimStateClosure::do_cld(ClassLoaderData* cld) {
}
SaveRestoreCLDClaimBits::SaveRestoreCLDClaimBits() : _claim_state_closure() {
// interferes with GC, so walk all oops that GC would.
ClassLoaderDataGraph::cld_do(&_claim_state_closure);
}

View File

@ -495,7 +495,7 @@ class JfrClassLoaderStatsVMOperation : public ClassLoaderStatsVMOperation {
void doit() {
JfrClassLoaderStatsClosure clsc;
ClassLoaderDataGraph::cld_do(&clsc);
ClassLoaderDataGraph::loaded_cld_do(&clsc);
clsc.createEvents();
}
};

View File

@ -939,7 +939,7 @@ void JfrTypeSet::do_class_loaders() {
ClassLoaderDataGraph::cld_unloading_do(&cld_cb);
return;
}
ClassLoaderDataGraph::cld_do(&cld_cb);
ClassLoaderDataGraph::loaded_cld_do(&cld_cb);
}
static void clear_artifacts(JfrArtifactSet* artifacts,

View File

@ -616,7 +616,7 @@ void MetaspaceUtils::print_report(outputStream* out, size_t scale, int flags) {
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) {