413 scan_strong_code_roots(r);
414 }
415 return false;
416 }
417
418 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
419 CodeBlobClosure* heap_region_codeblobs,
420 uint worker_i) {
421 double rs_time_start = os::elapsedTime();
422
423 G1ScanObjsDuringScanRSClosure scan_cl(_g1, pss);
424 G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
425 _g1->collection_set_iterate_from(&cl, worker_i);
426
427 double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
428 cl.strong_code_root_scan_time_sec();
429
430 G1GCPhaseTimes* p = _g1p->phase_times();
431
432 p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
433 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScannedCards);
434 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ClaimedCards);
435 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::SkippedCards);
436
437 p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
438 }
439
440 // Closure used for updating rem sets. Only called during an evacuation pause.
441 class G1RefineCardClosure: public CardTableEntryClosure {
442 G1RemSet* _g1rs;
443 G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
444 public:
445 G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
446 _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl)
447 {}
448
449 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
450 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
451
452 _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
453 return true;
454 }
455 };
456
457 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
458 G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1, pss, worker_i);
459 G1RefineCardClosure refine_card_cl(_g1, &update_rs_cl);
460
461 G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
462 if (G1HotCardCache::default_use_cache()) {
463 // Apply the closure to the entries of the hot card cache.
464 G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
465 _g1->iterate_hcc_closure(&refine_card_cl, worker_i);
466 }
467 // Apply the closure to all remaining log entries.
468 _g1->iterate_dirty_card_closure(&refine_card_cl, worker_i);
469 }
470
471 void G1RemSet::cleanupHRRS() {
472 HeapRegionRemSet::cleanup();
473 }
474
475 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
476 CodeBlobClosure* heap_region_codeblobs,
477 uint worker_i) {
478 update_rem_set(pss, worker_i);
479 scan_rem_set(pss, heap_region_codeblobs, worker_i);;
480 }
481
482 void G1RemSet::prepare_for_oops_into_collection_set_do() {
483 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
484 dcqs.concatenate_logs();
485
486 _scan_state->reset();
487 }
488
660 // part of the heap (e.g. a partially allocated object) while
661 // processing a stale card. Despite the card being stale, redirty
662 // and re-enqueue, because we've already cleaned the card. Without
663 // this we could incorrectly discard a non-stale card.
664 if (!card_processed) {
665 // The card might have gotten re-dirtied and re-enqueued while we
666 // worked. (In fact, it's pretty likely.)
667 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
668 *card_ptr = CardTableModRefBS::dirty_card_val();
669 MutexLockerEx x(Shared_DirtyCardQ_lock,
670 Mutex::_no_safepoint_check_flag);
671 DirtyCardQueue* sdcq =
672 JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
673 sdcq->enqueue(card_ptr);
674 }
675 } else {
676 _num_conc_refined_cards++; // Unsynchronized update, only used for logging.
677 }
678 }
679
680 void G1RemSet::refine_card_during_gc(jbyte* card_ptr,
681 G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
682 assert(_g1->is_gc_active(), "Only call during GC");
683
684 check_card_ptr(card_ptr, _ct_bs);
685
686 // If the card is no longer dirty, nothing to do. This covers cards that were already
687 // scanned as parts of the remembered sets.
688 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
689 return;
690 }
691
692 // During GC we can immediately clean the card since we will not re-enqueue stale
693 // cards as we know they can be disregarded.
694 *card_ptr = CardTableModRefBS::clean_card_val();
695
696 // Construct the region representing the card.
697 HeapWord* card_start = _ct_bs->addr_for(card_ptr);
698 // And find the region containing it.
699 HeapRegion* r = _g1->heap_region_containing(card_start);
700
701 HeapWord* scan_limit = _scan_state->scan_top(r->hrm_index());
702 if (scan_limit <= card_start) {
703 // If the card starts above the area in the region containing objects to scan, skip it.
704 return;
705 }
706
707 // Don't use addr_for(card_ptr + 1) which can ask for
708 // a card beyond the heap.
709 HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
710 MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
711 assert(!dirty_region.is_empty(), "sanity");
712
713 update_rs_cl->set_region(r);
714 bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
715 assert(card_processed, "must be");
716 }
717
718 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
719 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
720 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
721
722 G1RemSetSummary current(this);
723 _prev_period_summary.subtract_from(¤t);
724
725 Log(gc, remset) log;
726 log.trace("%s", header);
727 ResourceMark rm;
728 _prev_period_summary.print_on(log.trace_stream());
729
730 _prev_period_summary.set(¤t);
731 }
732 }
733
734 void G1RemSet::print_summary_info() {
735 Log(gc, remset, exit) log;
|
413 scan_strong_code_roots(r);
414 }
415 return false;
416 }
417
418 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
419 CodeBlobClosure* heap_region_codeblobs,
420 uint worker_i) {
421 double rs_time_start = os::elapsedTime();
422
423 G1ScanObjsDuringScanRSClosure scan_cl(_g1, pss);
424 G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
425 _g1->collection_set_iterate_from(&cl, worker_i);
426
427 double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
428 cl.strong_code_root_scan_time_sec();
429
430 G1GCPhaseTimes* p = _g1p->phase_times();
431
432 p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
433 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
434 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
435 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
436
437 p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
438 }
439
440 // Closure used for updating rem sets. Only called during an evacuation pause.
441 class G1RefineCardClosure: public CardTableEntryClosure {
442 G1RemSet* _g1rs;
443 G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
444
445 size_t _cards_scanned;
446 size_t _cards_skipped;
447 public:
448 G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
449 _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
450 {}
451
452 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
453 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
454
455 bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
456
457 if (card_scanned) {
458 _cards_scanned++;
459 } else {
460 _cards_skipped++;
461 }
462 return true;
463 }
464
465 size_t cards_scanned() const { return _cards_scanned; }
466 size_t cards_skipped() const { return _cards_skipped; }
467 };
468
469 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
470 G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1, pss, worker_i);
471 G1RefineCardClosure refine_card_cl(_g1, &update_rs_cl);
472
473 G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
474 if (G1HotCardCache::default_use_cache()) {
475 // Apply the closure to the entries of the hot card cache.
476 G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
477 _g1->iterate_hcc_closure(&refine_card_cl, worker_i);
478 }
479 // Apply the closure to all remaining log entries.
480 _g1->iterate_dirty_card_closure(&refine_card_cl, worker_i);
481
482 G1GCPhaseTimes* p = _g1p->phase_times();
483 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
484 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
485 }
486
487 void G1RemSet::cleanupHRRS() {
488 HeapRegionRemSet::cleanup();
489 }
490
491 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
492 CodeBlobClosure* heap_region_codeblobs,
493 uint worker_i) {
494 update_rem_set(pss, worker_i);
495 scan_rem_set(pss, heap_region_codeblobs, worker_i);;
496 }
497
498 void G1RemSet::prepare_for_oops_into_collection_set_do() {
499 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
500 dcqs.concatenate_logs();
501
502 _scan_state->reset();
503 }
504
676 // part of the heap (e.g. a partially allocated object) while
677 // processing a stale card. Despite the card being stale, redirty
678 // and re-enqueue, because we've already cleaned the card. Without
679 // this we could incorrectly discard a non-stale card.
680 if (!card_processed) {
681 // The card might have gotten re-dirtied and re-enqueued while we
682 // worked. (In fact, it's pretty likely.)
683 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
684 *card_ptr = CardTableModRefBS::dirty_card_val();
685 MutexLockerEx x(Shared_DirtyCardQ_lock,
686 Mutex::_no_safepoint_check_flag);
687 DirtyCardQueue* sdcq =
688 JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
689 sdcq->enqueue(card_ptr);
690 }
691 } else {
692 _num_conc_refined_cards++; // Unsynchronized update, only used for logging.
693 }
694 }
695
696 bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
697 G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
698 assert(_g1->is_gc_active(), "Only call during GC");
699
700 check_card_ptr(card_ptr, _ct_bs);
701
702 // If the card is no longer dirty, nothing to do. This covers cards that were already
703 // scanned as parts of the remembered sets.
704 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
705 return false;
706 }
707
708 // During GC we can immediately clean the card since we will not re-enqueue stale
709 // cards as we know they can be disregarded.
710 *card_ptr = CardTableModRefBS::clean_card_val();
711
712 // Construct the region representing the card.
713 HeapWord* card_start = _ct_bs->addr_for(card_ptr);
714 // And find the region containing it.
715 HeapRegion* r = _g1->heap_region_containing(card_start);
716
717 HeapWord* scan_limit = _scan_state->scan_top(r->hrm_index());
718 if (scan_limit <= card_start) {
719 // If the card starts above the area in the region containing objects to scan, skip it.
720 return false;
721 }
722
723 // Don't use addr_for(card_ptr + 1) which can ask for
724 // a card beyond the heap.
725 HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
726 MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
727 assert(!dirty_region.is_empty(), "sanity");
728
729 update_rs_cl->set_region(r);
730 bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
731 assert(card_processed, "must be");
732 return true;
733 }
734
735 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
736 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
737 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
738
739 G1RemSetSummary current(this);
740 _prev_period_summary.subtract_from(¤t);
741
742 Log(gc, remset) log;
743 log.trace("%s", header);
744 ResourceMark rm;
745 _prev_period_summary.print_on(log.trace_stream());
746
747 _prev_period_summary.set(¤t);
748 }
749 }
750
751 void G1RemSet::print_summary_info() {
752 Log(gc, remset, exit) log;
|