521 if (check_and_handle_cancelled_gc(terminator, sts_yield)) return;
522
523 while (satb_mq_set.completed_buffers_num() > 0) {
524 satb_mq_set.apply_closure_to_completed_buffer(&drain_satb);
525 }
526
527 uint work = 0;
528 for (uint i = 0; i < stride; i++) {
529 if (q->pop(task) ||
530 queues->steal(worker_id, task)) {
531 conc_mark->do_task<T>(q, cl, live_data, &task);
532 work++;
533 } else {
534 break;
535 }
536 }
537
538 if (work == 0) {
539 // No more work, try to terminate
540 ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield && ShenandoahSuspendibleWorkers);
541 ShenandoahTerminationTimingsTracker term_tracker(worker_id);
542 ShenandoahTerminatorTerminator tt(_heap);
543
544 if (terminator->offer_termination(&tt)) return;
545 }
546 }
547 }
548
549 bool ShenandoahTraversalGC::check_and_handle_cancelled_gc(TaskTerminator* terminator, bool sts_yield) {
550 if (_heap->cancelled_gc()) {
551 return true;
552 }
553 return false;
554 }
555
556 void ShenandoahTraversalGC::concurrent_traversal_collection() {
557 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal);
558 if (!_heap->cancelled_gc()) {
559 uint nworkers = _heap->workers()->active_workers();
560 task_queues()->reserve(nworkers);
561 ShenandoahTerminationTracker tracker(ShenandoahPhaseTimings::conc_traversal_termination);
562
563 TaskTerminator terminator(nworkers, task_queues());
564 ShenandoahConcurrentTraversalCollectionTask task(&terminator);
565 _heap->workers()->run_task(&task);
566 }
567
568 if (!_heap->cancelled_gc() && ShenandoahPreclean && _heap->process_references()) {
569 preclean_weak_refs();
570 }
571 }
572
573 void ShenandoahTraversalGC::final_traversal_collection() {
574 if (!_heap->cancelled_gc()) {
575 #if COMPILER2_OR_JVMCI
576 DerivedPointerTable::clear();
577 #endif
578 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::final_traversal_gc_work);
579 uint nworkers = _heap->workers()->active_workers();
580 task_queues()->reserve(nworkers);
581
582 // Finish traversal
583 ShenandoahAllRootScanner rp(nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
584 ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
585
586 TaskTerminator terminator(nworkers, task_queues());
587 ShenandoahFinalTraversalCollectionTask task(&rp, &terminator);
588 _heap->workers()->run_task(&task);
589 #if COMPILER2_OR_JVMCI
590 DerivedPointerTable::update_pointers();
591 #endif
592 }
593
594 if (!_heap->cancelled_gc() && _heap->process_references()) {
595 weak_refs_work();
596 }
597
598 if (!_heap->cancelled_gc()) {
599 assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
600 TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
601 TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
602
603 // No more marking expected
604 _heap->set_concurrent_traversal_in_progress(false);
605 _heap->mark_complete_marking_context();
|
521 if (check_and_handle_cancelled_gc(terminator, sts_yield)) return;
522
523 while (satb_mq_set.completed_buffers_num() > 0) {
524 satb_mq_set.apply_closure_to_completed_buffer(&drain_satb);
525 }
526
527 uint work = 0;
528 for (uint i = 0; i < stride; i++) {
529 if (q->pop(task) ||
530 queues->steal(worker_id, task)) {
531 conc_mark->do_task<T>(q, cl, live_data, &task);
532 work++;
533 } else {
534 break;
535 }
536 }
537
538 if (work == 0) {
539 // No more work, try to terminate
540 ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield && ShenandoahSuspendibleWorkers);
541 ShenandoahTerminatorTerminator tt(_heap);
542
543 if (terminator->offer_termination(&tt)) return;
544 }
545 }
546 }
547
548 bool ShenandoahTraversalGC::check_and_handle_cancelled_gc(TaskTerminator* terminator, bool sts_yield) {
549 if (_heap->cancelled_gc()) {
550 return true;
551 }
552 return false;
553 }
554
555 void ShenandoahTraversalGC::concurrent_traversal_collection() {
556 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal);
557 if (!_heap->cancelled_gc()) {
558 uint nworkers = _heap->workers()->active_workers();
559 task_queues()->reserve(nworkers);
560
561 TaskTerminator terminator(nworkers, task_queues());
562 ShenandoahConcurrentTraversalCollectionTask task(&terminator);
563 _heap->workers()->run_task(&task);
564 }
565
566 if (!_heap->cancelled_gc() && ShenandoahPreclean && _heap->process_references()) {
567 preclean_weak_refs();
568 }
569 }
570
571 void ShenandoahTraversalGC::final_traversal_collection() {
572 if (!_heap->cancelled_gc()) {
573 #if COMPILER2_OR_JVMCI
574 DerivedPointerTable::clear();
575 #endif
576 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::final_traversal_gc_work);
577 uint nworkers = _heap->workers()->active_workers();
578 task_queues()->reserve(nworkers);
579
580 // Finish traversal
581 ShenandoahAllRootScanner rp(nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
582 TaskTerminator terminator(nworkers, task_queues());
583 ShenandoahFinalTraversalCollectionTask task(&rp, &terminator);
584 _heap->workers()->run_task(&task);
585 #if COMPILER2_OR_JVMCI
586 DerivedPointerTable::update_pointers();
587 #endif
588 }
589
590 if (!_heap->cancelled_gc() && _heap->process_references()) {
591 weak_refs_work();
592 }
593
594 if (!_heap->cancelled_gc()) {
595 assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
596 TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());
597 TASKQUEUE_STATS_ONLY(_task_queues->reset_taskqueue_stats());
598
599 // No more marking expected
600 _heap->set_concurrent_traversal_in_progress(false);
601 _heap->mark_complete_marking_context();
|