185 }
186
187 ShenandoahCodeCacheRoots::~ShenandoahCodeCacheRoots() {
188 nmethod::oops_do_marking_epilogue();
189 }
190
191 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
192 _heap(ShenandoahHeap::heap()),
193 _phase(phase),
194 _worker_phase(phase) {
195 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
196 }
197
198 ShenandoahRootScanner::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
199 ShenandoahRootProcessor(phase),
200 _serial_roots(phase),
201 _thread_roots(phase, n_workers > 1),
202 _code_roots(phase),
203 _vm_roots(phase),
204 _dedup_roots(phase),
205 _cld_roots(phase) {
206 }
207
208 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops) {
209 CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
210 MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
211 roots_do(worker_id, oops, &clds_cl, &blobs_cl);
212 }
213
214 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops) {
215 CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
216 MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
217 strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
218 }
219
220 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
221 assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
222 !ShenandoahHeap::heap()->unload_classes(),
223 "Expect class unloading when Shenandoah cycle is running");
224 assert(clds != NULL, "Only possible with CLD closure");
225
226 AlwaysTrueClosure always_true;
227 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
228
229 ResourceMark rm;
230
231 // Process serial-claiming roots first
232 _serial_roots.oops_do(oops, worker_id);
233
234 // Process light-weight/limited parallel roots then
235 _vm_roots.oops_do(oops, worker_id);
236 _dedup_roots.oops_do(&always_true, oops, worker_id);
237
238 // Process heavy-weight/fully parallel roots the last
239 _cld_roots.cld_do(clds, worker_id);
240 _thread_roots.threads_do(&tc_cl, worker_id);
241 }
242
243 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
244 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
245 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
246
247 ResourceMark rm;
248
249 // Process serial-claiming roots first
250 _serial_roots.oops_do(oops, worker_id);
251
252 // Process light-weight/limited parallel roots then
253 _vm_roots.oops_do(oops, worker_id);
254
255 // Process heavy-weight/fully parallel roots the last
256 _cld_roots.always_strong_cld_do(clds, worker_id);
257 _thread_roots.threads_do(&tc_cl, worker_id);
258 }
259
260 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
261 ShenandoahPhaseTimings::Phase phase,
262 bool stw_roots_processing,
263 bool stw_class_unloading) :
264 ShenandoahRootProcessor(phase),
265 _serial_roots(phase),
266 _vm_roots(phase),
267 _cld_roots(phase),
268 _thread_roots(phase, n_workers > 1),
269 _serial_weak_roots(phase),
270 _weak_roots(phase),
271 _dedup_roots(phase),
272 _code_roots(phase),
273 _stw_roots_processing(stw_roots_processing),
274 _stw_class_unloading(stw_class_unloading) {
275 }
276
277 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
278 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
279 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
280 CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
281 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
282 static_cast<CodeBlobToOopClosure*>(&blobsCl);
283 AlwaysTrueClosure always_true;
284
285 // Process serial-claiming roots first
286 _serial_roots.oops_do(oops, worker_id);
287 _serial_weak_roots.weak_oops_do(oops, worker_id);
288
289 // Process light-weight/limited parallel roots then
290 if (_stw_roots_processing) {
291 _vm_roots.oops_do<OopClosure>(oops, worker_id);
292 _weak_roots.oops_do<OopClosure>(oops, worker_id);
293 _dedup_roots.oops_do(&always_true, oops, worker_id);
294 }
295
296 // Process heavy-weight/fully parallel roots the last
297 if (_stw_class_unloading) {
298 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
299 _cld_roots.cld_do(&clds, worker_id);
300 _code_roots.code_blobs_do(codes_cl, worker_id);
301 _thread_roots.oops_do(oops, NULL, worker_id);
302 } else {
303 _thread_roots.oops_do(oops, codes_cl, worker_id);
304 }
305 }
306
307 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
308 ShenandoahRootProcessor(phase),
309 _serial_roots(phase),
310 _vm_roots(phase),
311 _cld_roots(phase),
312 _thread_roots(phase, n_workers > 1),
313 _serial_weak_roots(phase),
314 _weak_roots(phase),
315 _dedup_roots(phase),
316 _code_roots(phase) {
317 }
318
319 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
320 ShenandoahRootProcessor(phase),
321 _serial_roots(phase),
322 _vm_roots(phase),
323 _cld_roots(phase),
324 _thread_roots(phase, n_workers > 1),
325 _serial_weak_roots(phase),
326 _weak_roots(phase),
327 _dedup_roots(phase),
328 _code_roots(phase) {
329 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
330 }
331
332 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
333 CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
334 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
335 CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
336 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
337 static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
338 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
339 AlwaysTrueClosure always_true;
340
341 // Process serial-claiming roots first
342 _serial_roots.oops_do(oops, worker_id);
343 _serial_weak_roots.weak_oops_do(oops, worker_id);
344
345 // Process light-weight/limited parallel roots then
346 _vm_roots.oops_do(oops, worker_id);
347 _weak_roots.oops_do<OopClosure>(oops, worker_id);
348 _dedup_roots.oops_do(&always_true, oops, worker_id);
349
350 // Process heavy-weight/fully parallel roots the last
351 _cld_roots.cld_do(&adjust_cld_closure, worker_id);
352 _code_roots.code_blobs_do(adjust_code_closure, worker_id);
353 _thread_roots.oops_do(oops, NULL, worker_id);
354 }
355
356 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
357 ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
358 _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
359 _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
360 _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
361 _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots),
362 _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
363 _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
364 _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
365 }
366
367 void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
368 assert(Thread::current()->is_VM_thread(), "Only by VM thread");
369 // Must use _claim_none to avoid interfering with concurrent CLDG iteration
370 CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
371 MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
372 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
373 AlwaysTrueClosure always_true;
374
375 ResourceMark rm;
376
377 // Process serial-claiming roots first
378 _serial_roots.oops_do(oops, 0);
379 _serial_weak_roots.weak_oops_do(oops, 0);
380
381 // Process light-weight/limited parallel roots then
382 _vm_roots.oops_do(oops, 0);
383 _weak_roots.oops_do<OopClosure>(oops, 0);
384 _dedup_roots.oops_do(&always_true, oops, 0);
385
386 // Process heavy-weight/fully parallel roots the last
387 _cld_roots.cld_do(&clds, 0);
388 _code_roots.code_blobs_do(&code, 0);
389 _thread_roots.threads_do(&tc_cl, 0);
390 }
|
185 }
186
187 ShenandoahCodeCacheRoots::~ShenandoahCodeCacheRoots() {
188 nmethod::oops_do_marking_epilogue();
189 }
190
191 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
192 _heap(ShenandoahHeap::heap()),
193 _phase(phase),
194 _worker_phase(phase) {
195 assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
196 }
197
198 ShenandoahRootScanner::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
199 ShenandoahRootProcessor(phase),
200 _serial_roots(phase),
201 _thread_roots(phase, n_workers > 1),
202 _code_roots(phase),
203 _vm_roots(phase),
204 _dedup_roots(phase),
205 _cld_roots(phase, n_workers) {
206 }
207
208 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops) {
209 CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
210 MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
211 roots_do(worker_id, oops, &clds_cl, &blobs_cl);
212 }
213
214 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops) {
215 CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
216 MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
217 strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
218 }
219
220 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
221 assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
222 !ShenandoahHeap::heap()->unload_classes(),
223 "Expect class unloading when Shenandoah cycle is running");
224 assert(clds != NULL, "Only possible with CLD closure");
225
226 AlwaysTrueClosure always_true;
227 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
228
229 ResourceMark rm;
230
231 // Process serial-claiming roots first
232 _serial_roots.oops_do(oops, worker_id);
233
234 // Process light-weight/limited parallel roots then
235 _vm_roots.oops_do(oops, worker_id);
236 _dedup_roots.oops_do(&always_true, oops, worker_id);
237 _cld_roots.cld_do(clds, worker_id);
238
239 // Process heavy-weight/fully parallel roots the last
240 _thread_roots.threads_do(&tc_cl, worker_id);
241 }
242
243 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
244 assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
245 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
246
247 ResourceMark rm;
248
249 // Process serial-claiming roots first
250 _serial_roots.oops_do(oops, worker_id);
251
252 // Process light-weight/limited parallel roots then
253 _vm_roots.oops_do(oops, worker_id);
254 _cld_roots.always_strong_cld_do(clds, worker_id);
255
256 // Process heavy-weight/fully parallel roots the last
257 _thread_roots.threads_do(&tc_cl, worker_id);
258 }
259
260 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
261 ShenandoahPhaseTimings::Phase phase,
262 bool stw_roots_processing,
263 bool stw_class_unloading) :
264 ShenandoahRootProcessor(phase),
265 _serial_roots(phase),
266 _vm_roots(phase),
267 _cld_roots(phase, n_workers),
268 _thread_roots(phase, n_workers > 1),
269 _serial_weak_roots(phase),
270 _weak_roots(phase),
271 _dedup_roots(phase),
272 _code_roots(phase),
273 _stw_roots_processing(stw_roots_processing),
274 _stw_class_unloading(stw_class_unloading) {
275 }
276
277 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
278 MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
279 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
280 CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
281 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
282 static_cast<CodeBlobToOopClosure*>(&blobsCl);
283 AlwaysTrueClosure always_true;
284
285 // Process serial-claiming roots first
286 _serial_roots.oops_do(oops, worker_id);
287 _serial_weak_roots.weak_oops_do(oops, worker_id);
288
289 // Process light-weight/limited parallel roots then
290 if (_stw_roots_processing) {
291 _vm_roots.oops_do<OopClosure>(oops, worker_id);
292 _weak_roots.oops_do<OopClosure>(oops, worker_id);
293 _dedup_roots.oops_do(&always_true, oops, worker_id);
294 }
295 if (_stw_class_unloading) {
296 CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
297 _cld_roots.cld_do(&clds, worker_id);
298 }
299
300 // Process heavy-weight/fully parallel roots the last
301 if (_stw_class_unloading) {
302 _code_roots.code_blobs_do(codes_cl, worker_id);
303 _thread_roots.oops_do(oops, NULL, worker_id);
304 } else {
305 _thread_roots.oops_do(oops, codes_cl, worker_id);
306 }
307 }
308
309 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
310 ShenandoahRootProcessor(phase),
311 _serial_roots(phase),
312 _vm_roots(phase),
313 _cld_roots(phase, n_workers),
314 _thread_roots(phase, n_workers > 1),
315 _serial_weak_roots(phase),
316 _weak_roots(phase),
317 _dedup_roots(phase),
318 _code_roots(phase) {
319 }
320
321 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
322 ShenandoahRootProcessor(phase),
323 _serial_roots(phase),
324 _vm_roots(phase),
325 _cld_roots(phase, n_workers),
326 _thread_roots(phase, n_workers > 1),
327 _serial_weak_roots(phase),
328 _weak_roots(phase),
329 _dedup_roots(phase),
330 _code_roots(phase) {
331 assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
332 }
333
334 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
335 CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
336 ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
337 CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
338 static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
339 static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
340 CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
341 AlwaysTrueClosure always_true;
342
343 // Process serial-claiming roots first
344 _serial_roots.oops_do(oops, worker_id);
345 _serial_weak_roots.weak_oops_do(oops, worker_id);
346
347 // Process light-weight/limited parallel roots then
348 _vm_roots.oops_do(oops, worker_id);
349 _weak_roots.oops_do<OopClosure>(oops, worker_id);
350 _dedup_roots.oops_do(&always_true, oops, worker_id);
351 _cld_roots.cld_do(&adjust_cld_closure, worker_id);
352
353 // Process heavy-weight/fully parallel roots the last
354 _code_roots.code_blobs_do(adjust_code_closure, worker_id);
355 _thread_roots.oops_do(oops, NULL, worker_id);
356 }
357
358 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
359 ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
360 _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
361 _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
362 _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
363 _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, 1),
364 _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
365 _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
366 _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
367 }
368
369 void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
370 assert(Thread::current()->is_VM_thread(), "Only by VM thread");
371 // Must use _claim_none to avoid interfering with concurrent CLDG iteration
372 CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
373 MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
374 ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
375 AlwaysTrueClosure always_true;
376
377 ResourceMark rm;
378
379 // Process serial-claiming roots first
380 _serial_roots.oops_do(oops, 0);
381 _serial_weak_roots.weak_oops_do(oops, 0);
382
383 // Process light-weight/limited parallel roots then
384 _vm_roots.oops_do(oops, 0);
385 _weak_roots.oops_do<OopClosure>(oops, 0);
386 _dedup_roots.oops_do(&always_true, oops, 0);
387 _cld_roots.cld_do(&clds, 0);
388
389 // Process heavy-weight/fully parallel roots the last
390 _code_roots.code_blobs_do(&code, 0);
391 _thread_roots.threads_do(&tc_cl, 0);
392 }
|