Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp @ 6812:988bf00cc564
7200261: G1: Liveness counting inconsistencies during marking verification
Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures.
Reviewed-by: brutisso, jwilhelm, jmasa
author | johnc |
---|---|
date | Thu, 27 Sep 2012 15:44:01 -0700 |
parents | 720b6a76dd9d |
children | 8a5ea0a9ccc4 |
comparison
equal
deleted
inserted
replaced
6788:7c2fd5948145 | 6812:988bf00cc564 |
---|---|
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP | 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP |
27 | 27 |
28 #include "gc_implementation/g1/concurrentMark.hpp" | 28 #include "gc_implementation/g1/concurrentMark.hpp" |
29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" | 29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
30 | 30 |
31 // Utility routine to set an exclusive range of cards on the given | |
32 // card liveness bitmap | |
33 inline void ConcurrentMark::set_card_bitmap_range(BitMap* card_bm, | |
34 BitMap::idx_t start_idx, | |
35 BitMap::idx_t end_idx, | |
36 bool is_par) { | |
37 | |
38 // Set the exclusive bit range [start_idx, end_idx). | |
39 assert((end_idx - start_idx) > 0, "at least one card"); | |
40 assert(end_idx <= card_bm->size(), "sanity"); | |
41 | |
42 // Silently clip the end index | |
43 end_idx = MIN2(end_idx, card_bm->size()); | |
44 | |
45 // For small ranges use a simple loop; otherwise use set_range or | |
46 // use par_at_put_range (if parallel). The range is made up of the | |
47 // cards that are spanned by an object/mem region so 8 cards will | |
48 // allow up to object sizes up to 4K to be handled using the loop. | |
49 if ((end_idx - start_idx) <= 8) { | |
50 for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) { | |
51 if (is_par) { | |
52 card_bm->par_set_bit(i); | |
53 } else { | |
54 card_bm->set_bit(i); | |
55 } | |
56 } | |
57 } else { | |
58 // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive. | |
59 if (is_par) { | |
60 card_bm->par_at_put_range(start_idx, end_idx, true); | |
61 } else { | |
62 card_bm->set_range(start_idx, end_idx); | |
63 } | |
64 } | |
65 } | |
66 | |
31 // Returns the index in the liveness accounting card bitmap | 67 // Returns the index in the liveness accounting card bitmap |
32 // for the given address | 68 // for the given address |
33 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) { | 69 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) { |
34 // Below, the term "card num" means the result of shifting an address | 70 // Below, the term "card num" means the result of shifting an address |
35 // by the card shift -- address 0 corresponds to card number 0. One | 71 // by the card shift -- address 0 corresponds to card number 0. One |
36 // must subtract the card num of the bottom of the heap to obtain a | 72 // must subtract the card num of the bottom of the heap to obtain a |
37 // card table index. | 73 // card table index. |
38 | |
39 intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift); | 74 intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift); |
40 return card_num - heap_bottom_card_num(); | 75 return card_num - heap_bottom_card_num(); |
41 } | 76 } |
42 | 77 |
43 // Counts the given memory region in the given task/worker | 78 // Counts the given memory region in the given task/worker |
44 // counting data structures. | 79 // counting data structures. |
45 inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr, | 80 inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr, |
46 size_t* marked_bytes_array, | 81 size_t* marked_bytes_array, |
47 BitMap* task_card_bm) { | 82 BitMap* task_card_bm) { |
48 G1CollectedHeap* g1h = _g1h; | 83 G1CollectedHeap* g1h = _g1h; |
84 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set()); | |
85 | |
49 HeapWord* start = mr.start(); | 86 HeapWord* start = mr.start(); |
50 HeapWord* last = mr.last(); | 87 HeapWord* end = mr.end(); |
51 size_t region_size_bytes = mr.byte_size(); | 88 size_t region_size_bytes = mr.byte_size(); |
52 uint index = hr->hrs_index(); | 89 uint index = hr->hrs_index(); |
53 | 90 |
54 assert(!hr->continuesHumongous(), "should not be HC region"); | 91 assert(!hr->continuesHumongous(), "should not be HC region"); |
55 assert(hr == g1h->heap_region_containing(start), "sanity"); | 92 assert(hr == g1h->heap_region_containing(start), "sanity"); |
59 | 96 |
60 // Add to the task local marked bytes for this region. | 97 // Add to the task local marked bytes for this region. |
61 marked_bytes_array[index] += region_size_bytes; | 98 marked_bytes_array[index] += region_size_bytes; |
62 | 99 |
63 BitMap::idx_t start_idx = card_bitmap_index_for(start); | 100 BitMap::idx_t start_idx = card_bitmap_index_for(start); |
64 BitMap::idx_t last_idx = card_bitmap_index_for(last); | 101 BitMap::idx_t end_idx = card_bitmap_index_for(end); |
65 | 102 |
66 // The card bitmap is task/worker specific => no need to use 'par' routines. | 103 // Note: if we're looking at the last region in heap - end |
67 // Set bits in the inclusive bit range [start_idx, last_idx]. | 104 // could be actually just beyond the end of the heap; end_idx |
68 // | 105 // will then correspond to a (non-existent) card that is also |
69 // For small ranges use a simple loop; otherwise use set_range | 106 // just beyond the heap. |
70 // The range are the cards that are spanned by the object/region | 107 if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) { |
71 // so 8 cards will allow objects/regions up to 4K to be handled | 108 // end of region is not card aligned - incremement to cover |
72 // using the loop. | 109 // all the cards spanned by the region. |
73 if ((last_idx - start_idx) <= 8) { | 110 end_idx += 1; |
74 for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) { | 111 } |
75 task_card_bm->set_bit(i); | 112 // The card bitmap is task/worker specific => no need to use |
76 } | 113 // the 'par' BitMap routines. |
77 } else { | 114 // Set bits in the exclusive bit range [start_idx, end_idx). |
78 assert(last_idx < task_card_bm->size(), "sanity"); | 115 set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */); |
79 // Note: BitMap::set_range() is exclusive. | |
80 task_card_bm->set_range(start_idx, last_idx+1); | |
81 } | |
82 } | 116 } |
83 | 117 |
84 // Counts the given memory region in the task/worker counting | 118 // Counts the given memory region in the task/worker counting |
85 // data structures for the given worker id. | 119 // data structures for the given worker id. |
86 inline void ConcurrentMark::count_region(MemRegion mr, | 120 inline void ConcurrentMark::count_region(MemRegion mr, |