197 }
198
199 AlwaysTrueClosure is_alive;
200 _dedup_roots.oops_do(&is_alive, &roots_cl, worker_id);
201 }
202 }
203 };
204
205 class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask {
206 private:
207 ShenandoahTaskTerminator* _terminator;
208 ShenandoahHeap* _heap;
209 public:
210 ShenandoahConcurrentTraversalCollectionTask(ShenandoahTaskTerminator* terminator) :
211 AbstractGangTask("Shenandoah Concurrent Traversal Collection"),
212 _terminator(terminator),
213 _heap(ShenandoahHeap::heap()) {}
214
215 void work(uint worker_id) {
216 ShenandoahConcurrentWorkerSession worker_session(worker_id);
217 ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
218 ShenandoahEvacOOMScope oom_evac_scope;
219 ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc();
220
221 // Drain all outstanding work in queues.
222 traversal_gc->main_loop(worker_id, _terminator, true);
223 }
224 };
225
226 class ShenandoahFinalTraversalCollectionTask : public AbstractGangTask {
227 private:
228 ShenandoahAllRootScanner* _rp;
229 ShenandoahTaskTerminator* _terminator;
230 ShenandoahHeap* _heap;
231 public:
232 ShenandoahFinalTraversalCollectionTask(ShenandoahAllRootScanner* rp, ShenandoahTaskTerminator* terminator) :
233 AbstractGangTask("Shenandoah Final Traversal Collection"),
234 _rp(rp),
235 _terminator(terminator),
236 _heap(ShenandoahHeap::heap()) {}
237
517 if (check_and_handle_cancelled_gc(terminator, sts_yield)) return;
518
519 while (satb_mq_set.completed_buffers_num() > 0) {
520 satb_mq_set.apply_closure_to_completed_buffer(&drain_satb);
521 }
522
523 uint work = 0;
524 for (uint i = 0; i < stride; i++) {
525 if (q->pop(task) ||
526 queues->steal(worker_id, task)) {
527 conc_mark->do_task<T>(q, cl, live_data, &task);
528 work++;
529 } else {
530 break;
531 }
532 }
533
534 if (work == 0) {
535 // No more work, try to terminate
536 ShenandoahEvacOOMScopeLeaver oom_scope_leaver;
537 ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield && ShenandoahSuspendibleWorkers);
538 ShenandoahTerminationTimingsTracker term_tracker(worker_id);
539 ShenandoahTerminatorTerminator tt(_heap);
540
541 if (terminator->offer_termination(&tt)) return;
542 }
543 }
544 }
545
546 bool ShenandoahTraversalGC::check_and_handle_cancelled_gc(ShenandoahTaskTerminator* terminator, bool sts_yield) {
547 if (_heap->cancelled_gc()) {
548 return true;
549 }
550 return false;
551 }
552
553 void ShenandoahTraversalGC::concurrent_traversal_collection() {
554 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal);
555 if (!_heap->cancelled_gc()) {
556 uint nworkers = _heap->workers()->active_workers();
557 task_queues()->reserve(nworkers);
830 _queue(q), _thread(Thread::current()),
831 _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
832 _mark_context(ShenandoahHeap::heap()->marking_context()) {}
833
834 void do_oop(narrowOop* p) { do_oop_work(p); }
835 void do_oop(oop* p) { do_oop_work(p); }
836 };
837
838 class ShenandoahTraversalPrecleanTask : public AbstractGangTask {
839 private:
840 ReferenceProcessor* _rp;
841
842 public:
843 ShenandoahTraversalPrecleanTask(ReferenceProcessor* rp) :
844 AbstractGangTask("Precleaning task"),
845 _rp(rp) {}
846
847 void work(uint worker_id) {
848 assert(worker_id == 0, "The code below is single-threaded, only one worker is expected");
849 ShenandoahParallelWorkerSession worker_session(worker_id);
850 ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
851 ShenandoahEvacOOMScope oom_evac_scope;
852
853 ShenandoahHeap* sh = ShenandoahHeap::heap();
854
855 ShenandoahObjToScanQueue* q = sh->traversal_gc()->task_queues()->queue(worker_id);
856
857 ShenandoahForwardedIsAliveClosure is_alive;
858 ShenandoahTraversalCancelledGCYieldClosure yield;
859 ShenandoahTraversalPrecleanCompleteGCClosure complete_gc;
860 ShenandoahTraversalKeepAliveUpdateClosure keep_alive(q);
861 ResourceMark rm;
862 _rp->preclean_discovered_references(&is_alive, &keep_alive,
863 &complete_gc, &yield,
864 NULL);
865 }
866 };
867
868 void ShenandoahTraversalGC::preclean_weak_refs() {
869 // Pre-cleaning weak references before diving into STW makes sense at the
870 // end of concurrent mark. This will filter out the references which referents
|
197 }
198
199 AlwaysTrueClosure is_alive;
200 _dedup_roots.oops_do(&is_alive, &roots_cl, worker_id);
201 }
202 }
203 };
204
205 class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask {
206 private:
207 ShenandoahTaskTerminator* _terminator;
208 ShenandoahHeap* _heap;
209 public:
210 ShenandoahConcurrentTraversalCollectionTask(ShenandoahTaskTerminator* terminator) :
211 AbstractGangTask("Shenandoah Concurrent Traversal Collection"),
212 _terminator(terminator),
213 _heap(ShenandoahHeap::heap()) {}
214
215 void work(uint worker_id) {
216 ShenandoahConcurrentWorkerSession worker_session(worker_id);
217 ShenandoahSuspendibleThreadSetJoiner stsj;
218 ShenandoahEvacOOMScope oom_evac_scope;
219 ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc();
220
221 // Drain all outstanding work in queues.
222 traversal_gc->main_loop(worker_id, _terminator, true);
223 }
224 };
225
226 class ShenandoahFinalTraversalCollectionTask : public AbstractGangTask {
227 private:
228 ShenandoahAllRootScanner* _rp;
229 ShenandoahTaskTerminator* _terminator;
230 ShenandoahHeap* _heap;
231 public:
232 ShenandoahFinalTraversalCollectionTask(ShenandoahAllRootScanner* rp, ShenandoahTaskTerminator* terminator) :
233 AbstractGangTask("Shenandoah Final Traversal Collection"),
234 _rp(rp),
235 _terminator(terminator),
236 _heap(ShenandoahHeap::heap()) {}
237
517 if (check_and_handle_cancelled_gc(terminator, sts_yield)) return;
518
519 while (satb_mq_set.completed_buffers_num() > 0) {
520 satb_mq_set.apply_closure_to_completed_buffer(&drain_satb);
521 }
522
523 uint work = 0;
524 for (uint i = 0; i < stride; i++) {
525 if (q->pop(task) ||
526 queues->steal(worker_id, task)) {
527 conc_mark->do_task<T>(q, cl, live_data, &task);
528 work++;
529 } else {
530 break;
531 }
532 }
533
534 if (work == 0) {
535 // No more work, try to terminate
536 ShenandoahEvacOOMScopeLeaver oom_scope_leaver;
537 ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield);
538 ShenandoahTerminationTimingsTracker term_tracker(worker_id);
539 ShenandoahTerminatorTerminator tt(_heap);
540
541 if (terminator->offer_termination(&tt)) return;
542 }
543 }
544 }
545
546 bool ShenandoahTraversalGC::check_and_handle_cancelled_gc(ShenandoahTaskTerminator* terminator, bool sts_yield) {
547 if (_heap->cancelled_gc()) {
548 return true;
549 }
550 return false;
551 }
552
553 void ShenandoahTraversalGC::concurrent_traversal_collection() {
554 ShenandoahGCPhase phase_work(ShenandoahPhaseTimings::conc_traversal);
555 if (!_heap->cancelled_gc()) {
556 uint nworkers = _heap->workers()->active_workers();
557 task_queues()->reserve(nworkers);
830 _queue(q), _thread(Thread::current()),
831 _traversal_gc(ShenandoahHeap::heap()->traversal_gc()),
832 _mark_context(ShenandoahHeap::heap()->marking_context()) {}
833
834 void do_oop(narrowOop* p) { do_oop_work(p); }
835 void do_oop(oop* p) { do_oop_work(p); }
836 };
837
838 class ShenandoahTraversalPrecleanTask : public AbstractGangTask {
839 private:
840 ReferenceProcessor* _rp;
841
842 public:
843 ShenandoahTraversalPrecleanTask(ReferenceProcessor* rp) :
844 AbstractGangTask("Precleaning task"),
845 _rp(rp) {}
846
847 void work(uint worker_id) {
848 assert(worker_id == 0, "The code below is single-threaded, only one worker is expected");
849 ShenandoahParallelWorkerSession worker_session(worker_id);
850 ShenandoahSuspendibleThreadSetJoiner stsj;
851 ShenandoahEvacOOMScope oom_evac_scope;
852
853 ShenandoahHeap* sh = ShenandoahHeap::heap();
854
855 ShenandoahObjToScanQueue* q = sh->traversal_gc()->task_queues()->queue(worker_id);
856
857 ShenandoahForwardedIsAliveClosure is_alive;
858 ShenandoahTraversalCancelledGCYieldClosure yield;
859 ShenandoahTraversalPrecleanCompleteGCClosure complete_gc;
860 ShenandoahTraversalKeepAliveUpdateClosure keep_alive(q);
861 ResourceMark rm;
862 _rp->preclean_discovered_references(&is_alive, &keep_alive,
863 &complete_gc, &yield,
864 NULL);
865 }
866 };
867
868 void ShenandoahTraversalGC::preclean_weak_refs() {
869 // Pre-cleaning weak references before diving into STW makes sense at the
870 // end of concurrent mark. This will filter out the references which referents
|