474 if (G1HRRSUseSparseTable &&
475 _sparse_table.add_card(from_hrs_ind, card_index)) {
476 if (G1RecordHRRSOops) {
477 HeapRegionRemSet::record(hr(), from);
478 if (G1TraceHeapRegionRememberedSet) {
479 gclog_or_tty->print(" Added card " PTR_FORMAT " to region "
480 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
481 align_size_down(uintptr_t(from),
482 CardTableModRefBS::card_size),
483 hr()->bottom(), from);
484 }
485 }
486 if (G1TraceHeapRegionRememberedSet) {
487 gclog_or_tty->print_cr(" added card to sparse table.");
488 }
489 assert(contains_reference_locked(from), "We just added it!");
490 return;
491 } else {
492 if (G1TraceHeapRegionRememberedSet) {
493 gclog_or_tty->print_cr(" [tid %d] sparse table entry "
494 "overflow(f: %d, t: %d)",
495 tid, from_hrs_ind, cur_hrs_ind);
496 }
497 }
498
499 if (_n_fine_entries == _max_fine_entries) {
500 prt = delete_region_table();
501 // There is no need to clear the links to the 'all' list here:
502 // prt will be reused immediately, i.e. remain in the 'all' list.
503 prt->init(from_hr, false /* clear_links_to_all_list */);
504 } else {
505 prt = PerRegionTable::alloc(from_hr);
506 link_to_all(prt);
507 }
508
509 PerRegionTable* first_prt = _fine_grain_regions[ind];
510 prt->set_collision_list_next(first_prt);
511 _fine_grain_regions[ind] = prt;
512 _n_fine_entries++;
513
514 if (G1HRRSUseSparseTable) {
593 }
594 i = i + _fine_eviction_stride;
595 if (i >= _n_fine_entries) i = i - _n_fine_entries;
596 }
597
598 _fine_eviction_start++;
599
600 if (_fine_eviction_start >= _n_fine_entries) {
601 _fine_eviction_start -= _n_fine_entries;
602 }
603
604 guarantee(max != NULL, "Since _n_fine_entries > 0");
605
606 // Set the corresponding coarse bit.
607 size_t max_hrs_index = (size_t) max->hr()->hrs_index();
608 if (!_coarse_map.at(max_hrs_index)) {
609 _coarse_map.at_put(max_hrs_index, true);
610 _n_coarse_entries++;
611 if (G1TraceHeapRegionRememberedSet) {
612 gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
613 "for region [" PTR_FORMAT "...] (%d coarse entries).\n",
614 hr()->bottom(),
615 max->hr()->bottom(),
616 _n_coarse_entries);
617 }
618 }
619
620 // Unsplice.
621 *max_prev = max->collision_list_next();
622 Atomic::inc(&_n_coarsenings);
623 _n_fine_entries--;
624 return max;
625 }
626
627
628 // At present, this must be called stop-world single-threaded.
629 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
630 BitMap* region_bm, BitMap* card_bm) {
631 // First eliminated garbage regions from the coarse map.
632 if (G1RSScrubVerbose) {
633 gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index());
886
887 void HeapRegionRemSet::set_iter_complete() {
888 _iter_state = Complete;
889 }
890
891 bool HeapRegionRemSet::iter_is_complete() {
892 return _iter_state == Complete;
893 }
894
895 #ifndef PRODUCT
896 void HeapRegionRemSet::print() {
897 HeapRegionRemSetIterator iter(this);
898 size_t card_index;
899 while (iter.has_next(card_index)) {
900 HeapWord* card_start =
901 G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
902 gclog_or_tty->print_cr(" Card " PTR_FORMAT, card_start);
903 }
904 if (iter.n_yielded() != occupied()) {
905 gclog_or_tty->print_cr("Yielded disagrees with occupied:");
906 gclog_or_tty->print_cr(" %6d yielded (%6d coarse, %6d fine).",
907 iter.n_yielded(),
908 iter.n_yielded_coarse(), iter.n_yielded_fine());
909 gclog_or_tty->print_cr(" %6d occ (%6d coarse, %6d fine).",
910 occupied(), occ_coarse(), occ_fine());
911 }
912 guarantee(iter.n_yielded() == occupied(),
913 "We should have yielded all the represented cards.");
914 }
915 #endif
916
917 void HeapRegionRemSet::cleanup() {
918 SparsePRT::cleanup_all();
919 }
920
921 void HeapRegionRemSet::clear() {
922 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
923 clear_locked();
924 }
925
926 void HeapRegionRemSet::clear_locked() {
927 _code_roots.clear();
928 _other_regions.clear();
929 assert(occupied_locked() == 0, "Should be clear.");
|
474 if (G1HRRSUseSparseTable &&
475 _sparse_table.add_card(from_hrs_ind, card_index)) {
476 if (G1RecordHRRSOops) {
477 HeapRegionRemSet::record(hr(), from);
478 if (G1TraceHeapRegionRememberedSet) {
479 gclog_or_tty->print(" Added card " PTR_FORMAT " to region "
480 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
481 align_size_down(uintptr_t(from),
482 CardTableModRefBS::card_size),
483 hr()->bottom(), from);
484 }
485 }
486 if (G1TraceHeapRegionRememberedSet) {
487 gclog_or_tty->print_cr(" added card to sparse table.");
488 }
489 assert(contains_reference_locked(from), "We just added it!");
490 return;
491 } else {
492 if (G1TraceHeapRegionRememberedSet) {
493 gclog_or_tty->print_cr(" [tid %d] sparse table entry "
494 "overflow(f: %d, t: %u)",
495 tid, from_hrs_ind, cur_hrs_ind);
496 }
497 }
498
499 if (_n_fine_entries == _max_fine_entries) {
500 prt = delete_region_table();
501 // There is no need to clear the links to the 'all' list here:
502 // prt will be reused immediately, i.e. remain in the 'all' list.
503 prt->init(from_hr, false /* clear_links_to_all_list */);
504 } else {
505 prt = PerRegionTable::alloc(from_hr);
506 link_to_all(prt);
507 }
508
509 PerRegionTable* first_prt = _fine_grain_regions[ind];
510 prt->set_collision_list_next(first_prt);
511 _fine_grain_regions[ind] = prt;
512 _n_fine_entries++;
513
514 if (G1HRRSUseSparseTable) {
593 }
594 i = i + _fine_eviction_stride;
595 if (i >= _n_fine_entries) i = i - _n_fine_entries;
596 }
597
598 _fine_eviction_start++;
599
600 if (_fine_eviction_start >= _n_fine_entries) {
601 _fine_eviction_start -= _n_fine_entries;
602 }
603
604 guarantee(max != NULL, "Since _n_fine_entries > 0");
605
606 // Set the corresponding coarse bit.
607 size_t max_hrs_index = (size_t) max->hr()->hrs_index();
608 if (!_coarse_map.at(max_hrs_index)) {
609 _coarse_map.at_put(max_hrs_index, true);
610 _n_coarse_entries++;
611 if (G1TraceHeapRegionRememberedSet) {
612 gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
613 "for region [" PTR_FORMAT "...] (" SIZE_FORMAT " coarse entries).\n",
614 hr()->bottom(),
615 max->hr()->bottom(),
616 _n_coarse_entries);
617 }
618 }
619
620 // Unsplice.
621 *max_prev = max->collision_list_next();
622 Atomic::inc(&_n_coarsenings);
623 _n_fine_entries--;
624 return max;
625 }
626
627
628 // At present, this must be called stop-world single-threaded.
629 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
630 BitMap* region_bm, BitMap* card_bm) {
631 // First eliminated garbage regions from the coarse map.
632 if (G1RSScrubVerbose) {
633 gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index());
886
887 void HeapRegionRemSet::set_iter_complete() {
888 _iter_state = Complete;
889 }
890
891 bool HeapRegionRemSet::iter_is_complete() {
892 return _iter_state == Complete;
893 }
894
895 #ifndef PRODUCT
896 void HeapRegionRemSet::print() {
897 HeapRegionRemSetIterator iter(this);
898 size_t card_index;
899 while (iter.has_next(card_index)) {
900 HeapWord* card_start =
901 G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
902 gclog_or_tty->print_cr(" Card " PTR_FORMAT, card_start);
903 }
904 if (iter.n_yielded() != occupied()) {
905 gclog_or_tty->print_cr("Yielded disagrees with occupied:");
906 gclog_or_tty->print_cr(" " SIZE_FORMAT_W(6) " yielded (" SIZE_FORMAT_W(6)
907 " coarse, " SIZE_FORMAT_W(6) " fine).",
908 iter.n_yielded(),
909 iter.n_yielded_coarse(), iter.n_yielded_fine());
910 gclog_or_tty->print_cr(" " SIZE_FORMAT_W(6) " occ (" SIZE_FORMAT_W(6)
911 " coarse, " SIZE_FORMAT_W(6) " fine).",
912 occupied(), occ_coarse(), occ_fine());
913 }
914 guarantee(iter.n_yielded() == occupied(),
915 "We should have yielded all the represented cards.");
916 }
917 #endif
918
919 void HeapRegionRemSet::cleanup() {
920 SparsePRT::cleanup_all();
921 }
922
923 void HeapRegionRemSet::clear() {
924 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
925 clear_locked();
926 }
927
928 void HeapRegionRemSet::clear_locked() {
929 _code_roots.clear();
930 _other_regions.clear();
931 assert(occupied_locked() == 0, "Should be clear.");
|