8213224: Move code related to GC threads calculation out of AdaptiveSizePolicy
authormanc
Fri, 07 Dec 2018 12:46:31 +0800
changeset 52904 d2f118d3f8e7
parent 52903 535144bfa542
child 52905 bec57b4a6d69
8213224: Move code related to GC threads calculation out of AdaptiveSizePolicy Summary: Consolidate code related to GC threads calculation into a single class Reviewed-by: tschatzl, pliden
src/hotspot/cpu/sparc/vm_version_sparc.cpp
src/hotspot/cpu/sparc/vm_version_sparc.hpp
src/hotspot/share/gc/cms/cmsArguments.cpp
src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
src/hotspot/share/gc/cms/parNewGeneration.cpp
src/hotspot/share/gc/g1/g1Arguments.cpp
src/hotspot/share/gc/g1/g1CollectedHeap.cpp
src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
src/hotspot/share/gc/g1/g1FullCollector.cpp
src/hotspot/share/gc/parallel/gcTaskManager.cpp
src/hotspot/share/gc/parallel/parallelArguments.cpp
src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp
src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp
src/hotspot/share/gc/shared/workerManager.hpp
src/hotspot/share/gc/shared/workerPolicy.cpp
src/hotspot/share/gc/shared/workerPolicy.hpp
src/hotspot/share/runtime/vm_version.cpp
src/hotspot/share/runtime/vm_version.hpp
--- a/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -521,15 +521,3 @@
 void VM_Version::revert() {
   _features = saved_features;
 }
-
-/* Determine a suitable number of threads on this particular machine.
- *
- * FIXME: Simply checking the processor family is insufficient.
- */
-unsigned int VM_Version::calc_parallel_worker_threads() {
-  const int num = 5;
-  const int den = is_post_niagara() ? 16 : 8;
-  const int threshold = 8;
-
-  return nof_parallel_worker_threads(num, den, threshold);
-}
--- a/src/hotspot/cpu/sparc/vm_version_sparc.hpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/cpu/sparc/vm_version_sparc.hpp	Fri Dec 07 12:46:31 2018 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -365,8 +365,12 @@
   //        this properly in order to enable complete page size support.
   static uint page_size_count() { return 2; }
 
-  // Calculates the number of parallel threads
-  static unsigned int calc_parallel_worker_threads();
+  // Override default denominator for ParallelGCThreads.
+  //
+  // FIXME: Simply checking the processor family is insufficient.
+  static uint parallel_worker_threads_denominator() {
+    return is_post_niagara() ? 16 : 8;
+  }
 };
 
 #endif // CPU_SPARC_VM_VM_VERSION_SPARC_HPP
