690 // scanned as parts of the remembered sets. |
690 // scanned as parts of the remembered sets. |
691 if (*card_ptr != CardTableModRefBS::dirty_card_val()) { |
691 if (*card_ptr != CardTableModRefBS::dirty_card_val()) { |
692 return; |
692 return; |
693 } |
693 } |
694 |
694 |
695 // During GC we can immediately clean the card since we will not re-enqueue stale |
695 // We claim lazily (so races are possible but they're benign), which reduces the |
696 // cards as we know they can be disregarded. |
696 // number of potential duplicate scans (multiple threads may enqueue the same card twice). |
697 *card_ptr = CardTableModRefBS::clean_card_val(); |
697 *card_ptr = CardTableModRefBS::clean_card_val() | CardTableModRefBS::claimed_card_val(); |
698 |
698 |
699 // Construct the region representing the card. |
699 // Construct the region representing the card. |
700 HeapWord* card_start = _ct_bs->addr_for(card_ptr); |
700 HeapWord* card_start = _ct_bs->addr_for(card_ptr); |
701 // And find the region containing it. |
701 // And find the region containing it. |
702 HeapRegion* r = _g1->heap_region_containing(card_start); |
702 uint const card_region_idx = _g1->addr_to_region(card_start); |
703 |
703 |
704 HeapWord* scan_limit = _scan_state->scan_top(r->hrm_index()); |
704 _scan_state->add_dirty_region(card_region_idx); |
|
705 HeapWord* scan_limit = _scan_state->scan_top(card_region_idx); |
705 if (scan_limit <= card_start) { |
706 if (scan_limit <= card_start) { |
706 // If the card starts above the area in the region containing objects to scan, skip it. |
707 // If the card starts above the area in the region containing objects to scan, skip it. |
707 return; |
708 return; |
708 } |
709 } |
709 |
710 |
711 // a card beyond the heap. |
712 // a card beyond the heap. |
712 HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words; |
713 HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words; |
713 MemRegion dirty_region(card_start, MIN2(scan_limit, card_end)); |
714 MemRegion dirty_region(card_start, MIN2(scan_limit, card_end)); |
714 assert(!dirty_region.is_empty(), "sanity"); |
715 assert(!dirty_region.is_empty(), "sanity"); |
715 |
716 |
716 update_rs_cl->set_region(r); |
717 HeapRegion* const card_region = _g1->region_at(card_region_idx); |
717 bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl); |
718 update_rs_cl->set_region(card_region); |
|
719 bool card_processed = card_region->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl); |
718 assert(card_processed, "must be"); |
720 assert(card_processed, "must be"); |
719 } |
721 } |
720 |
722 |
721 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) { |
723 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) { |
722 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) && |
724 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) && |