< prev index next >

src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp

Print this page




 364          "just checking");
 365 }
 366 
 367 int**  FromCardCache::_cache = NULL;
 368 uint   FromCardCache::_max_regions = 0;
 369 size_t FromCardCache::_static_mem_size = 0;
 370 
 371 void FromCardCache::initialize(uint n_par_rs, uint max_num_regions) {
 372   guarantee(_cache == NULL, "Should not call this multiple times");
 373 
 374   _max_regions = max_num_regions;
 375   _cache = Padded2DArray<int, mtGC>::create_unfreeable(n_par_rs,
 376                                                        _max_regions,
 377                                                        &_static_mem_size);
 378 
 379   invalidate(0, _max_regions);
 380 }
 381 
 382 void FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {
 383   guarantee((size_t)start_idx + new_num_regions <= max_uintx,
 384             err_msg("Trying to invalidate beyond maximum region, from %u size "SIZE_FORMAT,
 385                     start_idx, new_num_regions));
 386   for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 387     uint end_idx = (start_idx + (uint)new_num_regions);
 388     assert(end_idx <= _max_regions, "Must be within max.");
 389     for (uint j = start_idx; j < end_idx; j++) {
 390       set(i, j, InvalidCard);
 391     }
 392   }
 393 }
 394 
 395 #ifndef PRODUCT
 396 void FromCardCache::print(outputStream* out) {
 397   for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 398     for (uint j = 0; j < _max_regions; j++) {
 399       out->print_cr("_from_card_cache["UINT32_FORMAT"]["UINT32_FORMAT"] = "INT32_FORMAT".",
 400                     i, j, at(i, j));
 401     }
 402   }
 403 }
 404 #endif


 633   }
 634 
 635   // Unsplice.
 636   *max_prev = max->collision_list_next();
 637   Atomic::inc(&_n_coarsenings);
 638   _n_fine_entries--;
 639   return max;
 640 }
 641 
 642 
 643 // At present, this must be called stop-world single-threaded.
 644 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
 645                               BitMap* region_bm, BitMap* card_bm) {
 646   // First eliminated garbage regions from the coarse map.
 647   if (G1RSScrubVerbose) {
 648     gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index());
 649   }
 650 
 651   assert(_coarse_map.size() == region_bm->size(), "Precondition");
 652   if (G1RSScrubVerbose) {
 653     gclog_or_tty->print("   Coarse map: before = "SIZE_FORMAT"...",
 654                         _n_coarse_entries);
 655   }
 656   _coarse_map.set_intersection(*region_bm);
 657   _n_coarse_entries = _coarse_map.count_one_bits();
 658   if (G1RSScrubVerbose) {
 659     gclog_or_tty->print_cr("   after = "SIZE_FORMAT".", _n_coarse_entries);
 660   }
 661 
 662   // Now do the fine-grained maps.
 663   for (size_t i = 0; i < _max_fine_entries; i++) {
 664     PerRegionTable* cur = _fine_grain_regions[i];
 665     PerRegionTable** prev = &_fine_grain_regions[i];
 666     while (cur != NULL) {
 667       PerRegionTable* nxt = cur->collision_list_next();
 668       // If the entire region is dead, eliminate.
 669       if (G1RSScrubVerbose) {
 670         gclog_or_tty->print_cr("     For other region %u:",
 671                                cur->hr()->hrm_index());
 672       }
 673       if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
 674         *prev = nxt;
 675         cur->set_collision_list_next(NULL);
 676         _n_fine_entries--;
 677         if (G1RSScrubVerbose) {
 678           gclog_or_tty->print_cr("          deleted via region map.");
 679         }


1035 }
1036 
1037 bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) {
1038   if (fine_has_next()) {
1039     _cur_card_in_prt =
1040       _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
1041   }
1042   if (_cur_card_in_prt == HeapRegion::CardsPerRegion) {
1043     // _fine_cur_prt may still be NULL in case if there are not PRTs at all for
1044     // the remembered set.
1045     if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) {
1046       return false;
1047     }
1048     PerRegionTable* next_prt = _fine_cur_prt->next();
1049     switch_to_prt(next_prt);
1050     _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
1051   }
1052 
1053   card_index = _cur_region_card_offset + _cur_card_in_prt;
1054   guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
1055             err_msg("Card index "SIZE_FORMAT" must be within the region", _cur_card_in_prt));
1056   return true;
1057 }
1058 
1059 bool HeapRegionRemSetIterator::fine_has_next() {
1060   return _cur_card_in_prt != HeapRegion::CardsPerRegion;
1061 }
1062 
1063 void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) {
1064   assert(prt != NULL, "Cannot switch to NULL prt");
1065   _fine_cur_prt = prt;
1066 
1067   HeapWord* r_bot = _fine_cur_prt->hr()->bottom();
1068   _cur_region_card_offset = _bosa->index_for(r_bot);
1069 
1070   // The bitmap scan for the PRT always scans from _cur_region_cur_card + 1.
1071   // To avoid special-casing this start case, and not miss the first bitmap
1072   // entry, initialize _cur_region_cur_card with -1 instead of 0.
1073   _cur_card_in_prt = (size_t)-1;
1074 }
1075 


