215 private:
216 ShenandoahConcurrentMark* _cm;
217 ParallelTaskTerminator* _terminator;
218 bool _update_refs;
219 bool _unload_classes;
220 bool _dedup_string;
221
222 public:
223 ShenandoahFinalMarkingTask(ShenandoahConcurrentMark* cm, ParallelTaskTerminator* terminator,
224 bool update_refs, bool unload_classes, bool dedup_string) :
225 AbstractGangTask("Shenandoah Final Marking"), _cm(cm), _terminator(terminator),
226 _update_refs(update_refs), _unload_classes(unload_classes), _dedup_string(dedup_string) {
227 }
228
229 void work(uint worker_id) {
230 // First drain remaining SATB buffers.
231 // Notice that this is not strictly necessary for mark-compact. But since
232 // it requires a StrongRootsScope around the task, we need to claim the
233 // threads, and performance-wise it doesn't really matter. Adds about 1ms to
234 // full-gc.
235 _cm->drain_satb_buffers(worker_id);
236
237 ReferenceProcessor* rp;
238 if (_cm->process_references()) {
239 rp = ShenandoahHeap::heap()->ref_processor();
240 shenandoah_assert_rp_isalive_installed();
241 } else {
242 rp = NULL;
243 }
244
245 // Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
246 // let's check here.
247 _cm->concurrent_scan_code_roots(worker_id, rp, _update_refs);
248 _cm->mark_loop(worker_id, _terminator, rp,
249 false, // not cancellable
250 _unload_classes,
251 _update_refs,
252 _dedup_string);
253
254 assert(_cm->task_queues()->is_empty(), "Should be empty");
255 }
479 int _thread_parity;
480
481 public:
482 ShenandoahSATBThreadsClosure(ShenandoahSATBBufferClosure* satb_cl) :
483 _satb_cl(satb_cl),
484 _thread_parity(Threads::thread_claim_parity()) {}
485
486 void do_thread(Thread* thread) {
487 if (thread->is_Java_thread()) {
488 if (thread->claim_oops_do(true, _thread_parity)) {
489 JavaThread* jt = (JavaThread*)thread;
490 ShenandoahThreadLocalData::satb_mark_queue(jt).apply_closure_and_empty(_satb_cl);
491 }
492 } else if (thread->is_VM_thread()) {
493 if (thread->claim_oops_do(true, _thread_parity)) {
494 ShenandoahBarrierSet::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(_satb_cl);
495 }
496 }
497 }
498 };
499
500 void ShenandoahConcurrentMark::drain_satb_buffers(uint worker_id) {
501 ShenandoahObjToScanQueue* q = get_queue(worker_id);
502 ShenandoahSATBBufferClosure cl(q);
503 ShenandoahSATBThreadsClosure tc(&cl);
504 Threads::threads_do(&tc);
505 }
506
507 #if TASKQUEUE_STATS
508 void ShenandoahConcurrentMark::print_taskqueue_stats_hdr(outputStream* const st) {
509 st->print_raw_cr("GC Task Stats");
510 st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr();
511 st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
512 }
513
514 void ShenandoahConcurrentMark::print_taskqueue_stats() const {
515 if (!log_develop_is_enabled(Trace, gc, task, stats)) {
516 return;
517 }
518 Log(gc, task, stats) log;
519 ResourceMark rm;
520 LogStream ls(log.trace());
521 outputStream* st = &ls;
522 print_taskqueue_stats_hdr(st);
523
524 TaskQueueStats totals;
525 const uint n = _task_queues->size();
|
215 private:
216 ShenandoahConcurrentMark* _cm;
217 ParallelTaskTerminator* _terminator;
218 bool _update_refs;
219 bool _unload_classes;
220 bool _dedup_string;
221
222 public:
223 ShenandoahFinalMarkingTask(ShenandoahConcurrentMark* cm, ParallelTaskTerminator* terminator,
224 bool update_refs, bool unload_classes, bool dedup_string) :
225 AbstractGangTask("Shenandoah Final Marking"), _cm(cm), _terminator(terminator),
226 _update_refs(update_refs), _unload_classes(unload_classes), _dedup_string(dedup_string) {
227 }
228
229 void work(uint worker_id) {
230 // First drain remaining SATB buffers.
231 // Notice that this is not strictly necessary for mark-compact. But since
232 // it requires a StrongRootsScope around the task, we need to claim the
233 // threads, and performance-wise it doesn't really matter. Adds about 1ms to
234 // full-gc.
235 ShenandoahObjToScanQueue* q = get_queue(worker_id);
236 ShenandoahSATBBufferClosure cl(q);
237 SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
238 while (satb_mq_set.apply_closure_to_completed_buffer(&cl));
239 ShenandoahSATBThreadsClosure tc(&cl);
240 Threads::threads_do(&tc);
241
242 ReferenceProcessor* rp;
243 if (_cm->process_references()) {
244 rp = ShenandoahHeap::heap()->ref_processor();
245 shenandoah_assert_rp_isalive_installed();
246 } else {
247 rp = NULL;
248 }
249
250 // Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
251 // let's check here.
252 _cm->concurrent_scan_code_roots(worker_id, rp, _update_refs);
253 _cm->mark_loop(worker_id, _terminator, rp,
254 false, // not cancellable
255 _unload_classes,
256 _update_refs,
257 _dedup_string);
258
259 assert(_cm->task_queues()->is_empty(), "Should be empty");
260 }
484 int _thread_parity;
485
486 public:
487 ShenandoahSATBThreadsClosure(ShenandoahSATBBufferClosure* satb_cl) :
488 _satb_cl(satb_cl),
489 _thread_parity(Threads::thread_claim_parity()) {}
490
491 void do_thread(Thread* thread) {
492 if (thread->is_Java_thread()) {
493 if (thread->claim_oops_do(true, _thread_parity)) {
494 JavaThread* jt = (JavaThread*)thread;
495 ShenandoahThreadLocalData::satb_mark_queue(jt).apply_closure_and_empty(_satb_cl);
496 }
497 } else if (thread->is_VM_thread()) {
498 if (thread->claim_oops_do(true, _thread_parity)) {
499 ShenandoahBarrierSet::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(_satb_cl);
500 }
501 }
502 }
503 };
504
505 #if TASKQUEUE_STATS
506 void ShenandoahConcurrentMark::print_taskqueue_stats_hdr(outputStream* const st) {
507 st->print_raw_cr("GC Task Stats");
508 st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr();
509 st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr();
510 }
511
512 void ShenandoahConcurrentMark::print_taskqueue_stats() const {
513 if (!log_develop_is_enabled(Trace, gc, task, stats)) {
514 return;
515 }
516 Log(gc, task, stats) log;
517 ResourceMark rm;
518 LogStream ls(log.trace());
519 outputStream* st = &ls;
520 print_taskqueue_stats_hdr(st);
521
522 TaskQueueStats totals;
523 const uint n = _task_queues->size();
|