25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "gc_implementation/g1/concurrentG1Refine.hpp" |
26 #include "gc_implementation/g1/concurrentG1Refine.hpp" |
27 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" |
27 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" |
28 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
28 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
29 #include "gc_implementation/g1/heapRegionRemSet.hpp" |
29 #include "gc_implementation/g1/heapRegionRemSet.hpp" |
30 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" |
30 #include "gc_implementation/g1/heapRegionManager.inline.hpp" |
31 #include "memory/allocation.hpp" |
31 #include "memory/allocation.hpp" |
32 #include "memory/padded.inline.hpp" |
32 #include "memory/padded.inline.hpp" |
33 #include "memory/space.inline.hpp" |
33 #include "memory/space.inline.hpp" |
34 #include "oops/oop.inline.hpp" |
34 #include "oops/oop.inline.hpp" |
35 #include "utilities/bitMap.inline.hpp" |
35 #include "utilities/bitMap.inline.hpp" |
417 void OtherRegionsTable::print_from_card_cache() { |
417 void OtherRegionsTable::print_from_card_cache() { |
418 FromCardCache::print(); |
418 FromCardCache::print(); |
419 } |
419 } |
420 |
420 |
421 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { |
421 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { |
422 uint cur_hrs_ind = hr()->hrs_index(); |
422 uint cur_hrm_ind = hr()->hrm_index(); |
423 |
423 |
424 if (G1TraceHeapRegionRememberedSet) { |
424 if (G1TraceHeapRegionRememberedSet) { |
425 gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").", |
425 gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").", |
426 from, |
426 from, |
427 UseCompressedOops |
427 UseCompressedOops |
432 int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift); |
432 int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift); |
433 |
433 |
434 if (G1TraceHeapRegionRememberedSet) { |
434 if (G1TraceHeapRegionRememberedSet) { |
435 gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = "INT32_FORMAT")", |
435 gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = "INT32_FORMAT")", |
436 hr()->bottom(), from_card, |
436 hr()->bottom(), from_card, |
437 FromCardCache::at((uint)tid, cur_hrs_ind)); |
437 FromCardCache::at((uint)tid, cur_hrm_ind)); |
438 } |
438 } |
439 |
439 |
440 if (FromCardCache::contains_or_replace((uint)tid, cur_hrs_ind, from_card)) { |
440 if (FromCardCache::contains_or_replace((uint)tid, cur_hrm_ind, from_card)) { |
441 if (G1TraceHeapRegionRememberedSet) { |
441 if (G1TraceHeapRegionRememberedSet) { |
442 gclog_or_tty->print_cr(" from-card cache hit."); |
442 gclog_or_tty->print_cr(" from-card cache hit."); |
443 } |
443 } |
444 assert(contains_reference(from), "We just added it!"); |
444 assert(contains_reference(from), "We just added it!"); |
445 return; |
445 return; |
446 } |
446 } |
447 |
447 |
448 // Note that this may be a continued H region. |
448 // Note that this may be a continued H region. |
449 HeapRegion* from_hr = _g1h->heap_region_containing_raw(from); |
449 HeapRegion* from_hr = _g1h->heap_region_containing_raw(from); |
450 RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrs_index(); |
450 RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrm_index(); |
451 |
451 |
452 // If the region is already coarsened, return. |
452 // If the region is already coarsened, return. |
453 if (_coarse_map.at(from_hrs_ind)) { |
453 if (_coarse_map.at(from_hrs_ind)) { |
454 if (G1TraceHeapRegionRememberedSet) { |
454 if (G1TraceHeapRegionRememberedSet) { |
455 gclog_or_tty->print_cr(" coarse map hit."); |
455 gclog_or_tty->print_cr(" coarse map hit."); |
491 assert(contains_reference_locked(from), "We just added it!"); |
491 assert(contains_reference_locked(from), "We just added it!"); |
492 return; |
492 return; |
493 } else { |
493 } else { |
494 if (G1TraceHeapRegionRememberedSet) { |
494 if (G1TraceHeapRegionRememberedSet) { |
495 gclog_or_tty->print_cr(" [tid %d] sparse table entry " |
495 gclog_or_tty->print_cr(" [tid %d] sparse table entry " |
496 "overflow(f: %d, t: %d)", |
496 "overflow(f: %d, t: %u)", |
497 tid, from_hrs_ind, cur_hrs_ind); |
497 tid, from_hrs_ind, cur_hrm_ind); |
498 } |
498 } |
499 } |
499 } |
500 |
500 |
501 if (_n_fine_entries == _max_fine_entries) { |
501 if (_n_fine_entries == _max_fine_entries) { |
502 prt = delete_region_table(); |
502 prt = delete_region_table(); |
604 } |
604 } |
605 |
605 |
606 guarantee(max != NULL, "Since _n_fine_entries > 0"); |
606 guarantee(max != NULL, "Since _n_fine_entries > 0"); |
607 |
607 |
608 // Set the corresponding coarse bit. |
608 // Set the corresponding coarse bit. |
609 size_t max_hrs_index = (size_t) max->hr()->hrs_index(); |
609 size_t max_hrm_index = (size_t) max->hr()->hrm_index(); |
610 if (!_coarse_map.at(max_hrs_index)) { |
610 if (!_coarse_map.at(max_hrm_index)) { |
611 _coarse_map.at_put(max_hrs_index, true); |
611 _coarse_map.at_put(max_hrm_index, true); |
612 _n_coarse_entries++; |
612 _n_coarse_entries++; |
613 if (G1TraceHeapRegionRememberedSet) { |
613 if (G1TraceHeapRegionRememberedSet) { |
614 gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] " |
614 gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] " |
615 "for region [" PTR_FORMAT "...] (%d coarse entries).\n", |
615 "for region [" PTR_FORMAT "...] (%d coarse entries).\n", |
616 hr()->bottom(), |
616 hr()->bottom(), |
630 // At present, this must be called stop-world single-threaded. |
630 // At present, this must be called stop-world single-threaded. |
631 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs, |
631 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs, |
632 BitMap* region_bm, BitMap* card_bm) { |
632 BitMap* region_bm, BitMap* card_bm) { |
633 // First eliminated garbage regions from the coarse map. |
633 // First eliminated garbage regions from the coarse map. |
634 if (G1RSScrubVerbose) { |
634 if (G1RSScrubVerbose) { |
635 gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index()); |
635 gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index()); |
636 } |
636 } |
637 |
637 |
638 assert(_coarse_map.size() == region_bm->size(), "Precondition"); |
638 assert(_coarse_map.size() == region_bm->size(), "Precondition"); |
639 if (G1RSScrubVerbose) { |
639 if (G1RSScrubVerbose) { |
640 gclog_or_tty->print(" Coarse map: before = "SIZE_FORMAT"...", |
640 gclog_or_tty->print(" Coarse map: before = "SIZE_FORMAT"...", |
653 while (cur != NULL) { |
653 while (cur != NULL) { |
654 PerRegionTable* nxt = cur->collision_list_next(); |
654 PerRegionTable* nxt = cur->collision_list_next(); |
655 // If the entire region is dead, eliminate. |
655 // If the entire region is dead, eliminate. |
656 if (G1RSScrubVerbose) { |
656 if (G1RSScrubVerbose) { |
657 gclog_or_tty->print_cr(" For other region %u:", |
657 gclog_or_tty->print_cr(" For other region %u:", |
658 cur->hr()->hrs_index()); |
658 cur->hr()->hrm_index()); |
659 } |
659 } |
660 if (!region_bm->at((size_t) cur->hr()->hrs_index())) { |
660 if (!region_bm->at((size_t) cur->hr()->hrm_index())) { |
661 *prev = nxt; |
661 *prev = nxt; |
662 cur->set_collision_list_next(NULL); |
662 cur->set_collision_list_next(NULL); |
663 _n_fine_entries--; |
663 _n_fine_entries--; |
664 if (G1RSScrubVerbose) { |
664 if (G1RSScrubVerbose) { |
665 gclog_or_tty->print_cr(" deleted via region map."); |
665 gclog_or_tty->print_cr(" deleted via region map."); |
749 size_t OtherRegionsTable::fl_mem_size() { |
749 size_t OtherRegionsTable::fl_mem_size() { |
750 return PerRegionTable::fl_mem_size(); |
750 return PerRegionTable::fl_mem_size(); |
751 } |
751 } |
752 |
752 |
753 void OtherRegionsTable::clear_fcc() { |
753 void OtherRegionsTable::clear_fcc() { |
754 FromCardCache::clear(hr()->hrs_index()); |
754 FromCardCache::clear(hr()->hrm_index()); |
755 } |
755 } |
756 |
756 |
757 void OtherRegionsTable::clear() { |
757 void OtherRegionsTable::clear() { |
758 // if there are no entries, skip this step |
758 // if there are no entries, skip this step |
759 if (_first_all_fine_prts != NULL) { |
759 if (_first_all_fine_prts != NULL) { |
800 return contains_reference_locked(from); |
800 return contains_reference_locked(from); |
801 } |
801 } |
802 |
802 |
803 bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const { |
803 bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const { |
804 HeapRegion* hr = _g1h->heap_region_containing_raw(from); |
804 HeapRegion* hr = _g1h->heap_region_containing_raw(from); |
805 RegionIdx_t hr_ind = (RegionIdx_t) hr->hrs_index(); |
805 RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index(); |
806 // Is this region in the coarse map? |
806 // Is this region in the coarse map? |
807 if (_coarse_map.at(hr_ind)) return true; |
807 if (_coarse_map.at(hr_ind)) return true; |
808 |
808 |
809 PerRegionTable* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask, |
809 PerRegionTable* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask, |
810 hr); |
810 hr); |
837 } |
837 } |
838 |
838 |
839 HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, |
839 HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, |
840 HeapRegion* hr) |
840 HeapRegion* hr) |
841 : _bosa(bosa), |
841 : _bosa(bosa), |
842 _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrs_index()), true), |
842 _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true), |
843 _code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) { |
843 _code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) { |
844 reset_for_par_iteration(); |
844 reset_for_par_iteration(); |
845 } |
845 } |
846 |
846 |
847 void HeapRegionRemSet::setup_remset_size() { |
847 void HeapRegionRemSet::setup_remset_size() { |