1204 
1205 void HeapRegionRemSet::reset_for_cleanup_tasks() {
1206   SparsePRT::reset_for_cleanup_tasks();
1207 }
1208 
1209 void HeapRegionRemSet::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
1210   _other_regions.do_cleanup_work(hrrs_cleanup_task);
1211 }
1212 
1213 void
1214 HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) {
1215   SparsePRT::finish_cleanup_task(hrrs_cleanup_task);
1216 }
1217 
1218 #ifndef PRODUCT
1219 void PerRegionTable::test_fl_mem_size() {
1220   PerRegionTable* dummy = alloc(NULL);
1221 
1222   size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize;
1223   assert(dummy->mem_size() > min_prt_size,
1224          err_msg("PerRegionTable memory usage is suspiciously small, only has "SIZE_FORMAT" bytes. "
1225                  "Should be at least "SIZE_FORMAT" bytes.", dummy->mem_size(), min_prt_size));
1226   free(dummy);
1227   guarantee(dummy->mem_size() == fl_mem_size(), "fl_mem_size() does not return the correct element size");
1228   // try to reset the state
1229   _free_list = NULL;
1230   delete dummy;
1231 }
1232 
1233 void HeapRegionRemSet::test_prt() {
1234   PerRegionTable::test_fl_mem_size();
1235 }
1236 
1237 void HeapRegionRemSet::test() {
1238   os::sleep(Thread::current(), (jlong)5000, false);
1239   G1CollectedHeap* g1h = G1CollectedHeap::heap();
1240 
1241   // Run with "-XX:G1LogRSetRegionEntries=2", so that 1 and 5 end up in same
1242   // hash bucket.
1243   HeapRegion* hr0 = g1h->region_at(0);
1244   HeapRegion* hr1 = g1h->region_at(1);
1245   HeapRegion* hr2 = g1h->region_at(5);




 364          "just checking");
 365 }
 366 
 367 int**  FromCardCache::_cache = NULL;
 368 uint   FromCardCache::_max_regions = 0;
 369 size_t FromCardCache::_static_mem_size = 0;
 370 
 371 void FromCardCache::initialize(uint n_par_rs, uint max_num_regions) {
 372   guarantee(_cache == NULL, "Should not call this multiple times");
 373 
 374   _max_regions = max_num_regions;
 375   _cache = Padded2DArray<int, mtGC>::create_unfreeable(n_par_rs,
 376                                                        _max_regions,
 377                                                        &_static_mem_size);
 378 
 379   invalidate(0, _max_regions);
 380 }
 381 
 382 void FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {
 383   guarantee((size_t)start_idx + new_num_regions <= max_uintx,
 384             err_msg("Trying to invalidate beyond maximum region, from %u size " SIZE_FORMAT,
 385                     start_idx, new_num_regions));
 386   for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 387     uint end_idx = (start_idx + (uint)new_num_regions);
 388     assert(end_idx <= _max_regions, "Must be within max.");
 389     for (uint j = start_idx; j < end_idx; j++) {
 390       set(i, j, InvalidCard);
 391     }
 392   }
 393 }
 394 
 395 #ifndef PRODUCT
 396 void FromCardCache::print(outputStream* out) {
 397   for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 398     for (uint j = 0; j < _max_regions; j++) {
 399       out->print_cr("_from_card_cache["UINT32_FORMAT"]["UINT32_FORMAT"] = "INT32_FORMAT".",
 400                     i, j, at(i, j));
 401     }
 402   }
 403 }
 404 #endif


 633   }
 634 
 635   // Unsplice.
 636   *max_prev = max->collision_list_next();
 637   Atomic::inc(&_n_coarsenings);
 638   _n_fine_entries--;
 639   return max;
 640 }
 641 
 642 
 643 // At present, this must be called stop-world single-threaded.
 644 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
 645                               BitMap* region_bm, BitMap* card_bm) {
 646   // First eliminated garbage regions from the coarse map.
 647   if (G1RSScrubVerbose) {
 648     gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index());
 649   }
 650 
 651   assert(_coarse_map.size() == region_bm->size(), "Precondition");
 652   if (G1RSScrubVerbose) {
 653     gclog_or_tty->print("   Coarse map: before = " SIZE_FORMAT "...",
 654                         _n_coarse_entries);
 655   }
 656   _coarse_map.set_intersection(*region_bm);
 657   _n_coarse_entries = _coarse_map.count_one_bits();
 658   if (G1RSScrubVerbose) {
 659     gclog_or_tty->print_cr("   after = " SIZE_FORMAT ".", _n_coarse_entries);
 660   }
 661 
 662   // Now do the fine-grained maps.
 663   for (size_t i = 0; i < _max_fine_entries; i++) {
 664     PerRegionTable* cur = _fine_grain_regions[i];
 665     PerRegionTable** prev = &_fine_grain_regions[i];
 666     while (cur != NULL) {
 667       PerRegionTable* nxt = cur->collision_list_next();
 668       // If the entire region is dead, eliminate.
 669       if (G1RSScrubVerbose) {
 670         gclog_or_tty->print_cr("     For other region %u:",
 671                                cur->hr()->hrm_index());
 672       }
 673       if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
 674         *prev = nxt;
 675         cur->set_collision_list_next(NULL);
 676         _n_fine_entries--;
 677         if (G1RSScrubVerbose) {
 678           gclog_or_tty->print_cr("          deleted via region map.");
 679         }


1035 }
1036 
1037 bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) {
1038   if (fine_has_next()) {
1039     _cur_card_in_prt =
1040       _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
1041   }
1042   if (_cur_card_in_prt == HeapRegion::CardsPerRegion) {
1043     // _fine_cur_prt may still be NULL in case if there are not PRTs at all for
1044     // the remembered set.
1045     if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) {
1046       return false;
1047     }
1048     PerRegionTable* next_prt = _fine_cur_prt->next();
1049     switch_to_prt(next_prt);
1050     _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
1051   }
1052 
1053   card_index = _cur_region_card_offset + _cur_card_in_prt;
1054   guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
1055             err_msg("Card index " SIZE_FORMAT " must be within the region", _cur_card_in_prt));
1056   return true;
1057 }
1058 
1059 bool HeapRegionRemSetIterator::fine_has_next() {
1060   return _cur_card_in_prt != HeapRegion::CardsPerRegion;
1061 }
1062 
1063 void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) {
1064   assert(prt != NULL, "Cannot switch to NULL prt");
1065   _fine_cur_prt = prt;
1066 
1067   HeapWord* r_bot = _fine_cur_prt->hr()->bottom();
1068   _cur_region_card_offset = _bosa->index_for(r_bot);
1069 
1070   // The bitmap scan for the PRT always scans from _cur_region_cur_card + 1.
1071   // To avoid special-casing this start case, and not miss the first bitmap
1072   // entry, initialize _cur_region_cur_card with -1 instead of 0.
1073   _cur_card_in_prt = (size_t)-1;
1074 }
1075 


