8142402: G1 should not redirty cards in free regions
authorehelin
Wed, 29 Apr 2015 13:17:46 +0200
changeset 34613 bb8d0781175e
parent 34612 ed475e8089ef
child 34614 5f1e98f98bb7
8142402: G1 should not redirty cards in free regions Reviewed-by: mgerdin, tschatzl
hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Sun Nov 29 10:00:31 2015 +0100
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Wed Apr 29 13:17:46 2015 +0200
@@ -112,18 +112,37 @@
 
 class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure {
  private:
-  size_t _num_processed;
+  size_t _num_dirtied;
+  G1CollectedHeap* _g1h;
+  G1SATBCardTableLoggingModRefBS* _g1_bs;
+
+  HeapRegion* region_for_card(jbyte* card_ptr) const {
+    return _g1h->heap_region_containing(_g1_bs->addr_for(card_ptr));
+  }
+
+  bool will_become_free(HeapRegion* hr) const {
+    // A region will be freed by free_collection_set if the region is in the
+    // collection set and has not had an evacuation failure.
+    return _g1h->is_in_cset(hr) && !hr->evacuation_failed();
+  }
 
  public:
-  RedirtyLoggedCardTableEntryClosure() : CardTableEntryClosure(), _num_processed(0) { }
+  RedirtyLoggedCardTableEntryClosure(G1CollectedHeap* g1h) : CardTableEntryClosure(),
+    _num_dirtied(0), _g1h(g1h), _g1_bs(g1h->g1_barrier_set()) { }
 
   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
-    *card_ptr = CardTableModRefBS::dirty_card_val();
-    _num_processed++;
+    HeapRegion* hr = region_for_card(card_ptr);
+
+    // Should only dirty cards in regions that won't be freed.
+    if (!will_become_free(hr)) {
+      *card_ptr = CardTableModRefBS::dirty_card_val();
+      _num_dirtied++;
+    }
+
     return true;
   }
 
-  size_t num_processed() const { return _num_processed; }
+  size_t num_dirtied()   const { return _num_dirtied; }
 };
 
 
@@ -4619,24 +4638,26 @@
 class G1RedirtyLoggedCardsTask : public AbstractGangTask {
  private:
   DirtyCardQueueSet* _queue;
+  G1CollectedHeap* _g1h;
  public:
-  G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
+  G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue, G1CollectedHeap* g1h) : AbstractGangTask("Redirty Cards"),
+    _queue(queue), _g1h(g1h) { }
 
   virtual void work(uint worker_id) {
-    G1GCPhaseTimes* phase_times = G1CollectedHeap::heap()->g1_policy()->phase_times();
+    G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id);
 
-    RedirtyLoggedCardTableEntryClosure cl;
+    RedirtyLoggedCardTableEntryClosure cl(_g1h);
     _queue->par_apply_closure_to_all_completed_buffers(&cl);
 
-    phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_processed());
+    phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_dirtied());
   }
 };
 
 void G1CollectedHeap::redirty_logged_cards() {
   double redirty_logged_cards_start = os::elapsedTime();
 
-  G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
+  G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set(), this);
   dirty_card_queue_set().reset_for_par_iteration();
   workers()->run_task(&redirty_task);