8076225: Move the thread claim parity from SharedHeap to Thread
authormgerdin
Tue, 31 Mar 2015 07:54:56 +0200
changeset 29802 d485440c958a
parent 29801 2e4a5be5a595
child 29803 6e259ffa8b72
8076225: Move the thread claim parity from SharedHeap to Thread Reviewed-by: brutisso, jwilhelm, kbarrett
hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
hotspot/src/share/vm/memory/genCollectedHeap.cpp
hotspot/src/share/vm/memory/sharedHeap.cpp
hotspot/src/share/vm/memory/sharedHeap.hpp
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/runtime/thread.hpp
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Mar 30 17:21:54 2015 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Mar 31 07:54:56 2015 +0200
@@ -2581,7 +2581,7 @@
  public:
   G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task) :
     _cm_obj(task), _cm_cl(g1h, g1h->concurrent_mark(), task), _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),
-    _thread_parity(SharedHeap::heap()->strong_roots_parity()) {}
+    _thread_parity(Threads::thread_claim_parity()) {}
 
   void do_thread(Thread* thread) {
     if (thread->is_Java_thread()) {
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Mon Mar 30 17:21:54 2015 +0200
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Tue Mar 31 07:54:56 2015 +0200
@@ -589,7 +589,7 @@
   StrongRootsScope srs(this, activate_scope);
 
   // General roots.
-  assert(_strong_roots_parity != 0, "must have called prologue code");
+  assert(Threads::thread_claim_parity() != 0, "must have called prologue code");
   assert(code_roots != NULL, "code root closure should always be set");
   // _n_termination for _process_strong_tasks should be set up stream
   // in a method not running in a GC worker.  Otherwise the GC worker
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp	Mon Mar 30 17:21:54 2015 +0200
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp	Tue Mar 31 07:54:56 2015 +0200
@@ -40,7 +40,6 @@
 SharedHeap::SharedHeap(CollectorPolicy* policy_) :
   CollectedHeap(),
   _collector_policy(policy_),
-  _strong_roots_parity(0),
   _workers(NULL)
 {
   _sh = this;  // ch is static, should be set only once.
@@ -68,26 +67,20 @@
   _n_par_threads = t;
 }
 
-void SharedHeap::change_strong_roots_parity() {
-  // Also set the new collection parity.
-  assert(_strong_roots_parity >= 0 && _strong_roots_parity <= 2,
-         "Not in range.");
-  _strong_roots_parity++;
-  if (_strong_roots_parity == 3) _strong_roots_parity = 1;
-  assert(_strong_roots_parity >= 1 && _strong_roots_parity <= 2,
-         "Not in range.");
-}
-
 SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* heap, bool activate)
   : MarkScope(activate), _sh(heap)
 {
   if (_active) {
-    _sh->change_strong_roots_parity();
+    Threads::change_thread_claim_parity();
     // Zero the claimed high water mark in the StringTable
     StringTable::clear_parallel_claimed_index();
   }
 }
 
+SharedHeap::StrongRootsScope::~StrongRootsScope() {
+  Threads::assert_all_threads_claimed();
+}
+
 void SharedHeap::set_barrier_set(BarrierSet* bs) {
   _barrier_set = bs;
   // Cached barrier set for fast access in oops
--- a/hotspot/src/share/vm/memory/sharedHeap.hpp	Mon Mar 30 17:21:54 2015 +0200
+++ b/hotspot/src/share/vm/memory/sharedHeap.hpp	Tue Mar 31 07:54:56 2015 +0200
@@ -113,10 +113,6 @@
   // A gc policy, controls global gc resource issues
   CollectorPolicy *_collector_policy;
 
-  // See the discussion below, in the specification of the reader function
-  // for this variable.
-  int _strong_roots_parity;
-
   // If we're doing parallel GC, use this gang of threads.
   FlexibleWorkGang* _workers;
 
@@ -156,7 +152,10 @@
 
   bool no_gc_in_progress() { return !is_gc_active(); }
 
-  // Some collectors will perform "process_strong_roots" in parallel.
+  // Note, the below comment needs to be updated to reflect the changes
+  // introduced by JDK-8076225. This should be done as part of JDK-8076289.
+  //
+  //Some collectors will perform "process_strong_roots" in parallel.
   // Such a call will involve claiming some fine-grained tasks, such as
   // scanning of threads.  To make this process simpler, we provide the
   // "strong_roots_parity()" method.  Collectors that start parallel tasks
@@ -182,7 +181,6 @@
   //      task-claiming variables may be initialized, to indicate "never
   //      claimed".
  public:
-  int strong_roots_parity() { return _strong_roots_parity; }
 
   // Call these in sequential code around process_roots.
   // strong_roots_prologue calls change_strong_roots_parity, if
@@ -192,11 +190,10 @@
 
    public:
     StrongRootsScope(SharedHeap* heap, bool activate = true);
+    ~StrongRootsScope();
   };
-  friend class StrongRootsScope;
 
  private:
-  void change_strong_roots_parity();
 
  public:
   FlexibleWorkGang* workers() const { return _workers; }
--- a/hotspot/src/share/vm/runtime/thread.cpp	Mon Mar 30 17:21:54 2015 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue Mar 31 07:54:56 2015 +0200
@@ -3183,6 +3183,7 @@
 int         Threads::_number_of_threads = 0;
 int         Threads::_number_of_non_daemon_threads = 0;
 int         Threads::_return_code = 0;
+int         Threads::_thread_claim_parity = 0;
 size_t      JavaThread::_stack_size_at_create = 0;
 #ifdef ASSERT
 bool        Threads::_vm_complete = false;
@@ -3217,7 +3218,6 @@
   // If CompilerThreads ever become non-JavaThreads, add them here
 }
 
