57
58 void ShenandoahSTWMarkTask::work(uint worker_id) {
59 ShenandoahParallelWorkerSession worker_session(worker_id);
60 _mark->mark_roots(worker_id);
61 _mark->finish_mark(worker_id);
62 }
63
64 ShenandoahSTWMark::ShenandoahSTWMark(ShenandoahGeneration* generation, bool full_gc) :
65 ShenandoahMark(generation),
66 _root_scanner(full_gc ? ShenandoahPhaseTimings::full_gc_mark : ShenandoahPhaseTimings::degen_gc_mark),
67 _terminator(ShenandoahHeap::heap()->workers()->active_workers(), task_queues()),
68 _full_gc(full_gc) {
69 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a Shenandoah safepoint");
70 }
71
72 void ShenandoahSTWMark::mark() {
73 ShenandoahHeap* const heap = ShenandoahHeap::heap();
74
75 // Arm all nmethods. Even though this is STW mark, some marking code
76 // piggybacks on nmethod barriers for special instances.
77 ShenandoahCodeRoots::arm_nmethods();
78
79 // Weak reference processing
80 ShenandoahReferenceProcessor* rp = _generation->ref_processor();
81 rp->reset_thread_locals();
82
83 // Init mark, do not expect forwarded pointers in roots
84 if (ShenandoahVerify) {
85 assert(Thread::current()->is_VM_thread(), "Must be");
86 heap->verifier()->verify_roots_no_forwarded(_generation);
87 }
88
89 start_mark();
90
91 uint nworkers = heap->workers()->active_workers();
92 task_queues()->reserve(nworkers);
93
94 TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
95
96 {
97 // Mark
98 if (_generation->is_young()) {
99 // But only scan the remembered set for young generation.
100 _generation->scan_remembered_set(false /* is_concurrent */);
101 }
102
103 ShenandoahSTWMarkTask task(this);
104 heap->workers()->run_task(&task);
105
106 assert(task_queues()->is_empty(), "Should be empty");
107
108 if (!generation()->is_old()) {
109 // Lastly, ensure all the invisible roots are marked.
110 ShenandoahInvisibleRootsMarkClosure cl;
111 Threads::java_threads_do(&cl);
112 }
113 }
114
115 _generation->set_mark_complete();
116 end_mark();
117
118 // Mark is finished, can disarm the nmethods now.
119 ShenandoahCodeRoots::disarm_nmethods();
120
121 assert(task_queues()->is_empty(), "Should be empty");
122 TASKQUEUE_STATS_ONLY(task_queues()->print_and_reset_taskqueue_stats(""));
123 }
124
125 void ShenandoahSTWMark::mark_roots(uint worker_id) {
126 ShenandoahReferenceProcessor* rp = _generation->ref_processor();
127 auto queue = task_queues()->queue(worker_id);
128 switch (_generation->type()) {
129 case NON_GEN: {
130 ShenandoahMarkRefsClosure<NON_GEN> init_mark(queue, rp, nullptr);
131 _root_scanner.roots_do(&init_mark, worker_id);
132 break;
133 }
134 case GLOBAL: {
135 ShenandoahMarkRefsClosure<GLOBAL> init_mark(queue, rp, nullptr);
136 _root_scanner.roots_do(&init_mark, worker_id);
137 break;
138 }
139 case YOUNG: {
140 ShenandoahMarkRefsClosure<YOUNG> init_mark(queue, rp, nullptr);
|
57
58 void ShenandoahSTWMarkTask::work(uint worker_id) {
59 ShenandoahParallelWorkerSession worker_session(worker_id);
60 _mark->mark_roots(worker_id);
61 _mark->finish_mark(worker_id);
62 }
63
64 ShenandoahSTWMark::ShenandoahSTWMark(ShenandoahGeneration* generation, bool full_gc) :
65 ShenandoahMark(generation),
66 _root_scanner(full_gc ? ShenandoahPhaseTimings::full_gc_mark : ShenandoahPhaseTimings::degen_gc_mark),
67 _terminator(ShenandoahHeap::heap()->workers()->active_workers(), task_queues()),
68 _full_gc(full_gc) {
69 assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a Shenandoah safepoint");
70 }
71
72 void ShenandoahSTWMark::mark() {
73 ShenandoahHeap* const heap = ShenandoahHeap::heap();
74
75 // Arm all nmethods. Even though this is STW mark, some marking code
76 // piggybacks on nmethod barriers for special instances.
77 CodeCache::arm_all_nmethods();
78
79 // Weak reference processing
80 ShenandoahReferenceProcessor* rp = _generation->ref_processor();
81 rp->reset_thread_locals();
82
83 // Init mark, do not expect forwarded pointers in roots
84 if (ShenandoahVerify) {
85 assert(Thread::current()->is_VM_thread(), "Must be");
86 heap->verifier()->verify_roots_no_forwarded(_generation);
87 }
88
89 start_mark();
90
91 uint nworkers = heap->workers()->active_workers();
92 task_queues()->reserve(nworkers);
93
94 TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
95
96 {
97 // Mark
98 if (_generation->is_young()) {
99 // But only scan the remembered set for young generation.
100 _generation->scan_remembered_set(false /* is_concurrent */);
101 }
102
103 ShenandoahSTWMarkTask task(this);
104 heap->workers()->run_task(&task);
105
106 assert(task_queues()->is_empty(), "Should be empty");
107
108 if (!generation()->is_old()) {
109 // Lastly, ensure all the invisible roots are marked.
110 ShenandoahInvisibleRootsMarkClosure cl;
111 Threads::java_threads_do(&cl);
112 }
113 }
114
115 _generation->set_mark_complete();
116 end_mark();
117
118 assert(task_queues()->is_empty(), "Should be empty");
119 TASKQUEUE_STATS_ONLY(task_queues()->print_and_reset_taskqueue_stats(""));
120 }
121
122 void ShenandoahSTWMark::mark_roots(uint worker_id) {
123 ShenandoahReferenceProcessor* rp = _generation->ref_processor();
124 auto queue = task_queues()->queue(worker_id);
125 switch (_generation->type()) {
126 case NON_GEN: {
127 ShenandoahMarkRefsClosure<NON_GEN> init_mark(queue, rp, nullptr);
128 _root_scanner.roots_do(&init_mark, worker_id);
129 break;
130 }
131 case GLOBAL: {
132 ShenandoahMarkRefsClosure<GLOBAL> init_mark(queue, rp, nullptr);
133 _root_scanner.roots_do(&init_mark, worker_id);
134 break;
135 }
136 case YOUNG: {
137 ShenandoahMarkRefsClosure<YOUNG> init_mark(queue, rp, nullptr);
|