< prev index next >

src/share/vm/gc/g1/g1CardLiveData.cpp

Print this page
rev 10869 : [mq]: 8153170-kim-review

@@ -26,20 +26,22 @@
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1ConcurrentMark.inline.hpp"
 #include "gc/g1/g1CardLiveData.inline.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
 #include "gc/shared/workgroup.hpp"
+#include "logging/log.hpp"
 #include "memory/universe.hpp"
 #include "runtime/atomic.inline.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/debug.hpp"
 
 G1CardLiveData::G1CardLiveData() :
   _max_capacity(0),
   _cards_per_region(0),
+  _gc_timestamp_at_create(0),
   _live_regions(NULL),
   _live_regions_size_in_bits(0),
   _live_cards(NULL),
   _live_cards_size_in_bits(0) {
 }

@@ -125,10 +127,17 @@
   // We cache the last mark set. This avoids setting the same bit multiple times.
   // This is particularly interesting for dense bitmaps, as this avoids doing
   // lots of work most of the time.
   BitMap::idx_t _last_marked_bit_idx;
 
+  void clear_card_bitmap_range(HeapWord* start, HeapWord* end) {
+    BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
+    BitMap::idx_t end_idx = card_live_bitmap_index_for((HeapWord*)align_ptr_up(end, CardTableModRefBS::card_size));
+
+    _card_bm.clear_range(start_idx, end_idx);
+  }
+  
   // Mark the card liveness bitmap for the object spanning from start to end.
   void mark_card_bitmap_range(HeapWord* start, HeapWord* end) {
     BitMap::idx_t start_idx = card_live_bitmap_index_for(start);
     BitMap::idx_t end_idx = card_live_bitmap_index_for((HeapWord*)align_ptr_up(end, CardTableModRefBS::card_size));
 

@@ -167,10 +176,14 @@
   // bitmap to 1.
   void set_bit_for_region(HeapRegion* hr) {
     _region_bm.par_set_bit(hr->hrm_index());
   }
 
+  void reset_live_data(HeapRegion* hr) {
+    clear_card_bitmap_range(hr->next_top_at_mark_start(), hr->end());
+  }
+
   // Mark the range of bits covered by allocations done since the last marking
   // in the given heap region, i.e. from NTAMS to top of the given region.
   // Returns if there has been some allocation in this region since the last marking.
   bool mark_allocated_since_marking(HeapRegion* hr) {
     reset_mark_cache();

@@ -297,10 +310,12 @@
     g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer);
   }
 };
 
 void G1CardLiveData::create(WorkGang* workers, G1CMBitMap* mark_bitmap) {
+  _gc_timestamp_at_create = G1CollectedHeap::heap()->get_gc_time_stamp();
+
   uint n_workers = workers->active_workers();
 
   G1CreateCardLiveDataTask cl(mark_bitmap,
                               this,
                               n_workers);

@@ -314,18 +329,28 @@
   // card liveness bitmap. Also sets the bit for each region
   // containing live data, in the region liveness bitmap.
   class G1FinalizeCardLiveDataClosure: public HeapRegionClosure {
   private:
     G1CardLiveDataHelper _helper;
+
+    uint _gc_timestamp_at_create;
+
+    bool has_been_reclaimed(HeapRegion* hr) const {
+      return hr->get_gc_time_stamp() > _gc_timestamp_at_create;
+    }
   public:
     G1FinalizeCardLiveDataClosure(G1CollectedHeap* g1h,
                                   G1CMBitMap* bitmap,
                                   G1CardLiveData* live_data) :
       HeapRegionClosure(),
-      _helper(live_data, g1h->reserved_region().start()) { }
+      _helper(live_data, g1h->reserved_region().start()),
+      _gc_timestamp_at_create(live_data->gc_timestamp_at_create()) { }
 
     bool doHeapRegion(HeapRegion* hr) {
+      if (has_been_reclaimed(hr)) {
+        _helper.reset_live_data(hr);
+      }
       bool allocated_since_marking = _helper.mark_allocated_since_marking(hr);
       if (allocated_since_marking || hr->next_marked_bytes() > 0) {
         _helper.set_bit_for_region(hr);
       }
       return false;

@@ -451,12 +476,14 @@
       size_t exp_marked_bytes = create_live_data_count(hr);
       size_t act_marked_bytes = hr->next_marked_bytes();
       // Verify the marked bytes for this region.
 
       if (exp_marked_bytes != act_marked_bytes) {
+        log_error(gc)("Expected marked bytes " SIZE_FORMAT " != actual marked bytes " SIZE_FORMAT " in region %u", exp_marked_bytes, act_marked_bytes, hr->hrm_index());
         failures += 1;
       } else if (exp_marked_bytes > HeapRegion::GrainBytes) {
+        log_error(gc)("Expected marked bytes " SIZE_FORMAT " larger than possible " SIZE_FORMAT " in region %u", exp_marked_bytes, HeapRegion::GrainBytes, hr->hrm_index());
         failures += 1;
       }
 
       // Verify the bit, for this region, in the actual and expected
       // (which was just calculated) region bit maps.

@@ -464,11 +491,12 @@
       // bitmap is set and the bit in the actual region bitmap is not.
       uint index = hr->hrm_index();
 
       bool expected = _exp_live_data->is_region_live(index);
       bool actual = _act_live_data->is_region_live(index);
-      if (expected && !actual) {
+      if (expected != actual) {
+        log_error(gc)("Expected liveness %d not equal actual %d in region %u", expected, actual, hr->hrm_index());
         failures += 1;
       }
 
       // Verify that the card bit maps for the cards spanned by the current
       // region match. We have an error if we have a set bit in the expected

@@ -479,11 +507,12 @@
 
       for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) {
         expected = _exp_live_data->is_card_live_at(i);
         actual = _act_live_data->is_card_live_at(i);
 
-        if (expected && !actual) {
+        if (expected != actual) {
+          log_error(gc)("Expected card liveness %d not equal actual card liveness %d at card " SIZE_FORMAT " in region %u", expected, actual, i, hr->hrm_index());
           failures += 1;
         }
       }
 
       _failures += failures;
< prev index next >