diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 3632d2ee4d9..f9e0904e1d8 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -371,6 +371,7 @@ void ZGeneration::at_collection_start(ConcurrentGCTimer* gc_timer) { set_gc_timer(gc_timer); stat_cycle()->at_start(); stat_heap()->at_collection_start(_page_allocator->stats(this)); + stat_relocation()->at_collection_start(); workers()->set_active(); } diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp index 04f3bdbe5bc..b400a2cd6a2 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp @@ -41,6 +41,28 @@ ZRelocationSetSelectorGroupStats::ZRelocationSetSelectorGroupStats() : _npages_selected(0), _relocate(0) {} +ZRelocationSetSelectorStats::ZRelocationSetSelectorStats() : + _has_relocatable_pages(false) { + for (uint i = 0; i <= ZPageAgeMax; ++i) { + _small[i] = ZRelocationSetSelectorGroupStats(); + _medium[i] = ZRelocationSetSelectorGroupStats(); + _large[i] = ZRelocationSetSelectorGroupStats(); + } +} + +ZRelocationSetSelectorStats::ZRelocationSetSelectorStats(const ZRelocationSetSelectorGroup* small, + const ZRelocationSetSelectorGroup* medium, + const ZRelocationSetSelectorGroup* large, + bool has_relocatable_pages) : + _has_relocatable_pages(has_relocatable_pages) { + for (uint i = 0; i <= ZPageAgeMax; ++i) { + const ZPageAge age = static_cast<ZPageAge>(i); + _small[i] = small->stats(age); + _medium[i] = medium->stats(age); + _large[i] = large->stats(age); + } +} + ZRelocationSetSelectorGroup::ZRelocationSetSelectorGroup(const char* name, ZPageType page_type, size_t page_size, @@ -235,16 +257,6 @@ void ZRelocationSetSelector::select() { } ZRelocationSetSelectorStats ZRelocationSetSelector::stats() const { - ZRelocationSetSelectorStats stats; - - for (uint i = 0; i <= ZPageAgeMax; ++i) { - const ZPageAge age = static_cast<ZPageAge>(i); - stats._small[i] = _small.stats(age); - stats._medium[i] = _medium.stats(age); - stats._large[i] = _large.stats(age); - } - - stats._has_relocatable_pages = total() > 0; - - return stats; + const bool has_relocatable_pages = total() > 0; + return ZRelocationSetSelectorStats(&_small, &_medium, &_large, has_relocatable_pages); } diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp index 1557097568c..b8e792e5105 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp @@ -31,6 +31,7 @@ #include "memory/allocation.hpp" class ZPage; +class ZRelocationSetSelectorGroup; class ZRelocationSetSelectorGroupStats { friend class ZRelocationSetSelectorGroup; @@ -66,13 +67,22 @@ class ZRelocationSetSelectorStats { ZRelocationSetSelectorGroupStats _medium[ZPageAgeMax + 1]; ZRelocationSetSelectorGroupStats _large[ZPageAgeMax + 1]; - size_t _has_relocatable_pages; + bool _has_relocatable_pages; public: + ZRelocationSetSelectorStats(); + ZRelocationSetSelectorStats(const ZRelocationSetSelectorGroup* small, + const ZRelocationSetSelectorGroup* medium, + const ZRelocationSetSelectorGroup* large, + bool has_relocatable_pages); + const ZRelocationSetSelectorGroupStats& small(ZPageAge age) const; const ZRelocationSetSelectorGroupStats& medium(ZPageAge age) const; const ZRelocationSetSelectorGroupStats& large(ZPageAge age) const; + size_t live_bytes(ZPageAge age) const; + size_t npages(ZPageAge age) const; + bool has_relocatable_pages() const; }; diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp index 6f3a7130d6d..ecc3a646dd5 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp @@ -53,10 +53,6 @@ inline size_t ZRelocationSetSelectorGroupStats::relocate() const { return _relocate; } -inline bool ZRelocationSetSelectorStats::has_relocatable_pages() const { - return _has_relocatable_pages; -} - inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::small(ZPageAge age) const { return _small[static_cast<uint>(age)]; } @@ -69,6 +65,20 @@ inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::larg return _large[static_cast<uint>(age)]; } +inline size_t ZRelocationSetSelectorStats::live_bytes(ZPageAge age) const { + return small(age).live() + medium(age).live() + large(age).live(); +} + +inline size_t ZRelocationSetSelectorStats::npages(ZPageAge age) const { + return small(age).npages_candidates() + + medium(age).npages_candidates() + + large(age).npages_candidates(); +} + +inline bool ZRelocationSetSelectorStats::has_relocatable_pages() const { + return _has_relocatable_pages; +} + inline void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { const size_t size = page->size(); const size_t live = page->live_bytes(); diff --git a/src/hotspot/share/gc/z/zStat.cpp b/src/hotspot/share/gc/z/zStat.cpp index b282b6e4154..f9f8f26ca9b 100644 --- a/src/hotspot/share/gc/z/zStat.cpp +++ b/src/hotspot/share/gc/z/zStat.cpp @@ -1470,6 +1470,11 @@ ZStatRelocation::ZStatRelocation() : _medium_in_place_count() { } +void ZStatRelocation::at_collection_start() { + _previous_selector_stats = _selector_stats; + _selector_stats = {}; +} + void ZStatRelocation::at_select_relocation_set(const ZRelocationSetSelectorStats& selector_stats) { _selector_stats = selector_stats; } @@ -1483,7 +1488,7 @@ void ZStatRelocation::at_relocate_end(size_t small_in_place_count, size_t medium _medium_in_place_count = medium_in_place_count; } -void ZStatRelocation::print_page_summary() { +void ZStatRelocation::print_page_summary() const { LogTarget(Info, gc, reloc) lt; if (!_selector_stats.has_relocatable_pages() || !lt.is_enabled()) { @@ -1491,6 +1496,15 @@ void ZStatRelocation::print_page_summary() { return; } + struct ZStatRelocationSummary { + size_t npages_candidates; + size_t total; + size_t live; + size_t empty; + size_t npages_selected; + size_t relocate; + }; + // Zero initialize ZStatRelocationSummary small_summary{}; ZStatRelocationSummary medium_summary{}; @@ -1544,79 +1558,90 @@ void ZStatRelocation::print_page_summary() { lt.print("Forwarding Usage: " SIZE_FORMAT "M", _forwarding_usage / M); } -void ZStatRelocation::print_age_table() { +void ZStatRelocation::print_age_table() const { LogTarget(Info, gc, reloc) lt; + if (!_selector_stats.has_relocatable_pages() || !lt.is_enabled()) { // Nothing to log or logging not enabled. return; } + // Find range of pages to print + const uint end = [&]() { + for (uint i = 0; i <= ZPageAgeMax; ++i) { + const ZPageAge age = static_cast<ZPageAge>(i); + if (age == ZPageAge::old) { + return i; + } + + if (_selector_stats.npages(age) == 0 && _previous_selector_stats.npages(age) == 0) { + return i; + } + } + + return ZPageAgeMax; + }(); + ZStatTablePrinter age_table(11, 18); lt.print("Age Table:"); lt.print("%s", age_table() .fill() .center("Live") - .center("Garbage") .center("Small") .center("Medium") .center("Large") .end()); - size_t live[ZPageAgeMax + 1] = {}; - size_t total[ZPageAgeMax + 1] = {}; - - uint oldest_none_empty_age = 0; + auto unit = [](size_t bytes) { + if (bytes < K) { + return "B"; + } + if (bytes < M) { + return "K"; + } + return "M"; + }; - for (uint i = 0; i <= ZPageAgeMax; ++i) { - ZPageAge age = static_cast<ZPageAge>(i); - auto summarize_pages = [&](const ZRelocationSetSelectorGroupStats& stats) { - live[i] += stats.live(); - total[i] += stats.total(); - }; - - summarize_pages(_selector_stats.small(age)); - summarize_pages(_selector_stats.medium(age)); - summarize_pages(_selector_stats.large(age)); - - if (total[i] != 0) { - oldest_none_empty_age = i; + auto value = [](size_t bytes) { + if (bytes < K) { + return bytes; } - } + if (bytes < M) { + return bytes / K; + } + return bytes / M; + }; - for (uint i = 0; i <= oldest_none_empty_age; ++i) { - ZPageAge age = static_cast<ZPageAge>(i); + for (uint i = 0; i < end; ++i) { + const ZPageAge age = static_cast<ZPageAge>(i); - FormatBuffer<> age_str(""); + FormatBuffer<> desc(""); if (age == ZPageAge::eden) { - age_str.append("Eden"); - } else if (age != ZPageAge::old) { - age_str.append("Survivor %d", i); + desc.append("Eden"); + } else { + desc.append("Survivor %d", i); } - auto create_age_table = [&]() { - if (live[i] == 0) { - return age_table() - .left("%s", age_str.buffer()) - .left(ZTABLE_ARGS_NA); - } else { - return age_table() - .left("%s", age_str.buffer()) - .left(ZTABLE_ARGS(live[i])); - } - }; - - lt.print("%s", create_age_table() - .left(ZTABLE_ARGS(total[i] - live[i])) - .left(SIZE_FORMAT_W(7) " / " SIZE_FORMAT, - _selector_stats.small(age).npages_candidates(), - _selector_stats.small(age).npages_selected()) - .left(SIZE_FORMAT_W(7) " / " SIZE_FORMAT, - _selector_stats.medium(age).npages_candidates(), - _selector_stats.medium(age).npages_selected()) - .left(SIZE_FORMAT_W(7) " / " SIZE_FORMAT, - _selector_stats.large(age).npages_candidates(), - _selector_stats.large(age).npages_selected()) - .end()); + const size_t prev_live_bytes = _previous_selector_stats.live_bytes(age); + const size_t live_bytes = _selector_stats.live_bytes(age); + + lt.print("%s", age_table() + .left("%s", desc.buffer()) + .left(SIZE_FORMAT_W(8) "%s" " -> " SIZE_FORMAT "%s", + value(prev_live_bytes), + unit(prev_live_bytes), + value(live_bytes), + unit(live_bytes)) + .left(SIZE_FORMAT_W(7) " -> " SIZE_FORMAT, + _previous_selector_stats.small(age).npages_candidates(), + _selector_stats.small(age).npages_candidates()) + .left(SIZE_FORMAT_W(7) " -> " SIZE_FORMAT, + _previous_selector_stats.medium(age).npages_candidates(), + _selector_stats.medium(age).npages_candidates()) + .left(SIZE_FORMAT_W(7) " -> " SIZE_FORMAT, + _previous_selector_stats.large(age).npages_candidates(), + _selector_stats.large(age).npages_candidates()) + .end()); } } diff --git a/src/hotspot/share/gc/z/zStat.hpp b/src/hotspot/share/gc/z/zStat.hpp index 3bb719987c8..8fa6ddfae0f 100644 --- a/src/hotspot/share/gc/z/zStat.hpp +++ b/src/hotspot/share/gc/z/zStat.hpp @@ -510,40 +510,29 @@ class ZStatMark { void print(); }; -struct ZStatRelocationSummary { - size_t npages_candidates; - size_t total; - size_t live; - size_t empty; - size_t npages_selected; - size_t relocate; -}; - // // Stat relocation // class ZStatRelocation { private: ZRelocationSetSelectorStats _selector_stats; + ZRelocationSetSelectorStats _previous_selector_stats; size_t _forwarding_usage; size_t _small_selected; size_t _small_in_place_count; size_t _medium_selected; size_t _medium_in_place_count; - void print(const char* name, - ZStatRelocationSummary selector_group, - size_t in_place_count); - public: ZStatRelocation(); + void at_collection_start(); void at_select_relocation_set(const ZRelocationSetSelectorStats& selector_stats); void at_install_relocation_set(size_t forwarding_usage); void at_relocate_end(size_t small_in_place_count, size_t medium_in_place_count); - void print_page_summary(); - void print_age_table(); + void print_page_summary() const; + void print_age_table() const; }; //