--- a/src/hotspot/share/gc/cms/cmsArguments.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/cms/cmsArguments.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -30,10 +30,10 @@
 #include "gc/cms/compactibleFreeListSpace.hpp"
 #include "gc/shared/gcArguments.inline.hpp"
 #include "gc/shared/genCollectedHeap.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 #include "utilities/defaultStream.hpp"
 
 size_t CMSArguments::conservative_max_heap_alignment() {
@@ -46,7 +46,7 @@
   assert(UseConcMarkSweepGC, "CMS is expected to be on here");
 
   if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
-    FLAG_SET_DEFAULT(ParallelGCThreads, VM_Version::parallel_worker_threads());
+    FLAG_SET_DEFAULT(ParallelGCThreads, WorkerPolicy::parallel_worker_threads());
     assert(ParallelGCThreads > 0, "We should always have at least one thread by default");
   } else if (ParallelGCThreads == 0) {
     jio_fprintf(defaultStream::error_stream(),
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -61,6 +61,7 @@
 #include "gc/shared/strongRootsScope.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.hpp"
@@ -3488,9 +3489,9 @@
 
 bool CMSCollector::do_marking_mt() {
   assert(ConcGCThreads > 0 && conc_workers() != NULL, "precondition");
-  uint num_workers = AdaptiveSizePolicy::calc_active_conc_workers(conc_workers()->total_workers(),
-                                                                  conc_workers()->active_workers(),
-                                                                  Threads::number_of_non_daemon_threads());
+  uint num_workers = WorkerPolicy::calc_active_conc_workers(conc_workers()->total_workers(),
+                                                            conc_workers()->active_workers(),
+                                                            Threads::number_of_non_daemon_threads());
   num_workers = conc_workers()->update_active_workers(num_workers);
   log_info(gc,task)("Using %u workers of %u for marking", num_workers, conc_workers()->total_workers());
 
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -49,6 +49,7 @@
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.hpp"
 #include "gc/shared/workgroup.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/iterator.inline.hpp"
@@ -866,9 +867,9 @@
   WorkGang* workers = gch->workers();
   assert(workers != NULL, "Need workgang for parallel work");
   uint active_workers =
-       AdaptiveSizePolicy::calc_active_workers(workers->total_workers(),
-                                               workers->active_workers(),
-                                               Threads::number_of_non_daemon_threads());
+      WorkerPolicy::calc_active_workers(workers->total_workers(),
+                                        workers->active_workers(),
+                                        Threads::number_of_non_daemon_threads());
   active_workers = workers->update_active_workers(active_workers);
   log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers->total_workers());
 
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -30,9 +30,9 @@
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/shared/gcArguments.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 
 size_t G1Arguments::conservative_max_heap_alignment() {
   return HeapRegion::max_region_size();
@@ -77,7 +77,7 @@
 void G1Arguments::initialize() {
   GCArguments::initialize();
   assert(UseG1GC, "Error");
-  FLAG_SET_DEFAULT(ParallelGCThreads, VM_Version::parallel_worker_threads());
+  FLAG_SET_DEFAULT(ParallelGCThreads, WorkerPolicy::parallel_worker_threads());
   if (ParallelGCThreads == 0) {
     assert(!FLAG_IS_DEFAULT(ParallelGCThreads), "The default value for ParallelGCThreads should not be 0.");
     vm_exit_during_initialization("The flag -XX:+UseG1GC can not be combined with -XX:ParallelGCThreads=0", NULL);
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -61,7 +61,6 @@
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcBehaviours.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
 #include "gc/shared/gcId.hpp"
@@ -78,6 +77,7 @@
 #include "gc/shared/referenceProcessor.inline.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
@@ -2912,9 +2912,9 @@
     }
     GCTraceTime(Info, gc) tm(gc_string, NULL, gc_cause(), true);
 
-    uint active_workers = AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
-                                                                  workers()->active_workers(),
-                                                                  Threads::number_of_non_daemon_threads());
+    uint active_workers = WorkerPolicy::calc_active_workers(workers()->total_workers(),
+                                                            workers()->active_workers(),
+                                                            Threads::number_of_non_daemon_threads());
     active_workers = workers()->update_active_workers(active_workers);
     log_info(gc,task)("Using %u workers of %u for evacuation", active_workers, workers()->total_workers());
 
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -39,7 +39,6 @@
 #include "gc/g1/heapRegion.inline.hpp"
 #include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTrace.hpp"
@@ -51,6 +50,7 @@
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "include/jvm.h"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
@@ -858,10 +858,10 @@
     result = _max_concurrent_workers;
   } else {
     result =
-      AdaptiveSizePolicy::calc_default_active_workers(_max_concurrent_workers,
-                                                      1, /* Minimum workers */
-                                                      _num_concurrent_workers,
-                                                      Threads::number_of_non_daemon_threads());
+      WorkerPolicy::calc_default_active_workers(_max_concurrent_workers,
+                                                1, /* Minimum workers */
+                                                _num_concurrent_workers,
+                                                Threads::number_of_non_daemon_threads());
     // Don't scale the result down by scale_concurrent_workers() because
     // that scaling has already gone into "_max_concurrent_workers".
   }
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -37,11 +37,11 @@
 #include "gc/g1/g1OopClosures.hpp"
 #include "gc/g1/g1Policy.hpp"
 #include "gc/g1/g1StringDedup.hpp"
-#include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/preservedMarks.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/handles.inline.hpp"
@@ -88,15 +88,15 @@
   uint waste_worker_count = MAX2((max_wasted_regions_allowed * 2) , 1u);
   uint heap_waste_worker_limit = MIN2(waste_worker_count, max_worker_count);
 
-  // Also consider HeapSizePerGCThread by calling AdaptiveSizePolicy to calculate
+  // Also consider HeapSizePerGCThread by calling WorkerPolicy to calculate
   // the number of workers.
   uint current_active_workers = heap->workers()->active_workers();
-  uint adaptive_worker_limit = AdaptiveSizePolicy::calc_active_workers(max_worker_count, current_active_workers, 0);
+  uint active_worker_limit = WorkerPolicy::calc_active_workers(max_worker_count, current_active_workers, 0);
 
   // Update active workers to the lower of the limits.
-  uint worker_count = MIN2(heap_waste_worker_limit, adaptive_worker_limit);
+  uint worker_count = MIN2(heap_waste_worker_limit, active_worker_limit);
   log_debug(gc, task)("Requesting %u active workers for full compaction (waste limited workers: %u, adaptive workers: %u)",
-                      worker_count, heap_waste_worker_limit, adaptive_worker_limit);
+                      worker_count, heap_waste_worker_limit, active_worker_limit);
   worker_count = heap->workers()->update_active_workers(worker_count);
   log_info(gc, task)("Using %u workers of %u for full compaction", worker_count, max_worker_count);
 
--- a/src/hotspot/share/gc/parallel/gcTaskManager.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/parallel/gcTaskManager.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -27,6 +27,7 @@
 #include "gc/parallel/gcTaskThread.hpp"
 #include "gc/shared/gcId.hpp"
 #include "gc/shared/workerManager.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.hpp"
@@ -494,9 +495,9 @@
 
 void GCTaskManager::set_active_gang() {
   _active_workers =
-    AdaptiveSizePolicy::calc_active_workers(workers(),
-                                 active_workers(),
-                                 Threads::number_of_non_daemon_threads());
+    WorkerPolicy::calc_active_workers(workers(),
+                                      active_workers(),
+                                      Threads::number_of_non_daemon_threads());
 
   assert(!all_workers_active() || active_workers() == ParallelGCThreads,
          "all_workers_active() is  incorrect: "
--- a/src/hotspot/share/gc/parallel/parallelArguments.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -29,10 +29,10 @@
 #include "gc/shared/adaptiveSizePolicy.hpp"
 #include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcArguments.inline.hpp"
+#include "gc/shared/workerPolicy.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
-#include "runtime/vm_version.hpp"
 #include "utilities/defaultStream.hpp"
 
 size_t ParallelArguments::conservative_max_heap_alignment() {
@@ -51,7 +51,7 @@
   // If no heap maximum was requested explicitly, use some reasonable fraction
   // of the physical memory, up to a maximum of 1GB.
   FLAG_SET_DEFAULT(ParallelGCThreads,
-                   VM_Version::parallel_worker_threads());
+                   WorkerPolicy::parallel_worker_threads());
   if (ParallelGCThreads == 0) {
     jio_fprintf(defaultStream::error_stream(),
         "The Parallel GC can not be combined with -XX:ParallelGCThreads=0\n");
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,18 +24,14 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/adaptiveSizePolicy.hpp"
-#include "gc/shared/collectorPolicy.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcUtil.inline.hpp"
 #include "gc/shared/softRefPolicy.hpp"
-#include "gc/shared/workgroup.hpp"
 #include "logging/log.hpp"
 #include "runtime/timer.hpp"
-#include "utilities/ostream.hpp"
 
 elapsedTimer AdaptiveSizePolicy::_minor_timer;
 elapsedTimer AdaptiveSizePolicy::_major_timer;
-bool AdaptiveSizePolicy::_debug_perturbation = false;
 
 // The throughput goal is implemented as
 //      _throughput_goal = 1 - ( 1 / (1 + gc_cost_ratio))
@@ -94,129 +90,6 @@
   _young_gen_policy_is_ready = false;
 }
 
-//  If the number of GC threads was set on the command line,
-// use it.
-//  Else
-//    Calculate the number of GC threads based on the number of Java threads.
-//    Calculate the number of GC threads based on the size of the heap.
-//    Use the larger.
-
-uint AdaptiveSizePolicy::calc_default_active_workers(uintx total_workers,
-                                                     const uintx min_workers,
-                                                     uintx active_workers,
-                                                     uintx application_workers) {
-  // If the user has specifically set the number of
-  // GC threads, use them.
-
-  // If the user has turned off using a dynamic number of GC threads
-  // or the users has requested a specific number, set the active
-  // number of workers to all the workers.
-
-  uintx new_active_workers = total_workers;
-  uintx prev_active_workers = active_workers;
-  uintx active_workers_by_JT = 0;
-  uintx active_workers_by_heap_size = 0;
-
-  // Always use at least min_workers but use up to
-  // GCThreadsPerJavaThreads * application threads.
-  active_workers_by_JT =
-    MAX2((uintx) GCWorkersPerJavaThread * application_workers,
-         min_workers);
-
-  // Choose a number of GC threads based on the current size
-  // of the heap.  This may be complicated because the size of
-  // the heap depends on factors such as the throughput goal.
-  // Still a large heap should be collected by more GC threads.
-  active_workers_by_heap_size =
-      MAX2((size_t) 2U, Universe::heap()->capacity() / HeapSizePerGCThread);
-
-  uintx max_active_workers =
-    MAX2(active_workers_by_JT, active_workers_by_heap_size);
-
-  new_active_workers = MIN2(max_active_workers, (uintx) total_workers);
-
-  // Increase GC workers instantly but decrease them more
-  // slowly.
-  if (new_active_workers < prev_active_workers) {
-    new_active_workers =
-      MAX2(min_workers, (prev_active_workers + new_active_workers) / 2);
-  }
-
-  // Check once more that the number of workers is within the limits.
-  assert(min_workers <= total_workers, "Minimum workers not consistent with total workers");
-  assert(new_active_workers >= min_workers, "Minimum workers not observed");
-  assert(new_active_workers <= total_workers, "Total workers not observed");
-
-  if (ForceDynamicNumberOfGCThreads) {
-    // Assume this is debugging and jiggle the number of GC threads.
-    if (new_active_workers == prev_active_workers) {
-      if (new_active_workers < total_workers) {
-        new_active_workers++;
-      } else if (new_active_workers > min_workers) {
-        new_active_workers--;
-      }
-    }
-    if (new_active_workers == total_workers) {
-      if (_debug_perturbation) {
-        new_active_workers =  min_workers;
-      }
-      _debug_perturbation = !_debug_perturbation;
-    }
-    assert((new_active_workers <= ParallelGCThreads) &&
-           (new_active_workers >= min_workers),
-      "Jiggled active workers too much");
-  }
-
-  log_trace(gc, task)("GCTaskManager::calc_default_active_workers() : "
-     "active_workers(): " UINTX_FORMAT "  new_active_workers: " UINTX_FORMAT "  "
-     "prev_active_workers: " UINTX_FORMAT "\n"
-     " active_workers_by_JT: " UINTX_FORMAT "  active_workers_by_heap_size: " UINTX_FORMAT,
-     active_workers, new_active_workers, prev_active_workers,
-     active_workers_by_JT, active_workers_by_heap_size);
-  assert(new_active_workers > 0, "Always need at least 1");
-  return new_active_workers;
-}
-
-uint AdaptiveSizePolicy::calc_active_workers(uintx total_workers,
-                                             uintx active_workers,
-                                             uintx application_workers) {
-  // If the user has specifically set the number of
-  // GC threads, use them.
-
-  // If the user has turned off using a dynamic number of GC threads
-  // or the users has requested a specific number, set the active
-  // number of workers to all the workers.
-
-  uint new_active_workers;
-  if (!UseDynamicNumberOfGCThreads ||
-     (!FLAG_IS_DEFAULT(ParallelGCThreads) && !ForceDynamicNumberOfGCThreads)) {
-    new_active_workers = total_workers;
-  } else {
-    uintx min_workers = (total_workers == 1) ? 1 : 2;
-    new_active_workers = calc_default_active_workers(total_workers,
-                                                     min_workers,
-                                                     active_workers,
-                                                     application_workers);
-  }
-  assert(new_active_workers > 0, "Always need at least 1");
-  return new_active_workers;
-}
-
-uint AdaptiveSizePolicy::calc_active_conc_workers(uintx total_workers,
-                                                  uintx active_workers,
-                                                  uintx application_workers) {
-  if (!UseDynamicNumberOfGCThreads ||
-     (!FLAG_IS_DEFAULT(ConcGCThreads) && !ForceDynamicNumberOfGCThreads)) {
-    return ConcGCThreads;
-  } else {
-    uint no_of_gc_threads = calc_default_active_workers(total_workers,
-                                                        1, /* Minimum number of workers */
-                                                        active_workers,
-                                                        application_workers);
-    return no_of_gc_threads;
-  }
-}
-
 bool AdaptiveSizePolicy::tenuring_threshold_change() const {
   return decrement_tenuring_threshold_for_gc_cost() ||
          increment_tenuring_threshold_for_gc_cost() ||
--- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp	Fri Dec 07 12:46:31 2018 +0800
@@ -25,12 +25,9 @@
 #ifndef SHARE_VM_GC_SHARED_ADAPTIVESIZEPOLICY_HPP
 #define SHARE_VM_GC_SHARED_ADAPTIVESIZEPOLICY_HPP
 
-#include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcCause.hpp"
 #include "gc/shared/gcUtil.hpp"
-#include "logging/log.hpp"
 #include "memory/allocation.hpp"
-#include "memory/universe.hpp"
 
 // This class keeps statistical information and computes the
 // size of the heap.
@@ -188,8 +185,6 @@
   julong _young_gen_change_for_minor_throughput;
   julong _old_gen_change_for_major_throughput;
 
-  static const uint GCWorkersPerJavaThread  = 2;
-
   // Accessors
 
   double gc_pause_goal_sec() const { return _gc_pause_goal_sec; }
@@ -334,8 +329,6 @@
   // Return true if the policy suggested a change.
   bool tenuring_threshold_change() const;
 
-  static bool _debug_perturbation;
-
  public:
   AdaptiveSizePolicy(size_t init_eden_size,
                      size_t init_promo_size,
@@ -343,32 +336,6 @@
                      double gc_pause_goal_sec,
                      uint gc_cost_ratio);
 
-  // Return number default  GC threads to use in the next GC.
-  static uint calc_default_active_workers(uintx total_workers,
-                                          const uintx min_workers,
-                                          uintx active_workers,
-                                          uintx application_workers);
-
-  // Return number of GC threads to use in the next GC.
-  // This is called sparingly so as not to change the
-  // number of GC workers gratuitously.
-  //   For ParNew collections
-  //   For PS scavenge and ParOld collections
-  //   For G1 evacuation pauses (subject to update)
-  //   For G1 Full GCs (subject to update)
-  // Other collection phases inherit the number of
-  // GC workers from the calls above.  For example,
-  // a CMS parallel remark uses the same number of GC
-  // workers as the most recent ParNew collection.
-  static uint calc_active_workers(uintx total_workers,
-                                  uintx active_workers,
-                                  uintx application_workers);
-
-  // Return number of GC threads to use in the next concurrent GC phase.
-  static uint calc_active_conc_workers(uintx total_workers,
-                                       uintx active_workers,
-                                       uintx application_workers);
-
   bool is_gc_cms_adaptive_size_policy() {
     return kind() == _gc_cms_adaptive_size_policy;
   }
--- a/src/hotspot/share/gc/shared/workerManager.hpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/gc/shared/workerManager.hpp	Fri Dec 07 12:46:31 2018 +0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,11 @@
 #ifndef SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
 #define SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
 
-#include "gc/shared/adaptiveSizePolicy.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/os.inline.hpp"
+#include "runtime/thread.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 class WorkerManager : public AllStatic {
  public:
@@ -51,35 +55,7 @@
                            uint total_workers,
                            uint created_workers,
                            os::ThreadType worker_type,
-                           bool initializing) {
-    uint start = created_workers;
-    uint end = MIN2(active_workers, total_workers);
-    for (uint worker_id = start; worker_id < end; worker_id += 1) {
-      WorkerThread* new_worker = NULL;
-      if (initializing || !InjectGCWorkerCreationFailure) {
-        new_worker = holder->install_worker(worker_id);
-      }
-      if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
-        log_trace(gc, task)("WorkerManager::add_workers() : "
-                            "creation failed due to failed allocation of native %s",
-                            new_worker == NULL ?  "memory" : "thread");
-        if (new_worker != NULL) {
-           delete new_worker;
-        }
-        if (initializing) {
-          vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create worker GC thread. Out of system resources.");
-        }
-        break;
-      }
-      created_workers++;
-      os::start_thread(new_worker);
-    }
-
-    log_trace(gc, task)("WorkerManager::add_workers() : "
-                        "created_workers: %u", created_workers);
-
-    return created_workers;
-  }
+                           bool initializing);
 
   // Log (at trace level) a change in the number of created workers.
   template <class WorkerType>
@@ -87,12 +63,56 @@
                                   uint previous_created_workers,
                                   uint active_workers,
                                   uint created_workers,
-                                  bool initializing) {
-    if (previous_created_workers < created_workers) {
-      const char* initializing_msg =  initializing ? "Adding initial" : "Creating additional";
-      log_trace(gc, task)("%s %s(s) previously created workers %u active workers %u total created workers %u",
-                          initializing_msg, holder->group_name(), previous_created_workers, active_workers, created_workers);
+                                  bool initializing);
+};
+
+template <class WorkerType>
+uint WorkerManager::add_workers(WorkerType* holder,
+                                uint active_workers,
+                                uint total_workers,
+                                uint created_workers,
+                                os::ThreadType worker_type,
+                                bool initializing) {
+  uint start = created_workers;
+  uint end = MIN2(active_workers, total_workers);
+  for (uint worker_id = start; worker_id < end; worker_id += 1) {
+    WorkerThread* new_worker = NULL;
+    if (initializing || !InjectGCWorkerCreationFailure) {
+      new_worker = holder->install_worker(worker_id);
     }
+    if (new_worker == NULL || !os::create_thread(new_worker, worker_type)) {
+      log_trace(gc, task)("WorkerManager::add_workers() : "
+                          "creation failed due to failed allocation of native %s",
+                          new_worker == NULL ? "memory" : "thread");
+      if (new_worker != NULL) {
+        delete new_worker;
+      }
+      if (initializing) {
+        vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create worker GC thread. Out of system resources.");
+      }
+      break;
+    }
+    created_workers++;
+    os::start_thread(new_worker);
   }
-};
+
+  log_trace(gc, task)("WorkerManager::add_workers() : "
+                      "created_workers: %u", created_workers);
+
+  return created_workers;
+}
+
+template <class WorkerType>
+void WorkerManager::log_worker_creation(WorkerType* holder,
+                                        uint previous_created_workers,
+                                        uint active_workers,
+                                        uint created_workers,
+                                        bool initializing) {
+  if (previous_created_workers < created_workers) {
+    const char* initializing_msg = initializing ? "Adding initial" : "Creating additional";
+    log_trace(gc, task)("%s %s(s) previously created workers %u active workers %u total created workers %u",
+                        initializing_msg, holder->group_name(), previous_created_workers, active_workers, created_workers);
+  }
+}
+
 #endif // SHARE_VM_GC_SHARED_WORKERMANAGER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/workerPolicy.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/workerPolicy.hpp"
