File: | jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp |
Warning: | line 59, column 31 Value stored to 'q' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright (c) 2013, 2021, Red Hat, Inc. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | |
27 | #include "gc/shared/satbMarkQueue.hpp" |
28 | #include "gc/shared/strongRootsScope.hpp" |
29 | #include "gc/shared/taskTerminator.hpp" |
30 | #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" |
31 | #include "gc/shenandoah/shenandoahClosures.inline.hpp" |
32 | #include "gc/shenandoah/shenandoahConcurrentMark.hpp" |
33 | #include "gc/shenandoah/shenandoahHeap.inline.hpp" |
34 | #include "gc/shenandoah/shenandoahMark.inline.hpp" |
35 | #include "gc/shenandoah/shenandoahReferenceProcessor.hpp" |
36 | #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" |
37 | #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" |
38 | #include "gc/shenandoah/shenandoahPhaseTimings.hpp" |
39 | #include "gc/shenandoah/shenandoahStringDedup.hpp" |
40 | #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp" |
41 | #include "gc/shenandoah/shenandoahUtils.hpp" |
42 | #include "memory/iterator.inline.hpp" |
43 | #include "memory/resourceArea.hpp" |
44 | |
45 | class ShenandoahConcurrentMarkingTask : public WorkerTask { |
46 | private: |
47 | ShenandoahConcurrentMark* const _cm; |
48 | TaskTerminator* const _terminator; |
49 | |
50 | public: |
51 | ShenandoahConcurrentMarkingTask(ShenandoahConcurrentMark* cm, TaskTerminator* terminator) : |
52 | WorkerTask("Shenandoah Concurrent Mark"), _cm(cm), _terminator(terminator) { |
53 | } |
54 | |
55 | void work(uint worker_id) { |
56 | ShenandoahHeap* heap = ShenandoahHeap::heap(); |
57 | ShenandoahConcurrentWorkerSession worker_session(worker_id); |
58 | ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); |
59 | ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id); |
Value stored to 'q' during its initialization is never read | |
60 | ShenandoahReferenceProcessor* rp = heap->ref_processor(); |
61 | assert(rp != NULL, "need reference processor")do { if (!(rp != __null)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 61, "assert(" "rp != __null" ") failed", "need reference processor" ); ::breakpoint(); } } while (0); |
62 | StringDedup::Requests requests; |
63 | _cm->mark_loop(worker_id, _terminator, rp, |
64 | true /*cancellable*/, |
65 | ShenandoahStringDedup::is_enabled() ? ENQUEUE_DEDUP : NO_DEDUP, |
66 | &requests); |
67 | } |
68 | }; |
69 | |
70 | class ShenandoahSATBAndRemarkThreadsClosure : public ThreadClosure { |
71 | private: |
72 | SATBMarkQueueSet& _satb_qset; |
73 | OopClosure* const _cl; |
74 | uintx _claim_token; |
75 | |
76 | public: |
77 | ShenandoahSATBAndRemarkThreadsClosure(SATBMarkQueueSet& satb_qset, OopClosure* cl) : |
78 | _satb_qset(satb_qset), |
79 | _cl(cl), |
80 | _claim_token(Threads::thread_claim_token()) {} |
81 | |
82 | void do_thread(Thread* thread) { |
83 | if (thread->claim_threads_do(true, _claim_token)) { |
84 | // Transfer any partial buffer to the qset for completed buffer processing. |
85 | _satb_qset.flush_queue(ShenandoahThreadLocalData::satb_mark_queue(thread)); |
86 | if (thread->is_Java_thread()) { |
87 | if (_cl != NULL__null) { |
88 | ResourceMark rm; |
89 | thread->oops_do(_cl, NULL__null); |
90 | } |
91 | } |
92 | } |
93 | } |
94 | }; |
95 | |
96 | class ShenandoahFinalMarkingTask : public WorkerTask { |
97 | private: |
98 | ShenandoahConcurrentMark* _cm; |
99 | TaskTerminator* _terminator; |
100 | bool _dedup_string; |
101 | |
102 | public: |
103 | ShenandoahFinalMarkingTask(ShenandoahConcurrentMark* cm, TaskTerminator* terminator, bool dedup_string) : |
104 | WorkerTask("Shenandoah Final Mark"), _cm(cm), _terminator(terminator), _dedup_string(dedup_string) { |
105 | } |
106 | |
107 | void work(uint worker_id) { |
108 | ShenandoahHeap* heap = ShenandoahHeap::heap(); |
109 | |
110 | ShenandoahParallelWorkerSession worker_session(worker_id); |
111 | ShenandoahReferenceProcessor* rp = heap->ref_processor(); |
112 | StringDedup::Requests requests; |
113 | |
114 | // First drain remaining SATB buffers. |
115 | { |
116 | ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id); |
117 | |
118 | ShenandoahSATBBufferClosure cl(q); |
119 | SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set(); |
120 | while (satb_mq_set.apply_closure_to_completed_buffer(&cl)) {} |
121 | assert(!heap->has_forwarded_objects(), "Not expected")do { if (!(!heap->has_forwarded_objects())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 121, "assert(" "!heap->has_forwarded_objects()" ") failed" , "Not expected"); ::breakpoint(); } } while (0); |
122 | |
123 | ShenandoahMarkRefsClosure mark_cl(q, rp); |
124 | ShenandoahSATBAndRemarkThreadsClosure tc(satb_mq_set, |
125 | ShenandoahIUBarrier ? &mark_cl : NULL__null); |
126 | Threads::threads_do(&tc); |
127 | } |
128 | _cm->mark_loop(worker_id, _terminator, rp, |
129 | false /*not cancellable*/, |
130 | _dedup_string ? ENQUEUE_DEDUP : NO_DEDUP, |
131 | &requests); |
132 | assert(_cm->task_queues()->is_empty(), "Should be empty")do { if (!(_cm->task_queues()->is_empty())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 132, "assert(" "_cm->task_queues()->is_empty()" ") failed" , "Should be empty"); ::breakpoint(); } } while (0); |
133 | } |
134 | }; |
135 | |
136 | ShenandoahConcurrentMark::ShenandoahConcurrentMark() : |
137 | ShenandoahMark() {} |
138 | |
139 | // Mark concurrent roots during concurrent phases |
140 | class ShenandoahMarkConcurrentRootsTask : public WorkerTask { |
141 | private: |
142 | SuspendibleThreadSetJoiner _sts_joiner; |
143 | ShenandoahConcurrentRootScanner _root_scanner; |
144 | ShenandoahObjToScanQueueSet* const _queue_set; |
145 | ShenandoahReferenceProcessor* const _rp; |
146 | |
147 | public: |
148 | ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs, |
149 | ShenandoahReferenceProcessor* rp, |
150 | ShenandoahPhaseTimings::Phase phase, |
151 | uint nworkers); |
152 | void work(uint worker_id); |
153 | }; |
154 | |
155 | ShenandoahMarkConcurrentRootsTask::ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs, |
156 | ShenandoahReferenceProcessor* rp, |
157 | ShenandoahPhaseTimings::Phase phase, |
158 | uint nworkers) : |
159 | WorkerTask("Shenandoah Concurrent Mark Roots"), |
160 | _root_scanner(nworkers, phase), |
161 | _queue_set(qs), |
162 | _rp(rp) { |
163 | assert(!ShenandoahHeap::heap()->has_forwarded_objects(), "Not expected")do { if (!(!ShenandoahHeap::heap()->has_forwarded_objects( ))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 163, "assert(" "!ShenandoahHeap::heap()->has_forwarded_objects()" ") failed", "Not expected"); ::breakpoint(); } } while (0); |
164 | } |
165 | |
166 | void ShenandoahMarkConcurrentRootsTask::work(uint worker_id) { |
167 | ShenandoahConcurrentWorkerSession worker_session(worker_id); |
168 | ShenandoahObjToScanQueue* q = _queue_set->queue(worker_id); |
169 | ShenandoahMarkRefsClosure cl(q, _rp); |
170 | _root_scanner.roots_do(&cl, worker_id); |
171 | } |
172 | |
173 | void ShenandoahConcurrentMark::mark_concurrent_roots() { |
174 | ShenandoahHeap* const heap = ShenandoahHeap::heap(); |
175 | assert(!heap->has_forwarded_objects(), "Not expected")do { if (!(!heap->has_forwarded_objects())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 175, "assert(" "!heap->has_forwarded_objects()" ") failed" , "Not expected"); ::breakpoint(); } } while (0); |
176 | |
177 | TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats())task_queues()->reset_taskqueue_stats(); |
178 | |
179 | WorkerThreads* workers = heap->workers(); |
180 | ShenandoahReferenceProcessor* rp = heap->ref_processor(); |
181 | task_queues()->reserve(workers->active_workers()); |
182 | ShenandoahMarkConcurrentRootsTask task(task_queues(), rp, ShenandoahPhaseTimings::conc_mark_roots, workers->active_workers()); |
183 | |
184 | workers->run_task(&task); |
185 | } |
186 | |
187 | class ShenandoahFlushSATBHandshakeClosure : public HandshakeClosure { |
188 | private: |
189 | SATBMarkQueueSet& _qset; |
190 | public: |
191 | ShenandoahFlushSATBHandshakeClosure(SATBMarkQueueSet& qset) : |
192 | HandshakeClosure("Shenandoah Flush SATB Handshake"), |
193 | _qset(qset) {} |
194 | |
195 | void do_thread(Thread* thread) { |
196 | _qset.flush_queue(ShenandoahThreadLocalData::satb_mark_queue(thread)); |
197 | } |
198 | }; |
199 | |
200 | void ShenandoahConcurrentMark::concurrent_mark() { |
201 | ShenandoahHeap* const heap = ShenandoahHeap::heap(); |
202 | WorkerThreads* workers = heap->workers(); |
203 | uint nworkers = workers->active_workers(); |
204 | task_queues()->reserve(nworkers); |
205 | |
206 | ShenandoahSATBMarkQueueSet& qset = ShenandoahBarrierSet::satb_mark_queue_set(); |
207 | ShenandoahFlushSATBHandshakeClosure flush_satb(qset); |
208 | for (uint flushes = 0; flushes < ShenandoahMaxSATBBufferFlushes; flushes++) { |
209 | TaskTerminator terminator(nworkers, task_queues()); |
210 | ShenandoahConcurrentMarkingTask task(this, &terminator); |
211 | workers->run_task(&task); |
212 | |
213 | if (heap->cancelled_gc()) { |
214 | // GC is cancelled, break out. |
215 | break; |
216 | } |
217 | |
218 | size_t before = qset.completed_buffers_num(); |
219 | Handshake::execute(&flush_satb); |
220 | size_t after = qset.completed_buffers_num(); |
221 | |
222 | if (before == after) { |
223 | // No more retries needed, break out. |
224 | break; |
225 | } |
226 | } |
227 | assert(task_queues()->is_empty() || heap->cancelled_gc(), "Should be empty when not cancelled")do { if (!(task_queues()->is_empty() || heap->cancelled_gc ())) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 227, "assert(" "task_queues()->is_empty() || heap->cancelled_gc()" ") failed", "Should be empty when not cancelled"); ::breakpoint (); } } while (0); |
228 | } |
229 | |
230 | void ShenandoahConcurrentMark::finish_mark() { |
231 | assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint")do { if (!(ShenandoahSafepoint::is_at_shenandoah_safepoint()) ) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 231, "assert(" "ShenandoahSafepoint::is_at_shenandoah_safepoint()" ") failed", "Must be at a safepoint"); ::breakpoint(); } } while (0); |
232 | assert(Thread::current()->is_VM_thread(), "Must by VM Thread")do { if (!(Thread::current()->is_VM_thread())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 232, "assert(" "Thread::current()->is_VM_thread()" ") failed" , "Must by VM Thread"); ::breakpoint(); } } while (0); |
233 | finish_mark_work(); |
234 | assert(task_queues()->is_empty(), "Should be empty")do { if (!(task_queues()->is_empty())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 234, "assert(" "task_queues()->is_empty()" ") failed", "Should be empty" ); ::breakpoint(); } } while (0); |
235 | TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats())task_queues()->print_taskqueue_stats(); |
236 | TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats())task_queues()->reset_taskqueue_stats(); |
237 | |
238 | ShenandoahHeap* const heap = ShenandoahHeap::heap(); |
239 | heap->set_concurrent_mark_in_progress(false); |
240 | heap->mark_complete_marking_context(); |
241 | } |
242 | |
243 | void ShenandoahConcurrentMark::finish_mark_work() { |
244 | // Finally mark everything else we've got in our queues during the previous steps. |
245 | // It does two different things for concurrent vs. mark-compact GC: |
246 | // - For concurrent GC, it starts with empty task queues, drains the remaining |
247 | // SATB buffers, and then completes the marking closure. |
248 | // - For mark-compact GC, it starts out with the task queues seeded by initial |
249 | // root scan, and completes the closure, thus marking through all live objects |
250 | // The implementation is the same, so it's shared here. |
251 | ShenandoahHeap* const heap = ShenandoahHeap::heap(); |
252 | ShenandoahGCPhase phase(ShenandoahPhaseTimings::finish_mark); |
253 | uint nworkers = heap->workers()->active_workers(); |
254 | task_queues()->reserve(nworkers); |
255 | |
256 | StrongRootsScope scope(nworkers); |
257 | TaskTerminator terminator(nworkers, task_queues()); |
258 | ShenandoahFinalMarkingTask task(this, &terminator, ShenandoahStringDedup::is_enabled()); |
259 | heap->workers()->run_task(&task); |
260 | |
261 | assert(task_queues()->is_empty(), "Should be empty")do { if (!(task_queues()->is_empty())) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp" , 261, "assert(" "task_queues()->is_empty()" ") failed", "Should be empty" ); ::breakpoint(); } } while (0); |
262 | } |
263 | |
264 | |
265 | void ShenandoahConcurrentMark::cancel() { |
266 | clear(); |
267 | ShenandoahReferenceProcessor* rp = ShenandoahHeap::heap()->ref_processor(); |
268 | rp->abandon_partial_discovery(); |
269 | } |