# HG changeset patch # User eosterlund # Date 1539688571 -7200 # Node ID de6dc206a92bab4c884d8ecdbcf6d46b37d95959 # Parent 3a168f782e80ff2a9f7bb9726522cff07d94f5a7 8210330: Make CLD claiming allow multiple claim bits Reviewed-by: pliden, coleenp diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/classfile/classLoaderData.cpp --- a/src/hotspot/share/classfile/classLoaderData.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/classfile/classLoaderData.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -139,7 +139,7 @@ // it from being unloaded during parsing of the unsafe anonymous class. // The null-class-loader should always be kept alive. _keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0), - _claimed(0), + _claim(0), _handles(), _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL), _jmethod_ids(NULL), @@ -268,12 +268,17 @@ } #endif // PRODUCT -bool ClassLoaderData::claim() { - if (_claimed == 1) { - return false; +bool ClassLoaderData::try_claim(int claim) { + for (;;) { + int old_claim = Atomic::load(&_claim); + if ((old_claim & claim) == claim) { + return false; + } + int new_claim = old_claim | claim; + if (Atomic::cmpxchg(new_claim, &_claim, old_claim) == old_claim) { + return true; + } } - - return (int) Atomic::cmpxchg(1, &_claimed, 0) == 0; } // Unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive @@ -295,8 +300,8 @@ } } -void ClassLoaderData::oops_do(OopClosure* f, bool must_claim, bool clear_mod_oops) { - if (must_claim && !claim()) { +void ClassLoaderData::oops_do(OopClosure* f, int claim_value, bool clear_mod_oops) { + if (claim_value != ClassLoaderData::_claim_none && !try_claim(claim_value)) { return; } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/classfile/classLoaderData.hpp --- a/src/hotspot/share/classfile/classLoaderData.hpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/classfile/classLoaderData.hpp Tue Oct 16 13:16:11 2018 +0200 @@ -128,9 +128,8 @@ // loader. _keep_alive does not need to be volatile or // atomic since there is one unique CLD per unsafe anonymous class. - volatile int _claimed; // true if claimed, for example during GC traces. - // To avoid applying oop closure more than once. - // Has to be an int because we cas it. + volatile int _claim; // non-zero if claimed, for example during GC traces. + // To avoid applying oop closure more than once. ChunkedHandleList _handles; // Handles to constant pool arrays, Modules, etc, which // have the same life cycle of the corresponding ClassLoader. @@ -200,11 +199,22 @@ Dictionary* create_dictionary(); void initialize_name(Handle class_loader); + public: // GC interface. - void clear_claimed() { _claimed = 0; } - bool claimed() const { return _claimed == 1; } - bool claim(); + + // The "claim" is typically used to check if oops_do needs to be applied on + // the CLD or not. Most GCs only perform strong marking during the marking phase. + enum { + _claim_none = 0, + _claim_finalizable = 2, + _claim_strong = 3 + }; + void clear_claim() { _claim = 0; } + bool claimed() const { return _claim != 0; } + bool try_claim(int claim); + int get_claim() const { return _claim; } + void set_claim(int claim) { _claim = claim; } // Computes if the CLD is alive or not. This is safe to call in concurrent // contexts. @@ -264,7 +274,7 @@ void initialize_holder(Handle holder); - void oops_do(OopClosure* f, bool must_claim, bool clear_modified_oops = false); + void oops_do(OopClosure* f, int claim_value, bool clear_modified_oops = false); void classes_do(KlassClosure* klass_closure); Klass* klasses() { return _klasses; } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/classfile/classLoaderDataGraph.cpp --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -48,7 +48,7 @@ void ClassLoaderDataGraph::clear_claimed_marks() { for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { - cld->clear_claimed(); + cld->clear_claim(); } } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/cms/cmsOopClosures.inline.hpp --- a/src/hotspot/share/gc/cms/cmsOopClosures.inline.hpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/cms/cmsOopClosures.inline.hpp Tue Oct 16 13:16:11 2018 +0200 @@ -41,8 +41,7 @@ } inline void MetadataVisitingOopsInGenClosure::do_cld(ClassLoaderData* cld) { - bool claim = true; // Must claim the class loader data before processing. - cld->oops_do(this, claim); + cld->oops_do(this, ClassLoaderData::_claim_strong); } // Decode the oop and call do_oop on it. diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp --- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -2398,7 +2398,7 @@ public: VerifyCLDOopsCLDClosure(CMSBitMap* bitmap) : _oop_closure(bitmap) {} void do_cld(ClassLoaderData* cld) { - cld->oops_do(&_oop_closure, false, false); + cld->oops_do(&_oop_closure, ClassLoaderData::_claim_none, false); } }; @@ -2413,7 +2413,7 @@ // Mark from roots one level into CMS MarkRefsIntoVerifyClosure notOlder(_span, verification_mark_bm(), markBitMap()); - CLDToOopClosure cld_closure(¬Older, true); + CLDToOopClosure cld_closure(¬Older, ClassLoaderData::_claim_strong); heap->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. @@ -2886,7 +2886,7 @@ } } else { // The serial version. - CLDToOopClosure cld_closure(¬Older, true); + CLDToOopClosure cld_closure(¬Older, ClassLoaderData::_claim_strong); heap->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. StrongRootsScope srs(1); @@ -4269,7 +4269,7 @@ _timer.reset(); _timer.start(); - CLDToOopClosure cld_closure(&par_mri_cl, true); + CLDToOopClosure cld_closure(&par_mri_cl, ClassLoaderData::_claim_strong); heap->cms_process_roots(_strong_roots_scope, false, // yg was scanned above @@ -4331,7 +4331,7 @@ class RemarkCLDClosure : public CLDClosure { CLDToOopClosure _cm_closure; public: - RemarkCLDClosure(OopClosure* oop_closure) : _cm_closure(oop_closure) {} + RemarkCLDClosure(OopClosure* oop_closure) : _cm_closure(oop_closure, ClassLoaderData::_claim_strong) {} void do_cld(ClassLoaderData* cld) { // Check if we have modified any oops in the CLD during the concurrent marking. if (cld->has_accumulated_modified_oops()) { diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp --- a/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1FullGCAdjustTask.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -108,7 +108,7 @@ AlwaysTrueClosure always_alive; _weak_proc_task.work(worker_id, &always_alive, &_adjust); - CLDToOopClosure adjust_cld(&_adjust); + CLDToOopClosure adjust_cld(&_adjust, ClassLoaderData::_claim_strong); CodeBlobToOopClosure adjust_code(&_adjust, CodeBlobToOopClosure::FixRelocations); _root_processor.process_all_roots( &_adjust, diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/g1/g1FullGCMarker.cpp --- a/src/hotspot/share/gc/g1/g1FullGCMarker.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "gc/g1/g1FullGCMarker.inline.hpp" #include "gc/shared/referenceProcessor.hpp" #include "memory/iterator.inline.hpp" @@ -36,7 +37,7 @@ _mark_closure(worker_id, this, G1CollectedHeap::heap()->ref_processor_stw()), _verify_closure(VerifyOption_G1UseFullMarking), _stack_closure(this), - _cld_closure(mark_closure()) { + _cld_closure(mark_closure(), ClassLoaderData::_claim_strong) { _oop_stack.initialize(); _objarray_stack.initialize(); } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/g1/g1HeapVerifier.cpp --- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -170,10 +170,10 @@ public: VerifyCLDClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {} void do_cld(ClassLoaderData* cld) { - cld->oops_do(_oop_closure, false); + cld->oops_do(_oop_closure, ClassLoaderData::_claim_none); _young_ref_counter_closure.reset_count(); - cld->oops_do(&_young_ref_counter_closure, false); + cld->oops_do(&_young_ref_counter_closure, ClassLoaderData::_claim_none); if (_young_ref_counter_closure.count() > 0) { guarantee(cld->has_modified_oops(), "CLD " PTR_FORMAT ", has young %d refs but is not dirty.", p2i(cld), _young_ref_counter_closure.count()); } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/g1/g1OopClosures.cpp --- a/src/hotspot/share/gc/g1/g1OopClosures.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1OopClosures.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -52,7 +52,7 @@ // Clean the cld since we're going to scavenge all the metadata. // Clear modified oops only if this cld is claimed. - cld->oops_do(_closure, _must_claim, /*clear_modified_oops*/true); + cld->oops_do(_closure, _claim, /*clear_modified_oops*/true); _closure->set_scanned_cld(NULL); diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/g1/g1OopClosures.hpp --- a/src/hotspot/share/gc/g1/g1OopClosures.hpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp Tue Oct 16 13:16:11 2018 +0200 @@ -160,12 +160,12 @@ class G1CLDScanClosure : public CLDClosure { G1ParCopyHelper* _closure; bool _process_only_dirty; - bool _must_claim; + int _claim; int _count; public: G1CLDScanClosure(G1ParCopyHelper* closure, - bool process_only_dirty, bool must_claim) - : _closure(closure), _process_only_dirty(process_only_dirty), _must_claim(must_claim), _count(0) {} + bool process_only_dirty, int claim_value) + : _closure(closure), _process_only_dirty(process_only_dirty), _claim(claim_value), _count(0) {} void do_cld(ClassLoaderData* cld); }; diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/g1/g1RootClosures.cpp --- a/src/hotspot/share/gc/g1/g1RootClosures.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1RootClosures.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -35,7 +35,7 @@ G1EvacuationClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool in_young_gc) : - _closures(g1h, pss, in_young_gc, /* must_claim_cld */ false) {} + _closures(g1h, pss, in_young_gc, /* cld_claim */ ClassLoaderData::_claim_none) {} OopClosure* weak_oops() { return &_closures._oops; } OopClosure* strong_oops() { return &_closures._oops; } @@ -73,8 +73,8 @@ public: G1InitialMarkClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss) : - _strong(g1h, pss, /* process_only_dirty_klasses */ false, /* must_claim_cld */ true), - _weak(g1h, pss, /* process_only_dirty_klasses */ false, /* must_claim_cld */ true) {} + _strong(g1h, pss, /* process_only_dirty_klasses */ false, /* cld_claim */ ClassLoaderData::_claim_strong), + _weak(g1h, pss, /* process_only_dirty_klasses */ false, /* cld_claim */ ClassLoaderData::_claim_strong) {} OopClosure* weak_oops() { return &_weak._oops; } OopClosure* strong_oops() { return &_strong._oops; } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/g1/g1SharedClosures.hpp --- a/src/hotspot/share/gc/g1/g1SharedClosures.hpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1SharedClosures.hpp Tue Oct 16 13:16:11 2018 +0200 @@ -39,9 +39,9 @@ G1CLDScanClosure _clds; G1CodeBlobClosure _codeblobs; - G1SharedClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool process_only_dirty, bool must_claim_cld) : + G1SharedClosures(G1CollectedHeap* g1h, G1ParScanThreadState* pss, bool process_only_dirty, int cld_claim) : _oops(g1h, pss), _oops_in_cld(g1h, pss), - _clds(&_oops_in_cld, process_only_dirty, must_claim_cld), + _clds(&_oops_in_cld, process_only_dirty, cld_claim), _codeblobs(&_oops) {} }; diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/parallel/pcTasks.cpp --- a/src/hotspot/share/gc/parallel/pcTasks.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/parallel/pcTasks.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -110,7 +110,7 @@ break; case class_loader_data: { - CLDToOopClosure cld_closure(&mark_and_push_closure); + CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong); ClassLoaderDataGraph::always_strong_cld_do(&cld_closure); } break; diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/parallel/psParallelCompact.cpp --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -2213,7 +2213,7 @@ Management::oops_do(&oop_closure); JvmtiExport::oops_do(&oop_closure); SystemDictionary::oops_do(&oop_closure); - CLDToOopClosure cld_closure(&oop_closure); + CLDToOopClosure cld_closure(&oop_closure, ClassLoaderData::_claim_strong); ClassLoaderDataGraph::cld_do(&cld_closure); // Now adjust pointers in remaining weak roots. (All of which should diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/serial/defNewGeneration.cpp --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -137,7 +137,7 @@ _scavenge_closure->set_scanned_cld(cld); // Clean the cld since we're going to scavenge all the metadata. - cld->oops_do(_scavenge_closure, false, /*clear_modified_oops*/true); + cld->oops_do(_scavenge_closure, ClassLoaderData::_claim_none, /*clear_modified_oops*/true); _scavenge_closure->set_scanned_cld(NULL); } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/serial/markSweep.cpp --- a/src/hotspot/share/gc/serial/markSweep.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/serial/markSweep.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -58,9 +58,9 @@ MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; -MarkAndPushClosure MarkSweep::mark_and_push_closure; -CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure); -CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure); +MarkAndPushClosure MarkSweep::mark_and_push_closure; +CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong); +CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure, ClassLoaderData::_claim_strong); template inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) { mark_and_push(p); diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/gc/z/zRootsIterator.cpp --- a/src/hotspot/share/gc/z/zRootsIterator.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/gc/z/zRootsIterator.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -242,7 +242,7 @@ void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) { ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph); - CLDToOopClosure cld_cl(cl, _marking /* must_claim */); + CLDToOopClosure cld_cl(cl, _marking ? ClassLoaderData::_claim_strong : ClassLoaderData::_claim_none); ClassLoaderDataGraph::cld_do(&cld_cl); } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp --- a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -92,7 +92,7 @@ SaveRestoreCLDClaimBits save_restore_cld_claim_bits; RootSetClosureMarkScope mark_scope; - CLDToOopClosure cldt_closure(closure); + CLDToOopClosure cldt_closure(closure, ClassLoaderData::_claim_strong); ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure); CodeBlobToOopClosure blobs(closure, false); Threads::oops_do(closure, &blobs); diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -128,7 +128,7 @@ bool ReferenceToRootClosure::do_cldg_roots() { assert(!complete(), "invariant"); ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL); - CLDToOopClosure cldt_closure(&rlc); + CLDToOopClosure cldt_closure(&rlc, ClassLoaderData::_claim_strong); ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure); return rlc.complete(); } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp --- a/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -69,12 +69,12 @@ CLDClaimContext::CLDClaimContext(ClassLoaderData* cld) : _cld(cld) { assert(_cld->claimed(), "invariant"); - _cld->clear_claimed(); + _cld->clear_claim(); } CLDClaimContext::~CLDClaimContext() { if (_cld != NULL) { - _cld->claim(); + _cld->try_claim(ClassLoaderData::_claim_strong); assert(_cld->claimed(), "invariant"); } } diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/memory/iterator.cpp --- a/src/hotspot/share/memory/iterator.cpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/memory/iterator.cpp Tue Oct 16 13:16:11 2018 +0200 @@ -32,7 +32,7 @@ DoNothingClosure do_nothing_cl; void CLDToOopClosure::do_cld(ClassLoaderData* cld) { - cld->oops_do(_oop_closure, _must_claim_cld); + cld->oops_do(_oop_closure, _cld_claim); } void ObjectToOopClosure::do_object(oop obj) { diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/memory/iterator.hpp --- a/src/hotspot/share/memory/iterator.hpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/memory/iterator.hpp Tue Oct 16 13:16:11 2018 +0200 @@ -127,12 +127,13 @@ class CLDToOopClosure : public CLDClosure { OopClosure* _oop_closure; - bool _must_claim_cld; + int _cld_claim; public: - CLDToOopClosure(OopClosure* oop_closure, bool must_claim_cld = true) : + CLDToOopClosure(OopClosure* oop_closure, + int cld_claim) : _oop_closure(oop_closure), - _must_claim_cld(must_claim_cld) {} + _cld_claim(cld_claim) {} void do_cld(ClassLoaderData* cld); }; diff -r 3a168f782e80 -r de6dc206a92b src/hotspot/share/memory/iterator.inline.hpp --- a/src/hotspot/share/memory/iterator.inline.hpp Tue Oct 16 13:14:18 2018 +0200 +++ b/src/hotspot/share/memory/iterator.inline.hpp Tue Oct 16 13:16:11 2018 +0200 @@ -39,8 +39,7 @@ #include "utilities/debug.hpp" inline void MetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) { - bool claim = true; // Must claim the class loader data before processing. - cld->oops_do(this, claim); + cld->oops_do(this, ClassLoaderData::_claim_strong); } inline void MetadataVisitingOopIterateClosure::do_klass(Klass* k) {