< prev index next >

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

Print this page
rev 13241 : imported patch 8183128-erikd-review

@@ -23,17 +23,36 @@
  */
 
 #include "precompiled.hpp"
 #include "gc/g1/dirtyCardQueue.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1RemSet.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
 
+// Closure used for updating remembered sets and recording references that
+// point into the collection set while the mutator is running.
+// Assumed to be only executed concurrently with the mutator. Yields via
+// SuspendibleThreadSet after every card.
+class G1RefineCardConcurrentlyClosure: public CardTableEntryClosure {
+public:
+  bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
+    G1CollectedHeap::heap()->g1_rem_set()->refine_card_concurrently(card_ptr, worker_i);
+
+    if (SuspendibleThreadSet::should_yield()) {
+      // Caller will actually yield.
+      return false;
+    }
+    // Otherwise, we finished successfully; return true.
+    return true;
+  }
+};
+
 // Represents a set of free small integer ids.
 class FreeIdSet : public CHeapObj<mtGC> {
   enum {
     end_of_list = UINT_MAX,
     claimed = UINT_MAX - 1

@@ -110,11 +129,10 @@
   }
 }
 
 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
   PtrQueueSet(notify_when_complete),
-  _mut_process_closure(NULL),
   _shared_dirty_card_queue(this, true /* permanent */),
   _free_ids(NULL),
   _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
 {
   _all_active = true;

@@ -123,19 +141,17 @@
 // Determines how many mutator threads can process the buffers in parallel.
 uint DirtyCardQueueSet::num_par_ids() {
   return (uint)os::initial_active_processor_count();
 }
 
-void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
-                                   Monitor* cbl_mon,
+void DirtyCardQueueSet::initialize(Monitor* cbl_mon,
                                    Mutex* fl_lock,
                                    int process_completed_threshold,
                                    int max_completed_queue,
                                    Mutex* lock,
                                    DirtyCardQueueSet* fl_owner,
                                    bool init_free_ids) {
-  _mut_process_closure = cl;
   PtrQueueSet::initialize(cbl_mon,
                           fl_lock,
                           process_completed_threshold,
                           max_completed_queue,
                           fl_owner);

@@ -190,11 +206,12 @@
 
 bool DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
   guarantee(_free_ids != NULL, "must be");
 
   uint worker_i = _free_ids->claim_par_id(); // temporarily claim an id
-  bool result = apply_closure_to_buffer(_mut_process_closure, node, true, worker_i);
+  G1RefineCardConcurrentlyClosure cl;
+  bool result = apply_closure_to_buffer(&cl, node, true, worker_i);
   _free_ids->release_par_id(worker_i); // release the id
 
   if (result) {
     assert_fully_consumed(node, buffer_size());
     Atomic::inc(&_processed_buffers_mut);

@@ -224,10 +241,20 @@
   }
   DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
   return nd;
 }
 
+bool DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_i, size_t stop_at) {
+  G1RefineCardConcurrentlyClosure cl;
+  return apply_closure_to_completed_buffer(&cl, worker_i, stop_at, false);
+}
+
+bool DirtyCardQueueSet::apply_closure_during_gc(CardTableEntryClosure* cl, uint worker_i) {
+  assert_at_safepoint(false);
+  return apply_closure_to_completed_buffer(cl, worker_i, 0, true);
+}
+
 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
                                                           uint worker_i,
                                                           size_t stop_at,
                                                           bool during_pause) {
   assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
< prev index next >