src/share/vm/gc_implementation/g1/g1RemSet.cpp

Print this page
rev 4973 : imported patch checkpointing.diff

@@ -249,11 +249,11 @@
     // is during RSet updating within an evacuation pause.
     // In this case worker_i should be the id of a GC worker thread.
     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
     assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
 
-    if (_g1rs->refine_card(card_ptr, worker_i, true)) {
+    if (_g1rs->refine_card(card_ptr, worker_i, (_into_cset_dcq != NULL))) {
       // 'card_ptr' contains references that point into the collection
       // set. We need to record the card in the DCQS
       // (G1CollectedHeap::into_cset_dirty_card_queue_set())
       // that's used for that purpose.
       //

@@ -262,27 +262,62 @@
     }
     return true;
   }
 };
 
-void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
+class RefineTransferredCardsClosure: public CardTableEntryClosure {
+  G1RemSet* _g1rs;
+  DirtyCardQueue* _into_cset_dcq;
+public:
+  RefineTransferredCardsClosure(G1CollectedHeap* g1h,
+                                DirtyCardQueue* into_cset_dcq) :
+    _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq)
+  {}
+  bool do_card_ptr(jbyte* card_ptr, int worker_i) {
+    // The only time we care about recording cards that
+    // contain references that point into the collection set
+    // is during RSet updating within an evacuation pause.
+    // In this case worker_i should be the id of a GC worker thread.
+    assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
+    assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
+
+    if (_g1rs->refine_card_without_check(card_ptr, worker_i, (_into_cset_dcq != NULL))) {
+      // 'card_ptr' contains references that point into the collection
+      // set. We need to record the card in the DCQS
+      // (G1CollectedHeap::into_cset_dirty_card_queue_set())
+      // that's used for that purpose.
+      //
+      // Enqueue the card
+      _into_cset_dcq->enqueue(card_ptr);
+    }
+    return true;
+  }
+};
+
+void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i, bool update_accounting) {
   double start = os::elapsedTime();
   // Apply the given closure to all remaining log entries.
-  RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
+  RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, update_accounting ? into_cset_dcq : NULL);
+  RefineTransferredCardsClosure update_cleaned_cards_rs_cl(_g1, update_accounting ? into_cset_dcq : NULL);
 
-  _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i);
+  int processed_buffers = _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl,
+                                                          &update_cleaned_cards_rs_cl,
+                                                          into_cset_dcq, false, worker_i);
 
   // Now there should be no dirty cards.
   if (G1RSLogCheckCardTable) {
     CountNonCleanMemRegionClosure cl(_g1);
     _ct_bs->mod_card_iterate(&cl);
     // XXX This isn't true any more: keeping cards of young regions
     // marked dirty broke it.  Need some reasonable fix.
     guarantee(cl.n() == 0, "Card table should be clean.");
   }
 
+  if (update_accounting) {
+    _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, processed_buffers);
   _g1p->phase_times()->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
+  }
 }
 
 void G1RemSet::cleanupHRRS() {
   HeapRegionRemSet::cleanup();
 }

@@ -320,11 +355,11 @@
   // race conditions when these two operations are done in parallel
   // and they are causing failures. When we resolve said race
   // conditions, we'll revert back to parallel remembered set
   // updating and scanning. See CRs 6677707 and 6677708.
   if (G1UseParallelRSetUpdating || (worker_i == 0)) {
-    updateRS(&into_cset_dcq, worker_i);
+    updateRS(&into_cset_dcq, worker_i, /* update_accounting */ true);
   } else {
     _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, 0);
     _g1p->phase_times()->record_update_rs_time(worker_i, 0.0);
   }
   if (G1UseParallelRSetScanning || (worker_i == 0)) {

@@ -339,10 +374,11 @@
 
 void G1RemSet::prepare_for_oops_into_collection_set_do() {
   cleanupHRRS();
   ConcurrentG1Refine* cg1r = _g1->concurrent_g1_refine();
   _g1->set_refine_cte_cl_concurrency(false);
+  _g1->set_use_transferring_cte_cl(false);
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   dcqs.concatenate_logs();
 
   if (G1CollectedHeap::use_parallel_gc_threads()) {
     // Don't set the number of workers here.  It will be set

@@ -426,10 +462,11 @@
   }
   FREE_C_HEAP_ARRAY(size_t, _cards_scanned, mtGC);
   _cards_scanned = NULL;
   // Cleanup after copy
   _g1->set_refine_cte_cl_concurrency(true);
+  _g1->set_use_transferring_cte_cl(true);
   // Set all cards back to clean.
   _g1->cleanUpCardTable();
 
   DirtyCardQueueSet& into_cset_dcqs = _g1->into_cset_dirty_card_queue_set();
   int into_cset_n_buffers = into_cset_dcqs.completed_buffers_num();

@@ -535,10 +572,15 @@
     // No need to return that this card contains refs that point
     // into the collection set.
     return false;
   }
 
+  return refine_card_without_check(card_ptr, worker_i, check_for_refs_into_cset);
+}
+
+bool G1RemSet::refine_card_without_check(jbyte* card_ptr, int worker_i,
+                                         bool check_for_refs_into_cset) {
   // Construct the region representing the card.
   HeapWord* start = _ct_bs->addr_for(card_ptr);
   // And find the region containing it.
   HeapRegion* r = _g1->heap_region_containing(start);
   if (r == NULL) {

@@ -731,10 +773,11 @@
 #endif
 
   summary->print_on(gclog_or_tty);
 }
 
+
 void G1RemSet::prepare_for_verify() {
   if (G1HRRSFlushLogBuffersOnVerify &&
       (VerifyBeforeGC || VerifyAfterGC)
       &&  (!_g1->full_collection() || G1VerifyRSetsDuringFullGC)) {
     cleanupHRRS();

@@ -747,11 +790,11 @@
     G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
     bool use_hot_card_cache = hot_card_cache->use_cache();
     hot_card_cache->set_use_cache(false);
 
     DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
-    updateRS(&into_cset_dcq, 0);
+    updateRS(&into_cset_dcq, 0, /* update_accounting */ false);
     _g1->into_cset_dirty_card_queue_set().clear();
 
     hot_card_cache->set_use_cache(use_hot_card_cache);
     assert(JavaThread::dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
   }