6979279: remove special-case code for ParallelGCThreads==0
Reviewed-by: jwilhelm, brutisso, kbarrett
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -64,23 +64,6 @@
set_hint(hint);
}
-#ifndef PRODUCT
-template <class Chunk>
-void AdaptiveFreeList<Chunk>::assert_proper_lock_protection_work() const {
- assert(protecting_lock() != NULL, "Don't call this directly");
- assert(ParallelGCThreads > 0, "Don't call this directly");
- Thread* thr = Thread::current();
- if (thr->is_VM_thread() || thr->is_ConcurrentGC_thread()) {
- // assert that we are holding the freelist lock
- } else if (thr->is_GC_task_thread()) {
- assert(protecting_lock()->owned_by_self(), "FreeList RACE DETECTED");
- } else if (thr->is_Java_thread()) {
- assert(!SafepointSynchronize::is_at_safepoint(), "Should not be executing");
- } else {
- ShouldNotReachHere(); // unaccounted thread type?
- }
-}
-#endif
template <class Chunk>
void AdaptiveFreeList<Chunk>::init_statistics(bool split_birth) {
_allocation_stats.initialize(split_birth);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp Tue Oct 21 11:57:22 2014 +0200
@@ -81,8 +81,6 @@
// Reset the head, tail, hint, and count of a free list.
void reset(size_t hint);
- void assert_proper_lock_protection_work() const PRODUCT_RETURN;
-
void print_on(outputStream* st, const char* c = NULL) const;
size_t hint() const {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -149,18 +149,15 @@
check_free_list_consistency();
// Initialize locks for parallel case.
-
- if (CollectedHeap::use_parallel_gc_threads()) {
- for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- _indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1
- "a freelist par lock",
- true);
- DEBUG_ONLY(
- _indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]);
- )
- }
- _dictionary->set_par_lock(&_parDictionaryAllocLock);
+ for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
+ _indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1
+ "a freelist par lock",
+ true);
+ DEBUG_ONLY(
+ _indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]);
+ )
}
+ _dictionary->set_par_lock(&_parDictionaryAllocLock);
}
// Like CompactibleSpace forward() but always calls cross_threshold() to
@@ -622,17 +619,11 @@
// Mark the boundary of the new block in BOT
_bt.mark_block(prevEnd, value);
// put it all in the linAB
- if (ParallelGCThreads == 0) {
- _smallLinearAllocBlock._ptr = prevEnd;
- _smallLinearAllocBlock._word_size = newFcSize;
- repairLinearAllocBlock(&_smallLinearAllocBlock);
- } else { // ParallelGCThreads > 0
- MutexLockerEx x(parDictionaryAllocLock(),
- Mutex::_no_safepoint_check_flag);
- _smallLinearAllocBlock._ptr = prevEnd;
- _smallLinearAllocBlock._word_size = newFcSize;
- repairLinearAllocBlock(&_smallLinearAllocBlock);
- }
+ MutexLockerEx x(parDictionaryAllocLock(),
+ Mutex::_no_safepoint_check_flag);
+ _smallLinearAllocBlock._ptr = prevEnd;
+ _smallLinearAllocBlock._word_size = newFcSize;
+ repairLinearAllocBlock(&_smallLinearAllocBlock);
// Births of chunks put into a LinAB are not recorded. Births
// of chunks as they are allocated out of a LinAB are.
} else {
@@ -1740,10 +1731,7 @@
assert(chunk != NULL && is_in_reserved(chunk), "Not in this space!");
// One of the parallel gc task threads may be here
// whilst others are allocating.
- Mutex* lock = NULL;
- if (ParallelGCThreads != 0) {
- lock = &_parDictionaryAllocLock;
- }
+ Mutex* lock = &_parDictionaryAllocLock;
FreeChunk* ec;
{
MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
@@ -1760,7 +1748,7 @@
}
ec->set_size(size);
debug_only(ec->mangleFreed(size));
- if (size < SmallForDictionary && ParallelGCThreads != 0) {
+ if (size < SmallForDictionary) {
lock = _indexedFreeListParLocks[size];
}
MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -887,10 +887,8 @@
// along with all the other pointers into the heap but
// compaction is expected to be a rare event with
// a heap using cms so don't do it without seeing the need.
- if (CollectedHeap::use_parallel_gc_threads()) {
- for (uint i = 0; i < ParallelGCThreads; i++) {
- _par_gc_thread_states[i]->promo.reset();
- }
+ for (uint i = 0; i < ParallelGCThreads; i++) {
+ _par_gc_thread_states[i]->promo.reset();
}
}
@@ -2804,10 +2802,8 @@
collector()->gc_epilogue(full);
// Also reset promotion tracking in par gc thread states.
- if (CollectedHeap::use_parallel_gc_threads()) {
- for (uint i = 0; i < ParallelGCThreads; i++) {
- _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
- }
+ for (uint i = 0; i < ParallelGCThreads; i++) {
+ _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -612,74 +612,64 @@
ConcGCThreads, ParallelGCThreads);
return;
}
- if (ParallelGCThreads == 0) {
- // if we are not running with any parallel GC threads we will not
- // spawn any marking threads either
- _parallel_marking_threads = 0;
- _max_parallel_marking_threads = 0;
- _sleep_factor = 0.0;
- _marking_task_overhead = 1.0;
+ if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) {
+ // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent
+ // if both are set
+ _sleep_factor = 0.0;
+ _marking_task_overhead = 1.0;
+ } else if (G1MarkingOverheadPercent > 0) {
+ // We will calculate the number of parallel marking threads based
+ // on a target overhead with respect to the soft real-time goal
+ double marking_overhead = (double) G1MarkingOverheadPercent / 100.0;
+ double overall_cm_overhead =
+ (double) MaxGCPauseMillis * marking_overhead /
+ (double) GCPauseIntervalMillis;
+ double cpu_ratio = 1.0 / (double) os::processor_count();
+ double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio);
+ double marking_task_overhead =
+ overall_cm_overhead / marking_thread_num *
+ (double) os::processor_count();
+ double sleep_factor =
+ (1.0 - marking_task_overhead) / marking_task_overhead;
+
+ FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num);
+ _sleep_factor = sleep_factor;
+ _marking_task_overhead = marking_task_overhead;
} else {
- if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) {
- // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent
- // if both are set
- _sleep_factor = 0.0;
- _marking_task_overhead = 1.0;
- } else if (G1MarkingOverheadPercent > 0) {
- // We will calculate the number of parallel marking threads based
- // on a target overhead with respect to the soft real-time goal
- double marking_overhead = (double) G1MarkingOverheadPercent / 100.0;
- double overall_cm_overhead =
- (double) MaxGCPauseMillis * marking_overhead /
- (double) GCPauseIntervalMillis;
- double cpu_ratio = 1.0 / (double) os::processor_count();
- double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio);
- double marking_task_overhead =
- overall_cm_overhead / marking_thread_num *
- (double) os::processor_count();
- double sleep_factor =
- (1.0 - marking_task_overhead) / marking_task_overhead;
-
- FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num);
- _sleep_factor = sleep_factor;
- _marking_task_overhead = marking_task_overhead;
- } else {
- // Calculate the number of parallel marking threads by scaling
- // the number of parallel GC threads.
- uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads);
- FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num);
- _sleep_factor = 0.0;
- _marking_task_overhead = 1.0;
- }
-
- assert(ConcGCThreads > 0, "Should have been set");
- _parallel_marking_threads = (uint) ConcGCThreads;
- _max_parallel_marking_threads = _parallel_marking_threads;
-
- if (parallel_marking_threads() > 1) {
- _cleanup_task_overhead = 1.0;
- } else {
- _cleanup_task_overhead = marking_task_overhead();
- }
- _cleanup_sleep_factor =
- (1.0 - cleanup_task_overhead()) / cleanup_task_overhead();
+ // Calculate the number of parallel marking threads by scaling
+ // the number of parallel GC threads.
+ uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads);
+ FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num);
+ _sleep_factor = 0.0;
+ _marking_task_overhead = 1.0;
+ }
+
+ assert(ConcGCThreads > 0, "Should have been set");
+ _parallel_marking_threads = (uint) ConcGCThreads;
+ _max_parallel_marking_threads = _parallel_marking_threads;
+
+ if (parallel_marking_threads() > 1) {
+ _cleanup_task_overhead = 1.0;
+ } else {
+ _cleanup_task_overhead = marking_task_overhead();
+ }
+ _cleanup_sleep_factor =
+ (1.0 - cleanup_task_overhead()) / cleanup_task_overhead();
#if 0
- gclog_or_tty->print_cr("Marking Threads %d", parallel_marking_threads());
- gclog_or_tty->print_cr("CM Marking Task Overhead %1.4lf", marking_task_overhead());
- gclog_or_tty->print_cr("CM Sleep Factor %1.4lf", sleep_factor());
- gclog_or_tty->print_cr("CL Marking Task Overhead %1.4lf", cleanup_task_overhead());
- gclog_or_tty->print_cr("CL Sleep Factor %1.4lf", cleanup_sleep_factor());
+ gclog_or_tty->print_cr("Marking Threads %d", parallel_marking_threads());
+ gclog_or_tty->print_cr("CM Marking Task Overhead %1.4lf", marking_task_overhead());
+ gclog_or_tty->print_cr("CM Sleep Factor %1.4lf", sleep_factor());
+ gclog_or_tty->print_cr("CL Marking Task Overhead %1.4lf", cleanup_task_overhead());
+ gclog_or_tty->print_cr("CL Sleep Factor %1.4lf", cleanup_sleep_factor());
#endif
- guarantee(parallel_marking_threads() > 0, "peace of mind");
- _parallel_workers = new FlexibleWorkGang("G1 Parallel Marking Threads",
- _max_parallel_marking_threads, false, true);
- if (_parallel_workers == NULL) {
- vm_exit_during_initialization("Failed necessary allocation.");
- } else {
- _parallel_workers->initialize_workers();
- }
+ _parallel_workers = new FlexibleWorkGang("G1 Parallel Marking Threads",
+ _max_parallel_marking_threads, false, true);
+ if (_parallel_workers == NULL) {
+ vm_exit_during_initialization("Failed necessary allocation.");
+ } else {
+ _parallel_workers->initialize_workers();
}
if (FLAG_IS_DEFAULT(MarkStackSize)) {
@@ -1167,29 +1157,23 @@
// Calculates the number of active workers for a concurrent
// phase.
uint ConcurrentMark::calc_parallel_marking_threads() {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- uint n_conc_workers = 0;
- if (!UseDynamicNumberOfGCThreads ||
- (!FLAG_IS_DEFAULT(ConcGCThreads) &&
- !ForceDynamicNumberOfGCThreads)) {
- n_conc_workers = max_parallel_marking_threads();
- } else {
- n_conc_workers =
- AdaptiveSizePolicy::calc_default_active_workers(
- max_parallel_marking_threads(),
- 1, /* Minimum workers */
- parallel_marking_threads(),
- Threads::number_of_non_daemon_threads());
- // Don't scale down "n_conc_workers" by scale_parallel_threads() because
- // that scaling has already gone into "_max_parallel_marking_threads".
- }
- assert(n_conc_workers > 0, "Always need at least 1");
- return n_conc_workers;
+ uint n_conc_workers = 0;
+ if (!UseDynamicNumberOfGCThreads ||
+ (!FLAG_IS_DEFAULT(ConcGCThreads) &&
+ !ForceDynamicNumberOfGCThreads)) {
+ n_conc_workers = max_parallel_marking_threads();
+ } else {
+ n_conc_workers =
+ AdaptiveSizePolicy::calc_default_active_workers(
+ max_parallel_marking_threads(),
+ 1, /* Minimum workers */
+ parallel_marking_threads(),
+ Threads::number_of_non_daemon_threads());
+ // Don't scale down "n_conc_workers" by scale_parallel_threads() because
+ // that scaling has already gone into "_max_parallel_marking_threads".
}
- // If we are not running with any parallel GC threads we will not
- // have spawned any marking threads either. Hence the number of
- // concurrent workers should be 0.
- return 0;
+ assert(n_conc_workers > 0, "Always need at least 1");
+ return n_conc_workers;
}
void ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) {
@@ -1244,12 +1228,8 @@
uint active_workers = MAX2(1U, parallel_marking_threads());
CMRootRegionScanTask task(this);
- if (use_parallel_marking_threads()) {
- _parallel_workers->set_active_workers((int) active_workers);
- _parallel_workers->run_task(&task);
- } else {
- task.work(0);
- }
+ _parallel_workers->set_active_workers(active_workers);
+ _parallel_workers->run_task(&task);
// It's possible that has_aborted() is true here without actually
// aborting the survivor scan earlier. This is OK as it's
@@ -1280,15 +1260,11 @@
set_concurrency_and_phase(active_workers, true /* concurrent */);
CMConcurrentMarkingTask markingTask(this, cmThread());
- if (use_parallel_marking_threads()) {
- _parallel_workers->set_active_workers((int)active_workers);
- // Don't set _n_par_threads because it affects MT in process_roots()
- // and the decisions on that MT processing is made elsewhere.
- assert(_parallel_workers->active_workers() > 0, "Should have been set");
- _parallel_workers->run_task(&markingTask);
- } else {
- markingTask.work(0);
- }
+ _parallel_workers->set_active_workers(active_workers);
+ // Don't set _n_par_threads because it affects MT in process_roots()
+ // and the decisions on that MT processing is made elsewhere.
+ assert(_parallel_workers->active_workers() > 0, "Should have been set");
+ _parallel_workers->run_task(&markingTask);
print_stats();
}
@@ -1715,11 +1691,7 @@
_expected_card_bm,
_verbose);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
- } else {
- _g1h->heap_region_iterate(&verify_cl);
- }
+ _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
Atomic::add(verify_cl.failures(), &_failures);
}
@@ -1822,11 +1794,7 @@
_actual_region_bm,
_actual_card_bm);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer);
- } else {
- _g1h->heap_region_iterate(&final_update_cl);
- }
+ _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer);
}
};
@@ -1923,11 +1891,7 @@
HRRSCleanupTask hrrs_cleanup_task;
G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list,
&hrrs_cleanup_task);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer);
- } else {
- _g1h->heap_region_iterate(&g1_note_end);
- }
+ _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer);
assert(g1_note_end.complete(), "Shouldn't have yielded!");
// Now update the lists
@@ -1978,11 +1942,7 @@
}
void work(uint worker_id) {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1rs->scrub_par(_region_bm, _card_bm, worker_id, &_hrclaimer);
- } else {
- _g1rs->scrub(_region_bm, _card_bm);
- }
+ _g1rs->scrub(_region_bm, _card_bm, worker_id, &_hrclaimer);
}
};
@@ -2021,18 +1981,13 @@
// Do counting once more with the world stopped for good measure.
G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- g1h->set_par_threads();
- n_workers = g1h->n_par_threads();
- assert(g1h->n_par_threads() == n_workers,
- "Should not have been reset");
- g1h->workers()->run_task(&g1_par_count_task);
- // Done with the parallel phase so reset to 0.
- g1h->set_par_threads(0);
- } else {
- n_workers = 1;
- g1_par_count_task.work(0);
- }
+ g1h->set_par_threads();
+ n_workers = g1h->n_par_threads();
+ assert(g1h->n_par_threads() == n_workers,
+ "Should not have been reset");
+ g1h->workers()->run_task(&g1_par_count_task);
+ // Done with the parallel phase so reset to 0.
+ g1h->set_par_threads(0);
if (VerifyDuringGC) {
// Verify that the counting data accumulated during marking matches
@@ -2048,14 +2003,10 @@
&expected_region_bm,
&expected_card_bm);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- g1h->set_par_threads((int)n_workers);
- g1h->workers()->run_task(&g1_par_verify_task);
- // Done with the parallel phase so reset to 0.
- g1h->set_par_threads(0);
- } else {
- g1_par_verify_task.work(0);
- }
+ g1h->set_par_threads((int)n_workers);
+ g1h->workers()->run_task(&g1_par_verify_task);
+ // Done with the parallel phase so reset to 0.
+ g1h->set_par_threads(0);
guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
}
@@ -2079,13 +2030,9 @@
// Note end of marking in all heap regions.
G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list, n_workers);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- g1h->set_par_threads((int)n_workers);
- g1h->workers()->run_task(&g1_par_note_end_task);
- g1h->set_par_threads(0);
- } else {
- g1_par_note_end_task.work(0);
- }
+ g1h->set_par_threads((int)n_workers);
+ g1h->workers()->run_task(&g1_par_note_end_task);
+ g1h->set_par_threads(0);
g1h->check_gc_time_stamps();
if (!cleanup_list_is_empty()) {
@@ -2100,13 +2047,9 @@
if (G1ScrubRemSets) {
double rs_scrub_start = os::elapsedTime();
G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm, n_workers);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- g1h->set_par_threads((int)n_workers);
- g1h->workers()->run_task(&g1_par_scrub_rs_task);
- g1h->set_par_threads(0);
- } else {
- g1_par_scrub_rs_task.work(0);
- }
+ g1h->set_par_threads((int)n_workers);
+ g1h->workers()->run_task(&g1_par_scrub_rs_task);
+ g1h->set_par_threads(0);
double rs_scrub_end = os::elapsedTime();
double this_rs_scrub_time = (rs_scrub_end - rs_scrub_start);
@@ -2503,7 +2446,7 @@
// is not multi-threaded we use the current (VMThread) thread,
// otherwise we use the work gang from the G1CollectedHeap and
// we utilize all the worker threads we can.
- bool processing_is_mt = rp->processing_is_mt() && g1h->workers() != NULL;
+ bool processing_is_mt = rp->processing_is_mt();
uint active_workers = (processing_is_mt ? g1h->workers()->active_workers() : 1U);
active_workers = MAX2(MIN2(active_workers, _max_worker_id), 1U);
@@ -2622,16 +2565,15 @@
G1CMOopClosure _cm_cl;
MarkingCodeBlobClosure _code_cl;
int _thread_parity;
- bool _is_par;
public:
- G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task, bool is_par) :
+ 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()), _is_par(is_par) {}
+ _thread_parity(SharedHeap::heap()->strong_roots_parity()) {}
void do_thread(Thread* thread) {
if (thread->is_Java_thread()) {
- if (thread->claim_oops_do(_is_par, _thread_parity)) {
+ if (thread->claim_oops_do(true, _thread_parity)) {
JavaThread* jt = (JavaThread*)thread;
// In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking
@@ -2645,7 +2587,7 @@
jt->satb_mark_queue().apply_closure_and_empty(&_cm_obj);
}
} else if (thread->is_VM_thread()) {
- if (thread->claim_oops_do(_is_par, _thread_parity)) {
+ if (thread->claim_oops_do(true, _thread_parity)) {
JavaThread::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(&_cm_obj);
}
}
@@ -2655,7 +2597,6 @@
class CMRemarkTask: public AbstractGangTask {
private:
ConcurrentMark* _cm;
- bool _is_serial;
public:
void work(uint worker_id) {
// Since all available tasks are actually started, we should
@@ -2667,14 +2608,14 @@
ResourceMark rm;
HandleMark hm;
- G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task, !_is_serial);
+ G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
Threads::threads_do(&threads_f);
}
do {
task->do_marking_step(1000000000.0 /* something very large */,
true /* do_termination */,
- _is_serial);
+ false /* is_serial */);
} while (task->has_aborted() && !_cm->has_overflown());
// If we overflow, then we do not want to restart. We instead
// want to abort remark and do concurrent marking again.
@@ -2682,8 +2623,8 @@
}
}
- CMRemarkTask(ConcurrentMark* cm, int active_workers, bool is_serial) :
- AbstractGangTask("Par Remark"), _cm(cm), _is_serial(is_serial) {
+ CMRemarkTask(ConcurrentMark* cm, int active_workers) :
+ AbstractGangTask("Par Remark"), _cm(cm) {
_cm->terminator()->reset_for_reuse(active_workers);
}
};
@@ -2697,43 +2638,28 @@
g1h->ensure_parsability(false);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- G1CollectedHeap::StrongRootsScope srs(g1h);
- // this is remark, so we'll use up all active threads
- uint active_workers = g1h->workers()->active_workers();
- if (active_workers == 0) {
- assert(active_workers > 0, "Should have been set earlier");
- active_workers = (uint) ParallelGCThreads;
- g1h->workers()->set_active_workers(active_workers);
- }
- set_concurrency_and_phase(active_workers, false /* concurrent */);
- // Leave _parallel_marking_threads at it's
- // value originally calculated in the ConcurrentMark
- // constructor and pass values of the active workers
- // through the gang in the task.
-
- CMRemarkTask remarkTask(this, active_workers, false /* is_serial */);
- // We will start all available threads, even if we decide that the
- // active_workers will be fewer. The extra ones will just bail out
- // immediately.
- g1h->set_par_threads(active_workers);
- g1h->workers()->run_task(&remarkTask);
- g1h->set_par_threads(0);
- } else {
- G1CollectedHeap::StrongRootsScope srs(g1h);
- uint active_workers = 1;
- set_concurrency_and_phase(active_workers, false /* concurrent */);
-
- // Note - if there's no work gang then the VMThread will be
- // the thread to execute the remark - serially. We have
- // to pass true for the is_serial parameter so that
- // CMTask::do_marking_step() doesn't enter the sync
- // barriers in the event of an overflow. Doing so will
- // cause an assert that the current thread is not a
- // concurrent GC thread.
- CMRemarkTask remarkTask(this, active_workers, true /* is_serial*/);
- remarkTask.work(0);
+ G1CollectedHeap::StrongRootsScope srs(g1h);
+ // this is remark, so we'll use up all active threads
+ uint active_workers = g1h->workers()->active_workers();
+ if (active_workers == 0) {
+ assert(active_workers > 0, "Should have been set earlier");
+ active_workers = (uint) ParallelGCThreads;
+ g1h->workers()->set_active_workers(active_workers);
}
+ set_concurrency_and_phase(active_workers, false /* concurrent */);
+ // Leave _parallel_marking_threads at it's
+ // value originally calculated in the ConcurrentMark
+ // constructor and pass values of the active workers
+ // through the gang in the task.
+
+ CMRemarkTask remarkTask(this, active_workers);
+ // We will start all available threads, even if we decide that the
+ // active_workers will be fewer. The extra ones will just bail out
+ // immediately.
+ g1h->set_par_threads(active_workers);
+ g1h->workers()->run_task(&remarkTask);
+ g1h->set_par_threads(0);
+
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
guarantee(has_overflown() ||
satb_mq_set.completed_buffers_num() == 0,
@@ -3279,30 +3205,20 @@
void work(uint worker_id) {
AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer);
- } else {
- _g1h->heap_region_iterate(&cl);
- }
+ _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer);
}
};
void ConcurrentMark::aggregate_count_data() {
- int n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
- _g1h->workers()->active_workers() :
- 1);
+ int n_workers = _g1h->workers()->active_workers();
G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm,
_max_worker_id, n_workers);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- _g1h->set_par_threads(n_workers);
- _g1h->workers()->run_task(&g1_par_agg_task);
- _g1h->set_par_threads(0);
- } else {
- g1_par_agg_task.work(0);
- }
+ _g1h->set_par_threads(n_workers);
+ _g1h->workers()->run_task(&g1_par_agg_task);
+ _g1h->set_par_threads(0);
_g1h->allocation_context_stats().update_at_remark();
}
@@ -3430,9 +3346,7 @@
}
void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
- if (use_parallel_marking_threads()) {
- _parallel_workers->print_worker_threads_on(st);
- }
+ _parallel_workers->print_worker_threads_on(st);
}
void ConcurrentMark::print_on_error(outputStream* st) const {
@@ -3953,32 +3867,17 @@
CMObjectClosure oc(this);
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- satb_mq_set.set_par_closure(_worker_id, &oc);
- } else {
- satb_mq_set.set_closure(&oc);
- }
+ satb_mq_set.set_closure(_worker_id, &oc);
// This keeps claiming and applying the closure to completed buffers
// until we run out of buffers or we need to abort.
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- while (!has_aborted() &&
- satb_mq_set.par_apply_closure_to_completed_buffer(_worker_id)) {
- if (_cm->verbose_medium()) {
- gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
- }
- statsOnly( ++_satb_buffers_processed );
- regular_clock_call();
+ while (!has_aborted() &&
+ satb_mq_set.apply_closure_to_completed_buffer(_worker_id)) {
+ if (_cm->verbose_medium()) {
+ gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
}
- } else {
- while (!has_aborted() &&
- satb_mq_set.apply_closure_to_completed_buffer()) {
- if (_cm->verbose_medium()) {
- gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
- }
- statsOnly( ++_satb_buffers_processed );
- regular_clock_call();
- }
+ statsOnly( ++_satb_buffers_processed );
+ regular_clock_call();
}
_draining_satb_buffers = false;
@@ -3987,11 +3886,7 @@
concurrent() ||
satb_mq_set.completed_buffers_num() == 0, "invariant");
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- satb_mq_set.set_par_closure(_worker_id, NULL);
- } else {
- satb_mq_set.set_closure(NULL);
- }
+ satb_mq_set.set_closure(_worker_id, NULL);
// again, this was a potentially expensive operation, decrease the
// limits to get the regular clock call early
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Tue Oct 21 11:57:22 2014 +0200
@@ -519,15 +519,6 @@
double cleanup_sleep_factor() { return _cleanup_sleep_factor; }
double cleanup_task_overhead() { return _cleanup_task_overhead;}
- bool use_parallel_marking_threads() const {
- assert(parallel_marking_threads() <=
- max_parallel_marking_threads(), "sanity");
- assert((_parallel_workers == NULL && parallel_marking_threads() == 0) ||
- parallel_marking_threads() > 0,
- "parallel workers not set up correctly");
- return _parallel_workers != NULL;
- }
-
HeapWord* finger() { return _finger; }
bool concurrent() { return _concurrent; }
uint active_tasks() { return _active_tasks; }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -1439,36 +1439,31 @@
}
// Rebuild remembered sets of all regions.
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- uint n_workers =
- AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
- workers()->active_workers(),
- Threads::number_of_non_daemon_threads());
- assert(UseDynamicNumberOfGCThreads ||
- n_workers == workers()->total_workers(),
- "If not dynamic should be using all the workers");
- workers()->set_active_workers(n_workers);
- // Set parallel threads in the heap (_n_par_threads) only
- // before a parallel phase and always reset it to 0 after
- // the phase so that the number of parallel threads does
- // no get carried forward to a serial phase where there
- // may be code that is "possibly_parallel".
- set_par_threads(n_workers);
-
- ParRebuildRSTask rebuild_rs_task(this);
- assert(UseDynamicNumberOfGCThreads ||
- workers()->active_workers() == workers()->total_workers(),
- "Unless dynamic should use total workers");
- // Use the most recent number of active workers
- assert(workers()->active_workers() > 0,
- "Active workers not properly set");
- set_par_threads(workers()->active_workers());
- workers()->run_task(&rebuild_rs_task);
- set_par_threads(0);
- } else {
- RebuildRSOutOfRegionClosure rebuild_rs(this);
- heap_region_iterate(&rebuild_rs);
- }
+ uint n_workers =
+ AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
+ workers()->active_workers(),
+ Threads::number_of_non_daemon_threads());
+ assert(UseDynamicNumberOfGCThreads ||
+ n_workers == workers()->total_workers(),
+ "If not dynamic should be using all the workers");
+ workers()->set_active_workers(n_workers);
+ // Set parallel threads in the heap (_n_par_threads) only
+ // before a parallel phase and always reset it to 0 after
+ // the phase so that the number of parallel threads does
+ // no get carried forward to a serial phase where there
+ // may be code that is "possibly_parallel".
+ set_par_threads(n_workers);
+
+ ParRebuildRSTask rebuild_rs_task(this);
+ assert(UseDynamicNumberOfGCThreads ||
+ workers()->active_workers() == workers()->total_workers(),
+ "Unless dynamic should use total workers");
+ // Use the most recent number of active workers
+ assert(workers()->active_workers() > 0,
+ "Active workers not properly set");
+ set_par_threads(workers()->active_workers());
+ workers()->run_task(&rebuild_rs_task);
+ set_par_threads(0);
// Rebuild the strong code root lists for each region
rebuild_strong_code_roots();
@@ -2681,27 +2676,25 @@
// Then thread t will start at region floor ((t * n) / p)
result = g1_policy()->collection_set();
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- uint cs_size = g1_policy()->cset_region_length();
- uint active_workers = workers()->active_workers();
- assert(UseDynamicNumberOfGCThreads ||
- active_workers == workers()->total_workers(),
- "Unless dynamic should use total workers");
-
- uint end_ind = (cs_size * worker_i) / active_workers;
- uint start_ind = 0;
-
- if (worker_i > 0 &&
- _worker_cset_start_region_time_stamp[worker_i - 1] == gc_time_stamp) {
- // Previous workers starting region is valid
- // so let's iterate from there
- start_ind = (cs_size * (worker_i - 1)) / active_workers;
- result = _worker_cset_start_region[worker_i - 1];
- }
-
- for (uint i = start_ind; i < end_ind; i++) {
- result = result->next_in_collection_set();
- }
+ uint cs_size = g1_policy()->cset_region_length();
+ uint active_workers = workers()->active_workers();
+ assert(UseDynamicNumberOfGCThreads ||
+ active_workers == workers()->total_workers(),
+ "Unless dynamic should use total workers");
+
+ uint end_ind = (cs_size * worker_i) / active_workers;
+ uint start_ind = 0;
+
+ if (worker_i > 0 &&
+ _worker_cset_start_region_time_stamp[worker_i - 1] == gc_time_stamp) {
+ // Previous workers starting region is valid
+ // so let's iterate from there
+ start_ind = (cs_size * (worker_i - 1)) / active_workers;
+ result = _worker_cset_start_region[worker_i - 1];
+ }
+
+ for (uint i = start_ind; i < end_ind; i++) {
+ result = result->next_in_collection_set();
}
// Note: the calculated starting heap region may be NULL
@@ -3376,9 +3369,7 @@
}
void G1CollectedHeap::print_gc_threads_on(outputStream* st) const {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- workers()->print_worker_threads_on(st);
- }
+ workers()->print_worker_threads_on(st);
_cmThread->print_on(st);
st->cr();
_cm->print_worker_threads_on(st);
@@ -3389,9 +3380,7 @@
}
void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- workers()->threads_do(tc);
- }
+ workers()->threads_do(tc);
tc->do_thread(_cmThread);
_cg1r->threads_do(tc);
if (G1StringDedup::is_enabled()) {
@@ -3686,7 +3675,7 @@
print_taskqueue_stats_hdr(st);
TaskQueueStats totals;
- const int n = workers() != NULL ? workers()->total_workers() : 1;
+ const int n = workers()->total_workers();
for (int i = 0; i < n; ++i) {
st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr();
totals += task_queue(i)->stats;
@@ -3697,7 +3686,7 @@
}
void G1CollectedHeap::reset_taskqueue_stats() {
- const int n = workers() != NULL ? workers()->total_workers() : 1;
+ const int n = workers()->total_workers();
for (int i = 0; i < n; ++i) {
task_queue(i)->stats.reset();
}
@@ -3795,8 +3784,7 @@
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
- int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
- workers()->active_workers() : 1);
+ int active_workers = workers()->active_workers();
double pause_start_sec = os::elapsedTime();
g1_policy()->phase_times()->note_gc_start(active_workers);
log_gc_header();
@@ -4790,12 +4778,10 @@
int _symbols_processed;
int _symbols_removed;
- bool _do_in_parallel;
public:
G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) :
AbstractGangTask("String/Symbol Unlinking"),
_is_alive(is_alive),
- _do_in_parallel(G1CollectedHeap::use_parallel_gc_threads()),
_process_strings(process_strings), _strings_processed(0), _strings_removed(0),
_process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) {
@@ -4810,10 +4796,10 @@
}
~G1StringSymbolTableUnlinkTask() {
- guarantee(!_process_strings || !_do_in_parallel || StringTable::parallel_claimed_index() >= _initial_string_table_size,
+ guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size,
err_msg("claim value %d after unlink less than initial string table size %d",
StringTable::parallel_claimed_index(), _initial_string_table_size));
- guarantee(!_process_symbols || !_do_in_parallel || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
+ guarantee(!_process_symbols || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
err_msg("claim value %d after unlink less than initial symbol table size %d",
SymbolTable::parallel_claimed_index(), _initial_symbol_table_size));
@@ -4827,28 +4813,19 @@
}
void work(uint worker_id) {
- if (_do_in_parallel) {
- int strings_processed = 0;
- int strings_removed = 0;
- int symbols_processed = 0;
- int symbols_removed = 0;
- if (_process_strings) {
- StringTable::possibly_parallel_unlink(_is_alive, &strings_processed, &strings_removed);
- Atomic::add(strings_processed, &_strings_processed);
- Atomic::add(strings_removed, &_strings_removed);
- }
- if (_process_symbols) {
- SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed);
- Atomic::add(symbols_processed, &_symbols_processed);
- Atomic::add(symbols_removed, &_symbols_removed);
- }
- } else {
- if (_process_strings) {
- StringTable::unlink(_is_alive, &_strings_processed, &_strings_removed);
- }
- if (_process_symbols) {
- SymbolTable::unlink(&_symbols_processed, &_symbols_removed);
- }
+ int strings_processed = 0;
+ int strings_removed = 0;
+ int symbols_processed = 0;
+ int symbols_removed = 0;
+ if (_process_strings) {
+ StringTable::possibly_parallel_unlink(_is_alive, &strings_processed, &strings_removed);
+ Atomic::add(strings_processed, &_strings_processed);
+ Atomic::add(strings_removed, &_strings_removed);
+ }
+ if (_process_symbols) {
+ SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed);
+ Atomic::add(symbols_processed, &_symbols_processed);
+ Atomic::add(symbols_removed, &_symbols_removed);
}
}
@@ -5149,33 +5126,23 @@
bool process_strings,
bool process_symbols,
bool class_unloading_occurred) {
- uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
- workers()->active_workers() : 1);
+ uint n_workers = workers()->active_workers();
G1ParallelCleaningTask g1_unlink_task(is_alive, process_strings, process_symbols,
n_workers, class_unloading_occurred);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- set_par_threads(n_workers);
- workers()->run_task(&g1_unlink_task);
- set_par_threads(0);
- } else {
- g1_unlink_task.work(0);
- }
+ set_par_threads(n_workers);
+ workers()->run_task(&g1_unlink_task);
+ set_par_threads(0);
}
void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
bool process_strings, bool process_symbols) {
{
- uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
- _g1h->workers()->active_workers() : 1);
+ uint n_workers = _g1h->workers()->active_workers();
G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- set_par_threads(n_workers);
- workers()->run_task(&g1_unlink_task);
- set_par_threads(0);
- } else {
- g1_unlink_task.work(0);
- }
+ set_par_threads(n_workers);
+ workers()->run_task(&g1_unlink_task);
+ set_par_threads(0);
}
if (G1StringDedup::is_enabled()) {
@@ -5193,11 +5160,7 @@
double start_time = os::elapsedTime();
RedirtyLoggedCardTableEntryClosure cl;
- if (G1CollectedHeap::heap()->use_parallel_gc_threads()) {
- _queue->par_apply_closure_to_all_completed_buffers(&cl);
- } else {
- _queue->apply_closure_to_all_completed_buffers(&cl);
- }
+ _queue->par_apply_closure_to_all_completed_buffers(&cl);
G1GCPhaseTimes* timer = G1CollectedHeap::heap()->g1_policy()->phase_times();
timer->record_redirty_logged_cards_time_ms(worker_id, (os::elapsedTime() - start_time) * 1000.0);
@@ -5208,18 +5171,13 @@
void G1CollectedHeap::redirty_logged_cards() {
double redirty_logged_cards_start = os::elapsedTime();
- uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
- _g1h->workers()->active_workers() : 1);
+ uint n_workers = _g1h->workers()->active_workers();
G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
dirty_card_queue_set().reset_for_par_iteration();
- if (use_parallel_gc_threads()) {
- set_par_threads(n_workers);
- workers()->run_task(&redirty_task);
- set_par_threads(0);
- } else {
- redirty_task.work(0);
- }
+ set_par_threads(n_workers);
+ workers()->run_task(&redirty_task);
+ set_par_threads(0);
DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set();
dcq.merge_bufferlists(&dirty_card_queue_set());
@@ -5609,20 +5567,14 @@
// referents points to another object which is also referenced by an
// object discovered by the STW ref processor.
- assert(!G1CollectedHeap::use_parallel_gc_threads() ||
- no_of_gc_workers == workers()->active_workers(),
- "Need to reset active GC workers");
+ assert(no_of_gc_workers == workers()->active_workers(), "Need to reset active GC workers");
set_par_threads(no_of_gc_workers);
G1ParPreserveCMReferentsTask keep_cm_referents(this,
no_of_gc_workers,
_task_queues);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- workers()->run_task(&keep_cm_referents);
- } else {
- keep_cm_referents.work(0);
- }
+ workers()->run_task(&keep_cm_referents);
set_par_threads(0);
@@ -5749,21 +5701,15 @@
hot_card_cache->set_use_cache(false);
uint n_workers;
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- n_workers =
- AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
- workers()->active_workers(),
- Threads::number_of_non_daemon_threads());
- assert(UseDynamicNumberOfGCThreads ||
- n_workers == workers()->total_workers(),
- "If not dynamic should be using all the workers");
- workers()->set_active_workers(n_workers);
- set_par_threads(n_workers);
- } else {
- assert(n_par_threads() == 0,
- "Should be the original non-parallel value");
- n_workers = 1;
- }
+ n_workers =
+ AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
+ workers()->active_workers(),
+ Threads::number_of_non_daemon_threads());
+ assert(UseDynamicNumberOfGCThreads ||
+ n_workers == workers()->total_workers(),
+ "If not dynamic should be using all the workers");
+ workers()->set_active_workers(n_workers);
+ set_par_threads(n_workers);
G1ParTask g1_par_task(this, _task_queues);
@@ -5782,18 +5728,13 @@
ClassLoaderDataGraph::clear_claimed_marks();
}
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- // The individual threads will set their evac-failure closures.
- if (PrintTerminationStats) G1ParScanThreadState::print_termination_stats_hdr();
- // These tasks use ShareHeap::_process_strong_tasks
- assert(UseDynamicNumberOfGCThreads ||
- workers()->active_workers() == workers()->total_workers(),
- "If not dynamic should be using all the workers");
- workers()->run_task(&g1_par_task);
- } else {
- g1_par_task.set_for_termination(n_workers);
- g1_par_task.work(0);
- }
+ // The individual threads will set their evac-failure closures.
+ if (PrintTerminationStats) G1ParScanThreadState::print_termination_stats_hdr();
+ // These tasks use ShareHeap::_process_strong_tasks
+ assert(UseDynamicNumberOfGCThreads ||
+ workers()->active_workers() == workers()->total_workers(),
+ "If not dynamic should be using all the workers");
+ workers()->run_task(&g1_par_task);
end_par_time_sec = os::elapsedTime();
// Closing the inner scope will execute the destructor
@@ -6099,22 +6040,9 @@
// Iterate over the dirty cards region list.
G1ParCleanupCTTask cleanup_task(ct_bs, this);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- set_par_threads();
- workers()->run_task(&cleanup_task);
- set_par_threads(0);
- } else {
- while (_dirty_cards_region_list) {
- HeapRegion* r = _dirty_cards_region_list;
- cleanup_task.clear_cards(r);
- _dirty_cards_region_list = r->get_next_dirty_cards_region();
- if (_dirty_cards_region_list == r) {
- // The last region.
- _dirty_cards_region_list = NULL;
- }
- r->set_next_dirty_cards_region(NULL);
- }
- }
+ set_par_threads();
+ workers()->run_task(&cleanup_task);
+ set_par_threads(0);
#ifndef PRODUCT
if (G1VerifyCTCleanup || VerifyAfterGC) {
G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs);
@@ -6654,7 +6582,6 @@
void G1CollectedHeap::set_par_threads() {
// Don't change the number of workers. Use the value previously set
// in the workgroup.
- assert(G1CollectedHeap::use_parallel_gc_threads(), "shouldn't be here otherwise");
uint n_workers = workers()->active_workers();
assert(UseDynamicNumberOfGCThreads ||
n_workers == workers()->total_workers(),
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -84,8 +84,7 @@
};
G1CollectorPolicy::G1CollectorPolicy() :
- _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
- ? ParallelGCThreads : 1),
+ _parallel_gc_threads(ParallelGCThreads),
_recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
_stop_world_start(0.0),
@@ -1544,32 +1543,6 @@
}
}
-class KnownGarbageClosure: public HeapRegionClosure {
- G1CollectedHeap* _g1h;
- CollectionSetChooser* _hrSorted;
-
-public:
- KnownGarbageClosure(CollectionSetChooser* hrSorted) :
- _g1h(G1CollectedHeap::heap()), _hrSorted(hrSorted) { }
-
- bool doHeapRegion(HeapRegion* r) {
- // We only include humongous regions in collection
- // sets when concurrent mark shows that their contained object is
- // unreachable.
-
- // Do we have any marking information for this region?
- if (r->is_marked()) {
- // We will skip any region that's currently used as an old GC
- // alloc region (we should not consider those for collection
- // before we fill them up).
- if (_hrSorted->should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
- _hrSorted->add_region(r);
- }
- }
- return false;
- }
-};
-
class ParKnownGarbageHRClosure: public HeapRegionClosure {
G1CollectedHeap* _g1h;
CSetChooserParUpdater _cset_updater;
@@ -1617,34 +1590,29 @@
_collectionSetChooser->clear();
uint region_num = _g1->num_regions();
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- const uint OverpartitionFactor = 4;
- uint WorkUnit;
- // The use of MinChunkSize = 8 in the original code
- // causes some assertion failures when the total number of
- // region is less than 8. The code here tries to fix that.
- // Should the original code also be fixed?
- if (no_of_gc_threads > 0) {
- const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U);
- WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor),
- MinWorkUnit);
- } else {
- assert(no_of_gc_threads > 0,
- "The active gc workers should be greater than 0");
- // In a product build do something reasonable to avoid a crash.
- const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U);
- WorkUnit =
- MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
- MinWorkUnit);
- }
- _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
- WorkUnit);
- ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads);
- _g1->workers()->run_task(&parKnownGarbageTask);
+ const uint OverpartitionFactor = 4;
+ uint WorkUnit;
+ // The use of MinChunkSize = 8 in the original code
+ // causes some assertion failures when the total number of
+ // region is less than 8. The code here tries to fix that.
+ // Should the original code also be fixed?
+ if (no_of_gc_threads > 0) {
+ const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U);
+ WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor),
+ MinWorkUnit);
} else {
- KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
- _g1->heap_region_iterate(&knownGarbagecl);
+ assert(no_of_gc_threads > 0,
+ "The active gc workers should be greater than 0");
+ // In a product build do something reasonable to avoid a crash.
+ const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U);
+ WorkUnit =
+ MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
+ MinWorkUnit);
}
+ _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
+ WorkUnit);
+ ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads);
+ _g1->workers()->run_task(&parKnownGarbageTask);
_collectionSetChooser->sort_regions();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -292,36 +292,25 @@
if (_root_region_scan_wait_time_ms > 0.0) {
print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
}
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
- _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
- _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
- if (_last_satb_filtering_times_ms.sum() > 0.0) {
- _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
- }
- _last_update_rs_times_ms.print(2, "Update RS (ms)");
- _last_update_rs_processed_buffers.print(3, "Processed Buffers");
- _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
- _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
- _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
- _last_termination_times_ms.print(2, "Termination (ms)");
- if (G1Log::finest()) {
- _last_termination_attempts.print(3, "Termination Attempts");
- }
- _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
- _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
- _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
- } else {
- _last_ext_root_scan_times_ms.print(1, "Ext Root Scanning (ms)");
- if (_last_satb_filtering_times_ms.sum() > 0.0) {
- _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
- }
- _last_update_rs_times_ms.print(1, "Update RS (ms)");
- _last_update_rs_processed_buffers.print(2, "Processed Buffers");
- _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
- _last_strong_code_root_scan_times_ms.print(1, "Code Root Scanning (ms)");
- _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
+ print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
+ _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
+ _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
+ if (_last_satb_filtering_times_ms.sum() > 0.0) {
+ _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
}
+ _last_update_rs_times_ms.print(2, "Update RS (ms)");
+ _last_update_rs_processed_buffers.print(3, "Processed Buffers");
+ _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+ _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
+ _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
+ _last_termination_times_ms.print(2, "Termination (ms)");
+ if (G1Log::finest()) {
+ _last_termination_attempts.print(3, "Termination Attempts");
+ }
+ _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
+ _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
+ _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
+
print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
print_stats(1, "Code Root Purge", _cur_strong_code_root_purge_time_ms);
if (G1StringDedup::is_enabled()) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -43,7 +43,7 @@
_hot_cache_idx = 0;
// For refining the cards in the hot cache in parallel
- _hot_cache_par_chunk_size = (ParallelGCThreads > 0 ? ClaimChunkSize : _hot_cache_size);
+ _hot_cache_par_chunk_size = ClaimChunkSize;
_hot_cache_par_claimed_idx = 0;
_card_counts.initialize(card_counts_storage);
@@ -119,7 +119,7 @@
// RSet updating while within an evacuation pause.
// In this case worker_i should be the id of a GC worker thread
assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
- assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads),
+ assert(worker_i < ParallelGCThreads,
err_msg("incorrect worker id: %u", worker_i));
into_cset_dcq->enqueue(card_ptr);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -80,7 +80,6 @@
_prev_period_summary()
{
_seq_task = new SubTasksDone(NumSeqTasks);
- guarantee(n_workers() > 0, "There should be some workers");
_cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC);
for (uint i = 0; i < n_workers(); i++) {
_cset_rs_update_cl[i] = NULL;
@@ -282,7 +281,7 @@
// is during RSet updating within an evacuation pause.
// In this case worker_i should be the id of a GC worker thread.
assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
- assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
+ assert(worker_i < ParallelGCThreads, "should be a GC worker");
if (_g1rs->refine_card(card_ptr, worker_i, true)) {
// 'card_ptr' contains references that point into the collection
@@ -343,8 +342,6 @@
// DirtyCardQueueSet that is used to manage RSet updates
DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
- assert((ParallelGCThreads > 0) || worker_i == 0, "invariant");
-
updateRS(&into_cset_dcq, worker_i);
scanRS(oc, code_root_cl, worker_i);
@@ -420,12 +417,7 @@
}
};
-void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
- ScrubRSClosure scrub_cl(region_bm, card_bm);
- _g1->heap_region_iterate(&scrub_cl);
-}
-
-void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
+void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
ScrubRSClosure scrub_cl(region_bm, card_bm);
_g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Tue Oct 21 11:57:22 2014 +0200
@@ -124,14 +124,10 @@
// Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
// or card, respectively, such that a region or card with a corresponding
// 0 bit contains no part of any live object. Eliminates any remembered
- // set entries that correspond to dead heap ranges.
- void scrub(BitMap* region_bm, BitMap* card_bm);
-
- // Like the above, but assumes is called in parallel: "worker_num" is the
- // parallel thread id of the current thread, and "hrclaimer" is the shared
- // HeapRegionClaimer that should be used to claim heap regions.
- void scrub_par(BitMap* region_bm, BitMap* card_bm,
- uint worker_num, HeapRegionClaimer* hrclaimer);
+ // set entries that correspond to dead heap ranges. "worker_num" is the
+ // parallel thread id of the current thread, and "hrclaimer" is the
+ // HeapRegionClaimer that should be used.
+ void scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer* hrclaimer);
// Refine the card corresponding to "card_ptr".
// If check_for_refs_into_cset is true, a true result is returned
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp Tue Oct 21 11:57:22 2014 +0200
@@ -31,11 +31,7 @@
#include "oops/oop.inline.hpp"
inline uint G1RemSet::n_workers() {
- if (_g1->workers() != NULL) {
- return _g1->workers()->total_workers();
- } else {
- return 1;
- }
+ return _g1->workers()->total_workers();
}
template <class T>
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -154,14 +154,10 @@
double fixup_start = os::elapsedTime();
G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash);
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- g1h->set_par_threads();
- g1h->workers()->run_task(&task);
- g1h->set_par_threads(0);
- } else {
- task.work(0);
- }
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ g1h->set_par_threads();
+ g1h->workers()->run_task(&task);
+ g1h->set_par_threads(0);
double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
g1p->phase_times()->record_string_dedup_fixup_time(fixup_time_ms);
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -202,7 +202,7 @@
#endif // _MSC_VER
SATBMarkQueueSet::SATBMarkQueueSet() :
- PtrQueueSet(), _closure(NULL), _par_closures(NULL),
+ PtrQueueSet(), _closures(NULL),
_shared_satb_queue(this, true /*perm*/) { }
void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
@@ -210,9 +210,7 @@
Mutex* lock) {
PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
_shared_satb_queue.set_lock(lock);
- if (ParallelGCThreads > 0) {
- _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
- }
+ _closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
}
void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
@@ -276,17 +274,13 @@
shared_satb_queue()->filter();
}
-void SATBMarkQueueSet::set_closure(ObjectClosure* closure) {
- _closure = closure;
+void SATBMarkQueueSet::set_closure(uint worker, ObjectClosure* closure) {
+ assert(_closures != NULL, "Precondition");
+ assert(worker < ParallelGCThreads, "Worker index must be in range [0...ParallelGCThreads)");
+ _closures[worker] = closure;
}
-void SATBMarkQueueSet::set_par_closure(int i, ObjectClosure* par_closure) {
- assert(ParallelGCThreads > 0 && _par_closures != NULL, "Precondition");
- _par_closures[i] = par_closure;
-}
-
-bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
- uint worker) {
+bool SATBMarkQueueSet::apply_closure_to_completed_buffer(uint worker) {
BufferNode* nd = NULL;
{
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
@@ -298,7 +292,7 @@
if (_n_completed_buffers == 0) _process_completed = false;
}
}
- ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
+ ObjectClosure* cl = _closures[worker];
if (nd != NULL) {
void **buf = BufferNode::make_buffer_from_node(nd);
ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Tue Oct 21 11:57:22 2014 +0200
@@ -78,16 +78,10 @@
};
class SATBMarkQueueSet: public PtrQueueSet {
- ObjectClosure* _closure;
- ObjectClosure** _par_closures; // One per ParGCThread.
+ ObjectClosure** _closures; // One per ParGCThread.
ObjPtrQueue _shared_satb_queue;
- // Utility function to support sequential and parallel versions. If
- // "par" is true, then "worker" is the par thread id; if "false", worker
- // is ignored.
- bool apply_closure_to_completed_buffer_work(bool par, uint worker);
-
#ifdef ASSERT
void dump_active_states(bool expected_active);
void verify_active_states(bool expected_active);
@@ -111,26 +105,16 @@
// Filter all the currently-active SATB buffers.
void filter_thread_buffers();
- // Register "blk" as "the closure" for all queues. Only one such closure
- // is allowed. The "apply_closure_to_completed_buffer" method will apply
- // this closure to a completed buffer, and "iterate_closure_all_threads"
+ // Register closure for the given worker thread. The "apply_closure_to_completed_buffer"
+ // method will apply this closure to a completed buffer, and "iterate_closure_all_threads"
// applies it to partially-filled buffers (the latter should only be done
// with the world stopped).
- void set_closure(ObjectClosure* closure);
- // Set the parallel closures: pointer is an array of pointers to
- // closures, one for each parallel GC thread.
- void set_par_closure(int i, ObjectClosure* closure);
+ void set_closure(uint worker, ObjectClosure* closure);
// If there exists some completed buffer, pop it, then apply the
// registered closure to all its elements, and return true. If no
// completed buffers exist, return false.
- bool apply_closure_to_completed_buffer() {
- return apply_closure_to_completed_buffer_work(false, 0);
- }
- // Parallel version of the above.
- bool par_apply_closure_to_completed_buffer(uint worker) {
- return apply_closure_to_completed_buffer_work(true, worker);
- }
+ bool apply_closure_to_completed_buffer(uint worker);
// Apply the given closure on enqueued and currently-active buffers
// respectively. Both methods are read-only, i.e., they do not
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -479,7 +479,7 @@
_next_gen.par_oop_since_save_marks_iterate_done(i);
}
- if (UseConcMarkSweepGC && ParallelGCThreads > 0) {
+ if (UseConcMarkSweepGC) {
// We need to call this even when ResizeOldPLAB is disabled
// so as to avoid breaking some asserts. While we may be able
// to avoid this by reorganizing the code a bit, I am loathe
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -47,11 +47,6 @@
// Do basic sizing work
GenCollectorPolicy::initialize_flags();
- assert(UseSerialGC ||
- !FLAG_IS_DEFAULT(ParallelGCThreads) ||
- (ParallelGCThreads > 0),
- "ParallelGCThreads should be set before flag initialization");
-
// The survivor ratio's are calculated "raw", unlike the
// default gc, which adds 2 to the ratio value. We need to
// make sure the values are valid before using them.
--- a/hotspot/src/share/vm/memory/freeBlockDictionary.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -43,12 +43,10 @@
template <class Chunk> void FreeBlockDictionary<Chunk>::verify_par_locked() const {
#ifdef ASSERT
- if (ParallelGCThreads > 0) {
- Thread* my_thread = Thread::current();
- if (my_thread->is_GC_task_thread()) {
- assert(par_lock() != NULL, "Should be using locking?");
- assert_lock_strong(par_lock());
- }
+ Thread* my_thread = Thread::current();
+ if (my_thread->is_GC_task_thread()) {
+ assert(par_lock() != NULL, "Should be using locking?");
+ assert_lock_strong(par_lock());
}
#endif // ASSERT
}
--- a/hotspot/src/share/vm/memory/freeList.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/memory/freeList.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -287,11 +287,14 @@
return false;
}
-#ifndef PRODUCT
+#ifdef ASSERT
template <class Chunk>
void FreeList<Chunk>::assert_proper_lock_protection_work() const {
- assert(protecting_lock() != NULL, "Don't call this directly");
- assert(ParallelGCThreads > 0, "Don't call this directly");
+ // Nothing to do if the list has no assigned protecting lock
+ if (protecting_lock() == NULL) {
+ return;
+ }
+
Thread* thr = Thread::current();
if (thr->is_VM_thread() || thr->is_ConcurrentGC_thread()) {
// assert that we are holding the freelist lock
--- a/hotspot/src/share/vm/memory/freeList.hpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/memory/freeList.hpp Tue Oct 21 11:57:22 2014 +0200
@@ -56,15 +56,12 @@
#ifdef ASSERT
Mutex* _protecting_lock;
+ void assert_proper_lock_protection_work() const;
#endif
// Asserts false if the protecting lock (if any) is not held.
- void assert_proper_lock_protection_work() const PRODUCT_RETURN;
void assert_proper_lock_protection() const {
-#ifdef ASSERT
- if (_protecting_lock != NULL)
- assert_proper_lock_protection_work();
-#endif
+ DEBUG_ONLY(assert_proper_lock_protection_work());
}
void increment_count() {
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp Mon Oct 20 10:18:17 2014 +0200
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp Tue Oct 21 11:57:22 2014 +0200
@@ -68,11 +68,9 @@
vm_exit_during_initialization("Failed necessary allocation.");
}
_sh = this; // ch is static, should be set only once.
- if ((UseParNewGC ||
- (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
- CMSParallelRemarkEnabled)) ||
- UseG1GC) &&
- ParallelGCThreads > 0) {
+ if (UseParNewGC ||
+ UseG1GC ||
+ (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled || CMSParallelRemarkEnabled) && use_parallel_gc_threads())) {
_workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
/* are_GC_task_threads */true,
/* are_ConcurrentGC_threads */false);