< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp

Print this page
rev 50928 : Process remaining SATB buffers in final mark/traverse loop instead of separate phase
rev 50929 : [mq]: satb1.patch


 194     SuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
 195     ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
 196     jushort* live_data = _cm->get_liveness(worker_id);
 197     ReferenceProcessor* rp;
 198     if (_cm->process_references()) {
 199       rp = ShenandoahHeap::heap()->ref_processor();
 200       shenandoah_assert_rp_isalive_installed();
 201     } else {
 202       rp = NULL;
 203     }
 204 
 205     _cm->concurrent_scan_code_roots(worker_id, rp, _update_refs);
 206     _cm->mark_loop(worker_id, _terminator, rp,
 207                    true, // cancellable
 208                    _cm->unload_classes(),
 209                    _update_refs,
 210                    ShenandoahStringDedup::is_enabled()); // perform string dedup
 211   }
 212 };
 213 























 214 class ShenandoahFinalMarkingTask : public AbstractGangTask {
 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   }


 455       ShenandoahFinalMarkingTask task(this, &terminator, sh->has_forwarded_objects(),
 456         unload_classes(), full_gc && ShenandoahStringDedup::is_enabled());
 457       sh->workers()->run_task(&task);
 458     }
 459   }
 460 
 461   assert(task_queues()->is_empty(), "Should be empty");
 462 
 463   // When we're done marking everything, we process weak references.
 464   if (process_references()) {
 465     weak_refs_work(full_gc);
 466   }
 467 
 468   // And finally finish class unloading
 469   if (unload_classes()) {
 470     sh->unload_classes_and_cleanup_tables(full_gc);
 471   }
 472 
 473   assert(task_queues()->is_empty(), "Should be empty");
 474 
 475 }
 476 
 477 class ShenandoahSATBThreadsClosure : public ThreadClosure {
 478   ShenandoahSATBBufferClosure* _satb_cl;
 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;




 194     SuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
 195     ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
 196     jushort* live_data = _cm->get_liveness(worker_id);
 197     ReferenceProcessor* rp;
 198     if (_cm->process_references()) {
 199       rp = ShenandoahHeap::heap()->ref_processor();
 200       shenandoah_assert_rp_isalive_installed();
 201     } else {
 202       rp = NULL;
 203     }
 204 
 205     _cm->concurrent_scan_code_roots(worker_id, rp, _update_refs);
 206     _cm->mark_loop(worker_id, _terminator, rp,
 207                    true, // cancellable
 208                    _cm->unload_classes(),
 209                    _update_refs,
 210                    ShenandoahStringDedup::is_enabled()); // perform string dedup
 211   }
 212 };
 213 
 214 class ShenandoahSATBThreadsClosure : public ThreadClosure {
 215   ShenandoahSATBBufferClosure* _satb_cl;
 216   int _thread_parity;
 217 
 218  public:
 219   ShenandoahSATBThreadsClosure(ShenandoahSATBBufferClosure* satb_cl) :
 220     _satb_cl(satb_cl),
 221     _thread_parity(Threads::thread_claim_parity()) {}
 222 
 223   void do_thread(Thread* thread) {
 224     if (thread->is_Java_thread()) {
 225       if (thread->claim_oops_do(true, _thread_parity)) {
 226         JavaThread* jt = (JavaThread*)thread;
 227         ShenandoahThreadLocalData::satb_mark_queue(jt).apply_closure_and_empty(_satb_cl);
 228       }
 229     } else if (thread->is_VM_thread()) {
 230       if (thread->claim_oops_do(true, _thread_parity)) {
 231         ShenandoahBarrierSet::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(_satb_cl);
 232       }
 233     }
 234   }
 235 };
 236 
 237 class ShenandoahFinalMarkingTask : public AbstractGangTask {
 238 private:
 239   ShenandoahConcurrentMark* _cm;
 240   ParallelTaskTerminator* _terminator;
 241   bool _update_refs;
 242   bool _unload_classes;
 243   bool _dedup_string;
 244 
 245 public:
 246   ShenandoahFinalMarkingTask(ShenandoahConcurrentMark* cm, ParallelTaskTerminator* terminator,
 247                              bool update_refs, bool unload_classes, bool dedup_string) :
 248     AbstractGangTask("Shenandoah Final Marking"), _cm(cm), _terminator(terminator),
 249     _update_refs(update_refs), _unload_classes(unload_classes), _dedup_string(dedup_string) {
 250   }
 251 
 252   void work(uint worker_id) {
 253     // First drain remaining SATB buffers.
 254     // Notice that this is not strictly necessary for mark-compact. But since
 255     // it requires a StrongRootsScope around the task, we need to claim the
 256     // threads, and performance-wise it doesn't really matter. Adds about 1ms to
 257     // full-gc.
 258     ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
 259     ShenandoahSATBBufferClosure cl(q);
 260     SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
 261     while (satb_mq_set.apply_closure_to_completed_buffer(&cl));
 262     ShenandoahSATBThreadsClosure tc(&cl);
 263     Threads::threads_do(&tc);
 264 
 265     ReferenceProcessor* rp;
 266     if (_cm->process_references()) {
 267       rp = ShenandoahHeap::heap()->ref_processor();
 268       shenandoah_assert_rp_isalive_installed();
 269     } else {
 270       rp = NULL;
 271     }
 272 
 273     // Degenerated cycle may bypass concurrent cycle, so code roots might not be scanned,
 274     // let's check here.
 275     _cm->concurrent_scan_code_roots(worker_id, rp, _update_refs);
 276     _cm->mark_loop(worker_id, _terminator, rp,
 277                    false, // not cancellable
 278                    _unload_classes,
 279                    _update_refs,
 280                    _dedup_string);
 281 
 282     assert(_cm->task_queues()->is_empty(), "Should be empty");
 283   }


 483       ShenandoahFinalMarkingTask task(this, &terminator, sh->has_forwarded_objects(),
 484         unload_classes(), full_gc && ShenandoahStringDedup::is_enabled());
 485       sh->workers()->run_task(&task);
 486     }
 487   }
 488 
 489   assert(task_queues()->is_empty(), "Should be empty");
 490 
 491   // When we're done marking everything, we process weak references.
 492   if (process_references()) {
 493     weak_refs_work(full_gc);
 494   }
 495 
 496   // And finally finish class unloading
 497   if (unload_classes()) {
 498     sh->unload_classes_and_cleanup_tables(full_gc);
 499   }
 500 
 501   assert(task_queues()->is_empty(), "Should be empty");
 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;


< prev index next >