comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @ 17754:d7070f371770

8035815: Cache-align and pad the from card cache Summary: The from card cache is a very frequently accessed data structure. It is essentially a 2d array of per-region values, one row of values for every GC thread. Pad and align the data structure to avoid false sharing. Reviewed-by: stefank
author tschatzl
date Mon, 24 Mar 2014 15:30:30 +0100
parents 191174b49bec
children 96b1c2e06e25
comparison
equal deleted inserted replaced
17753:191174b49bec 17754:d7070f371770
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/heapRegionSeq.inline.hpp"
31 #include "memory/allocation.hpp" 31 #include "memory/allocation.hpp"
32 #include "memory/padded.inline.hpp"
32 #include "memory/space.inline.hpp" 33 #include "memory/space.inline.hpp"
33 #include "oops/oop.inline.hpp" 34 #include "oops/oop.inline.hpp"
34 #include "utilities/bitMap.inline.hpp" 35 #include "utilities/bitMap.inline.hpp"
35 #include "utilities/globalDefinitions.hpp" 36 #include "utilities/globalDefinitions.hpp"
36 #include "utilities/growableArray.hpp" 37 #include "utilities/growableArray.hpp"
356 assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL, 357 assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
357 "just checking"); 358 "just checking");
358 } 359 }
359 360
360 int** OtherRegionsTable::_from_card_cache = NULL; 361 int** OtherRegionsTable::_from_card_cache = NULL;
361 size_t OtherRegionsTable::_from_card_cache_max_regions = 0; 362 uint OtherRegionsTable::_from_card_cache_max_regions = 0;
362 size_t OtherRegionsTable::_from_card_cache_mem_size = 0; 363 size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
363 364
364 void OtherRegionsTable::init_from_card_cache(size_t max_regions) { 365 void OtherRegionsTable::init_from_card_cache(uint max_regions) {
366 guarantee(_from_card_cache == NULL, "Should not call this multiple times");
367 uint n_par_rs = HeapRegionRemSet::num_par_rem_sets();
368
365 _from_card_cache_max_regions = max_regions; 369 _from_card_cache_max_regions = max_regions;
366 370 _from_card_cache = Padded2DArray<int, mtGC>::create_unfreeable(n_par_rs,
367 int n_par_rs = HeapRegionRemSet::num_par_rem_sets(); 371 _from_card_cache_max_regions,
368 _from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC); 372 &_from_card_cache_mem_size);
369 for (int i = 0; i < n_par_rs; i++) { 373
370 _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, max_regions, mtGC); 374 for (uint i = 0; i < n_par_rs; i++) {
371 for (size_t j = 0; j < max_regions; j++) { 375 for (uint j = 0; j < _from_card_cache_max_regions; j++) {
372 _from_card_cache[i][j] = -1; // An invalid value. 376 _from_card_cache[i][j] = -1; // An invalid value.
373 } 377 }
374 } 378 }
375 _from_card_cache_mem_size = n_par_rs * max_regions * sizeof(int); 379 }
376 } 380
377 381 void OtherRegionsTable::shrink_from_card_cache(uint new_n_regs) {
378 void OtherRegionsTable::shrink_from_card_cache(size_t new_n_regs) { 382 for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
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."); 383 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++) { 384 for (uint j = new_n_regs; j < _from_card_cache_max_regions; j++) {
382 _from_card_cache[i][j] = -1; // An invalid value. 385 _from_card_cache[i][j] = -1; // An invalid value.
383 } 386 }
384 } 387 }
385 } 388 }
386 389
387 #ifndef PRODUCT 390 #ifndef PRODUCT
388 void OtherRegionsTable::print_from_card_cache() { 391 void OtherRegionsTable::print_from_card_cache() {
389 for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { 392 for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
390 for (size_t j = 0; j < _from_card_cache_max_regions; j++) { 393 for (uint j = 0; j < _from_card_cache_max_regions; j++) {
391 gclog_or_tty->print_cr("_from_card_cache[%d][%d] = %d.", 394 gclog_or_tty->print_cr("_from_card_cache[%d][%d] = %d.",
392 i, j, _from_card_cache[i][j]); 395 i, j, _from_card_cache[i][j]);
393 } 396 }
394 } 397 }
395 } 398 }
725 size_t OtherRegionsTable::fl_mem_size() { 728 size_t OtherRegionsTable::fl_mem_size() {
726 return PerRegionTable::fl_mem_size(); 729 return PerRegionTable::fl_mem_size();
727 } 730 }
728 731
729 void OtherRegionsTable::clear_fcc() { 732 void OtherRegionsTable::clear_fcc() {
730 size_t hrs_idx = hr()->hrs_index(); 733 uint hrs_idx = hr()->hrs_index();
731 for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { 734 for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
732 _from_card_cache[i][hrs_idx] = -1; 735 _from_card_cache[i][hrs_idx] = -1;
733 } 736 }
734 } 737 }
735 738
736 void OtherRegionsTable::clear() { 739 void OtherRegionsTable::clear() {
760 assert(!_coarse_map.at(hrs_ind), "Inv"); 763 assert(!_coarse_map.at(hrs_ind), "Inv");
761 } else { 764 } else {
762 _coarse_map.par_at_put(hrs_ind, 0); 765 _coarse_map.par_at_put(hrs_ind, 0);
763 } 766 }
764 // Check to see if any of the fcc entries come from here. 767 // Check to see if any of the fcc entries come from here.
765 size_t hr_ind = (size_t) hr()->hrs_index(); 768 uint hr_ind = hr()->hrs_index();
766 for (int tid = 0; tid < HeapRegionRemSet::num_par_rem_sets(); tid++) { 769 for (uint tid = 0; tid < HeapRegionRemSet::num_par_rem_sets(); tid++) {
767 int fcc_ent = _from_card_cache[tid][hr_ind]; 770 int fcc_ent = _from_card_cache[tid][hr_ind];
768 if (fcc_ent != -1) { 771 if (fcc_ent != -1) {
769 HeapWord* card_addr = (HeapWord*) 772 HeapWord* card_addr = (HeapWord*)
770 (uintptr_t(fcc_ent) << CardTableModRefBS::card_shift); 773 (uintptr_t(fcc_ent) << CardTableModRefBS::card_shift);
771 if (hr()->is_in_reserved(card_addr)) { 774 if (hr()->is_in_reserved(card_addr)) {
836 } 839 }
837 840
838 // Determines how many threads can add records to an rset in parallel. 841 // Determines how many threads can add records to an rset in parallel.
839 // This can be done by either mutator threads together with the 842 // This can be done by either mutator threads together with the
840 // concurrent refinement threads or GC threads. 843 // concurrent refinement threads or GC threads.
841 int HeapRegionRemSet::num_par_rem_sets() { 844 uint HeapRegionRemSet::num_par_rem_sets() {
842 return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); 845 return (uint)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
843 } 846 }
844 847
845 HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, 848 HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
846 HeapRegion* hr) 849 HeapRegion* hr)
847 : _bosa(bosa), 850 : _bosa(bosa),