+#include "logging/log.hpp"
+#include "memory/universe.hpp"
+#include "runtime/os.inline.hpp"
+#include "runtime/vm_version.hpp"
+
+bool WorkerPolicy::_debug_perturbation = false;
+uint WorkerPolicy::_parallel_worker_threads = 0;
+bool WorkerPolicy::_parallel_worker_threads_initialized = false;
+
+uint WorkerPolicy::nof_parallel_worker_threads(uint num,
+                                               uint den,
+                                               uint switch_pt) {
+  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+    assert(ParallelGCThreads == 0, "Default ParallelGCThreads is not 0");
+    uint threads;
+    // For very large machines, there are diminishing returns
+    // for large numbers of worker threads.  Instead of
+    // hogging the whole system, use a fraction of the workers for every
+    // processor after the first 8.  For example, on a 72 cpu machine
+    // and a chosen fraction of 5/8
+    // use 8 + (72 - 8) * (5/8) == 48 worker threads.
+    uint ncpus = (uint) os::initial_active_processor_count();
+    threads = (ncpus <= switch_pt) ?
+              ncpus :
+              (switch_pt + ((ncpus - switch_pt) * num) / den);
+#ifndef _LP64
+    // On 32-bit binaries the virtual address space available to the JVM
+    // is usually limited to 2-3 GB (depends on the platform).
+    // Do not use up address space with too many threads (stacks and per-thread
+    // data). Note that x86 apps running on Win64 have 2 stacks per thread.
+    // GC may more generally scale down threads by max heap size (etc), but the
+    // consequences of over-provisioning threads are higher on 32-bit JVMS,
+    // so add hard limit here:
+    threads = MIN2(threads, (2 * switch_pt));
+#endif
+    return threads;
+  } else {
+    return ParallelGCThreads;
+  }
+}
+
+uint WorkerPolicy::calc_parallel_worker_threads() {
+  uint den = VM_Version::parallel_worker_threads_denominator();
+  return nof_parallel_worker_threads(5, den, 8);
+}
+
+uint WorkerPolicy::parallel_worker_threads() {
+  if (!_parallel_worker_threads_initialized) {
+    if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+      _parallel_worker_threads = WorkerPolicy::calc_parallel_worker_threads();
+    } else {
+      _parallel_worker_threads = ParallelGCThreads;
+    }
+    _parallel_worker_threads_initialized = true;
+  }
+  return _parallel_worker_threads;
+}
+
+//  If the number of GC threads was set on the command line, use it.
+//  Else
+//    Calculate the number of GC threads based on the number of Java threads.
+//    Calculate the number of GC threads based on the size of the heap.
+//    Use the larger.
+uint WorkerPolicy::calc_default_active_workers(uintx total_workers,
+                                               const uintx min_workers,
+                                               uintx active_workers,
+                                               uintx application_workers) {
+  // If the user has specifically set the number of GC threads, use them.
+
+  // If the user has turned off using a dynamic number of GC threads
+  // or the users has requested a specific number, set the active
+  // number of workers to all the workers.
+
+  uintx new_active_workers = total_workers;
+  uintx prev_active_workers = active_workers;
+  uintx active_workers_by_JT = 0;
+  uintx active_workers_by_heap_size = 0;
+
+  // Always use at least min_workers but use up to
+  // GCThreadsPerJavaThreads * application threads.
+  active_workers_by_JT =
+    MAX2((uintx) GCWorkersPerJavaThread * application_workers,
+         min_workers);
+
+  // Choose a number of GC threads based on the current size
+  // of the heap.  This may be complicated because the size of
+  // the heap depends on factors such as the throughput goal.
+  // Still a large heap should be collected by more GC threads.
+  active_workers_by_heap_size =
+    MAX2((size_t) 2U, Universe::heap()->capacity() / HeapSizePerGCThread);
+
+  uintx max_active_workers =
+    MAX2(active_workers_by_JT, active_workers_by_heap_size);
+
+  new_active_workers = MIN2(max_active_workers, (uintx) total_workers);
+
+  // Increase GC workers instantly but decrease them more
+  // slowly.
+  if (new_active_workers < prev_active_workers) {
+    new_active_workers =
+      MAX2(min_workers, (prev_active_workers + new_active_workers) / 2);
+  }
+
+  // Check once more that the number of workers is within the limits.
+  assert(min_workers <= total_workers, "Minimum workers not consistent with total workers");
+  assert(new_active_workers >= min_workers, "Minimum workers not observed");
+  assert(new_active_workers <= total_workers, "Total workers not observed");
+
+  if (ForceDynamicNumberOfGCThreads) {
+    // Assume this is debugging and jiggle the number of GC threads.
+    if (new_active_workers == prev_active_workers) {
+      if (new_active_workers < total_workers) {
+        new_active_workers++;
+      } else if (new_active_workers > min_workers) {
+        new_active_workers--;
+      }
+    }
+    if (new_active_workers == total_workers) {
+      if (_debug_perturbation) {
+        new_active_workers =  min_workers;
+      }
+      _debug_perturbation = !_debug_perturbation;
+    }
+    assert((new_active_workers <= ParallelGCThreads) &&
+           (new_active_workers >= min_workers),
+           "Jiggled active workers too much");
+  }
+
+  log_trace(gc, task)("WorkerPolicy::calc_default_active_workers() : "
+    "active_workers(): " UINTX_FORMAT "  new_active_workers: " UINTX_FORMAT "  "
+    "prev_active_workers: " UINTX_FORMAT "\n"
+    " active_workers_by_JT: " UINTX_FORMAT "  active_workers_by_heap_size: " UINTX_FORMAT,
+    active_workers, new_active_workers, prev_active_workers,
+    active_workers_by_JT, active_workers_by_heap_size);
+  assert(new_active_workers > 0, "Always need at least 1");
+  return new_active_workers;
+}
+
+uint WorkerPolicy::calc_active_workers(uintx total_workers,
+                                       uintx active_workers,
+                                       uintx application_workers) {
+  // If the user has specifically set the number of GC threads, use them.
+
+  // If the user has turned off using a dynamic number of GC threads
+  // or the users has requested a specific number, set the active
+  // number of workers to all the workers.
+
+  uint new_active_workers;
+  if (!UseDynamicNumberOfGCThreads ||
+     (!FLAG_IS_DEFAULT(ParallelGCThreads) && !ForceDynamicNumberOfGCThreads)) {
+    new_active_workers = total_workers;
+  } else {
+    uintx min_workers = (total_workers == 1) ? 1 : 2;
+    new_active_workers = calc_default_active_workers(total_workers,
+                                                     min_workers,
+                                                     active_workers,
+                                                     application_workers);
+  }
+  assert(new_active_workers > 0, "Always need at least 1");
+  return new_active_workers;
+}
+
+uint WorkerPolicy::calc_active_conc_workers(uintx total_workers,
+                                            uintx active_workers,
+                                            uintx application_workers) {
+  if (!UseDynamicNumberOfGCThreads ||
+     (!FLAG_IS_DEFAULT(ConcGCThreads) && !ForceDynamicNumberOfGCThreads)) {
+    return ConcGCThreads;
+  } else {
+    uint no_of_gc_threads = calc_default_active_workers(total_workers,
+                                                        1, /* Minimum number of workers */
+                                                        active_workers,
+                                                        application_workers);
+    return no_of_gc_threads;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/workerPolicy.hpp	Fri Dec 07 12:46:31 2018 +0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_SHARED_WORKERPOLICY_HPP
+#define SHARE_VM_GC_SHARED_WORKERPOLICY_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class WorkerPolicy : public AllStatic {
+  static const uint GCWorkersPerJavaThread = 2;
+
+  static bool _debug_perturbation;
+  static uint _parallel_worker_threads;
+  static bool _parallel_worker_threads_initialized;
+
+  static uint nof_parallel_worker_threads(uint num,
+                                          uint den,
+                                          uint switch_pt);
+
+  // Calculates and returns the number of parallel GC threads. May
+  // be CPU-architecture-specific.
+  static uint calc_parallel_worker_threads();
+
+public:
+  // Returns the number of parallel threads to be used as default value of
+  // ParallelGCThreads. If that number has not been calculated, do so and
+  // save it.  Returns ParallelGCThreads if it is set on the
+  // command line.
+  static uint parallel_worker_threads();
+
+  // Return number default GC threads to use in the next GC.
+  static uint calc_default_active_workers(uintx total_workers,
+                                          const uintx min_workers,
+                                          uintx active_workers,
+                                          uintx application_workers);
+
+  // Return number of GC threads to use in the next GC.
+  // This is called sparingly so as not to change the
+  // number of GC workers gratuitously.
+  //   For ParNew collections
+  //   For PS scavenge and ParOld collections
+  //   For G1 evacuation pauses (subject to update)
+  //   For G1 Full GCs (subject to update)
+  // Other collection phases inherit the number of
+  // GC workers from the calls above.  For example,
+  // a CMS parallel remark uses the same number of GC
+  // workers as the most recent ParNew collection.
+  static uint calc_active_workers(uintx total_workers,
+                                  uintx active_workers,
+                                  uintx application_workers);
+
+  // Return number of GC threads to use in the next concurrent GC phase.
+  static uint calc_active_conc_workers(uintx total_workers,
+                                       uintx active_workers,
+                                       uintx application_workers);
+
+};
+
+#endif // SHARE_VM_GC_SHARED_WORKERPOLICY_HPP
--- a/src/hotspot/share/runtime/vm_version.cpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/runtime/vm_version.cpp	Fri Dec 07 12:46:31 2018 +0800
@@ -81,8 +81,6 @@
 int Abstract_VM_Version::_vm_security_version = VERSION_UPDATE;
 int Abstract_VM_Version::_vm_patch_version = VERSION_PATCH;
 int Abstract_VM_Version::_vm_build_number = VERSION_BUILD;
-unsigned int Abstract_VM_Version::_parallel_worker_threads = 0;
-bool Abstract_VM_Version::_parallel_worker_threads_initialized = false;
 
 #if defined(_LP64)
   #define VMLP "64-Bit "
@@ -312,55 +310,3 @@
     os::print_cpu_info(&ls, buf, sizeof(buf));
   }
 }
