Mercurial > hg > graal-compiler
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), |