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

Print this page

        

@@ -174,13 +174,45 @@
 
     return false;
   }
 };
 
+class ParClearNextMarkBitmapTask : public AbstractGangTask {
+  ClearBitmapHRClosure* _cl;
+  uint                  _workload;
+  bool                  _suspendible; // If the task is suspendible, workers must join the STS.
+public:
+  ParClearNextMarkBitmapTask(ClearBitmapHRClosure *cl, uint n_workers, bool suspendible) : _cl(cl), _suspendible(suspendible), AbstractGangTask("Parallel Clear Bitmap Task") {
+    assert(n_workers > 0, "Must have at least one worker.");
+    uint max_regions = G1CollectedHeap::heap()->max_regions();
+    _workload = (max_regions + n_workers - 1) / n_workers;
+    assert(n_workers * _workload >= max_regions, "Workloads should cover all regions.");
+  }
+
+  void work(uint worker_id) {
+    if (_suspendible) {
+      SuspendibleThreadSet::join();
+    }
+    uint start = worker_id * _workload;
+    uint end = MIN2(start + _workload, G1CollectedHeap::heap()->max_regions());
+    G1CollectedHeap::heap()->heap_region_iterate_range(_cl, start, end);
+    if (_suspendible) {
+      SuspendibleThreadSet::leave();
+    }
+  }
+};
+
 void CMBitMap::clearAll() {
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
   ClearBitmapHRClosure cl(NULL, this, false /* may_yield */);
-  G1CollectedHeap::heap()->heap_region_iterate(&cl);
+  if (g1h->use_parallel_gc_threads()) {
+    uint n_workers = g1h->workers()->active_workers();
+    ParClearNextMarkBitmapTask task(&cl, n_workers, false);
+    g1h->workers()->run_task(&task);
+  } else {
+    g1h->heap_region_iterate(&cl);
+  }
   guarantee(cl.complete(), "Must have completed iteration.");
   return;
 }
 
 void CMBitMap::markRange(MemRegion mr) {

@@ -869,11 +901,17 @@
   // this time no other cycle can start. So, let's make sure that this
   // is the case.
   guarantee(!g1h->mark_in_progress(), "invariant");
 
   ClearBitmapHRClosure cl(this, _nextMarkBitMap, true /* may_yield */);
+  if (use_parallel_marking_threads()) {
+    ParClearNextMarkBitmapTask task(&cl, parallel_marking_threads(), true);
+    _parallel_workers->run_task(&task);
+  } else {
+    SuspendibleThreadSetJoiner sts;
   g1h->heap_region_iterate(&cl);
+  }
 
   // Clear the liveness counting data. If the marking has been aborted, the abort()
   // call already did that.
   if (cl.complete()) {
     clear_all_count_data();