-
-unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
-                                                      unsigned int num,
-                                                      unsigned int den,
-                                                      unsigned int switch_pt) {
-  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
-    assert(ParallelGCThreads == 0, "Default ParallelGCThreads is not 0");
-    unsigned int threads;
-    // For very large machines, there are diminishing returns
-    // for large numbers of worker threads.  Instead of
-    // hogging the whole system, use a fraction of the workers for every
-    // processor after the first 8.  For example, on a 72 cpu machine
-    // and a chosen fraction of 5/8
-    // use 8 + (72 - 8) * (5/8) == 48 worker threads.
-    unsigned int ncpus = (unsigned int) os::initial_active_processor_count();
-    threads = (ncpus <= switch_pt) ?
-             ncpus :
-             (switch_pt + ((ncpus - switch_pt) * num) / den);
-#ifndef _LP64
-    // On 32-bit binaries the virtual address space available to the JVM
-    // is usually limited to 2-3 GB (depends on the platform).
-    // Do not use up address space with too many threads (stacks and per-thread
-    // data). Note that x86 apps running on Win64 have 2 stacks per thread.
-    // GC may more generally scale down threads by max heap size (etc), but the
-    // consequences of over-provisioning threads are higher on 32-bit JVMS,
-    // so add hard limit here:
-    threads = MIN2(threads, (2*switch_pt));
-#endif
-    return threads;
-  } else {
-    return ParallelGCThreads;
-  }
-}
-
-unsigned int Abstract_VM_Version::calc_parallel_worker_threads() {
-  return nof_parallel_worker_threads(5, 8, 8);
-}
-
-
-// Does not set the _initialized flag since it is
-// a global flag.
-unsigned int Abstract_VM_Version::parallel_worker_threads() {
-  if (!_parallel_worker_threads_initialized) {
-    if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
-      _parallel_worker_threads = VM_Version::calc_parallel_worker_threads();
-    } else {
-      _parallel_worker_threads = ParallelGCThreads;
-    }
-    _parallel_worker_threads_initialized = true;
-  }
-  return _parallel_worker_threads;
-}
--- a/src/hotspot/share/runtime/vm_version.hpp	Fri Dec 07 18:00:41 2018 +0100
+++ b/src/hotspot/share/runtime/vm_version.hpp	Fri Dec 07 12:46:31 2018 +0800
@@ -56,12 +56,7 @@
   static int          _vm_security_version;
   static int          _vm_patch_version;
   static int          _vm_build_number;
-  static unsigned int _parallel_worker_threads;
-  static bool         _parallel_worker_threads_initialized;
 
-  static unsigned int nof_parallel_worker_threads(unsigned int num,
-                                                  unsigned int dem,
-                                                  unsigned int switch_pt);
  public:
   // Called as part of the runtime services initialization which is
   // called from the management module initialization (via init_globals())
@@ -153,9 +148,10 @@
   // save it.  Returns ParallelGCThreads if it is set on the
   // command line.
   static unsigned int parallel_worker_threads();
-  // Calculates and returns the number of parallel threads.  May
-  // be VM version specific.
-  static unsigned int calc_parallel_worker_threads();
+
+  // Denominator for computing default ParallelGCThreads for machines with
+  // a large number of cores.
+  static uint parallel_worker_threads_denominator() { return 8; }
 
   // Does this CPU support spin wait instruction?
   static bool supports_on_spin_wait() { return false; }