8076225: Move the thread claim parity from SharedHeap to Thread
Reviewed-by: brutisso, jwilhelm, kbarrett
--- 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);