144 void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
145 if (ShenandoahStringDedup::is_enabled()) {
146 ShenandoahStringDedup::parallel_oops_do(_phase, is_alive, keep_alive, worker_id);
147 }
148 }
149
150 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
151 _heap(ShenandoahHeap::heap()),
152 _phase(phase),
153 _worker_phase(phase) {
154 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
155 }
156
157 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
158 ShenandoahPhaseTimings::Phase phase,
159 bool stw_roots_processing,
160 bool stw_class_unloading) :
161 ShenandoahRootProcessor(phase),
162 _serial_roots(phase),
163 _vm_roots(phase),
164 _cld_roots(phase),
165 _thread_roots(phase, n_workers > 1),
166 _serial_weak_roots(phase),
167 _weak_roots(phase),
168 _dedup_roots(phase),
169 _code_roots(phase),
170 _stw_roots_processing(stw_roots_processing),
171 _stw_class_unloading(stw_class_unloading) {
172 }
173
174 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
175 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
176 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
177 CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
178 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
179 static_cast<CodeBlobToOopClosure*>(&blobsCl);
180 AlwaysTrueClosure always_true;
181
182 // Process serial-claiming roots first
183 _serial_roots.oops_do(oops, worker_id);
184 _serial_weak_roots.weak_oops_do(oops, worker_id);
185
186 // Process light-weight/limited parallel roots then
187 if (_stw_roots_processing) {
188 _vm_roots.oops_do<OopClosure>(oops, worker_id);
189 _weak_roots.oops_do<OopClosure>(oops, worker_id);
190 }
191 _dedup_roots.oops_do(&always_true, oops, worker_id);
192
193 // Process heavy-weight/fully parallel roots the last
194 if (_stw_class_unloading) {
195 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
196 _cld_roots.cld_do(&clds, worker_id);
197 _code_roots.code_blobs_do(codes_cl, worker_id);
198 _thread_roots.oops_do(oops, NULL, worker_id);
199 } else {
200 _thread_roots.oops_do(oops, codes_cl, worker_id);
201 }
202 }
203
204 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
205 ShenandoahRootProcessor(phase),
206 _serial_roots(phase),
207 _vm_roots(phase),
208 _cld_roots(phase),
209 _thread_roots(phase, n_workers > 1),
210 _serial_weak_roots(phase),
211 _weak_roots(phase),
212 _dedup_roots(phase),
213 _code_roots(phase) {
214 }
215
216 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
217 ShenandoahRootProcessor(phase),
218 _serial_roots(phase),
219 _vm_roots(phase),
220 _cld_roots(phase),
221 _thread_roots(phase, n_workers > 1),
222 _serial_weak_roots(phase),
223 _weak_roots(phase),
224 _dedup_roots(phase),
225 _code_roots(phase) {
226 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
227 }
228
229 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
230 CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
231 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
232 CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
233 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
234 static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
235 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
236 AlwaysTrueClosure always_true;
237
238 // Process serial-claiming roots first
239 _serial_roots.oops_do(oops, worker_id);
240 _serial_weak_roots.weak_oops_do(oops, worker_id);
241
242 // Process light-weight/limited parallel roots then
243 _vm_roots.oops_do(oops, worker_id);
244 _weak_roots.oops_do<OopClosure>(oops, worker_id);
245 _dedup_roots.oops_do(&always_true, oops, worker_id);
246
247 // Process heavy-weight/fully parallel roots the last
248 _cld_roots.cld_do(&adjust_cld_closure, worker_id);
249 _code_roots.code_blobs_do(adjust_code_closure, worker_id);
250 _thread_roots.oops_do(oops, NULL, worker_id);
251 }
252
253 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
254 ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
255 _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
256 _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
257 _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
258 _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots),
259 _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
260 _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
261 _dedup_roots(ShenandoahPhaseTimings::heap_iteration_roots),
262 _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
263 }
264
265 void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
266 assert(Thread::current()->is_VM_thread(), "Only by VM thread");
267 // Must use _claim_none to avoid interfering with concurrent CLDG iteration
268 CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
269 MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
270 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
271 AlwaysTrueClosure always_true;
272
273 ResourceMark rm;
274
275 // Process serial-claiming roots first
276 _serial_roots.oops_do(oops, 0);
277 _serial_weak_roots.weak_oops_do(oops, 0);
278
279 // Process light-weight/limited parallel roots then
280 _vm_roots.oops_do(oops, 0);
281 _weak_roots.oops_do<OopClosure>(oops, 0);
282 _dedup_roots.oops_do(&always_true, oops, 0);
283
284 // Process heavy-weight/fully parallel roots the last
285 _cld_roots.cld_do(&clds, 0);
286 _code_roots.code_blobs_do(&code, 0);
287 _thread_roots.threads_do(&tc_cl, 0);
288 }
|
144 void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
145 if (ShenandoahStringDedup::is_enabled()) {
146 ShenandoahStringDedup::parallel_oops_do(_phase, is_alive, keep_alive, worker_id);
147 }
148 }
149
150 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
151 _heap(ShenandoahHeap::heap()),
152 _phase(phase),
153 _worker_phase(phase) {
154 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
155 }
156
157 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
158 ShenandoahPhaseTimings::Phase phase,
159 bool stw_roots_processing,
160 bool stw_class_unloading) :
161 ShenandoahRootProcessor(phase),
162 _serial_roots(phase),
163 _vm_roots(phase),
164 _cld_roots(phase, n_workers),
165 _thread_roots(phase, n_workers > 1),
166 _serial_weak_roots(phase),
167 _weak_roots(phase),
168 _dedup_roots(phase),
169 _code_roots(phase),
170 _stw_roots_processing(stw_roots_processing),
171 _stw_class_unloading(stw_class_unloading) {
172 }
173
174 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
175 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
176 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
177 CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
178 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
179 static_cast<CodeBlobToOopClosure*>(&blobsCl);
180 AlwaysTrueClosure always_true;
181
182 // Process serial-claiming roots first
183 _serial_roots.oops_do(oops, worker_id);
184 _serial_weak_roots.weak_oops_do(oops, worker_id);
185
186 // Process light-weight/limited parallel roots then
187 if (_stw_roots_processing) {
188 _vm_roots.oops_do<OopClosure>(oops, worker_id);
189 _weak_roots.oops_do<OopClosure>(oops, worker_id);
190 }
191 _dedup_roots.oops_do(&always_true, oops, worker_id);
192 if (_stw_class_unloading) {
193 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
194 _cld_roots.cld_do(&clds, worker_id);
195 }
196
197 // Process heavy-weight/fully parallel roots the last
198 if (_stw_class_unloading) {
199 _code_roots.code_blobs_do(codes_cl, worker_id);
200 _thread_roots.oops_do(oops, NULL, worker_id);
201 } else {
202 _thread_roots.oops_do(oops, codes_cl, worker_id);
203 }
204 }
205
206 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
207 ShenandoahRootProcessor(phase),
208 _serial_roots(phase),
209 _vm_roots(phase),
210 _cld_roots(phase, n_workers),
211 _thread_roots(phase, n_workers > 1),
212 _serial_weak_roots(phase),
213 _weak_roots(phase),
214 _dedup_roots(phase),
215 _code_roots(phase) {
216 }
217
218 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
219 ShenandoahRootProcessor(phase),
220 _serial_roots(phase),
221 _vm_roots(phase),
222 _cld_roots(phase, n_workers),
223 _thread_roots(phase, n_workers > 1),
224 _serial_weak_roots(phase),
225 _weak_roots(phase),
226 _dedup_roots(phase),
227 _code_roots(phase) {
228 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
229 }
230
231 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
232 CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
233 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
234 CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
235 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
236 static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
237 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
238 AlwaysTrueClosure always_true;
239
240 // Process serial-claiming roots first
241 _serial_roots.oops_do(oops, worker_id);
242 _serial_weak_roots.weak_oops_do(oops, worker_id);
243
244 // Process light-weight/limited parallel roots then
245 _vm_roots.oops_do(oops, worker_id);
246 _weak_roots.oops_do<OopClosure>(oops, worker_id);
247 _dedup_roots.oops_do(&always_true, oops, worker_id);
248 _cld_roots.cld_do(&adjust_cld_closure, worker_id);
249
250 // Process heavy-weight/fully parallel roots the last
251 _code_roots.code_blobs_do(adjust_code_closure, worker_id);
252 _thread_roots.oops_do(oops, NULL, worker_id);
253 }
254
255 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
256 ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
257 _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
258 _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
259 _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
260 _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, 1),
261 _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
262 _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
263 _dedup_roots(ShenandoahPhaseTimings::heap_iteration_roots),
264 _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
265 }
266
267 void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
268 assert(Thread::current()->is_VM_thread(), "Only by VM thread");
269 // Must use _claim_none to avoid interfering with concurrent CLDG iteration
270 CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
271 MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
272 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
273 AlwaysTrueClosure always_true;
274
275 ResourceMark rm;
276
277 // Process serial-claiming roots first
278 _serial_roots.oops_do(oops, 0);
279 _serial_weak_roots.weak_oops_do(oops, 0);
280
281 // Process light-weight/limited parallel roots then
282 _vm_roots.oops_do(oops, 0);
283 _weak_roots.oops_do<OopClosure>(oops, 0);
284 _dedup_roots.oops_do(&always_true, oops, 0);
285 _cld_roots.cld_do(&clds, 0);
286
287 // Process heavy-weight/fully parallel roots the last
288 _code_roots.code_blobs_do(&code, 0);
289 _thread_roots.threads_do(&tc_cl, 0);
290 }
|