407 heap->entry_strong_roots();
408 }
409
410 // Continue the cycle with evacuation and optional update-refs.
411 // This may be skipped if there is nothing to evacuate.
412 // If so, evac_in_progress would be unset by collection set preparation code.
413 if (heap->is_evacuation_in_progress()) {
414 // Concurrently evacuate
415 heap->entry_evac();
416 if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_evac)) return;
417
418 // Perform update-refs phase.
419 heap->vmop_entry_init_updaterefs();
420 heap->entry_updaterefs();
421 if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_updaterefs)) return;
422
423 heap->vmop_entry_final_updaterefs();
424
425 // Update references freed up collection set, kick the cleanup to reclaim the space.
426 heap->entry_cleanup_complete();
427 }
428
429 // Cycle is complete
430 heap->heuristics()->record_success_concurrent();
431 heap->shenandoah_policy()->record_success_concurrent();
432 }
433
434 bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahHeap::ShenandoahDegenPoint point) {
435 ShenandoahHeap* heap = ShenandoahHeap::heap();
436 if (heap->cancelled_gc()) {
437 assert (is_alloc_failure_gc() || in_graceful_shutdown(), "Cancel GC either for alloc failure GC, or gracefully exiting");
438 if (!in_graceful_shutdown()) {
439 assert (_degen_point == ShenandoahHeap::_degenerated_outside_cycle,
440 "Should not be set yet: %s", ShenandoahHeap::degen_point_to_string(_degen_point));
441 _degen_point = point;
442 }
443 return true;
444 }
445 return false;
446 }
|
407 heap->entry_strong_roots();
408 }
409
410 // Continue the cycle with evacuation and optional update-refs.
411 // This may be skipped if there is nothing to evacuate.
412 // If so, evac_in_progress would be unset by collection set preparation code.
413 if (heap->is_evacuation_in_progress()) {
414 // Concurrently evacuate
415 heap->entry_evac();
416 if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_evac)) return;
417
418 // Perform update-refs phase.
419 heap->vmop_entry_init_updaterefs();
420 heap->entry_updaterefs();
421 if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_updaterefs)) return;
422
423 heap->vmop_entry_final_updaterefs();
424
425 // Update references freed up collection set, kick the cleanup to reclaim the space.
426 heap->entry_cleanup_complete();
427 } else {
428 // Concurrent weak/strong root flags are unset concurrently. We depend on updateref GC safepoints
429 // to ensure the changes are visible to all mutators before gc cycle is completed.
430 // In case of no evacuation, updateref GC safepoints are skipped. Therefore, we will need
431 // to perform thread handshake to ensure their consistences.
432 heap->entry_rendezvous_roots();
433 }
434
435 // Cycle is complete
436 heap->heuristics()->record_success_concurrent();
437 heap->shenandoah_policy()->record_success_concurrent();
438 }
439
440 bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahHeap::ShenandoahDegenPoint point) {
441 ShenandoahHeap* heap = ShenandoahHeap::heap();
442 if (heap->cancelled_gc()) {
443 assert (is_alloc_failure_gc() || in_graceful_shutdown(), "Cancel GC either for alloc failure GC, or gracefully exiting");
444 if (!in_graceful_shutdown()) {
445 assert (_degen_point == ShenandoahHeap::_degenerated_outside_cycle,
446 "Should not be set yet: %s", ShenandoahHeap::degen_point_to_string(_degen_point));
447 _degen_point = point;
448 }
449 return true;
450 }
451 return false;
452 }
|