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

Print this page
rev 5920 : 8035406: Improve data structure for Code Cache remembered sets
Summary: Change the code cache remembered sets data structure from a GrowableArray to a chunked list of nmethods. This makes the data structure more amenable to parallelization, and decreases freeing time.
Reviewed-by:
rev 5921 : 8027295: Free CSet takes ~50% of young pause time
Summary: Improve fast card cache iteration and avoid taking locks when freeing the collection set.
Reviewed-by:


 345     prt->next()->set_prev(prt->prev());
 346   }
 347 
 348   prt->set_next(NULL);
 349   prt->set_prev(NULL);
 350 
 351   assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
 352          (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
 353          "just checking");
 354   assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
 355          "just checking");
 356   assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
 357          "just checking");
 358 }
 359 
 360 int**  OtherRegionsTable::_from_card_cache = NULL;
 361 size_t OtherRegionsTable::_from_card_cache_max_regions = 0;
 362 size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
 363 
 364 void OtherRegionsTable::init_from_card_cache(size_t max_regions) {
 365   _from_card_cache_max_regions = max_regions;

 366 
 367   int n_par_rs = HeapRegionRemSet::num_par_rem_sets();
 368   _from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC);
 369   for (int i = 0; i < n_par_rs; i++) {
 370     _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, max_regions, mtGC);
 371     for (size_t j = 0; j < max_regions; j++) {
 372       _from_card_cache[i][j] = -1;  // An invalid value.
 373     }
 374   }
 375   _from_card_cache_mem_size = n_par_rs * max_regions * sizeof(int);
 376 }
 377 
 378 void OtherRegionsTable::shrink_from_card_cache(size_t new_n_regs) {
 379   for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 380     assert(new_n_regs <= _from_card_cache_max_regions, "Must be within max.");
 381     for (size_t j = new_n_regs; j < _from_card_cache_max_regions; j++) {
 382       _from_card_cache[i][j] = -1;  // An invalid value.
 383     }
 384   }
 385 }
 386 
 387 #ifndef PRODUCT
 388 void OtherRegionsTable::print_from_card_cache() {
 389   for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 390     for (size_t j = 0; j < _from_card_cache_max_regions; j++) {
 391       gclog_or_tty->print_cr("_from_card_cache[%d][%d] = %d.",
 392                     i, j, _from_card_cache[i][j]);
 393     }
 394   }
 395 }


 711       _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
 712     sum += _first_all_fine_prts->mem_size() * _n_fine_entries;
 713   }
 714   sum += (sizeof(PerRegionTable*) * _max_fine_entries);
 715   sum += (_coarse_map.size_in_words() * HeapWordSize);
 716   sum += (_sparse_table.mem_size());
 717   sum += sizeof(*this) - sizeof(_sparse_table); // Avoid double counting above.
 718   return sum;
 719 }
 720 
 721 size_t OtherRegionsTable::static_mem_size() {
 722   return _from_card_cache_mem_size;
 723 }
 724 
 725 size_t OtherRegionsTable::fl_mem_size() {
 726   return PerRegionTable::fl_mem_size();
 727 }
 728 
 729 void OtherRegionsTable::clear_fcc() {
 730   size_t hrs_idx = hr()->hrs_index();
 731   for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {

 732     _from_card_cache[i][hrs_idx] = -1;
 733   }
 734 }
 735 
 736 void OtherRegionsTable::clear() {
 737   // if there are no entries, skip this step
 738   if (_first_all_fine_prts != NULL) {
 739     guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking");
 740     PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts);
 741     memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
 742   } else {
 743     guarantee(_first_all_fine_prts == NULL && _last_all_fine_prts == NULL, "just checking");
 744   }
 745 
 746   _first_all_fine_prts = _last_all_fine_prts = NULL;
 747   _sparse_table.clear();
 748   _coarse_map.clear();
 749   _n_fine_entries = 0;
 750   _n_coarse_entries = 0;
 751 




 345     prt->next()->set_prev(prt->prev());
 346   }
 347 
 348   prt->set_next(NULL);
 349   prt->set_prev(NULL);
 350 
 351   assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
 352          (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
 353          "just checking");
 354   assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
 355          "just checking");
 356   assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
 357          "just checking");
 358 }
 359 
 360 int**  OtherRegionsTable::_from_card_cache = NULL;
 361 size_t OtherRegionsTable::_from_card_cache_max_regions = 0;
 362 size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
 363 
 364 void OtherRegionsTable::init_from_card_cache(size_t max_regions) {
 365   // pad rows to cache line sizes.
 366   _from_card_cache_max_regions = align_size_up(max_regions, DEFAULT_CACHE_LINE_SIZE / sizeof(int));
 367 
 368   int n_par_rs = HeapRegionRemSet::num_par_rem_sets();
 369   _from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC);
 370   for (int i = 0; i < n_par_rs; i++) {
 371     _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, _from_card_cache_max_regions, mtGC);
 372     for (size_t j = 0; j < _from_card_cache_max_regions; j++) {
 373       _from_card_cache[i][j] = -1;  // An invalid value.
 374     }
 375   }
 376   _from_card_cache_mem_size = n_par_rs * _from_card_cache_max_regions * sizeof(int);
 377 }
 378 
 379 void OtherRegionsTable::shrink_from_card_cache(size_t new_n_regs) {
 380   for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 381     assert(new_n_regs <= _from_card_cache_max_regions, "Must be within max.");
 382     for (size_t j = new_n_regs; j < _from_card_cache_max_regions; j++) {
 383       _from_card_cache[i][j] = -1;  // An invalid value.
 384     }
 385   }
 386 }
 387 
 388 #ifndef PRODUCT
 389 void OtherRegionsTable::print_from_card_cache() {
 390   for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
 391     for (size_t j = 0; j < _from_card_cache_max_regions; j++) {
 392       gclog_or_tty->print_cr("_from_card_cache[%d][%d] = %d.",
 393                     i, j, _from_card_cache[i][j]);
 394     }
 395   }
 396 }


 712       _first_all_fine_prts->mem_size() == _last_all_fine_prts->mem_size(), "check that mem_size() is constant");
 713     sum += _first_all_fine_prts->mem_size() * _n_fine_entries;
 714   }
 715   sum += (sizeof(PerRegionTable*) * _max_fine_entries);
 716   sum += (_coarse_map.size_in_words() * HeapWordSize);
 717   sum += (_sparse_table.mem_size());
 718   sum += sizeof(*this) - sizeof(_sparse_table); // Avoid double counting above.
 719   return sum;
 720 }
 721 
 722 size_t OtherRegionsTable::static_mem_size() {
 723   return _from_card_cache_mem_size;
 724 }
 725 
 726 size_t OtherRegionsTable::fl_mem_size() {
 727   return PerRegionTable::fl_mem_size();
 728 }
 729 
 730 void OtherRegionsTable::clear_fcc() {
 731   size_t hrs_idx = hr()->hrs_index();
 732   uint num_par_remsets = HeapRegionRemSet::num_par_rem_sets();
 733   for (uint i = 0; i < num_par_remsets; i++) {
 734     _from_card_cache[i][hrs_idx] = -1;
 735   }
 736 }
 737 
 738 void OtherRegionsTable::clear() {
 739   // if there are no entries, skip this step
 740   if (_first_all_fine_prts != NULL) {
 741     guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking");
 742     PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts);
 743     memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
 744   } else {
 745     guarantee(_first_all_fine_prts == NULL && _last_all_fine_prts == NULL, "just checking");
 746   }
 747 
 748   _first_all_fine_prts = _last_all_fine_prts = NULL;
 749   _sparse_table.clear();
 750   _coarse_map.clear();
 751   _n_fine_entries = 0;
 752   _n_coarse_entries = 0;
 753