317 _pss(pss),
318 _scan_objs_on_card_cl(scan_obj_on_card),
319 _scan_state(scan_state),
320 _worker_i(worker_i),
321 _cards_scanned(0),
322 _cards_claimed(0),
323 _cards_skipped(0),
324 _rem_set_root_scan_time(),
325 _rem_set_trim_partially_time(),
326 _strong_code_root_scan_time(),
327 _strong_code_trim_partially_time() {
328 }
329
330 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
331 _ct->set_card_claimed(card_index);
332 _scan_state->add_dirty_region(region_idx_for_card);
333 }
334
335 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
336 HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
337 _scan_objs_on_card_cl->set_region(card_region);
338 card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
339 _scan_objs_on_card_cl->trim_queue_partially();
340 _cards_scanned++;
341 }
342
343 void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
344 EventGCPhaseParallel event;
345 uint const region_idx = r->hrm_index();
346
347 if (_scan_state->claim_iter(region_idx)) {
348 // If we ever free the collection set concurrently, we should also
349 // clear the card table concurrently therefore we won't need to
350 // add regions of the collection set to the dirty cards region.
351 _scan_state->add_dirty_region(region_idx);
352 }
353
354 if (r->rem_set()->cardset_is_empty()) {
355 return;
356 }
357
477 if (card_scanned) {
478 _update_rs_cl->trim_queue_partially();
479 _cards_scanned++;
480 } else {
481 _cards_skipped++;
482 }
483 return true;
484 }
485
486 size_t cards_scanned() const { return _cards_scanned; }
487 size_t cards_skipped() const { return _cards_skipped; }
488 };
489
490 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
491 G1GCPhaseTimes* p = _g1p->phase_times();
492
493 // Apply closure to log entries in the HCC.
494 if (G1HotCardCache::default_use_cache()) {
495 G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
496
497 G1ScanObjsDuringUpdateRSClosure scan_hcc_cl(_g1h, pss, worker_i);
498 G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
499 _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
500 }
501
502 // Now apply the closure to all remaining log entries.
503 {
504 G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
505
506 G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss, worker_i);
507 G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
508 _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
509
510 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
511 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
512 }
513 }
514
515 void G1RemSet::cleanupHRRS() {
516 HeapRegionRemSet::cleanup();
517 }
518
519 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss, uint worker_i) {
520 update_rem_set(pss, worker_i);
521 scan_rem_set(pss, worker_i);;
522 }
523
524 void G1RemSet::prepare_for_oops_into_collection_set_do() {
525 DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
526 dcqs.concatenate_logs();
712 return false;
713 }
714
715 // We claim lazily (so races are possible but they're benign), which reduces the
716 // number of potential duplicate scans (multiple threads may enqueue the same card twice).
717 *card_ptr = G1CardTable::clean_card_val() | G1CardTable::claimed_card_val();
718
719 _scan_state->add_dirty_region(card_region_idx);
720 if (scan_limit <= card_start) {
721 // If the card starts above the area in the region containing objects to scan, skip it.
722 return false;
723 }
724
725 // Don't use addr_for(card_ptr + 1) which can ask for
726 // a card beyond the heap.
727 HeapWord* card_end = card_start + G1CardTable::card_size_in_words;
728 MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
729 assert(!dirty_region.is_empty(), "sanity");
730
731 HeapRegion* const card_region = _g1h->region_at(card_region_idx);
732 update_rs_cl->set_region(card_region);
733 bool card_processed = card_region->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
734 assert(card_processed, "must be");
735 return true;
736 }
737
738 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
739 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
740 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
741
742 G1RemSetSummary current(this);
743 _prev_period_summary.subtract_from(¤t);
744
745 Log(gc, remset) log;
746 log.trace("%s", header);
747 ResourceMark rm;
748 LogStream ls(log.trace());
749 _prev_period_summary.print_on(&ls);
750
751 _prev_period_summary.set(¤t);
752 }
|
317 _pss(pss),
318 _scan_objs_on_card_cl(scan_obj_on_card),
319 _scan_state(scan_state),
320 _worker_i(worker_i),
321 _cards_scanned(0),
322 _cards_claimed(0),
323 _cards_skipped(0),
324 _rem_set_root_scan_time(),
325 _rem_set_trim_partially_time(),
326 _strong_code_root_scan_time(),
327 _strong_code_trim_partially_time() {
328 }
329
330 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
331 _ct->set_card_claimed(card_index);
332 _scan_state->add_dirty_region(region_idx_for_card);
333 }
334
335 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
336 HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
337 assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
338 card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
339 _scan_objs_on_card_cl->trim_queue_partially();
340 _cards_scanned++;
341 }
342
343 void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
344 EventGCPhaseParallel event;
345 uint const region_idx = r->hrm_index();
346
347 if (_scan_state->claim_iter(region_idx)) {
348 // If we ever free the collection set concurrently, we should also
349 // clear the card table concurrently therefore we won't need to
350 // add regions of the collection set to the dirty cards region.
351 _scan_state->add_dirty_region(region_idx);
352 }
353
354 if (r->rem_set()->cardset_is_empty()) {
355 return;
356 }
357
477 if (card_scanned) {
478 _update_rs_cl->trim_queue_partially();
479 _cards_scanned++;
480 } else {
481 _cards_skipped++;
482 }
483 return true;
484 }
485
486 size_t cards_scanned() const { return _cards_scanned; }
487 size_t cards_skipped() const { return _cards_skipped; }
488 };
489
490 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
491 G1GCPhaseTimes* p = _g1p->phase_times();
492
493 // Apply closure to log entries in the HCC.
494 if (G1HotCardCache::default_use_cache()) {
495 G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
496
497 G1ScanObjsDuringUpdateRSClosure scan_hcc_cl(_g1h, pss);
498 G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
499 _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
500 }
501
502 // Now apply the closure to all remaining log entries.
503 {
504 G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
505
506 G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss);
507 G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
508 _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
509
510 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
511 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
512 }
513 }
514
515 void G1RemSet::cleanupHRRS() {
516 HeapRegionRemSet::cleanup();
517 }
518
519 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss, uint worker_i) {
520 update_rem_set(pss, worker_i);
521 scan_rem_set(pss, worker_i);;
522 }
523
524 void G1RemSet::prepare_for_oops_into_collection_set_do() {
525 DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
526 dcqs.concatenate_logs();
712 return false;
713 }
714
715 // We claim lazily (so races are possible but they're benign), which reduces the
716 // number of potential duplicate scans (multiple threads may enqueue the same card twice).
717 *card_ptr = G1CardTable::clean_card_val() | G1CardTable::claimed_card_val();
718
719 _scan_state->add_dirty_region(card_region_idx);
720 if (scan_limit <= card_start) {
721 // If the card starts above the area in the region containing objects to scan, skip it.
722 return false;
723 }
724
725 // Don't use addr_for(card_ptr + 1) which can ask for
726 // a card beyond the heap.
727 HeapWord* card_end = card_start + G1CardTable::card_size_in_words;
728 MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
729 assert(!dirty_region.is_empty(), "sanity");
730
731 HeapRegion* const card_region = _g1h->region_at(card_region_idx);
732 assert(!card_region->is_young(), "Should not scan card in young region %u", card_region_idx);
733 bool card_processed = card_region->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
734 assert(card_processed, "must be");
735 return true;
736 }
737
738 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
739 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
740 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
741
742 G1RemSetSummary current(this);
743 _prev_period_summary.subtract_from(¤t);
744
745 Log(gc, remset) log;
746 log.trace("%s", header);
747 ResourceMark rm;
748 LogStream ls(log.trace());
749 _prev_period_summary.print_on(&ls);
750
751 _prev_period_summary.set(¤t);
752 }
|