src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
changeset 47696 d011b1650071
parent 47695 75aa2a8e7304
child 47697 2e54e9324e1c
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Wed Oct 25 16:12:15 2017 +0200
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Wed Oct 25 16:13:09 2017 +0200
@@ -326,16 +326,19 @@
   return true;
 }
 
-uint G1ConcurrentMark::scale_parallel_threads(uint n_par_threads) {
-  return MAX2((n_par_threads + 2) / 4, 1U);
+// Returns the maximum number of workers to be used in a concurrent
+// phase based on the number of GC workers being used in a STW
+// phase.
+static uint scale_concurrent_worker_threads(uint num_gc_workers) {
+  return MAX2((num_gc_workers + 2) / 4, 1U);
 }
 
 G1ConcurrentMark::G1ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev_bitmap_storage, G1RegionToSpaceMapper* next_bitmap_storage) :
   _g1h(g1h),
   _mark_bitmap_1(),
   _mark_bitmap_2(),
-  _parallel_marking_threads(0),
-  _max_parallel_marking_threads(0),
+  _num_concurrent_workers(0),
+  _max_concurrent_workers(0),
   _cleanup_list("Concurrent Mark Cleanup List"),
 
   _prev_mark_bitmap(&_mark_bitmap_1),
@@ -344,11 +347,11 @@
   _global_mark_stack(),
   // _finger set in set_non_marking_state
 
-  _max_worker_id(ParallelGCThreads),
+  _max_num_tasks(ParallelGCThreads),
   // _active_tasks set in set_non_marking_state
   // _tasks set inside the constructor
-  _task_queues(new G1CMTaskQueueSet((int) _max_worker_id)),
-  _terminator(ParallelTaskTerminator((int) _max_worker_id, _task_queues)),
+  _task_queues(new G1CMTaskQueueSet((int) _max_num_tasks)),
+  _terminator(ParallelTaskTerminator((int) _max_num_tasks, _task_queues)),
 
   _has_overflown(false),
   _concurrent(false),
@@ -368,7 +371,7 @@
   _total_counting_time(0.0),
   _total_rs_scrub_time(0.0),
 
-  _parallel_workers(NULL),
+  _concurrent_workers(NULL),
 
   _completed_initialization(false) {
 
@@ -390,37 +393,33 @@
 
   _root_regions.init(_g1h->survivor(), this);
 
+  if (FLAG_IS_DEFAULT(ConcGCThreads) || ConcGCThreads == 0) {
+    // Calculate the number of concurrent worker threads by scaling
+    // the number of parallel GC threads.
+    uint marking_thread_num = scale_concurrent_worker_threads(ParallelGCThreads);
+    FLAG_SET_ERGO(uint, ConcGCThreads, marking_thread_num);
+  }
+
+  assert(ConcGCThreads > 0, "ConcGCThreads have been set.");
   if (ConcGCThreads > ParallelGCThreads) {
     log_warning(gc)("More ConcGCThreads (%u) than ParallelGCThreads (%u).",
                     ConcGCThreads, ParallelGCThreads);
     return;
   }
 
-  if (FLAG_IS_DEFAULT(ConcGCThreads) || ConcGCThreads == 0) {
-    // Calculate the number of parallel marking threads by scaling
-    // the number of parallel GC threads.
-    uint marking_thread_num = scale_parallel_threads(ParallelGCThreads);
-    FLAG_SET_ERGO(uint, ConcGCThreads, marking_thread_num);
-  }
-
-  assert(ConcGCThreads > 0, "Should have been set");
   log_debug(gc)("ConcGCThreads: %u", ConcGCThreads);
   log_debug(gc)("ParallelGCThreads: %u", ParallelGCThreads);
 
-  _parallel_marking_threads = ConcGCThreads;
-  _max_parallel_marking_threads = _parallel_marking_threads;
-
-  _parallel_workers = new WorkGang("G1 Marker", _max_parallel_marking_threads, false, true);
-  if (_parallel_workers == NULL) {
-    vm_exit_during_initialization("Failed necessary allocation.");
-  } else {
-    _parallel_workers->initialize_workers();
-  }
+  _num_concurrent_workers = ConcGCThreads;
+  _max_concurrent_workers = _num_concurrent_workers;
+
+  _concurrent_workers = new WorkGang("G1 Conc", _max_concurrent_workers, false, true);
+  _concurrent_workers->initialize_workers();
 
   if (FLAG_IS_DEFAULT(MarkStackSize)) {
     size_t mark_stack_size =
       MIN2(MarkStackSizeMax,
-          MAX2(MarkStackSize, (size_t) (_parallel_marking_threads * TASKQUEUE_SIZE)));
+          MAX2(MarkStackSize, (size_t) (_max_concurrent_workers * TASKQUEUE_SIZE)));
     // Verify that the calculated value for MarkStackSize is in range.
     // It would be nice to use the private utility routine from Arguments.
     if (!(mark_stack_size >= 1 && mark_stack_size <= MarkStackSizeMax)) {
@@ -455,13 +454,13 @@
     vm_exit_during_initialization("Failed to allocate initial concurrent mark overflow mark stack.");
   }
 
-  _tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC);
-  _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_worker_id, mtGC);
+  _tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_num_tasks, mtGC);
+  _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_num_tasks, mtGC);
 
   // so that the assertion in MarkingTaskQueue::task_queue doesn't fail
