19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/concurrentG1Refine.hpp"
27 #include "gc/g1/dirtyCardQueue.hpp"
28 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
29 #include "gc/g1/g1CollectedHeap.inline.hpp"
30 #include "gc/g1/g1FromCardCache.hpp"
31 #include "gc/g1/g1GCPhaseTimes.hpp"
32 #include "gc/g1/g1HotCardCache.hpp"
33 #include "gc/g1/g1OopClosures.inline.hpp"
34 #include "gc/g1/g1RemSet.inline.hpp"
35 #include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
36 #include "gc/g1/heapRegion.inline.hpp"
37 #include "gc/g1/heapRegionManager.inline.hpp"
38 #include "gc/g1/heapRegionRemSet.hpp"
39 #include "gc/shared/gcTraceTime.inline.hpp"
40 #include "memory/iterator.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "utilities/align.hpp"
44 #include "utilities/globalDefinitions.hpp"
45 #include "utilities/intHisto.hpp"
46 #include "utilities/stack.inline.hpp"
47
48 // Collects information about the overall remembered set scan progress during an evacuation.
49 class G1RemSetScanState : public CHeapObj<mtGC> {
50 private:
51 class G1ClearCardTableTask : public AbstractGangTask {
52 G1CollectedHeap* _g1h;
53 uint* _dirty_region_list;
54 size_t _num_dirty_regions;
55 size_t _chunk_length;
56
57 size_t volatile _cur_dirty_regions;
58 public:
275 G1CollectedHeap::heap()->wait_while_free_regions_coming();
276 G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
277 #endif
278 }
279 };
280
281 G1RemSet::G1RemSet(G1CollectedHeap* g1,
282 CardTableModRefBS* ct_bs,
283 G1HotCardCache* hot_card_cache) :
284 _g1(g1),
285 _scan_state(new G1RemSetScanState()),
286 _num_conc_refined_cards(0),
287 _ct_bs(ct_bs),
288 _g1p(_g1->g1_policy()),
289 _hot_card_cache(hot_card_cache),
290 _prev_period_summary(),
291 _into_cset_dirty_card_queue_set(false)
292 {
293 // Initialize the card queue set used to hold cards containing
294 // references into the collection set.
295 _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
296 DirtyCardQ_CBL_mon,
297 DirtyCardQ_FL_lock,
298 -1, // never trigger processing
299 -1, // no limit on length
300 Shared_DirtyCardQ_lock,
301 &JavaThread::dirty_card_queue_set());
302 }
303
304 G1RemSet::~G1RemSet() {
305 if (_scan_state != NULL) {
306 delete _scan_state;
307 }
308 }
309
310 uint G1RemSet::num_par_rem_sets() {
311 return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
312 }
313
314 void G1RemSet::initialize(size_t capacity, uint max_regions) {
315 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
316 _scan_state->initialize(max_regions);
502
503 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
504 CodeBlobClosure* heap_region_codeblobs,
505 uint worker_i) {
506 // A DirtyCardQueue that is used to hold cards containing references
507 // that point into the collection set. This DCQ is associated with a
508 // special DirtyCardQueueSet (see g1CollectedHeap.hpp). Under normal
509 // circumstances (i.e. the pause successfully completes), these cards
510 // are just discarded (there's no need to update the RSets of regions
511 // that were in the collection set - after the pause these regions
512 // are wholly 'free' of live objects. In the event of an evacuation
513 // failure the cards/buffers in this queue set are passed to the
514 // DirtyCardQueueSet that is used to manage RSet updates
515 DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
516
517 update_rem_set(&into_cset_dcq, pss, worker_i);
518 scan_rem_set(pss, heap_region_codeblobs, worker_i);;
519 }
520
521 void G1RemSet::prepare_for_oops_into_collection_set_do() {
522 _g1->set_refine_cte_cl_concurrency(false);
523 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
524 dcqs.concatenate_logs();
525
526 _scan_state->reset();
527 }
528
529 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
530 G1GCPhaseTimes* phase_times = _g1->g1_policy()->phase_times();
531 // Cleanup after copy
532 _g1->set_refine_cte_cl_concurrency(true);
533
534 // Set all cards back to clean.
535 double start = os::elapsedTime();
536 _scan_state->clear_card_table(_g1->workers());
537 phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
538
539 DirtyCardQueueSet& into_cset_dcqs = _into_cset_dirty_card_queue_set;
540
541 if (_g1->evacuation_failed()) {
542 double restore_remembered_set_start = os::elapsedTime();
543
544 // Restore remembered sets for the regions pointing into the collection set.
545 // We just need to transfer the completed buffers from the DirtyCardQueueSet
546 // used to hold cards that contain references that point into the collection set
547 // to the DCQS used to hold the deferred RS updates.
548 _g1->dirty_card_queue_set().merge_bufferlists(&into_cset_dcqs);
549 phase_times->record_evac_fail_restore_remsets((os::elapsedTime() - restore_remembered_set_start) * 1000.0);
550 }
551
552 // Free any completed buffers in the DirtyCardQueueSet used to hold cards
786 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
787 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
788 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
789
790 G1RemSetSummary current(this);
791 _prev_period_summary.subtract_from(¤t);
792
793 Log(gc, remset) log;
794 log.trace("%s", header);
795 ResourceMark rm;
796 _prev_period_summary.print_on(log.trace_stream());
797
798 _prev_period_summary.set(¤t);
799 }
800 }
801
802 void G1RemSet::print_summary_info() {
803 Log(gc, remset, exit) log;
804 if (log.is_trace()) {
805 log.trace(" Cumulative RS summary");
806 G1RemSetSummary current;
807 ResourceMark rm;
808 current.print_on(log.trace_stream());
809 }
810 }
811
812 void G1RemSet::create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
813 _card_live_data.create(workers, mark_bitmap);
814 }
815
816 void G1RemSet::finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
817 _card_live_data.finalize(workers, mark_bitmap);
818 }
819
820 void G1RemSet::verify_card_live_data(WorkGang* workers, G1CMBitMap* bitmap) {
821 _card_live_data.verify(workers, bitmap);
822 }
823
824 void G1RemSet::clear_card_live_data(WorkGang* workers) {
825 _card_live_data.clear(workers);
826 }
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "gc/g1/concurrentG1Refine.hpp"
27 #include "gc/g1/dirtyCardQueue.hpp"
28 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
29 #include "gc/g1/g1CollectedHeap.inline.hpp"
30 #include "gc/g1/g1FromCardCache.hpp"
31 #include "gc/g1/g1GCPhaseTimes.hpp"
32 #include "gc/g1/g1HotCardCache.hpp"
33 #include "gc/g1/g1OopClosures.inline.hpp"
34 #include "gc/g1/g1RemSet.inline.hpp"
35 #include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
36 #include "gc/g1/heapRegion.inline.hpp"
37 #include "gc/g1/heapRegionManager.inline.hpp"
38 #include "gc/g1/heapRegionRemSet.hpp"
39 #include "gc/g1/suspendibleThreadSet.hpp"
40 #include "gc/shared/gcTraceTime.inline.hpp"
41 #include "memory/iterator.hpp"
42 #include "memory/resourceArea.hpp"
43 #include "oops/oop.inline.hpp"
44 #include "utilities/align.hpp"
45 #include "utilities/globalDefinitions.hpp"
46 #include "utilities/intHisto.hpp"
47 #include "utilities/stack.inline.hpp"
48
49 // Collects information about the overall remembered set scan progress during an evacuation.
50 class G1RemSetScanState : public CHeapObj<mtGC> {
51 private:
52 class G1ClearCardTableTask : public AbstractGangTask {
53 G1CollectedHeap* _g1h;
54 uint* _dirty_region_list;
55 size_t _num_dirty_regions;
56 size_t _chunk_length;
57
58 size_t volatile _cur_dirty_regions;
59 public:
276 G1CollectedHeap::heap()->wait_while_free_regions_coming();
277 G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
278 #endif
279 }
280 };
281
282 G1RemSet::G1RemSet(G1CollectedHeap* g1,
283 CardTableModRefBS* ct_bs,
284 G1HotCardCache* hot_card_cache) :
285 _g1(g1),
286 _scan_state(new G1RemSetScanState()),
287 _num_conc_refined_cards(0),
288 _ct_bs(ct_bs),
289 _g1p(_g1->g1_policy()),
290 _hot_card_cache(hot_card_cache),
291 _prev_period_summary(),
292 _into_cset_dirty_card_queue_set(false)
293 {
294 // Initialize the card queue set used to hold cards containing
295 // references into the collection set.
296 _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon,
297 DirtyCardQ_FL_lock,
298 -1, // never trigger processing
299 -1, // no limit on length
300 Shared_DirtyCardQ_lock,
301 &JavaThread::dirty_card_queue_set());
302 }
303
304 G1RemSet::~G1RemSet() {
305 if (_scan_state != NULL) {
306 delete _scan_state;
307 }
308 }
309
310 uint G1RemSet::num_par_rem_sets() {
311 return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
312 }
313
314 void G1RemSet::initialize(size_t capacity, uint max_regions) {
315 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
316 _scan_state->initialize(max_regions);
502
503 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
504 CodeBlobClosure* heap_region_codeblobs,
505 uint worker_i) {
506 // A DirtyCardQueue that is used to hold cards containing references
507 // that point into the collection set. This DCQ is associated with a
508 // special DirtyCardQueueSet (see g1CollectedHeap.hpp). Under normal
509 // circumstances (i.e. the pause successfully completes), these cards
510 // are just discarded (there's no need to update the RSets of regions
511 // that were in the collection set - after the pause these regions
512 // are wholly 'free' of live objects. In the event of an evacuation
513 // failure the cards/buffers in this queue set are passed to the
514 // DirtyCardQueueSet that is used to manage RSet updates
515 DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
516
517 update_rem_set(&into_cset_dcq, pss, worker_i);
518 scan_rem_set(pss, heap_region_codeblobs, worker_i);;
519 }
520
521 void G1RemSet::prepare_for_oops_into_collection_set_do() {
522 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
523 dcqs.concatenate_logs();
524
525 _scan_state->reset();
526 }
527
528 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
529 G1GCPhaseTimes* phase_times = _g1->g1_policy()->phase_times();
530
531 // Set all cards back to clean.
532 double start = os::elapsedTime();
533 _scan_state->clear_card_table(_g1->workers());
534 phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
535
536 DirtyCardQueueSet& into_cset_dcqs = _into_cset_dirty_card_queue_set;
537
538 if (_g1->evacuation_failed()) {
539 double restore_remembered_set_start = os::elapsedTime();
540
541 // Restore remembered sets for the regions pointing into the collection set.
542 // We just need to transfer the completed buffers from the DirtyCardQueueSet
543 // used to hold cards that contain references that point into the collection set
544 // to the DCQS used to hold the deferred RS updates.
545 _g1->dirty_card_queue_set().merge_bufferlists(&into_cset_dcqs);
546 phase_times->record_evac_fail_restore_remsets((os::elapsedTime() - restore_remembered_set_start) * 1000.0);
547 }
548
549 // Free any completed buffers in the DirtyCardQueueSet used to hold cards
783 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
784 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
785 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
786
787 G1RemSetSummary current(this);
788 _prev_period_summary.subtract_from(¤t);
789
790 Log(gc, remset) log;
791 log.trace("%s", header);
792 ResourceMark rm;
793 _prev_period_summary.print_on(log.trace_stream());
794
795 _prev_period_summary.set(¤t);
796 }
797 }
798
799 void G1RemSet::print_summary_info() {
800 Log(gc, remset, exit) log;
801 if (log.is_trace()) {
802 log.trace(" Cumulative RS summary");
803 G1RemSetSummary current(this);
804 ResourceMark rm;
805 current.print_on(log.trace_stream());
806 }
807 }
808
809 void G1RemSet::create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
810 _card_live_data.create(workers, mark_bitmap);
811 }
812
813 void G1RemSet::finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) {
814 _card_live_data.finalize(workers, mark_bitmap);
815 }
816
817 void G1RemSet::verify_card_live_data(WorkGang* workers, G1CMBitMap* bitmap) {
818 _card_live_data.verify(workers, bitmap);
819 }
820
821 void G1RemSet::clear_card_live_data(WorkGang* workers) {
822 _card_live_data.clear(workers);
823 }
|