-
 void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
   TraceTime timer("Initialize java.lang classes", TraceStartupTime);
 
@@ -4046,6 +4046,26 @@
   VMThread::vm_thread()->oops_do(f, cld_f, cf);
 }
 
+void Threads::change_thread_claim_parity() {
+  // Set the new claim parity.
+  assert(_thread_claim_parity >= 0 && _thread_claim_parity <= 2,
+         "Not in range.");
+  _thread_claim_parity++;
+  if (_thread_claim_parity == 3) _thread_claim_parity = 1;
+  assert(_thread_claim_parity >= 1 && _thread_claim_parity <= 2,
+         "Not in range.");
+}
+
+#ifndef PRODUCT
+void Threads::assert_all_threads_claimed() {
+  ALL_JAVA_THREADS(p) {
+    const int thread_parity = p->oops_do_parity();
+    assert((thread_parity == _thread_claim_parity),
+        err_msg("Thread " PTR_FORMAT " has incorrect parity %d != %d", p2i(p), thread_parity, _thread_claim_parity));
+  }
+}
+#endif // PRODUCT
+
 void Threads::possibly_parallel_oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
   // Introduce a mechanism allowing parallel threads to claim threads as
   // root groups.  Overhead should be small enough to use all the time,
@@ -4060,7 +4080,7 @@
   assert(!is_par ||
          (SharedHeap::heap()->n_par_threads() ==
          SharedHeap::heap()->workers()->active_workers()), "Mismatch");
-  int cp = SharedHeap::heap()->strong_roots_parity();
+  int cp = Threads::thread_claim_parity();
   ALL_JAVA_THREADS(p) {
     if (p->claim_oops_do(is_par, cp)) {
       p->oops_do(f, cld_f, cf);
--- a/hotspot/src/share/vm/runtime/thread.hpp	Mon Mar 30 17:21:54 2015 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Tue Mar 31 07:54:56 2015 +0200
@@ -551,6 +551,7 @@
   Monitor* owned_locks() const                   { return _owned_locks;          }
   bool owns_locks() const                        { return owned_locks() != NULL; }
   bool owns_locks_but_compiled_lock() const;
+  int oops_do_parity() const                     { return _oops_do_parity; }
 
   // Deadlock detection
   bool allow_allocation()                        { return _allow_allocation_count == 0; }
@@ -1855,6 +1856,7 @@
   static int         _number_of_threads;
   static int         _number_of_non_daemon_threads;
   static int         _return_code;
+  static int         _thread_claim_parity;
 #ifdef ASSERT
   static bool        _vm_complete;
 #endif
@@ -1884,9 +1886,10 @@
   // Does not include JNI_VERSION_1_1
   static jboolean is_supported_jni_version(jint version);
 
-  // Garbage collection
-  static void follow_other_roots(void f(oop*));
+  static int thread_claim_parity() { return _thread_claim_parity; }
+  static void change_thread_claim_parity();
 
+  static void assert_all_threads_claimed() PRODUCT_RETURN;
   // Apply "f->do_oop" to all root oops in all threads.
   // This version may only be called by sequential code.
   static void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);