8076225: Move the thread claim parity from SharedHeap to Thread

Reviewed-by: brutisso, jwilhelm, kbarrett
This commit is contained in:
Mikael Gerdin 2015-03-31 07:54:56 +02:00
parent 0efa369ffb
commit 062cf882e0
6 changed files with 39 additions and 26 deletions

View File

@ -2581,7 +2581,7 @@ class G1RemarkThreadsClosure : public ThreadClosure {
public: public:
G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task) : G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task) :
_cm_obj(task), _cm_cl(g1h, g1h->concurrent_mark(), task), _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations), _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) { void do_thread(Thread* thread) {
if (thread->is_Java_thread()) { if (thread->is_Java_thread()) {

View File

@ -589,7 +589,7 @@ void GenCollectedHeap::process_roots(bool activate_scope,
StrongRootsScope srs(this, activate_scope); StrongRootsScope srs(this, activate_scope);
// General roots. // 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"); assert(code_roots != NULL, "code root closure should always be set");
// _n_termination for _process_strong_tasks should be set up stream // _n_termination for _process_strong_tasks should be set up stream
// in a method not running in a GC worker. Otherwise the GC worker // in a method not running in a GC worker. Otherwise the GC worker

View File

@ -40,7 +40,6 @@ SharedHeap* SharedHeap::_sh;
SharedHeap::SharedHeap(CollectorPolicy* policy_) : SharedHeap::SharedHeap(CollectorPolicy* policy_) :
CollectedHeap(), CollectedHeap(),
_collector_policy(policy_), _collector_policy(policy_),
_strong_roots_parity(0),
_workers(NULL) _workers(NULL)
{ {
_sh = this; // ch is static, should be set only once. _sh = this; // ch is static, should be set only once.
@ -68,26 +67,20 @@ void SharedHeap::set_par_threads(uint t) {
_n_par_threads = t; _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) SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* heap, bool activate)
: MarkScope(activate), _sh(heap) : MarkScope(activate), _sh(heap)
{ {
if (_active) { if (_active) {
_sh->change_strong_roots_parity(); Threads::change_thread_claim_parity();
// Zero the claimed high water mark in the StringTable // Zero the claimed high water mark in the StringTable
StringTable::clear_parallel_claimed_index(); StringTable::clear_parallel_claimed_index();
} }
} }
SharedHeap::StrongRootsScope::~StrongRootsScope() {
Threads::assert_all_threads_claimed();
}
void SharedHeap::set_barrier_set(BarrierSet* bs) { void SharedHeap::set_barrier_set(BarrierSet* bs) {
_barrier_set = bs; _barrier_set = bs;
// Cached barrier set for fast access in oops // Cached barrier set for fast access in oops

View File

@ -113,10 +113,6 @@ protected:
// A gc policy, controls global gc resource issues // A gc policy, controls global gc resource issues
CollectorPolicy *_collector_policy; 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. // If we're doing parallel GC, use this gang of threads.
FlexibleWorkGang* _workers; FlexibleWorkGang* _workers;
@ -156,7 +152,10 @@ public:
bool no_gc_in_progress() { return !is_gc_active(); } 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 // Such a call will involve claiming some fine-grained tasks, such as
// scanning of threads. To make this process simpler, we provide the // scanning of threads. To make this process simpler, we provide the
// "strong_roots_parity()" method. Collectors that start parallel tasks // "strong_roots_parity()" method. Collectors that start parallel tasks
@ -182,7 +181,6 @@ public:
// task-claiming variables may be initialized, to indicate "never // task-claiming variables may be initialized, to indicate "never
// claimed". // claimed".
public: public:
int strong_roots_parity() { return _strong_roots_parity; }
// Call these in sequential code around process_roots. // Call these in sequential code around process_roots.
// strong_roots_prologue calls change_strong_roots_parity, if // strong_roots_prologue calls change_strong_roots_parity, if
@ -192,11 +190,10 @@ public:
public: public:
StrongRootsScope(SharedHeap* heap, bool activate = true); StrongRootsScope(SharedHeap* heap, bool activate = true);
~StrongRootsScope();
}; };
friend class StrongRootsScope;
private: private:
void change_strong_roots_parity();
public: public:
FlexibleWorkGang* workers() const { return _workers; } FlexibleWorkGang* workers() const { return _workers; }

View File

@ -3183,6 +3183,7 @@ JavaThread* Threads::_thread_list = NULL;
int Threads::_number_of_threads = 0; int Threads::_number_of_threads = 0;
int Threads::_number_of_non_daemon_threads = 0; int Threads::_number_of_non_daemon_threads = 0;
int Threads::_return_code = 0; int Threads::_return_code = 0;
int Threads::_thread_claim_parity = 0;
size_t JavaThread::_stack_size_at_create = 0; size_t JavaThread::_stack_size_at_create = 0;
#ifdef ASSERT #ifdef ASSERT
bool Threads::_vm_complete = false; bool Threads::_vm_complete = false;
@ -3217,7 +3218,6 @@ void Threads::threads_do(ThreadClosure* tc) {
// If CompilerThreads ever become non-JavaThreads, add them here // If CompilerThreads ever become non-JavaThreads, add them here
} }
void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) { void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
TraceTime timer("Initialize java.lang classes", TraceStartupTime); TraceTime timer("Initialize java.lang classes", TraceStartupTime);
@ -4046,6 +4046,26 @@ void Threads::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
VMThread::vm_thread()->oops_do(f, cld_f, cf); 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) { void Threads::possibly_parallel_oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) {
// Introduce a mechanism allowing parallel threads to claim threads as // Introduce a mechanism allowing parallel threads to claim threads as
// root groups. Overhead should be small enough to use all the time, // root groups. Overhead should be small enough to use all the time,
@ -4060,7 +4080,7 @@ void Threads::possibly_parallel_oops_do(OopClosure* f, CLDClosure* cld_f, CodeBl
assert(!is_par || assert(!is_par ||
(SharedHeap::heap()->n_par_threads() == (SharedHeap::heap()->n_par_threads() ==
SharedHeap::heap()->workers()->active_workers()), "Mismatch"); SharedHeap::heap()->workers()->active_workers()), "Mismatch");
int cp = SharedHeap::heap()->strong_roots_parity(); int cp = Threads::thread_claim_parity();
ALL_JAVA_THREADS(p) { ALL_JAVA_THREADS(p) {
if (p->claim_oops_do(is_par, cp)) { if (p->claim_oops_do(is_par, cp)) {
p->oops_do(f, cld_f, cf); p->oops_do(f, cld_f, cf);

View File

@ -551,6 +551,7 @@ protected:
Monitor* owned_locks() const { return _owned_locks; } Monitor* owned_locks() const { return _owned_locks; }
bool owns_locks() const { return owned_locks() != NULL; } bool owns_locks() const { return owned_locks() != NULL; }
bool owns_locks_but_compiled_lock() const; bool owns_locks_but_compiled_lock() const;
int oops_do_parity() const { return _oops_do_parity; }
// Deadlock detection // Deadlock detection
bool allow_allocation() { return _allow_allocation_count == 0; } bool allow_allocation() { return _allow_allocation_count == 0; }
@ -1855,6 +1856,7 @@ class Threads: AllStatic {
static int _number_of_threads; static int _number_of_threads;
static int _number_of_non_daemon_threads; static int _number_of_non_daemon_threads;
static int _return_code; static int _return_code;
static int _thread_claim_parity;
#ifdef ASSERT #ifdef ASSERT
static bool _vm_complete; static bool _vm_complete;
#endif #endif
@ -1884,9 +1886,10 @@ class Threads: AllStatic {
// Does not include JNI_VERSION_1_1 // Does not include JNI_VERSION_1_1
static jboolean is_supported_jni_version(jint version); static jboolean is_supported_jni_version(jint version);
// Garbage collection static int thread_claim_parity() { return _thread_claim_parity; }
static void follow_other_roots(void f(oop*)); 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. // Apply "f->do_oop" to all root oops in all threads.
// This version may only be called by sequential code. // This version may only be called by sequential code.
static void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf); static void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);