Skip to content
Permalink
Browse files
Merge
  • Loading branch information
Andrew Haley committed Mar 11, 2020
2 parents 0992e17 + eb974fa commit 6275aee6905b4f6b1c8ce333c5a76e1e28956f97
@@ -33,10 +33,7 @@
#include "utilities/quickSort.hpp"

ShenandoahAdaptiveHeuristics::ShenandoahAdaptiveHeuristics() :
ShenandoahHeuristics(),
_cycle_gap_history(new TruncatedSeq(5)),
_conc_mark_duration_history(new TruncatedSeq(5)),
_conc_uprefs_duration_history(new TruncatedSeq(5)) {}
ShenandoahHeuristics() {}

ShenandoahAdaptiveHeuristics::~ShenandoahAdaptiveHeuristics() {}

@@ -102,16 +99,6 @@ void ShenandoahAdaptiveHeuristics::choose_collection_set_from_regiondata(Shenand

void ShenandoahAdaptiveHeuristics::record_cycle_start() {
ShenandoahHeuristics::record_cycle_start();
double last_cycle_gap = (_cycle_start - _last_cycle_end);
_cycle_gap_history->add(last_cycle_gap);
}

void ShenandoahAdaptiveHeuristics::record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs) {
if (phase == ShenandoahPhaseTimings::conc_mark) {
_conc_mark_duration_history->add(secs);
} else if (phase == ShenandoahPhaseTimings::conc_update_refs) {
_conc_uprefs_duration_history->add(secs);
} // Else ignore
}

bool ShenandoahAdaptiveHeuristics::should_start_gc() const {
@@ -176,29 +163,6 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() const {
return ShenandoahHeuristics::should_start_gc();
}

bool ShenandoahAdaptiveHeuristics::should_start_update_refs() {
if (! _update_refs_adaptive) {
return _update_refs_early;
}

double cycle_gap_avg = _cycle_gap_history->avg();
double conc_mark_avg = _conc_mark_duration_history->avg();
double conc_uprefs_avg = _conc_uprefs_duration_history->avg();

if (_update_refs_early) {
double threshold = ShenandoahMergeUpdateRefsMinGap / 100.0;
if (conc_mark_avg + conc_uprefs_avg > cycle_gap_avg * threshold) {
_update_refs_early = false;
}
} else {
double threshold = ShenandoahMergeUpdateRefsMaxGap / 100.0;
if (conc_mark_avg + conc_uprefs_avg < cycle_gap_avg * threshold) {
_update_refs_early = true;
}
}
return _update_refs_early;
}

const char* ShenandoahAdaptiveHeuristics::name() {
return "adaptive";
}
@@ -30,11 +30,6 @@
#include "utilities/numberSeq.hpp"

class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics {
private:
TruncatedSeq* _cycle_gap_history;
TruncatedSeq* _conc_mark_duration_history;
TruncatedSeq* _conc_uprefs_duration_history;

public:
ShenandoahAdaptiveHeuristics();

@@ -46,12 +41,8 @@ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics {

void record_cycle_start();

virtual void record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs);

virtual bool should_start_gc() const;

virtual bool should_start_update_refs();

virtual const char* name();

virtual bool is_diagnostic();
@@ -316,19 +316,18 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau
// If second allocation failure happens during Degenerated GC cycle (for example, when GC
// tries to evac something and no memory is available), cycle degrades to Full GC.
//
// There are also two shortcuts through the normal cycle: a) immediate garbage shortcut, when
// There are also a shortcut through the normal cycle: immediate garbage shortcut, when
// heuristics says there are no regions to compact, and all the collection comes from immediately
// reclaimable regions; b) coalesced UR shortcut, when heuristics decides to coalesce UR with the
// mark from the next cycle.
// reclaimable regions.
//
// ................................................................................................
//
// (immediate garbage shortcut) Concurrent GC
// /-------------------------------------------\
// | (coalesced UR) v
// | /----------------------->o
// | | |
// | | v
// | |
// | |
// | |
// | v
// [START] ----> Conc Mark ----o----> Conc Evac --o--> Conc Update-Refs ---o----> [END]
// | | | ^
// | (af) | (af) | (af) |
@@ -392,22 +391,15 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau
heap->entry_evac();
if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_evac)) return;

// Perform update-refs phase, if required. This phase can be skipped if heuristics
// decides to piggy-back the update-refs on the next marking cycle. On either path,
// we need to turn off evacuation: either in init-update-refs, or in final-evac.
if (heap->heuristics()->should_start_update_refs()) {
heap->vmop_entry_init_updaterefs();
heap->entry_updaterefs();
if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_updaterefs)) return;
// Perform update-refs phase.
heap->vmop_entry_init_updaterefs();
heap->entry_updaterefs();
if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_updaterefs)) return;

heap->vmop_entry_final_updaterefs();
heap->vmop_entry_final_updaterefs();

// Update references freed up collection set, kick the cleanup to reclaim the space.
heap->entry_cleanup();

} else {
heap->vmop_entry_final_evac();
}
// Update references freed up collection set, kick the cleanup to reclaim the space.
heap->entry_cleanup();
}

