hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp
changeset 13919 01f6d01a9004
parent 12381 1438e0fbfa27
child 14073 6012178c0c19
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Tue Sep 25 18:28:16 2012 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Thu Sep 27 15:44:01 2012 -0700
@@ -28,6 +28,42 @@
 #include "gc_implementation/g1/concurrentMark.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 
+// Utility routine to set an exclusive range of cards on the given
+// card liveness bitmap
+inline void ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
+                                                  BitMap::idx_t start_idx,
+                                                  BitMap::idx_t end_idx,
+                                                  bool is_par) {
+
+  // Set the exclusive bit range [start_idx, end_idx).
+  assert((end_idx - start_idx) > 0, "at least one card");
+  assert(end_idx <= card_bm->size(), "sanity");
+
+  // Silently clip the end index
+  end_idx = MIN2(end_idx, card_bm->size());
+
+  // For small ranges use a simple loop; otherwise use set_range or
+  // use par_at_put_range (if parallel). The range is made up of the
+  // cards that are spanned by an object/mem region so 8 cards will
+  // allow up to object sizes up to 4K to be handled using the loop.
+  if ((end_idx - start_idx) <= 8) {
+    for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
+      if (is_par) {
+        card_bm->par_set_bit(i);
+      } else {
+        card_bm->set_bit(i);
+      }
+    }
+  } else {
+    // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
+    if (is_par) {
+      card_bm->par_at_put_range(start_idx, end_idx, true);
+    } else {
+      card_bm->set_range(start_idx, end_idx);
+    }
+  }
+}
+
 // Returns the index in the liveness accounting card bitmap
 // for the given address
 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
@@ -35,7 +71,6 @@
   // by the card shift -- address 0 corresponds to card number 0.  One
   // must subtract the card num of the bottom of the heap to obtain a
   // card table index.
-
   intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
   return card_num - heap_bottom_card_num();
 }
@@ -46,8 +81,10 @@
                                          size_t* marked_bytes_array,
                                          BitMap* task_card_bm) {
   G1CollectedHeap* g1h = _g1h;
+  CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
+
   HeapWord* start = mr.start();
-  HeapWord* last = mr.last();
+  HeapWord* end = mr.end();
   size_t region_size_bytes = mr.byte_size();
   uint index = hr->hrs_index();
 
@@ -61,24 +98,21 @@
   marked_bytes_array[index] += region_size_bytes;
 
   BitMap::idx_t start_idx = card_bitmap_index_for(start);
-  BitMap::idx_t last_idx = card_bitmap_index_for(last);
+  BitMap::idx_t end_idx = card_bitmap_index_for(end);
 
-  // The card bitmap is task/worker specific => no need to use 'par' routines.
-  // Set bits in the inclusive bit range [start_idx, last_idx].
-  //
-  // For small ranges use a simple loop; otherwise use set_range
-  // The range are the cards that are spanned by the object/region
-  // so 8 cards will allow objects/regions up to 4K to be handled
-  // using the loop.
-  if ((last_idx - start_idx) <= 8) {
-    for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
-     task_card_bm->set_bit(i);
-    }
-  } else {
-    assert(last_idx < task_card_bm->size(), "sanity");
-    // Note: BitMap::set_range() is exclusive.
-    task_card_bm->set_range(start_idx, last_idx+1);
+  // Note: if we're looking at the last region in heap - end
+  // could be actually just beyond the end of the heap; end_idx
+  // will then correspond to a (non-existent) card that is also
+  // just beyond the heap.
+  if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
+    // end of region is not card aligned - incremement to cover
+    // all the cards spanned by the region.
+    end_idx += 1;
   }
+  // The card bitmap is task/worker specific => no need to use
+  // the 'par' BitMap routines.
+  // Set bits in the exclusive bit range [start_idx, end_idx).
+  set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
 }
 
 // Counts the given memory region in the task/worker counting