< prev index next >

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

Print this page
rev 12234 : [mq]: no_requeue
rev 12237 : [mq]: revert_no_enqueue
rev 12238 : [mq]: invalidate_unprocessed

@@ -673,25 +673,20 @@
     r->oops_on_card_seq_iterate_careful(dirtyRegion,
                                         &filter_then_update_rs_oop_cl,
                                         card_ptr);
 
   // If unable to process the card then we encountered an unparsable
-  // part of the heap (e.g. a partially allocated object).  Redirty
-  // and re-enqueue: if we put off the card until a GC pause, then the
-  // allocation will have completed.
+  // part of the heap (e.g. a partially allocated object) while
+  // processing a stale card.  Despite the card being stale, redirty
+  // and re-enqueue, because we've already cleaned the card.  Without
+  // this we could incorrectly discard a non-stale card.
   if (!card_processed) {
     assert(!_g1->is_gc_active(), "Unparsable heap during GC");
-    // The card might have gotten re-dirtied and re-enqueued while we
-    // worked.  (In fact, it's pretty likely.)
-    if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
-      *card_ptr = CardTableModRefBS::dirty_card_val();
-      MutexLockerEx x(Shared_DirtyCardQ_lock,
-                      Mutex::_no_safepoint_check_flag);
-      DirtyCardQueue* sdcq =
-        JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
-      sdcq->enqueue(card_ptr);
-    }
+    // Using invalidate for one card is simple but expensive, but this
+    // should be rare; processing a stale card while a humongous
+    // object is in the midst of being allocated in the same region.
+    _ct_bs->invalidate(dirtyRegion);
   } else {
     _conc_refine_cards++;
   }
 
   // This gets set to true if the card being refined has
< prev index next >