// Cycle is complete
@@ -1586,25 +1586,6 @@ void ShenandoahHeap::op_final_mark() {
}
}

void ShenandoahHeap::op_final_evac() {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should be at safepoint");

set_evacuation_in_progress(false);

{
ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_evac_retire_gclabs);
retire_and_reset_gclabs();
}

if (ShenandoahVerify) {
verifier()->verify_after_evacuation();
}

if (VerifyAfterGC) {
Universe::verify();
}
}

void ShenandoahHeap::op_conc_evac() {
ShenandoahEvacuationTask task(this, _collection_set, true);
workers()->run_task(&task);
@@ -2647,15 +2628,6 @@ void ShenandoahHeap::vmop_entry_final_mark() {
VMThread::execute(&op); // jump to entry_final_mark under safepoint
}

void ShenandoahHeap::vmop_entry_final_evac() {
TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross);
ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_evac_gross);

VM_ShenandoahFinalEvac op;
VMThread::execute(&op); // jump to entry_final_evac under safepoint
}

void ShenandoahHeap::vmop_entry_init_updaterefs() {
TraceCollectorStats tcs(monitoring_support()->stw_collection_counters());
ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross);
@@ -2743,16 +2715,6 @@ void ShenandoahHeap::entry_final_mark() {
op_final_mark();
}

void ShenandoahHeap::entry_final_evac() {
ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause);
ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_evac);
static const char* msg = "Pause Final Evac";
GCTraceTime(Info, gc) time(msg, gc_timer());
EventMark em("%s", msg);

op_final_evac();
}

void ShenandoahHeap::entry_init_updaterefs() {
ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause);
ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs);
@@ -3050,20 +3012,13 @@ void ShenandoahHeap::deduplicate_string(oop str) {
}