1204 
1205 void HeapRegionRemSet::reset_for_cleanup_tasks() {
1206   SparsePRT::reset_for_cleanup_tasks();
1207 }
1208 
1209 void HeapRegionRemSet::do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task) {
1210   _other_regions.do_cleanup_work(hrrs_cleanup_task);
1211 }
1212 
1213 void
1214 HeapRegionRemSet::finish_cleanup_task(HRRSCleanupTask* hrrs_cleanup_task) {
1215   SparsePRT::finish_cleanup_task(hrrs_cleanup_task);
1216 }
1217 
1218 #ifndef PRODUCT
1219 void PerRegionTable::test_fl_mem_size() {
1220   PerRegionTable* dummy = alloc(NULL);
1221 
1222   size_t min_prt_size = sizeof(void*) + dummy->bm()->size_in_words() * HeapWordSize;
1223   assert(dummy->mem_size() > min_prt_size,
1224          err_msg("PerRegionTable memory usage is suspiciously small, only has " SIZE_FORMAT " bytes. "
1225                  "Should be at least " SIZE_FORMAT " bytes.", dummy->mem_size(), min_prt_size));
1226   free(dummy);
1227   guarantee(dummy->mem_size() == fl_mem_size(), "fl_mem_size() does not return the correct element size");
1228   // try to reset the state
1229   _free_list = NULL;
1230   delete dummy;
1231 }
1232 
1233 void HeapRegionRemSet::test_prt() {
1234   PerRegionTable::test_fl_mem_size();
1235 }
1236 
1237 void HeapRegionRemSet::test() {
1238   os::sleep(Thread::current(), (jlong)5000, false);
1239   G1CollectedHeap* g1h = G1CollectedHeap::heap();
1240 
1241   // Run with "-XX:G1LogRSetRegionEntries=2", so that 1 and 5 end up in same
1242   // hash bucket.
1243   HeapRegion* hr0 = g1h->region_at(0);
1244   HeapRegion* hr1 = g1h->region_at(1);
1245   HeapRegion* hr2 = g1h->region_at(5);


< prev index next >