1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Tue Sep 25 18:28:16 2012 +0200 1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp Thu Sep 27 15:44:01 2012 -0700 1.3 @@ -28,6 +28,42 @@ 1.4 #include "gc_implementation/g1/concurrentMark.hpp" 1.5 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 1.6 1.7 +// Utility routine to set an exclusive range of cards on the given 1.8 +// card liveness bitmap 1.9 +inline void ConcurrentMark::set_card_bitmap_range(BitMap* card_bm, 1.10 + BitMap::idx_t start_idx, 1.11 + BitMap::idx_t end_idx, 1.12 + bool is_par) { 1.13 + 1.14 + // Set the exclusive bit range [start_idx, end_idx). 1.15 + assert((end_idx - start_idx) > 0, "at least one card"); 1.16 + assert(end_idx <= card_bm->size(), "sanity"); 1.17 + 1.18 + // Silently clip the end index 1.19 + end_idx = MIN2(end_idx, card_bm->size()); 1.20 + 1.21 + // For small ranges use a simple loop; otherwise use set_range or 1.22 + // use par_at_put_range (if parallel). The range is made up of the 1.23 + // cards that are spanned by an object/mem region so 8 cards will 1.24 + // allow up to object sizes up to 4K to be handled using the loop. 1.25 + if ((end_idx - start_idx) <= 8) { 1.26 + for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) { 1.27 + if (is_par) { 1.28 + card_bm->par_set_bit(i); 1.29 + } else { 1.30 + card_bm->set_bit(i); 1.31 + } 1.32 + } 1.33 + } else { 1.34 + // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive. 1.35 + if (is_par) { 1.36 + card_bm->par_at_put_range(start_idx, end_idx, true); 1.37 + } else { 1.38 + card_bm->set_range(start_idx, end_idx); 1.39 + } 1.40 + } 1.41 +} 1.42 + 1.43 // Returns the index in the liveness accounting card bitmap 1.44 // for the given address 1.45 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) { 1.46 @@ -35,7 +71,6 @@ 1.47 // by the card shift -- address 0 corresponds to card number 0. One 1.48 // must subtract the card num of the bottom of the heap to obtain a 1.49 // card table index. 1.50 - 1.51 intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift); 1.52 return card_num - heap_bottom_card_num(); 1.53 } 1.54 @@ -46,8 +81,10 @@ 1.55 size_t* marked_bytes_array, 1.56 BitMap* task_card_bm) { 1.57 G1CollectedHeap* g1h = _g1h; 1.58 + CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set()); 1.59 + 1.60 HeapWord* start = mr.start(); 1.61 - HeapWord* last = mr.last(); 1.62 + HeapWord* end = mr.end(); 1.63 size_t region_size_bytes = mr.byte_size(); 1.64 uint index = hr->hrs_index(); 1.65 1.66 @@ -61,24 +98,21 @@ 1.67 marked_bytes_array[index] += region_size_bytes; 1.68 1.69 BitMap::idx_t start_idx = card_bitmap_index_for(start); 1.70 - BitMap::idx_t last_idx = card_bitmap_index_for(last); 1.71 + BitMap::idx_t end_idx = card_bitmap_index_for(end); 1.72 1.73 - // The card bitmap is task/worker specific => no need to use 'par' routines. 1.74 - // Set bits in the inclusive bit range [start_idx, last_idx]. 1.75 - // 1.76 - // For small ranges use a simple loop; otherwise use set_range 1.77 - // The range are the cards that are spanned by the object/region 1.78 - // so 8 cards will allow objects/regions up to 4K to be handled 1.79 - // using the loop. 1.80 - if ((last_idx - start_idx) <= 8) { 1.81 - for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) { 1.82 - task_card_bm->set_bit(i); 1.83 - } 1.84 - } else { 1.85 - assert(last_idx < task_card_bm->size(), "sanity"); 1.86 - // Note: BitMap::set_range() is exclusive. 1.87 - task_card_bm->set_range(start_idx, last_idx+1); 1.88 + // Note: if we're looking at the last region in heap - end 1.89 + // could be actually just beyond the end of the heap; end_idx 1.90 + // will then correspond to a (non-existent) card that is also 1.91 + // just beyond the heap. 1.92 + if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) { 1.93 + // end of region is not card aligned - incremement to cover 1.94 + // all the cards spanned by the region. 1.95 + end_idx += 1; 1.96 } 1.97 + // The card bitmap is task/worker specific => no need to use 1.98 + // the 'par' BitMap routines. 1.99 + // Set bits in the exclusive bit range [start_idx, end_idx). 1.100 + set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */); 1.101 } 1.102 1.103 // Counts the given memory region in the task/worker counting