const char* ShenandoahHeap::init_mark_event_message() const {
bool update_refs = has_forwarded_objects();
assert(!has_forwarded_objects(), "Should not have forwarded objects here");

bool proc_refs = process_references();
bool unload_cls = unload_classes();

if (update_refs && proc_refs && unload_cls) {
return "Pause Init Mark (update refs) (process weakrefs) (unload classes)";
} else if (update_refs && proc_refs) {
return "Pause Init Mark (update refs) (process weakrefs)";
} else if (update_refs && unload_cls) {
return "Pause Init Mark (update refs) (unload classes)";
} else if (proc_refs && unload_cls) {
if (proc_refs && unload_cls) {
return "Pause Init Mark (process weakrefs) (unload classes)";
} else if (update_refs) {
return "Pause Init Mark (update refs)";
} else if (proc_refs) {
return "Pause Init Mark (process weakrefs)";
} else if (unload_cls) {
@@ -3074,20 +3029,13 @@ const char* ShenandoahHeap::init_mark_event_message() const {
}

const char* ShenandoahHeap::final_mark_event_message() const {
bool update_refs = has_forwarded_objects();
assert(!has_forwarded_objects(), "Should not have forwarded objects here");

bool proc_refs = process_references();
bool unload_cls = unload_classes();

if (update_refs && proc_refs && unload_cls) {
return "Pause Final Mark (update refs) (process weakrefs) (unload classes)";
} else if (update_refs && proc_refs) {
return "Pause Final Mark (update refs) (process weakrefs)";
} else if (update_refs && unload_cls) {
return "Pause Final Mark (update refs) (unload classes)";
} else if (proc_refs && unload_cls) {
if (proc_refs && unload_cls) {
return "Pause Final Mark (process weakrefs) (unload classes)";
} else if (update_refs) {
return "Pause Final Mark (update refs)";
} else if (proc_refs) {
return "Pause Final Mark (process weakrefs)";
} else if (unload_cls) {
@@ -3098,20 +3046,13 @@ const char* ShenandoahHeap::final_mark_event_message() const {
}

const char* ShenandoahHeap::conc_mark_event_message() const {
bool update_refs = has_forwarded_objects();
assert(!has_forwarded_objects(), "Should not have forwarded objects here");

bool proc_refs = process_references();
bool unload_cls = unload_classes();

if (update_refs && proc_refs && unload_cls) {
return "Concurrent marking (update refs) (process weakrefs) (unload classes)";
} else if (update_refs && proc_refs) {
return "Concurrent marking (update refs) (process weakrefs)";
} else if (update_refs && unload_cls) {
return "Concurrent marking (update refs) (unload classes)";
} else if (proc_refs && unload_cls) {
if (proc_refs && unload_cls) {
return "Concurrent marking (process weakrefs) (unload classes)";
} else if (update_refs) {
return "Concurrent marking (update refs)";
} else if (proc_refs) {
return "Concurrent marking (process weakrefs)";
} else if (unload_cls) {
@@ -376,7 +376,6 @@ class ShenandoahHeap : public CollectedHeap {
// call the entry method below
void vmop_entry_init_mark();
void vmop_entry_final_mark();
void vmop_entry_final_evac();
void vmop_entry_init_updaterefs();
void vmop_entry_final_updaterefs();
void vmop_entry_init_traversal();
@@ -388,7 +387,6 @@ class ShenandoahHeap : public CollectedHeap {
// and workers for net VM operation
void entry_init_mark();
void entry_final_mark();
void entry_final_evac();
void entry_init_updaterefs();
void entry_final_updaterefs();
void entry_init_traversal();
@@ -412,7 +410,6 @@ class ShenandoahHeap : public CollectedHeap {
// Actual work for the phases
void op_init_mark();
void op_final_mark();
void op_final_evac();
void op_init_updaterefs();
void op_final_updaterefs();
void op_init_traversal();
@@ -63,8 +63,6 @@ int ShenandoahHeuristics::compare_by_alloc_seq_descending(RegionData a, RegionDa
}

ShenandoahHeuristics::ShenandoahHeuristics() :
_update_refs_early(false),
_update_refs_adaptive(false),
_region_data(NULL),
_region_data_size(0),
_degenerated_cycles_in_a_row(0),
@@ -77,19 +75,6 @@ ShenandoahHeuristics::ShenandoahHeuristics() :
_gc_time_history(new TruncatedSeq(5)),
_metaspace_oom()
{
if (strcmp(ShenandoahUpdateRefsEarly, "on") == 0 ||
strcmp(ShenandoahUpdateRefsEarly, "true") == 0 ) {
_update_refs_early = true;
} else if (strcmp(ShenandoahUpdateRefsEarly, "off") == 0 ||
strcmp(ShenandoahUpdateRefsEarly, "false") == 0 ) {
_update_refs_early = false;
} else if (strcmp(ShenandoahUpdateRefsEarly, "adaptive") == 0) {
_update_refs_adaptive = true;
_update_refs_early = true;
} else {
vm_exit_during_initialization("Unknown -XX:ShenandoahUpdateRefsEarly option: %s", ShenandoahUpdateRefsEarly);
}

// No unloading during concurrent mark? Communicate that to heuristics
if (!ClassUnloadingWithConcurrentMark) {
FLAG_SET_DEFAULT(ShenandoahUnloadClassesFrequency, 0);
@@ -229,14 +214,6 @@ void ShenandoahHeuristics::record_cycle_end() {
_last_cycle_end = os::elapsedTime();
}

void ShenandoahHeuristics::record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs) {
// Do nothing
}

bool ShenandoahHeuristics::should_start_update_refs() {
return _update_refs_early;
}

bool ShenandoahHeuristics::should_start_gc() const {
// Perform GC to cleanup metaspace
if (has_metaspace_oom()) {
@@ -78,9 +78,6 @@ class ShenandoahHeuristics : public CHeapObj<mtGC> {
uint64_t _seqnum_last_alloc;
} RegionData;

bool _update_refs_early;
bool _update_refs_adaptive;

RegionData* _region_data;
size_t _region_data_size;

@@ -128,12 +125,8 @@ class ShenandoahHeuristics : public CHeapObj<mtGC> {

virtual void record_cycle_end();

virtual void record_phase_time(ShenandoahPhaseTimings::Phase phase, double secs);

virtual bool should_start_gc() const;

virtual bool should_start_update_refs();

virtual bool should_degenerate_cycle();

virtual void record_success_concurrent();
@@ -59,7 +59,6 @@ void ShenandoahPhaseTimings::record_phase_time(Phase phase, double time) {
if (!_policy->is_at_shutdown()) {
_timing_data[phase].add(time);
}
ShenandoahHeap::heap()->heuristics()->record_phase_time(phase, time);
}

void ShenandoahPhaseTimings::record_workers_start(Phase phase) {
@@ -86,10 +86,6 @@ class outputStream;
f(init_evac, " Initial Evacuation") \
SHENANDOAH_GC_PAR_PHASE_DO(evac_, " E: ", f) \
\
f(final_evac_gross, "Pause Final Evac (G)") \
f(final_evac, "Pause Final Evac (N)") \
f(final_evac_retire_gclabs, " Retire GCLABs") \
\
f(init_update_refs_gross, "Pause Init Update Refs (G)") \
f(init_update_refs, "Pause Init Update Refs (N)") \
f(init_update_refs_retire_gclabs, " Retire GCLABs") \
@@ -108,7 +108,6 @@ class ShenandoahSafepoint : public AllStatic {
VM_Operation::VMOp_Type type = vm_op->type();
return type == VM_Operation::VMOp_ShenandoahInitMark ||
type == VM_Operation::VMOp_ShenandoahFinalMarkStartEvac ||
type == VM_Operation::VMOp_ShenandoahFinalEvac ||
type == VM_Operation::VMOp_ShenandoahInitTraversalGC ||
type == VM_Operation::VMOp_ShenandoahFinalTraversalGC ||
type == VM_Operation::VMOp_ShenandoahInitUpdateRefs ||

0 comments on commit 6275aee

Please sign in to comment.