-  _active_tasks = _max_worker_id;
-
-  for (uint i = 0; i < _max_worker_id; ++i) {
+  _num_active_tasks = _max_num_tasks;
+
+  for (uint i = 0; i < _max_num_tasks; ++i) {
     G1CMTaskQueue* task_queue = new G1CMTaskQueue();
     task_queue->initialize();
     _task_queues->register_queue(i, task_queue);
@@ -495,7 +494,7 @@
   // We reset all of them, since different phases will use
   // different number of active threads. So, it's easiest to have all
   // of them ready.
-  for (uint i = 0; i < _max_worker_id; ++i) {
+  for (uint i = 0; i < _max_num_tasks; ++i) {
     _tasks[i]->reset(_next_mark_bitmap);
   }
 
@@ -516,16 +515,16 @@
   clear_has_overflown();
   _finger = _heap_start;
 
-  for (uint i = 0; i < _max_worker_id; ++i) {
+  for (uint i = 0; i < _max_num_tasks; ++i) {
     G1CMTaskQueue* queue = _task_queues->queue(i);
     queue->set_empty();
   }
 }
 
 void G1ConcurrentMark::set_concurrency(uint active_tasks) {
-  assert(active_tasks <= _max_worker_id, "we should not have more");
-
-  _active_tasks = active_tasks;
+  assert(active_tasks <= _max_num_tasks, "we should not have more");
+
+  _num_active_tasks = active_tasks;
   // Need to update the three data structures below according to the
   // number of active threads for this phase.
   _terminator   = ParallelTaskTerminator((int) active_tasks, _task_queues);
@@ -538,7 +537,7 @@
 
   _concurrent = concurrent;
   // We propagate this to all tasks, not just the active ones.
-  for (uint i = 0; i < _max_worker_id; ++i) {
+  for (uint i = 0; i < _max_num_tasks; ++i) {
     _tasks[i]->set_concurrent(concurrent);
   }
 
@@ -559,7 +558,7 @@
   // We set the global marking state to some default values when we're
   // not doing marking.
   reset_marking_state();
-  _active_tasks = 0;
+  _num_active_tasks = 0;
   clear_concurrent_marking_in_progress();
 }
 
@@ -659,12 +658,12 @@
   // is the case.
   guarantee(!_g1h->collector_state()->mark_in_progress(), "invariant");
 
-  clear_bitmap(_next_mark_bitmap, _parallel_workers, true);
+  clear_bitmap(_next_mark_bitmap, _concurrent_workers, true);
 
   // Clear the live count data. If the marking has been aborted, the abort()
   // call already did that.
   if (!has_aborted()) {
-    clear_live_data(_parallel_workers);
+    clear_live_data(_concurrent_workers);
     DEBUG_ONLY(verify_live_data_clear());
   }
 
@@ -857,27 +856,25 @@
   ~G1CMConcurrentMarkingTask() { }
 };
 
-// Calculates the number of active workers for a concurrent
-// phase.
-uint G1ConcurrentMark::calc_parallel_marking_threads() {
-  uint n_conc_workers = 0;
+uint G1ConcurrentMark::calc_active_marking_workers() {
+  uint result = 0;
   if (!UseDynamicNumberOfGCThreads ||
       (!FLAG_IS_DEFAULT(ConcGCThreads) &&
        !ForceDynamicNumberOfGCThreads)) {
-    n_conc_workers = _max_parallel_marking_threads;
+    result = _max_concurrent_workers;
   } else {
-    n_conc_workers =
-      AdaptiveSizePolicy::calc_default_active_workers(_max_parallel_marking_threads,
+    result =
+      AdaptiveSizePolicy::calc_default_active_workers(_max_concurrent_workers,
                                                       1, /* Minimum workers */
-                                                      _parallel_marking_threads,
+                                                      _num_concurrent_workers,
                                                       Threads::number_of_non_daemon_threads());
-    // Don't scale down "n_conc_workers" by scale_parallel_threads() because
-    // that scaling has already gone into "_max_parallel_marking_threads".
+    // Don't scale the result down by scale_concurrent_workers() because
+    // that scaling has already gone into "_max_concurrent_workers".
   }
-  assert(n_conc_workers > 0 && n_conc_workers <= _max_parallel_marking_threads,
-         "Calculated number of workers must be larger than zero and at most the maximum %u, but is %u",
-         _max_parallel_marking_threads, n_conc_workers);
-  return n_conc_workers;
+  assert(result > 0 && result <= _max_concurrent_workers,
+         "Calculated number of marking workers must be larger than zero and at most the maximum %u, but is %u",
+         _max_concurrent_workers, result);
+  return result;
 }
 
 void G1ConcurrentMark::scan_root_region(HeapRegion* hr) {
@@ -925,17 +922,17 @@
   if (root_regions()->scan_in_progress()) {
     assert(!has_aborted(), "Aborting before root region scanning is finished not supported.");
 
-    _parallel_marking_threads = MIN2(calc_parallel_marking_threads(),
-                                     // We distribute work on a per-region basis, so starting
-                                     // more threads than that is useless.
-                                     root_regions()->num_root_regions());
-    assert(_parallel_marking_threads <= _max_parallel_marking_threads,
+    _num_concurrent_workers = MIN2(calc_active_marking_workers(),
+                                   // We distribute work on a per-region basis, so starting
+                                   // more threads than that is useless.
+                                   root_regions()->num_root_regions());
+    assert(_num_concurrent_workers <= _max_concurrent_workers,
            "Maximum number of marking threads exceeded");
 
     G1CMRootRegionScanTask task(this);
     log_debug(gc, ergo)("Running %s using %u workers for %u work units.",
-                        task.name(), _parallel_marking_threads, root_regions()->num_root_regions());
-    _parallel_workers->run_task(&task, _parallel_marking_threads);
+                        task.name(), _num_concurrent_workers, root_regions()->num_root_regions());
+    _concurrent_workers->run_task(&task, _num_concurrent_workers);
 
     // It's possible that has_aborted() is true here without actually
     // aborting the survivor scan earlier. This is OK as it's
@@ -974,25 +971,21 @@
 
   _restart_for_overflow = false;
 
-  // _g1h has _n_par_threads
-  _parallel_marking_threads = calc_parallel_marking_threads();
-  assert(_parallel_marking_threads <= _max_parallel_marking_threads,
-    "Maximum number of marking threads exceeded");
-
-  uint active_workers = MAX2(1U, _parallel_marking_threads);
-  assert(active_workers > 0, "Should have been set");
+  _num_concurrent_workers = calc_active_marking_workers();
+
+  uint active_workers = MAX2(1U, _num_concurrent_workers);
 
   // Setting active workers is not guaranteed since fewer
   // worker threads may currently exist and more may not be
   // available.
-  active_workers = _parallel_workers->update_active_workers(active_workers);
-  log_info(gc, task)("Using %u workers of %u for marking", active_workers, _parallel_workers->total_workers());
+  active_workers = _concurrent_workers->update_active_workers(active_workers);
+  log_info(gc, task)("Using %u workers of %u for marking", active_workers, _concurrent_workers->total_workers());
 
   // Parallel task terminator is set in "set_concurrency_and_phase()"
   set_concurrency_and_phase(active_workers, true /* concurrent */);
 
   G1CMConcurrentMarkingTask marking_task(this, cm_thread());
-  _parallel_workers->run_task(&marking_task);
+  _concurrent_workers->run_task(&marking_task);
   print_stats();
 }
 
@@ -1604,7 +1597,7 @@
     // we utilize all the worker threads we can.
     bool processing_is_mt = rp->processing_is_mt();
     uint active_workers = (processing_is_mt ? g1h->workers()->active_workers() : 1U);
-    active_workers = MAX2(MIN2(active_workers, _max_worker_id), 1U);
+    active_workers = MAX2(MIN2(active_workers, _max_num_tasks), 1U);
 
     // Parallel processing task executor.
     G1CMRefProcTaskExecutor par_task_executor(g1h, this,
@@ -1909,7 +1902,7 @@
   _global_mark_stack.iterate(VerifyNoCSetOops("Stack"));
 
   // Verify entries on the task queues
-  for (uint i = 0; i < _max_worker_id; ++i) {
+  for (uint i = 0; i < _max_num_tasks; ++i) {
     G1CMTaskQueue* queue = _task_queues->queue(i);
     queue->iterate(VerifyNoCSetOops("Queue", i));
   }
@@ -1926,8 +1919,8 @@
   }
 
   // Verify the task fingers
-  assert(_parallel_marking_threads <= _max_worker_id, "sanity");
-  for (uint i = 0; i < _parallel_marking_threads; ++i) {
+  assert(_num_concurrent_workers <= _max_num_tasks, "sanity");
+  for (uint i = 0; i < _num_concurrent_workers; ++i) {
     G1CMTask* task = _tasks[i];
     HeapWord* task_finger = task->finger();
     if (task_finger != NULL && task_finger < _heap_end) {
@@ -1942,7 +1935,7 @@
 }
 #endif // PRODUCT
 void G1ConcurrentMark::create_live_data() {
-  _g1h->g1_rem_set()->create_card_live_data(_parallel_workers, _next_mark_bitmap);
+  _g1h->g1_rem_set()->create_card_live_data(_concurrent_workers, _next_mark_bitmap);
 }
 
 void G1ConcurrentMark::finalize_live_data() {
@@ -1968,7 +1961,7 @@
     return;
   }
   log_debug(gc, stats)("---------------------------------------------------------------------");
-  for (size_t i = 0; i < _active_tasks; ++i) {
+  for (size_t i = 0; i < _num_active_tasks; ++i) {
     _tasks[i]->print_stats();
     log_debug(gc, stats)("---------------------------------------------------------------------");
   }
@@ -2000,7 +1993,7 @@
   })
   // Empty mark stack
   reset_marking_state();
-  for (uint i = 0; i < _max_worker_id; ++i) {
+  for (uint i = 0; i < _max_num_tasks; ++i) {
     _tasks[i]->clear_region_fields();
   }
   _first_overflow_barrier_sync.abort();
@@ -2054,11 +2047,11 @@
 }
 
 void G1ConcurrentMark::print_worker_threads_on(outputStream* st) const {
-  _parallel_workers->print_worker_threads_on(st);
+  _concurrent_workers->print_worker_threads_on(st);
 }
 
 void G1ConcurrentMark::threads_do(ThreadClosure* tc) const {
-  _parallel_workers->threads_do(tc);
+  _concurrent_workers->threads_do(tc);
 }
 
 void G1ConcurrentMark::print_on_error(outputStream* st) const {