< prev index next >

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

Print this page
rev 59104 : 8244243: Shenandoah: Cleanup Shenandoah phase timing tracking and JFR event supporting


 334   _heap->workers()->run_task(&update_roots);
 335 
 336 #if COMPILER2_OR_JVMCI
 337   DerivedPointerTable::update_pointers();
 338 #endif
 339 }
 340 
 341 class ShenandoahUpdateThreadRootsTask : public AbstractGangTask {
 342 private:
 343   ShenandoahThreadRoots           _thread_roots;
 344   ShenandoahPhaseTimings::Phase   _phase;
 345   ShenandoahGCWorkerPhase         _worker_phase;
 346 public:
 347   ShenandoahUpdateThreadRootsTask(bool is_par, ShenandoahPhaseTimings::Phase phase) :
 348     AbstractGangTask("Shenandoah Update Thread Roots"),
 349     _thread_roots(phase, is_par),
 350     _phase(phase),
 351     _worker_phase(phase) {}
 352 
 353   void work(uint worker_id) {

 354     ShenandoahUpdateRefsClosure cl;
 355     _thread_roots.oops_do(&cl, NULL, worker_id);
 356   }
 357 };
 358 
 359 void ShenandoahConcurrentMark::update_thread_roots(ShenandoahPhaseTimings::Phase root_phase) {
 360   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
 361 
 362   ShenandoahGCPhase phase(root_phase);
 363 
 364 #if COMPILER2_OR_JVMCI
 365   DerivedPointerTable::clear();
 366 #endif
 367 
 368   WorkGang* workers = _heap->workers();
 369   bool is_par = workers->active_workers() > 1;
 370 
 371   ShenandoahUpdateThreadRootsTask task(is_par, root_phase);
 372   workers->run_task(&task);
 373 


 571 };
 572 
 573 class ShenandoahRefProcTaskProxy : public AbstractGangTask {
 574 private:
 575   AbstractRefProcTaskExecutor::ProcessTask& _proc_task;
 576   TaskTerminator* _terminator;
 577 
 578 public:
 579   ShenandoahRefProcTaskProxy(AbstractRefProcTaskExecutor::ProcessTask& proc_task,
 580                              TaskTerminator* t) :
 581     AbstractGangTask("Process reference objects in parallel"),
 582     _proc_task(proc_task),
 583     _terminator(t) {
 584   }
 585 
 586   void work(uint worker_id) {
 587     ResourceMark rm;
 588     HandleMark hm;
 589     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
 590     ShenandoahHeap* heap = ShenandoahHeap::heap();

 591     ShenandoahCMDrainMarkingStackClosure complete_gc(worker_id, _terminator);
 592     if (heap->has_forwarded_objects()) {
 593       ShenandoahForwardedIsAliveClosure is_alive;
 594       ShenandoahCMKeepAliveUpdateClosure keep_alive(heap->concurrent_mark()->get_queue(worker_id));
 595       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
 596     } else {
 597       ShenandoahIsAliveClosure is_alive;
 598       ShenandoahCMKeepAliveClosure keep_alive(heap->concurrent_mark()->get_queue(worker_id));
 599       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
 600     }
 601   }
 602 };
 603 
 604 class ShenandoahRefProcTaskExecutor : public AbstractRefProcTaskExecutor {
 605 private:
 606   WorkGang* _workers;
 607 
 608 public:
 609   ShenandoahRefProcTaskExecutor(WorkGang* workers) :
 610     _workers(workers) {


 665   uint nworkers = workers->active_workers();
 666 
 667   rp->setup_policy(_heap->soft_ref_policy()->should_clear_all_soft_refs());
 668   rp->set_active_mt_degree(nworkers);
 669 
 670   assert(task_queues()->is_empty(), "Should be empty");
 671 
 672   // complete_gc and keep_alive closures instantiated here are only needed for
 673   // single-threaded path in RP. They share the queue 0 for tracking work, which
 674   // simplifies implementation. Since RP may decide to call complete_gc several
 675   // times, we need to be able to reuse the terminator.
 676   uint serial_worker_id = 0;
 677   TaskTerminator terminator(1, task_queues());
 678   ShenandoahCMDrainMarkingStackClosure complete_gc(serial_worker_id, &terminator, /* reset_terminator = */ true);
 679 
 680   ShenandoahRefProcTaskExecutor executor(workers);
 681 
 682   ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues());
 683 
 684   {
 685     ShenandoahGCPhase phase(phase_process);




 686 
 687     if (_heap->has_forwarded_objects()) {
 688       ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id));
 689       const ReferenceProcessorStats& stats =
 690         rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
 691                                           &complete_gc, &executor,
 692                                           &pt);
 693        _heap->tracer()->report_gc_reference_stats(stats);
 694     } else {
 695       ShenandoahCMKeepAliveClosure keep_alive(get_queue(serial_worker_id));
 696       const ReferenceProcessorStats& stats =
 697         rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
 698                                           &complete_gc, &executor,
 699                                           &pt);
 700       _heap->tracer()->report_gc_reference_stats(stats);
 701     }
 702 
 703     pt.print_all_references();
 704 
 705     assert(task_queues()->is_empty(), "Should be empty");




 334   _heap->workers()->run_task(&update_roots);
 335 
 336 #if COMPILER2_OR_JVMCI
 337   DerivedPointerTable::update_pointers();
 338 #endif
 339 }
 340 
 341 class ShenandoahUpdateThreadRootsTask : public AbstractGangTask {
 342 private:
 343   ShenandoahThreadRoots           _thread_roots;
 344   ShenandoahPhaseTimings::Phase   _phase;
 345   ShenandoahGCWorkerPhase         _worker_phase;
 346 public:
 347   ShenandoahUpdateThreadRootsTask(bool is_par, ShenandoahPhaseTimings::Phase phase) :
 348     AbstractGangTask("Shenandoah Update Thread Roots"),
 349     _thread_roots(phase, is_par),
 350     _phase(phase),
 351     _worker_phase(phase) {}
 352 
 353   void work(uint worker_id) {
 354     ShenandoahParallelWorkerSession worker_session(worker_id);
 355     ShenandoahUpdateRefsClosure cl;
 356     _thread_roots.oops_do(&cl, NULL, worker_id);
 357   }
 358 };
 359 
 360 void ShenandoahConcurrentMark::update_thread_roots(ShenandoahPhaseTimings::Phase root_phase) {
 361   assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
 362 
 363   ShenandoahGCPhase phase(root_phase);
 364 
 365 #if COMPILER2_OR_JVMCI
 366   DerivedPointerTable::clear();
 367 #endif
 368 
 369   WorkGang* workers = _heap->workers();
 370   bool is_par = workers->active_workers() > 1;
 371 
 372   ShenandoahUpdateThreadRootsTask task(is_par, root_phase);
 373   workers->run_task(&task);
 374 


 572 };
 573 
 574 class ShenandoahRefProcTaskProxy : public AbstractGangTask {
 575 private:
 576   AbstractRefProcTaskExecutor::ProcessTask& _proc_task;
 577   TaskTerminator* _terminator;
 578 
 579 public:
 580   ShenandoahRefProcTaskProxy(AbstractRefProcTaskExecutor::ProcessTask& proc_task,
 581                              TaskTerminator* t) :
 582     AbstractGangTask("Process reference objects in parallel"),
 583     _proc_task(proc_task),
 584     _terminator(t) {
 585   }
 586 
 587   void work(uint worker_id) {
 588     ResourceMark rm;
 589     HandleMark hm;
 590     assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint");
 591     ShenandoahHeap* heap = ShenandoahHeap::heap();
 592     ShenandoahParallelWorkerSession worker_session(worker_id);
 593     ShenandoahCMDrainMarkingStackClosure complete_gc(worker_id, _terminator);
 594     if (heap->has_forwarded_objects()) {
 595       ShenandoahForwardedIsAliveClosure is_alive;
 596       ShenandoahCMKeepAliveUpdateClosure keep_alive(heap->concurrent_mark()->get_queue(worker_id));
 597       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
 598     } else {
 599       ShenandoahIsAliveClosure is_alive;
 600       ShenandoahCMKeepAliveClosure keep_alive(heap->concurrent_mark()->get_queue(worker_id));
 601       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
 602     }
 603   }
 604 };
 605 
 606 class ShenandoahRefProcTaskExecutor : public AbstractRefProcTaskExecutor {
 607 private:
 608   WorkGang* _workers;
 609 
 610 public:
 611   ShenandoahRefProcTaskExecutor(WorkGang* workers) :
 612     _workers(workers) {


 667   uint nworkers = workers->active_workers();
 668 
 669   rp->setup_policy(_heap->soft_ref_policy()->should_clear_all_soft_refs());
 670   rp->set_active_mt_degree(nworkers);
 671 
 672   assert(task_queues()->is_empty(), "Should be empty");
 673 
 674   // complete_gc and keep_alive closures instantiated here are only needed for
 675   // single-threaded path in RP. They share the queue 0 for tracking work, which
 676   // simplifies implementation. Since RP may decide to call complete_gc several
 677   // times, we need to be able to reuse the terminator.
 678   uint serial_worker_id = 0;
 679   TaskTerminator terminator(1, task_queues());
 680   ShenandoahCMDrainMarkingStackClosure complete_gc(serial_worker_id, &terminator, /* reset_terminator = */ true);
 681 
 682   ShenandoahRefProcTaskExecutor executor(workers);
 683 
 684   ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues());
 685 
 686   {
 687     // Note: Don't emit JFR event for this phase, to avoid overflow nesting phase level.
 688     // Reference Processor emits 2 levels JFR event, that can get us over the JFR
 689     // event nesting level limits, in case of degenerated GC gets upgraded to
 690     // full GC.
 691     ShenandoahGCPhaseTiming phase_timing(phase_process);
 692 
 693     if (_heap->has_forwarded_objects()) {
 694       ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id));
 695       const ReferenceProcessorStats& stats =
 696         rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
 697                                           &complete_gc, &executor,
 698                                           &pt);
 699        _heap->tracer()->report_gc_reference_stats(stats);
 700     } else {
 701       ShenandoahCMKeepAliveClosure keep_alive(get_queue(serial_worker_id));
 702       const ReferenceProcessorStats& stats =
 703         rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive,
 704                                           &complete_gc, &executor,
 705                                           &pt);
 706       _heap->tracer()->report_gc_reference_stats(stats);
 707     }
 708 
 709     pt.print_all_references();
 710 
 711     assert(task_queues()->is_empty(), "Should be empty");


< prev index next >