8368499: GenShen: Do not collect age census during evac when adaptive tenuring is disabled

Reviewed-by: kdnilsen, ysr
This commit is contained in:
William Kemper 2025-09-25 15:37:02 +00:00
parent 569e78080b
commit 8ca1feaf7e
11 changed files with 113 additions and 195 deletions

View File

@ -43,7 +43,7 @@ ShenandoahAgeCensus::ShenandoahAgeCensus(uint max_workers)
ShenandoahGenerationalMinTenuringAge, ShenandoahGenerationalMaxTenuringAge));
}
_global_age_table = NEW_C_HEAP_ARRAY(AgeTable*, MAX_SNAPSHOTS, mtGC);
_global_age_tables = NEW_C_HEAP_ARRAY(AgeTable*, MAX_SNAPSHOTS, mtGC);
CENSUS_NOISE(_global_noise = NEW_C_HEAP_ARRAY(ShenandoahNoiseStats, MAX_SNAPSHOTS, mtGC);)
_tenuring_threshold = NEW_C_HEAP_ARRAY(uint, MAX_SNAPSHOTS, mtGC);
CENSUS_NOISE(_skipped = 0);
@ -52,36 +52,40 @@ ShenandoahAgeCensus::ShenandoahAgeCensus(uint max_workers)
for (int i = 0; i < MAX_SNAPSHOTS; i++) {
// Note that we don't now get perfdata from age_table
_global_age_table[i] = new AgeTable(false);
_global_age_tables[i] = new AgeTable(false);
CENSUS_NOISE(_global_noise[i].clear();)
// Sentinel value
_tenuring_threshold[i] = MAX_COHORTS;
}
if (ShenandoahGenerationalAdaptiveTenuring) {
_local_age_table = NEW_C_HEAP_ARRAY(AgeTable*, _max_workers, mtGC);
_local_age_tables = NEW_C_HEAP_ARRAY(AgeTable*, _max_workers, mtGC);
CENSUS_NOISE(_local_noise = NEW_C_HEAP_ARRAY(ShenandoahNoiseStats, max_workers, mtGC);)
for (uint i = 0; i < _max_workers; i++) {
_local_age_table[i] = new AgeTable(false);
_local_age_tables[i] = new AgeTable(false);
CENSUS_NOISE(_local_noise[i].clear();)
}
} else {
_local_age_table = nullptr;
_local_age_tables = nullptr;
}
_epoch = MAX_SNAPSHOTS - 1; // see prepare_for_census_update()
if (!ShenandoahGenerationalAdaptiveTenuring) {
_tenuring_threshold[_epoch] = InitialTenuringThreshold;
}
_epoch = MAX_SNAPSHOTS - 1; // see update_epoch()
}
ShenandoahAgeCensus::~ShenandoahAgeCensus() {
for (uint i = 0; i < MAX_SNAPSHOTS; i++) {
delete _global_age_table[i];
delete _global_age_tables[i];
}
FREE_C_HEAP_ARRAY(AgeTable*, _global_age_table);
FREE_C_HEAP_ARRAY(AgeTable*, _global_age_tables);
FREE_C_HEAP_ARRAY(uint, _tenuring_threshold);
CENSUS_NOISE(FREE_C_HEAP_ARRAY(ShenandoahNoiseStats, _global_noise));
if (_local_age_table) {
if (_local_age_tables) {
for (uint i = 0; i < _max_workers; i++) {
delete _local_age_table[i];
delete _local_age_tables[i];
}
FREE_C_HEAP_ARRAY(AgeTable*, _local_age_table);
FREE_C_HEAP_ARRAY(AgeTable*, _local_age_tables);
CENSUS_NOISE(FREE_C_HEAP_ARRAY(ShenandoahNoiseStats, _local_noise));
}
}
@ -142,37 +146,31 @@ void ShenandoahAgeCensus::prepare_for_census_update() {
if (++_epoch >= MAX_SNAPSHOTS) {
_epoch=0;
}
_global_age_table[_epoch]->clear();
_global_age_tables[_epoch]->clear();
CENSUS_NOISE(_global_noise[_epoch].clear();)
}
// Update the census data from appropriate sources,
// and compute the new tenuring threshold.
void ShenandoahAgeCensus::update_census(size_t age0_pop, AgeTable* pv1, AgeTable* pv2) {
void ShenandoahAgeCensus::update_census(size_t age0_pop) {
prepare_for_census_update();
assert(_global_age_table[_epoch]->is_clear(), "Dirty decks");
assert(ShenandoahGenerationalAdaptiveTenuring, "Only update census when adaptive tenuring is enabled");
assert(_global_age_tables[_epoch]->is_clear(), "Dirty decks");
CENSUS_NOISE(assert(_global_noise[_epoch].is_clear(), "Dirty decks");)
if (ShenandoahGenerationalAdaptiveTenuring) {
assert(pv1 == nullptr && pv2 == nullptr, "Error, check caller");
// Seed cohort 0 with population that may have been missed during
// regular census.
_global_age_table[_epoch]->add(0u, age0_pop);
// Merge data from local age tables into the global age table for the epoch,
// clearing the local tables.
for (uint i = 0; i < _max_workers; i++) {
// age stats
_global_age_table[_epoch]->merge(_local_age_table[i]);
_local_age_table[i]->clear(); // clear for next census
// Merge noise stats
CENSUS_NOISE(_global_noise[_epoch].merge(_local_noise[i]);)
CENSUS_NOISE(_local_noise[i].clear();)
}
} else {
// census during evac
assert(pv1 != nullptr && pv2 != nullptr, "Error, check caller");
_global_age_table[_epoch]->merge(pv1);
_global_age_table[_epoch]->merge(pv2);
// Seed cohort 0 with population that may have been missed during
// regular census.
_global_age_tables[_epoch]->add(0u, age0_pop);
// Merge data from local age tables into the global age table for the epoch,
// clearing the local tables.
for (uint i = 0; i < _max_workers; i++) {
// age stats
_global_age_tables[_epoch]->merge(_local_age_tables[i]);
_local_age_tables[i]->clear(); // clear for next census
// Merge noise stats
CENSUS_NOISE(_global_noise[_epoch].merge(_local_noise[i]);)
CENSUS_NOISE(_local_noise[i].clear();)
}
update_tenuring_threshold();
@ -188,7 +186,7 @@ void ShenandoahAgeCensus::update_census(size_t age0_pop, AgeTable* pv1, AgeTable
void ShenandoahAgeCensus::reset_global() {
assert(_epoch < MAX_SNAPSHOTS, "Out of bounds");
for (uint i = 0; i < MAX_SNAPSHOTS; i++) {
_global_age_table[i]->clear();
_global_age_tables[i]->clear();
CENSUS_NOISE(_global_noise[i].clear();)
}
_epoch = MAX_SNAPSHOTS;
@ -198,11 +196,11 @@ void ShenandoahAgeCensus::reset_global() {
// Reset the local age tables, clearing any partial census.
void ShenandoahAgeCensus::reset_local() {
if (!ShenandoahGenerationalAdaptiveTenuring) {
assert(_local_age_table == nullptr, "Error");
assert(_local_age_tables == nullptr, "Error");
return;
}
for (uint i = 0; i < _max_workers; i++) {
_local_age_table[i]->clear();
_local_age_tables[i]->clear();
CENSUS_NOISE(_local_noise[i].clear();)
}
}
@ -212,7 +210,7 @@ void ShenandoahAgeCensus::reset_local() {
bool ShenandoahAgeCensus::is_clear_global() {
assert(_epoch < MAX_SNAPSHOTS, "Out of bounds");
for (uint i = 0; i < MAX_SNAPSHOTS; i++) {
bool clear = _global_age_table[i]->is_clear();
bool clear = _global_age_tables[i]->is_clear();
CENSUS_NOISE(clear |= _global_noise[i].is_clear();)
if (!clear) {
return false;
@ -224,11 +222,11 @@ bool ShenandoahAgeCensus::is_clear_global() {
// Is local census information clear?
bool ShenandoahAgeCensus::is_clear_local() {
if (!ShenandoahGenerationalAdaptiveTenuring) {
assert(_local_age_table == nullptr, "Error");
assert(_local_age_tables == nullptr, "Error");
return true;
}
for (uint i = 0; i < _max_workers; i++) {
bool clear = _local_age_table[i]->is_clear();
bool clear = _local_age_tables[i]->is_clear();
CENSUS_NOISE(clear |= _local_noise[i].is_clear();)
if (!clear) {
return false;
@ -240,7 +238,7 @@ bool ShenandoahAgeCensus::is_clear_local() {
size_t ShenandoahAgeCensus::get_all_ages(uint snap) {
assert(snap < MAX_SNAPSHOTS, "Out of bounds");
size_t pop = 0;
const AgeTable* pv = _global_age_table[snap];
const AgeTable* pv = _global_age_tables[snap];
for (uint i = 0; i < MAX_COHORTS; i++) {
pop += pv->sizes[i];
}
@ -260,13 +258,11 @@ void ShenandoahAgeCensus::update_total() {
#endif // !PRODUCT
void ShenandoahAgeCensus::update_tenuring_threshold() {
if (!ShenandoahGenerationalAdaptiveTenuring) {
_tenuring_threshold[_epoch] = InitialTenuringThreshold;
} else {
uint tt = compute_tenuring_threshold();
assert(tt <= MAX_COHORTS, "Out of bounds");
_tenuring_threshold[_epoch] = tt;
}
assert(ShenandoahGenerationalAdaptiveTenuring, "Only update when adaptive tenuring is enabled");
uint tt = compute_tenuring_threshold();
assert(tt <= MAX_COHORTS, "Out of bounds");
_tenuring_threshold[_epoch] = tt;
print();
log_info(gc, age)("New tenuring threshold %zu (min %zu, max %zu)",
(uintx) _tenuring_threshold[_epoch], ShenandoahGenerationalMinTenuringAge, ShenandoahGenerationalMaxTenuringAge);
@ -296,8 +292,8 @@ uint ShenandoahAgeCensus::compute_tenuring_threshold() {
const uint prev_epoch = cur_epoch > 0 ? cur_epoch - 1 : markWord::max_age;
// Current and previous population vectors in ring
const AgeTable* cur_pv = _global_age_table[cur_epoch];
const AgeTable* prev_pv = _global_age_table[prev_epoch];
const AgeTable* cur_pv = _global_age_tables[cur_epoch];
const AgeTable* prev_pv = _global_age_tables[prev_epoch];
uint upper_bound = ShenandoahGenerationalMaxTenuringAge;
const uint prev_tt = previous_tenuring_threshold();
if (ShenandoahGenerationalCensusIgnoreOlderCohorts && prev_tt > 0) {
@ -372,8 +368,8 @@ void ShenandoahAgeCensus::print() {
const uint cur_epoch = _epoch;
const uint prev_epoch = cur_epoch > 0 ? cur_epoch - 1: markWord::max_age;
const AgeTable* cur_pv = _global_age_table[cur_epoch];
const AgeTable* prev_pv = _global_age_table[prev_epoch];
const AgeTable* cur_pv = _global_age_tables[cur_epoch];
const AgeTable* prev_pv = _global_age_tables[prev_epoch];
const uint tt = tenuring_threshold();

View File

@ -97,8 +97,8 @@ struct ShenandoahNoiseStats {
// once the per-worker data is consolidated into the appropriate population vector
// per minor collection. The _local_age_table is thus C x N, for N GC workers.
class ShenandoahAgeCensus: public CHeapObj<mtGC> {
AgeTable** _global_age_table; // Global age table used for adapting tenuring threshold, one per snapshot
AgeTable** _local_age_table; // Local scratch age tables to track object ages, one per worker
AgeTable** _global_age_tables; // Global age tables used for adapting tenuring threshold, one per snapshot
AgeTable** _local_age_tables; // Local scratch age tables to track object ages, one per worker
#ifdef SHENANDOAH_CENSUS_NOISE
ShenandoahNoiseStats* _global_noise; // Noise stats, one per snapshot
@ -175,7 +175,7 @@ class ShenandoahAgeCensus: public CHeapObj<mtGC> {
// Return the local age table (population vector) for worker_id.
// Only used in the case of ShenandoahGenerationalAdaptiveTenuring
AgeTable* get_local_age_table(uint worker_id) const {
return _local_age_table[worker_id];
return _local_age_tables[worker_id];
}
// Return the most recently computed tenuring threshold.
@ -209,11 +209,7 @@ class ShenandoahAgeCensus: public CHeapObj<mtGC> {
// age0_pop is the population of Cohort 0 that may have been missed in
// the regular census during the marking cycle, corresponding to objects
// allocated when the concurrent marking was in progress.
// Optional parameters, pv1 and pv2 are population vectors that together
// provide object census data (only) for the case when
// ShenandoahGenerationalCensusAtEvac. In this case, the age0_pop
// is 0, because the evacuated objects have all had their ages incremented.
void update_census(size_t age0_pop, AgeTable* pv1 = nullptr, AgeTable* pv2 = nullptr);
void update_census(size_t age0_pop);
// Reset the epoch, clearing accumulated census history
// Note: this isn't currently used, but reserved for planned

View File

@ -201,26 +201,8 @@ void ShenandoahControlThread::run_service() {
heuristics->clear_metaspace_oom();
}
// Commit worker statistics to cycle data
heap->phase_timings()->flush_par_workers_to_cycle();
// Print GC stats for current cycle
{
LogTarget(Info, gc, stats) lt;
if (lt.is_enabled()) {
ResourceMark rm;
LogStream ls(lt);
heap->phase_timings()->print_cycle_on(&ls);
if (ShenandoahEvacTracking) {
ShenandoahEvacuationTracker* evac_tracker = heap->evac_tracker();
ShenandoahCycleStats evac_stats = evac_tracker->flush_cycle_to_global();
evac_tracker->print_evacuations_on(&ls, &evac_stats.workers, &evac_stats.mutators);
}
}
}
// Commit statistics to globals
heap->phase_timings()->flush_cycle_to_global();
// Manage and print gc stats
heap->process_gc_stats();
// Print Metaspace change following GC (if logging is enabled).
MetaspaceUtils::print_metaspace_change(meta_sizes);

View File

@ -23,7 +23,6 @@
*
*/
#include "gc/shenandoah/shenandoahAgeCensus.hpp"
#include "gc/shenandoah/shenandoahEvacTracker.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahThreadLocalData.hpp"
@ -44,19 +43,6 @@ ShenandoahEvacuationStats::ShenandoahEvacuations* ShenandoahEvacuationStats::get
return &_old;
}
ShenandoahEvacuationStats::ShenandoahEvacuationStats()
: _use_age_table(!ShenandoahGenerationalAdaptiveTenuring),
_age_table(nullptr) {
if (_use_age_table) {
_age_table = new AgeTable(false);
}
}
AgeTable* ShenandoahEvacuationStats::age_table() const {
assert(_use_age_table, "Don't call");
return _age_table;
}
void ShenandoahEvacuationStats::begin_evacuation(size_t bytes, ShenandoahAffiliation from, ShenandoahAffiliation to) {
ShenandoahEvacuations* category = get_category(from, to);
category->_evacuations_attempted++;
@ -70,31 +56,16 @@ void ShenandoahEvacuationStats::end_evacuation(size_t bytes, ShenandoahAffiliati
category->_bytes_completed += bytes;
}
void ShenandoahEvacuationStats::record_age(size_t bytes, uint age) {
assert(_use_age_table, "Don't call!");
if (age <= markWord::max_age) { // Filter age sentinel.
_age_table->add(age, bytes >> LogBytesPerWord);
}
}
void ShenandoahEvacuationStats::accumulate(const ShenandoahEvacuationStats* other) {
_young.accumulate(other->_young);
_old.accumulate(other->_old);
_promotion.accumulate(other->_promotion);
if (_use_age_table) {
_age_table->merge(other->age_table());
}
}
void ShenandoahEvacuationStats::reset() {
_young.reset();
_old.reset();
_promotion.reset();
if (_use_age_table) {
_age_table->clear();
}
}
void ShenandoahEvacuationStats::ShenandoahEvacuations::print_on(outputStream* st) const {
@ -112,10 +83,6 @@ void ShenandoahEvacuationStats::print_on(outputStream* st) const {
st->print("Promotion: "); _promotion.print_on(st);
st->print("Old: "); _old.print_on(st);
}
if (_use_age_table) {
_age_table->print_on(st);
}
}
void ShenandoahEvacuationTracker::print_global_on(outputStream* st) {
@ -125,28 +92,13 @@ void ShenandoahEvacuationTracker::print_global_on(outputStream* st) {
void ShenandoahEvacuationTracker::print_evacuations_on(outputStream* st,
ShenandoahEvacuationStats* workers,
ShenandoahEvacuationStats* mutators) {
if (ShenandoahEvacTracking) {
st->print_cr("Workers: ");
workers->print_on(st);
st->cr();
st->print_cr("Mutators: ");
mutators->print_on(st);
st->cr();
}
ShenandoahHeap* heap = ShenandoahHeap::heap();
if (heap->mode()->is_generational()) {
AgeTable young_region_ages(false);
for (uint i = 0; i < heap->num_regions(); ++i) {
ShenandoahHeapRegion* r = heap->get_region(i);
if (r->is_young()) {
young_region_ages.add(r->age(), r->get_live_data_words());
}
}
st->print("Young regions: ");
young_region_ages.print_on(st);
st->cr();
}
assert(ShenandoahEvacTracking, "Only when evac tracking is enabled");
st->print_cr("Workers: ");
workers->print_on(st);
st->cr();
st->print_cr("Mutators: ");
mutators->print_on(st);
st->cr();
}
class ShenandoahStatAggregator : public ThreadClosure {
@ -173,15 +125,6 @@ ShenandoahCycleStats ShenandoahEvacuationTracker::flush_cycle_to_global() {
_mutators_global.accumulate(&mutators);
_workers_global.accumulate(&workers);
if (!ShenandoahGenerationalAdaptiveTenuring) {
// Ingest mutator & worker collected population vectors into the heap's
// global census data, and use it to compute an appropriate tenuring threshold
// for use in the next cycle.
// The first argument is used for any age 0 cohort population that we may otherwise have
// missed during the census. This is non-zero only when census happens at marking.
ShenandoahGenerationalHeap::heap()->age_census()->update_census(0, mutators.age_table(), workers.age_table());
}
return {workers, mutators};
}
@ -192,7 +135,3 @@ void ShenandoahEvacuationTracker::begin_evacuation(Thread* thread, size_t bytes,
void ShenandoahEvacuationTracker::end_evacuation(Thread* thread, size_t bytes, ShenandoahAffiliation from, ShenandoahAffiliation to) {
ShenandoahThreadLocalData::end_evacuation(thread, bytes, from, to);
}
void ShenandoahEvacuationTracker::record_age(Thread* thread, size_t bytes, uint age) {
ShenandoahThreadLocalData::record_age(thread, bytes, age);
}

View File

@ -66,20 +66,12 @@ private:
ShenandoahEvacuations _old;
ShenandoahEvacuations _promotion;
bool _use_age_table;
AgeTable* _age_table;
public:
ShenandoahEvacuationStats();
AgeTable* age_table() const;
// Record that the current thread is attempting to copy this many bytes.
void begin_evacuation(size_t bytes, ShenandoahAffiliation from, ShenandoahAffiliation to);
// Record that the current thread has completed copying this many bytes.
void end_evacuation(size_t bytes, ShenandoahAffiliation from, ShenandoahAffiliation to);
void record_age(size_t bytes, uint age);
void print_on(outputStream* st) const;
void accumulate(const ShenandoahEvacuationStats* other);
@ -106,7 +98,6 @@ public:
// Multiple threads may attempt to evacuate the same object, but only the successful thread will end the evacuation.
// Evacuations that were begun, but not ended are considered 'abandoned'.
void end_evacuation(Thread* thread, size_t bytes, ShenandoahAffiliation from, ShenandoahAffiliation to);
void record_age(Thread* thread, size_t bytes, uint age);
void print_global_on(outputStream* st);
void print_evacuations_on(outputStream* st,

View File

@ -201,6 +201,24 @@ ShenandoahGenerationalControlThread::GCMode ShenandoahGenerationalControlThread:
return request.generation->is_old() ? servicing_old : concurrent_normal;
}
void ShenandoahGenerationalControlThread::maybe_print_young_region_ages() const {
LogTarget(Debug, gc, age) lt;
if (lt.is_enabled()) {
LogStream ls(lt);
AgeTable young_region_ages(false);
for (uint i = 0; i < _heap->num_regions(); ++i) {
const ShenandoahHeapRegion* r = _heap->get_region(i);
if (r->is_young()) {
young_region_ages.add(r->age(), r->get_live_data_words());
}
}
ls.print("Young regions: ");
young_region_ages.print_on(&ls);
ls.cr();
}
}
void ShenandoahGenerationalControlThread::maybe_set_aging_cycle() {
if (_age_period-- == 0) {
_heap->set_aging_cycle(true);
@ -298,7 +316,11 @@ void ShenandoahGenerationalControlThread::run_gc_cycle(const ShenandoahGCRequest
_heap->global_generation()->heuristics()->clear_metaspace_oom();
}
process_phase_timings();
// Manage and print gc stats
_heap->process_gc_stats();
// Print table for young region ages if log is enabled
maybe_print_young_region_ages();
// Print Metaspace change following GC (if logging is enabled).
MetaspaceUtils::print_metaspace_change(meta_sizes);
@ -317,29 +339,6 @@ void ShenandoahGenerationalControlThread::run_gc_cycle(const ShenandoahGCRequest
gc_mode_name(gc_mode()), GCCause::to_string(request.cause), request.generation->name(), GCCause::to_string(_heap->cancelled_cause()));
}
void ShenandoahGenerationalControlThread::process_phase_timings() const {
// Commit worker statistics to cycle data
_heap->phase_timings()->flush_par_workers_to_cycle();
ShenandoahEvacuationTracker* evac_tracker = _heap->evac_tracker();
ShenandoahCycleStats evac_stats = evac_tracker->flush_cycle_to_global();
// Print GC stats for current cycle
{
LogTarget(Info, gc, stats) lt;
if (lt.is_enabled()) {
ResourceMark rm;
LogStream ls(lt);
_heap->phase_timings()->print_cycle_on(&ls);
evac_tracker->print_evacuations_on(&ls, &evac_stats.workers,
&evac_stats.mutators);
}
}
// Commit statistics to globals
_heap->phase_timings()->flush_cycle_to_global();
}
// Young and old concurrent cycles are initiated by the regulator. Implicit
// and explicit GC requests are handled by the controller thread and always
// run a global cycle (which is concurrent by default, but may be overridden
@ -417,7 +416,7 @@ void ShenandoahGenerationalControlThread::service_concurrent_old_cycle(const She
set_gc_mode(bootstrapping_old);
young_generation->set_old_gen_task_queues(old_generation->task_queues());
service_concurrent_cycle(young_generation, request.cause, true);
process_phase_timings();
_heap->process_gc_stats();
if (_heap->cancelled_gc()) {
// Young generation bootstrap cycle has failed. Concurrent mark for old generation
// is going to resume after degenerated bootstrap cycle completes.

View File

@ -129,9 +129,6 @@ private:
// Returns true if the old generation marking was interrupted to allow a young cycle.
bool preempt_old_marking(ShenandoahGeneration* generation);
// Flushes cycle timings to global timings and prints the phase timings for the last completed cycle.
void process_phase_timings() const;
// Set the gc mode and post a notification if it has changed. The overloaded variant should be used
// when the _control_lock is already held.
void set_gc_mode(GCMode new_mode);
@ -160,6 +157,9 @@ private:
GCMode prepare_for_allocation_failure_gc(ShenandoahGCRequest &request);
GCMode prepare_for_explicit_gc(ShenandoahGCRequest &request) const;
GCMode prepare_for_concurrent_gc(const ShenandoahGCRequest &request) const;
// Print table for young region ages if log is enabled
void maybe_print_young_region_ages() const;
};
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONALCONTROLTHREAD_HPP

View File

@ -360,11 +360,6 @@ oop ShenandoahGenerationalHeap::try_evacuate_object(oop p, Thread* thread, Shena
// When copying to the old generation above, we don't care
// about recording object age in the census stats.
assert(target_gen == YOUNG_GENERATION, "Error");
// We record this census only when simulating pre-adaptive tenuring behavior, or
// when we have been asked to record the census at evacuation rather than at mark
if (!ShenandoahGenerationalAdaptiveTenuring) {
evac_tracker()->record_age(thread, size * HeapWordSize, ShenandoahHeap::get_object_age(copy_val));
}
}
shenandoah_assert_correct(nullptr, copy_val);
return copy_val;

View File

@ -1441,6 +1441,27 @@ void ShenandoahHeap::print_heap_regions_on(outputStream* st) const {
}
}
void ShenandoahHeap::process_gc_stats() const {
// Commit worker statistics to cycle data
phase_timings()->flush_par_workers_to_cycle();
// Print GC stats for current cycle
LogTarget(Info, gc, stats) lt;
if (lt.is_enabled()) {
ResourceMark rm;
LogStream ls(lt);
phase_timings()->print_cycle_on(&ls);
if (ShenandoahEvacTracking) {
ShenandoahCycleStats evac_stats = evac_tracker()->flush_cycle_to_global();
evac_tracker()->print_evacuations_on(&ls, &evac_stats.workers,
&evac_stats.mutators);
}
}
// Commit statistics to globals
phase_timings()->flush_cycle_to_global();
}
size_t ShenandoahHeap::trash_humongous_region_at(ShenandoahHeapRegion* start) const {
assert(start->is_humongous_start(), "reclaim regions starting with the first one");
assert(!start->has_live(), "liveness must be zero");

View File

@ -206,9 +206,12 @@ public:
void initialize_serviceability() override;
void print_heap_on(outputStream* st) const override;
void print_gc_on(outputStream *st) const override;
void print_gc_on(outputStream* st) const override;
void print_heap_regions_on(outputStream* st) const;
// Flushes cycle timings to global timings and prints the phase timings for the last completed cycle.
void process_gc_stats() const;
void prepare_for_verify() override;
void verify(VerifyOption vo) override;

View File

@ -166,10 +166,6 @@ public:
data(thread)->_evacuation_stats->end_evacuation(bytes, from, to);
}
static void record_age(Thread* thread, size_t bytes, uint age) {
data(thread)->_evacuation_stats->record_age(bytes, age);
}
static ShenandoahEvacuationStats* evacuation_stats(Thread* thread) {
return data(thread)->_evacuation_stats;
}