src/hotspot/share/gc/shared/weakProcessor.cpp
changeset 51546 b9f6a4427da9
parent 50297 580744d900c8
child 53536 482109fae02b
--- a/src/hotspot/share/gc/shared/weakProcessor.cpp	Wed Aug 22 09:33:18 2018 -0700
+++ b/src/hotspot/share/gc/shared/weakProcessor.cpp	Tue Aug 28 12:57:40 2018 -0400
@@ -23,24 +23,107 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/systemDictionary.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageParState.inline.hpp"
 #include "gc/shared/weakProcessor.hpp"
-#include "prims/jvmtiExport.hpp"
-#include "runtime/jniHandles.hpp"
+#include "gc/shared/weakProcessor.inline.hpp"
+#include "gc/shared/weakProcessorPhases.hpp"
+#include "gc/shared/weakProcessorPhaseTimes.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/iterator.hpp"
+#include "runtime/globals.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_JFR
-#include "jfr/jfr.hpp"
-#endif
 
 void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) {
-  JNIHandles::weak_oops_do(is_alive, keep_alive);
-  JvmtiExport::weak_oops_do(is_alive, keep_alive);
-  SystemDictionary::vm_weak_oop_storage()->weak_oops_do(is_alive, keep_alive);
-  JFR_ONLY(Jfr::weak_oops_do(is_alive, keep_alive);)
+  FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
+    if (WeakProcessorPhases::is_serial(phase)) {
+      WeakProcessorPhases::processor(phase)(is_alive, keep_alive);
+    } else {
+      WeakProcessorPhases::oop_storage(phase)->weak_oops_do(is_alive, keep_alive);
+    }
+  }
 }
 
 void WeakProcessor::oops_do(OopClosure* closure) {
   AlwaysTrueClosure always_true;
   weak_oops_do(&always_true, closure);
 }
+
+uint WeakProcessor::ergo_workers(uint max_workers) {
+  // Ignore ParallelRefProcEnabled; that's for j.l.r.Reference processing.
+  if (ReferencesPerThread == 0) {
+    // Configuration says always use all the threads.
+    return max_workers;
+  }
+
+  // One thread per ReferencesPerThread references (or fraction thereof)
+  // in the various OopStorage objects, bounded by max_threads.
+  //
+  // Serial phases are ignored in this calculation, because of the
+  // cost of running unnecessary threads.  These phases are normally
+  // small or empty (assuming they are configured to exist at all),
+  // and development oriented, so not allocating any threads
+  // specifically for them is okay.
+  size_t ref_count = 0;
+  FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
+    ref_count += WeakProcessorPhases::oop_storage(phase)->allocation_count();
+  }
+
+  // +1 to (approx) round up the ref per thread division.
+  size_t nworkers = 1 + (ref_count / ReferencesPerThread);
+  nworkers = MIN2(nworkers, static_cast<size_t>(max_workers));
+  return static_cast<uint>(nworkers);
+}
+
+void WeakProcessor::Task::initialize() {
+  assert(_nworkers != 0, "must be");
+  assert(_phase_times == NULL || _nworkers <= _phase_times->max_threads(),
+         "nworkers (%u) exceeds max threads (%u)",
+         _nworkers, _phase_times->max_threads());
+
+  if (_phase_times) {
+    _phase_times->set_active_workers(_nworkers);
+  }
+
+  uint storage_count = WeakProcessorPhases::oop_storage_phase_count;
+  _storage_states = NEW_C_HEAP_ARRAY(StorageState, storage_count, mtGC);
+
+  StorageState* states = _storage_states;
+  FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
+    OopStorage* storage = WeakProcessorPhases::oop_storage(phase);
+    new (states++) StorageState(storage, _nworkers);
+  }
+}
+
+WeakProcessor::Task::Task(uint nworkers) :
+  _phase_times(NULL),
+  _nworkers(nworkers),
+  _serial_phases_done(WeakProcessorPhases::serial_phase_count),
+  _storage_states(NULL)
+{
+  initialize();
+}
+
+WeakProcessor::Task::Task(WeakProcessorPhaseTimes* phase_times, uint nworkers) :
+  _phase_times(phase_times),
+  _nworkers(nworkers),
+  _serial_phases_done(WeakProcessorPhases::serial_phase_count),
+  _storage_states(NULL)
+{
+  initialize();
+}
+
+WeakProcessor::Task::~Task() {
+  if (_storage_states != NULL) {
+    StorageState* states = _storage_states;
+    FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
+      states->StorageState::~StorageState();
+      ++states;
+    }
+    FREE_C_HEAP_ARRAY(StorageState, _storage_states);
+  }
+}
+
+void WeakProcessor::GangTask::work(uint worker_id) {
+  _erased_do_work(this, worker_id);
+}