--- old/src/share/vm/gc/g1/g1CollectedHeap.cpp 2017-07-10 14:22:43.587119367 +0200 +++ new/src/share/vm/gc/g1/g1CollectedHeap.cpp 2017-07-10 14:22:43.486116234 +0200 @@ -95,28 +95,6 @@ // apply to TLAB allocation, which is not part of this interface: it // is done by clients of this interface.) -// Local to this file. - -class RefineCardTableEntryClosure: public CardTableEntryClosure { - bool _concurrent; -public: - RefineCardTableEntryClosure() : _concurrent(true) { } - - bool do_card_ptr(jbyte* card_ptr, uint worker_i) { - G1CollectedHeap::heap()->g1_rem_set()->refine_card_concurrently(card_ptr, worker_i); - - if (_concurrent && SuspendibleThreadSet::should_yield()) { - // Caller will actually yield. - return false; - } - // Otherwise, we finished successfully; return true. - return true; - } - - void set_concurrent(bool b) { _concurrent = b; } -}; - - class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure { private: size_t _num_dirtied; @@ -1582,7 +1560,6 @@ _g1_rem_set(NULL), _cg1r(NULL), _g1mm(NULL), - _refine_cte_cl(NULL), _preserved_marks_set(true /* in_c_heap */), _secondary_free_list("Secondary Free List", new SecondaryFreeRegionListMtSafeChecker()), _old_set("Old Set", false /* humongous */, new OldRegionSetMtSafeChecker()), @@ -1661,10 +1638,8 @@ } jint G1CollectedHeap::initialize_concurrent_refinement() { - _refine_cte_cl = new RefineCardTableEntryClosure(); - jint ecode = JNI_OK; - _cg1r = ConcurrentG1Refine::create(_refine_cte_cl, &ecode); + _cg1r = ConcurrentG1Refine::create(_g1_rem_set->refine_card_concurrently_closure(), &ecode); return ecode; } @@ -1821,7 +1796,7 @@ return ecode; } - JavaThread::dirty_card_queue_set().initialize(_refine_cte_cl, + JavaThread::dirty_card_queue_set().initialize(_g1_rem_set->refine_card_concurrently_closure(), DirtyCardQ_CBL_mon, DirtyCardQ_FL_lock, (int)concurrent_g1_refine()->yellow_zone(), @@ -5167,10 +5142,6 @@ used_unlocked(), recalculate_used()); } -void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) { - _refine_cte_cl->set_concurrent(concurrent); -} - bool G1CollectedHeap::is_in_closed_subset(const void* p) const { HeapRegion* hr = heap_region_containing(p); return hr->is_in(p); --- old/src/share/vm/gc/g1/g1CollectedHeap.hpp 2017-07-10 14:22:44.173137541 +0200 +++ new/src/share/vm/gc/g1/g1CollectedHeap.hpp 2017-07-10 14:22:44.075134502 +0200 @@ -111,7 +111,7 @@ bool do_object_b(oop p); }; -class RefineCardTableEntryClosure; +class G1RefineCardConcurrentlyClosure; class G1RegionMappingChangedListener : public G1MappingChangedListener { private: @@ -794,9 +794,6 @@ // concurrently after the collection. DirtyCardQueueSet _dirty_card_queue_set; - // The closure used to refine a single card. - RefineCardTableEntryClosure* _refine_cte_cl; - // After a collection pause, convert the regions in the collection set into free // regions. void free_collection_set(G1CollectionSet* collection_set, EvacuationInfo& evacuation_info, const size_t* surviving_young_words); @@ -953,8 +950,6 @@ public: - void set_refine_cte_cl_concurrency(bool concurrent); - RefToScanQueue *task_queue(uint i) const; uint num_task_queues() const; --- old/src/share/vm/gc/g1/g1RemSet.cpp 2017-07-10 14:22:44.718154444 +0200 +++ new/src/share/vm/gc/g1/g1RemSet.cpp 2017-07-10 14:22:44.622151466 +0200 @@ -36,6 +36,7 @@ #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" +#include "gc/g1/suspendibleThreadSet.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" @@ -283,6 +284,7 @@ G1HotCardCache* hot_card_cache) : _g1(g1), _scan_state(new G1RemSetScanState()), + _refine_card_concurrently_cl(), _num_conc_refined_cards(0), _ct_bs(ct_bs), _g1p(_g1->g1_policy()), @@ -446,6 +448,17 @@ p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec()); } +bool G1RefineCardConcurrentlyClosure::do_card_ptr(jbyte* card_ptr, uint worker_i) { + G1CollectedHeap::heap()->g1_rem_set()->refine_card_concurrently(card_ptr, worker_i); + + if (SuspendibleThreadSet::should_yield()) { + // Caller will actually yield. + return false; + } + // Otherwise, we finished successfully; return true. + return true; +} + // Closure used for updating RSets and recording references that // point into the collection set. Only called during an // evacuation pause. @@ -519,7 +532,6 @@ } void G1RemSet::prepare_for_oops_into_collection_set_do() { - _g1->set_refine_cte_cl_concurrency(false); DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); dcqs.concatenate_logs(); @@ -528,8 +540,6 @@ void G1RemSet::cleanup_after_oops_into_collection_set_do() { G1GCPhaseTimes* phase_times = _g1->g1_policy()->phase_times(); - // Cleanup after copy - _g1->set_refine_cte_cl_concurrency(true); // Set all cards back to clean. double start = os::elapsedTime(); --- old/src/share/vm/gc/g1/g1RemSet.hpp 2017-07-10 14:22:45.240170633 +0200 +++ new/src/share/vm/gc/g1/g1RemSet.hpp 2017-07-10 14:22:45.145167687 +0200 @@ -49,11 +49,22 @@ class G1ScanObjsDuringUpdateRSClosure; class HeapRegionClaimer; +// Closure used for updating remembered sets and recording references that +// point into the collection set while the mutator is running. +// Assumed to be only executed concurrently with the mutator. Yields via +// SuspendibleThreadSet after every card. +class G1RefineCardConcurrentlyClosure: public CardTableEntryClosure { +public: + bool do_card_ptr(jbyte* card_ptr, uint worker_i); +}; + // A G1RemSet in which each heap region has a rem set that records the // external heap references into it. Uses a mod ref bs to track updates, // so that they can be used to update the individual region remsets. class G1RemSet: public CHeapObj { private: + G1RefineCardConcurrentlyClosure _refine_card_concurrently_cl; + G1RemSetScanState* _scan_state; G1CardLiveData _card_live_data; @@ -127,6 +138,8 @@ // Eliminates any remembered set entries that correspond to dead heap ranges. void scrub(uint worker_num, HeapRegionClaimer* hrclaimer); + G1RefineCardConcurrentlyClosure* refine_card_concurrently_closure() { return &_refine_card_concurrently_cl; } + // Refine the card corresponding to "card_ptr". Safe to be called concurrently // to the mutator. void refine_card_concurrently(jbyte* card_ptr,