src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp

Print this page
rev 3640 : 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:
* * *
[mq]: code-review-comments


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
  26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
  27 
  28 #include "gc_implementation/g1/concurrentMark.hpp"
  29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  30 




































  31 // Returns the index in the liveness accounting card bitmap
  32 // for the given address
  33 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
  34   // 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
  36   // must subtract the card num of the bottom of the heap to obtain a
  37   // card table index.
  38 
  39   intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
  40   return card_num - heap_bottom_card_num();
  41 }
  42 
  43 // Counts the given memory region in the given task/worker
  44 // counting data structures.
  45 inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
  46                                          size_t* marked_bytes_array,
  47                                          BitMap* task_card_bm) {
  48   G1CollectedHeap* g1h = _g1h;


  49   HeapWord* start = mr.start();
  50   HeapWord* last = mr.last();
  51   size_t region_size_bytes = mr.byte_size();
  52   uint index = hr->hrs_index();
  53 
  54   assert(!hr->continuesHumongous(), "should not be HC region");
  55   assert(hr == g1h->heap_region_containing(start), "sanity");
  56   assert(hr == g1h->heap_region_containing(mr.last()), "sanity");
  57   assert(marked_bytes_array != NULL, "pre-condition");
  58   assert(task_card_bm != NULL, "pre-condition");
  59 
  60   // Add to the task local marked bytes for this region.
  61   marked_bytes_array[index] += region_size_bytes;
  62 
  63   BitMap::idx_t start_idx = card_bitmap_index_for(start);
  64   BitMap::idx_t last_idx = card_bitmap_index_for(last);
  65 
  66   // The card bitmap is task/worker specific => no need to use 'par' routines.
  67   // Set bits in the inclusive bit range [start_idx, last_idx].
  68   //
  69   // For small ranges use a simple loop; otherwise use set_range
  70   // The range are the cards that are spanned by the object/region
  71   // so 8 cards will allow objects/regions up to 4K to be handled
  72   // using the loop.
  73   if ((last_idx - start_idx) <= 8) {
  74     for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
  75      task_card_bm->set_bit(i);
  76     }
  77   } else {
  78     assert(last_idx < task_card_bm->size(), "sanity");
  79     // Note: BitMap::set_range() is exclusive.
  80     task_card_bm->set_range(start_idx, last_idx+1);
  81   }
  82 }
  83 
  84 // Counts the given memory region in the task/worker counting
  85 // data structures for the given worker id.
  86 inline void ConcurrentMark::count_region(MemRegion mr,
  87                                          HeapRegion* hr,
  88                                          uint worker_id) {
  89   size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
  90   BitMap* task_card_bm = count_card_bitmap_for(worker_id);
  91   count_region(mr, hr, marked_bytes_array, task_card_bm);
  92 }
  93 
  94 // Counts the given memory region, which may be a single object, in the
  95 // task/worker counting data structures for the given worker id.
  96 inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
  97   HeapWord* addr = mr.start();
  98   HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
  99   count_region(mr, hr, worker_id);
 100 }
 101 




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
  26 #define SHARE_VM_GC_IMPLEMENTATION_G1_CONCURRENTMARK_INLINE_HPP
  27 
  28 #include "gc_implementation/g1/concurrentMark.hpp"
  29 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  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 
  67 // Returns the index in the liveness accounting card bitmap
  68 // for the given address
  69 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
  70   // Below, the term "card num" means the result of shifting an address
  71   // by the card shift -- address 0 corresponds to card number 0.  One
  72   // must subtract the card num of the bottom of the heap to obtain a
  73   // card table index.

  74   intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
  75   return card_num - heap_bottom_card_num();
  76 }
  77 
  78 // Counts the given memory region in the given task/worker
  79 // counting data structures.
  80 inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
  81                                          size_t* marked_bytes_array,
  82                                          BitMap* task_card_bm) {
  83   G1CollectedHeap* g1h = _g1h;
  84   CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
  85 
  86   HeapWord* start = mr.start();
  87   HeapWord* end = mr.end();
  88   size_t region_size_bytes = mr.byte_size();
  89   uint index = hr->hrs_index();
  90 
  91   assert(!hr->continuesHumongous(), "should not be HC region");
  92   assert(hr == g1h->heap_region_containing(start), "sanity");
  93   assert(hr == g1h->heap_region_containing(mr.last()), "sanity");
  94   assert(marked_bytes_array != NULL, "pre-condition");
  95   assert(task_card_bm != NULL, "pre-condition");
  96 
  97   // Add to the task local marked bytes for this region.
  98   marked_bytes_array[index] += region_size_bytes;
  99 
 100   BitMap::idx_t start_idx = card_bitmap_index_for(start);
 101   BitMap::idx_t end_idx = card_bitmap_index_for(end);
 102 
 103   // Note: if we're looking at a region that coincides with the end
 104   // of the heap - end could actually be outside the heap and end_idx
 105   // correspond to a card that is also outside the heap.
 106   if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
 107     // end of region is not card aligned - incremement to cover
 108     // all the cards spanned by the region.
 109     end_idx += 1;
 110   }
 111   // The card bitmap is task/worker specific => no need to use
 112   // the 'par' BitMap routines.
 113   // Set bits in the exclusive bit range [start_idx, end_idx).
 114   set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);




 115 }
 116 
 117 // Counts the given memory region in the task/worker counting
 118 // data structures for the given worker id.
 119 inline void ConcurrentMark::count_region(MemRegion mr,
 120                                          HeapRegion* hr,
 121                                          uint worker_id) {
 122   size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
 123   BitMap* task_card_bm = count_card_bitmap_for(worker_id);
 124   count_region(mr, hr, marked_bytes_array, task_card_bm);
 125 }
 126 
 127 // Counts the given memory region, which may be a single object, in the
 128 // task/worker counting data structures for the given worker id.
 129 inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
 130   HeapWord* addr = mr.start();
 131   HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
 132   count_region(mr, hr, worker_id);
 133 }
 134