# HG changeset patch # User mgerdin # Date 1427781296 -7200 # Node ID d485440c958a126b3449d160af300468f5e7b6f0 # Parent 2e4a5be5a5951ae894ed7ed1650440981a8a73e1 8076225: Move the thread claim parity from SharedHeap to Thread Reviewed-by: brutisso, jwilhelm, kbarrett diff -r 2e4a5be5a595 -r d485440c958a hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- 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()) { diff -r 2e4a5be5a595 -r d485440c958a hotspot/src/share/vm/memory/genCollectedHeap.cpp --- 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 diff -r 2e4a5be5a595 -r d485440c958a hotspot/src/share/vm/memory/sharedHeap.cpp --- 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 diff -r 2e4a5be5a595 -r d485440c958a hotspot/src/share/vm/memory/sharedHeap.hpp --- 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; } diff -r 2e4a5be5a595 -r d485440c958a hotspot/src/share/vm/runtime/thread.cpp --- 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); diff -r 2e4a5be5a595 -r d485440c958a hotspot/src/share/vm/runtime/thread.hpp --- 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);