< prev index next > src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp
Print this page
#include "gc/shenandoah/shenandoahConcurrentGC.hpp"
#include "gc/shenandoah/shenandoahControlThread.hpp"
#include "gc/shenandoah/shenandoahDegeneratedGC.hpp"
#include "gc/shenandoah/shenandoahFreeSet.hpp"
#include "gc/shenandoah/shenandoahFullGC.hpp"
+ #include "gc/shenandoah/shenandoahGeneration.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
#include "gc/shenandoah/shenandoahPacer.inline.hpp"
#include "gc/shenandoah/shenandoahUtils.hpp"
#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
GCCause::Cause cause = GCCause::_last_gc_cause;
ShenandoahGC::ShenandoahDegenPoint degen_point = ShenandoahGC::_degenerated_unset;
if (alloc_failure_pending) {
// Allocation failure takes precedence: we have to deal with it first thing
! log_info(gc)("Trigger: Handle Allocation Failure");
cause = GCCause::_allocation_failure;
// Consume the degen point, and seed it with default value
degen_point = _degen_point;
GCCause::Cause cause = GCCause::_last_gc_cause;
ShenandoahGC::ShenandoahDegenPoint degen_point = ShenandoahGC::_degenerated_unset;
if (alloc_failure_pending) {
// Allocation failure takes precedence: we have to deal with it first thing
! heuristics->log_trigger("Handle Allocation Failure");
cause = GCCause::_allocation_failure;
// Consume the degen point, and seed it with default value
degen_point = _degen_point;
policy->record_alloc_failure_to_full();
mode = stw_full;
}
} else if (is_gc_requested) {
cause = requested_gc_cause;
! log_info(gc)("Trigger: GC request (%s)", GCCause::to_string(cause));
heuristics->record_requested_gc();
if (ShenandoahCollectorPolicy::should_run_full_gc(cause)) {
mode = stw_full;
} else {
policy->record_alloc_failure_to_full();
mode = stw_full;
}
} else if (is_gc_requested) {
cause = requested_gc_cause;
! heuristics->log_trigger("GC request (%s)", GCCause::to_string(cause));
heuristics->record_requested_gc();
if (ShenandoahCollectorPolicy::should_run_full_gc(cause)) {
mode = stw_full;
} else {
//
ShenandoahHeap* heap = ShenandoahHeap::heap();
if (check_cancellation_or_degen(ShenandoahGC::_degenerated_outside_cycle)) return;
GCIdMark gc_id_mark;
! ShenandoahGCSession session(cause);
TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
! ShenandoahConcurrentGC gc;
if (gc.collect(cause)) {
// Cycle is complete. There were no failed allocation requests and no degeneration, so count this as good progress.
heap->notify_gc_progress();
! heap->heuristics()->record_success_concurrent();
! heap->shenandoah_policy()->record_success_concurrent(gc.abbreviated());
} else {
assert(heap->cancelled_gc(), "Must have been cancelled");
check_cancellation_or_degen(gc.degen_point());
}
}
bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point) {
ShenandoahHeap* heap = ShenandoahHeap::heap();
//
ShenandoahHeap* heap = ShenandoahHeap::heap();
if (check_cancellation_or_degen(ShenandoahGC::_degenerated_outside_cycle)) return;
GCIdMark gc_id_mark;
! ShenandoahGCSession session(cause, heap->global_generation());
TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters());
! ShenandoahConcurrentGC gc(heap->global_generation(), false);
if (gc.collect(cause)) {
// Cycle is complete. There were no failed allocation requests and no degeneration, so count this as good progress.
heap->notify_gc_progress();
! heap->global_generation()->heuristics()->record_success_concurrent();
! heap->shenandoah_policy()->record_success_concurrent(false, gc.abbreviated());
+ heap->log_heap_status("At end of GC");
} else {
assert(heap->cancelled_gc(), "Must have been cancelled");
check_cancellation_or_degen(gc.degen_point());
+ heap->log_heap_status("At end of cancelled GC");
}
}
bool ShenandoahControlThread::check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point) {
ShenandoahHeap* heap = ShenandoahHeap::heap();
void ShenandoahControlThread::stop_service() {
// Nothing to do here.
}
void ShenandoahControlThread::service_stw_full_cycle(GCCause::Cause cause) {
GCIdMark gc_id_mark;
! ShenandoahGCSession session(cause);
ShenandoahFullGC gc;
gc.collect(cause);
}
void ShenandoahControlThread::service_stw_degenerated_cycle(GCCause::Cause cause, ShenandoahGC::ShenandoahDegenPoint point) {
assert (point != ShenandoahGC::_degenerated_unset, "Degenerated point should be set");
!
GCIdMark gc_id_mark;
! ShenandoahGCSession session(cause);
! ShenandoahDegenGC gc(point);
gc.collect(cause);
}
void ShenandoahControlThread::request_gc(GCCause::Cause cause) {
if (ShenandoahCollectorPolicy::should_handle_requested_gc(cause)) {
void ShenandoahControlThread::stop_service() {
// Nothing to do here.
}
void ShenandoahControlThread::service_stw_full_cycle(GCCause::Cause cause) {
+ ShenandoahHeap* const heap = ShenandoahHeap::heap();
GCIdMark gc_id_mark;
! ShenandoahGCSession session(cause, heap->global_generation());
ShenandoahFullGC gc;
gc.collect(cause);
}
void ShenandoahControlThread::service_stw_degenerated_cycle(GCCause::Cause cause, ShenandoahGC::ShenandoahDegenPoint point) {
assert (point != ShenandoahGC::_degenerated_unset, "Degenerated point should be set");
! ShenandoahHeap* const heap = ShenandoahHeap::heap();
GCIdMark gc_id_mark;
! ShenandoahGCSession session(cause, heap->global_generation());
! ShenandoahDegenGC gc(point, heap->global_generation());
gc.collect(cause);
}
void ShenandoahControlThread::request_gc(GCCause::Cause cause) {
if (ShenandoahCollectorPolicy::should_handle_requested_gc(cause)) {
< prev index next >