< prev index next >
src/share/vm/gc_implementation/g1/concurrentMark.cpp
Print this page
rev 7209 : 6979279
rev 7210 : imported patch rev1
@@ -609,18 +609,10 @@
warning("Can't have more ConcGCThreads (" UINTX_FORMAT ") "
"than ParallelGCThreads (" UINTX_FORMAT ").",
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;
- } 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;
@@ -669,19 +661,17 @@
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();
}
- }
if (FLAG_IS_DEFAULT(MarkStackSize)) {
uintx mark_stack_size =
MIN2(MarkStackSizeMax,
MAX2(MarkStackSize, (uintx) (parallel_marking_threads() * TASKQUEUE_SIZE)));
@@ -1164,11 +1154,10 @@
};
// 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();
@@ -1182,15 +1171,10 @@
// 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;
- }
- // 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;
}
void ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) {
// Currently, only survivors can be root regions.
assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant");
@@ -1241,16 +1225,12 @@
assert(parallel_marking_threads() <= max_parallel_marking_threads(),
"Maximum number of marking threads exceeded");
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->set_active_workers(active_workers);
_parallel_workers->run_task(&task);
- } else {
- task.work(0);
- }
// It's possible that has_aborted() is true here without actually
// aborting the survivor scan earlier. This is OK as it's
// mainly used for sanity checking.
root_regions()->scan_finished();
@@ -1277,19 +1257,15 @@
// Parallel task terminator is set in "set_concurrency_and_phase()"
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);
+ _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);
- } else {
- markingTask.work(0);
- }
print_stats();
}
// Helper class to get rid of some boilerplate code.
class G1CMTraceTime : public GCTraceTime {
@@ -1712,15 +1688,11 @@
_actual_region_bm, _actual_card_bm,
_expected_region_bm,
_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);
- }
Atomic::add(verify_cl.failures(), &_failures);
}
int failures() const { return _failures; }
@@ -1819,15 +1791,11 @@
FinalCountDataUpdateClosure final_update_cl(_g1h,
_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);
- }
}
};
class G1ParNoteEndTask;
@@ -1920,15 +1888,11 @@
double start = os::elapsedTime();
FreeRegionList local_cleanup_list("Local Cleanup List");
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);
- }
assert(g1_note_end.complete(), "Shouldn't have yielded!");
// Now update the lists
_g1h->remove_from_old_sets(g1_note_end.old_regions_removed(), g1_note_end.humongous_regions_removed());
{
@@ -1975,15 +1939,11 @@
G1ParScrubRemSetTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm, uint n_workers) :
AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()), _region_bm(region_bm), _card_bm(card_bm), _hrclaimer(n_workers) {
}
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);
}
};
void ConcurrentMark::cleanup() {
@@ -2018,22 +1978,17 @@
uint n_workers;
// 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);
- }
if (VerifyDuringGC) {
// Verify that the counting data accumulated during marking matches
// that calculated by walking the marking bitmap.
@@ -2045,18 +2000,14 @@
&_region_bm,
&_card_bm,
&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);
- }
guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
}
size_t start_used_bytes = g1h->used();
@@ -2076,17 +2027,13 @@
g1h->reset_gc_time_stamp();
// 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->check_gc_time_stamps();
if (!cleanup_list_is_empty()) {
// The cleanup list is not empty, so we'll have to process it
// concurrently. Notify anyone else that might be wanting free
@@ -2097,17 +2044,13 @@
// call below, since it affects the metric by which we sort the heap
// regions.
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);
- }
double rs_scrub_end = os::elapsedTime();
double this_rs_scrub_time = (rs_scrub_end - rs_scrub_start);
_total_rs_scrub_time += this_rs_scrub_time;
}
@@ -2500,11 +2443,11 @@
// We need at least one active thread. If reference processing
// 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);
// Parallel processing task executor.
G1CMRefProcTaskExecutor par_task_executor(g1h, this,
@@ -2609,20 +2552,19 @@
class G1RemarkThreadsClosure : public ThreadClosure {
CMObjectClosure _cm_obj;
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
// however the liveness of oops reachable from nmethods have very complex lifecycles:
// * Alive if on the stack of an executing method
@@ -2632,21 +2574,20 @@
jt->nmethods_do(&_code_cl);
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);
}
}
}
};
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
// only proceed if we're supposed to be active.
if (worker_id < _cm->active_tasks()) {
@@ -2654,27 +2595,27 @@
task->record_start_time();
{
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.
task->record_end_time();
}
}
- 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);
}
};
void ConcurrentMark::checkpointRootsFinalWork() {
@@ -2684,11 +2625,10 @@
G1CMTraceTime trace("Finalize Marking", G1Log::finer());
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");
@@ -2699,32 +2639,18 @@
// 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 */);
+ 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);
- } 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);
- }
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
guarantee(has_overflown() ||
satb_mq_set.completed_buffers_num() == 0,
err_msg("Invariant: has_overflown = %s, num buffers = %d",
BOOL_TO_STR(has_overflown()),
@@ -3266,34 +3192,24 @@
}
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);
- }
}
};
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->allocation_context_stats().update_at_remark();
}
// Clear the per-worker arrays used to store the per-region counting data
void ConcurrentMark::clear_all_count_data() {
@@ -3417,13 +3333,11 @@
cmThread()->vtime_accum(),
cmThread()->vtime_mark_accum());
}
void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
- if (use_parallel_marking_threads()) {
_parallel_workers->print_worker_threads_on(st);
- }
}
void ConcurrentMark::print_on_error(outputStream* st) const {
st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT,
p2i(_prevMarkBitMap), p2i(_nextMarkBitMap));
@@ -3940,49 +3854,30 @@
// very counter productive if it did that. :-)
_draining_satb_buffers = true;
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();
- }
- } else {
while (!has_aborted() &&
- satb_mq_set.apply_closure_to_completed_buffer()) {
+ 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);
}
statsOnly( ++_satb_buffers_processed );
regular_clock_call();
}
- }
_draining_satb_buffers = false;
assert(has_aborted() ||
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
decrease_limits();
}
< prev index next >