--- old/src/hotspot/share/gc/z/zHeap.cpp 2020-01-21 12:41:08.453656920 +0100 +++ new/src/hotspot/share/gc/z/zHeap.cpp 2020-01-21 12:41:07.929646288 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ #include "gc/z/zPage.inline.hpp" #include "gc/z/zPageTable.inline.hpp" #include "gc/z/zRelocationSet.inline.hpp" -#include "gc/z/zRelocationSetSelector.hpp" +#include "gc/z/zRelocationSetSelector.inline.hpp" #include "gc/z/zResurrection.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zThread.inline.hpp" @@ -412,10 +412,8 @@ } // Update statistics - ZStatRelocation::set_at_select_relocation_set(selector.relocating()); - ZStatHeap::set_at_select_relocation_set(selector.live(), - selector.garbage(), - reclaimed()); + ZStatRelocation::set_at_select_relocation_set(selector.stats()); + ZStatHeap::set_at_select_relocation_set(selector.stats(), reclaimed()); } void ZHeap::reset_relocation_set() { --- old/src/hotspot/share/gc/z/zRelocationSetSelector.cpp 2020-01-21 12:41:09.137670798 +0100 +++ new/src/hotspot/share/gc/z/zRelocationSetSelector.cpp 2020-01-21 12:41:08.620660308 +0100 @@ -25,11 +25,20 @@ #include "gc/z/zArray.inline.hpp" #include "gc/z/zPage.inline.hpp" #include "gc/z/zRelocationSet.hpp" -#include "gc/z/zRelocationSetSelector.hpp" +#include "gc/z/zRelocationSetSelector.inline.hpp" #include "logging/log.hpp" #include "runtime/globals.hpp" #include "utilities/debug.hpp" +ZRelocationSetSelectorGroupStats::ZRelocationSetSelectorGroupStats() : + _npages(0), + _total(0), + _live(0), + _garbage(0), + _empty(0), + _compacting_from(0), + _compacting_to(0) {} + ZRelocationSetSelectorGroup::ZRelocationSetSelectorGroup(const char* name, size_t page_size, size_t object_size_limit) : @@ -40,16 +49,35 @@ _registered_pages(), _sorted_pages(NULL), _nselected(0), - _relocating(0) {} + _stats() {} ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() { FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages); } -void ZRelocationSetSelectorGroup::register_live_page(ZPage* page, size_t garbage) { +void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { + const uint8_t type = page->type(); + const size_t size = page->size(); + const size_t live = page->live_bytes(); + const size_t garbage = size - live; + if (garbage > _fragmentation_limit) { _registered_pages.add(page); } + + _stats._npages++; + _stats._total += size; + _stats._live += live; + _stats._garbage += garbage; +} + +void ZRelocationSetSelectorGroup::register_garbage_page(ZPage* page) { + const size_t size = page->size(); + + _stats._npages++; + _stats._total += size; + _stats._garbage += size; + _stats._empty += size; } void ZRelocationSetSelectorGroup::semi_sort() { @@ -64,7 +92,8 @@ size_t partitions[npartitions]; // Allocate destination array - _sorted_pages = REALLOC_C_HEAP_ARRAY(ZPage*, _sorted_pages, npages, mtGC); + assert(_sorted_pages == NULL, "Already initialized"); + _sorted_pages = NEW_C_HEAP_ARRAY(ZPage*, npages, mtGC); debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*))); // Calculate partition slots @@ -105,7 +134,6 @@ const size_t npages = _registered_pages.size(); size_t selected_from = 0; size_t selected_to = 0; - size_t selected_from_size = 0; size_t from_size = 0; semi_sort(); @@ -130,7 +158,6 @@ if (diff_reclaimable > ZFragmentationLimit) { selected_from = from; selected_to = to; - selected_from_size = from_size; } log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): " @@ -140,47 +167,42 @@ // Finalize selection _nselected = selected_from; - _relocating = selected_from_size; - - log_debug(gc, reloc)("Relocation Set (%s Pages): " SIZE_FORMAT "->" SIZE_FORMAT ", " SIZE_FORMAT " skipped", - _name, selected_from, selected_to, npages - _nselected); -} -ZPage* const* ZRelocationSetSelectorGroup::selected() const { - return _sorted_pages; -} - -size_t ZRelocationSetSelectorGroup::nselected() const { - return _nselected; -} + // Update statistics + _stats._compacting_from = selected_from * _page_size; + _stats._compacting_to = selected_to * _page_size; -size_t ZRelocationSetSelectorGroup::relocating() const { - return _relocating; + log_trace(gc, reloc)("Relocation Set (%s Pages): " SIZE_FORMAT "->" SIZE_FORMAT ", " SIZE_FORMAT " skipped", + _name, selected_from, selected_to, npages - _nselected); } ZRelocationSetSelector::ZRelocationSetSelector() : _small("Small", ZPageSizeSmall, ZObjectSizeLimitSmall), _medium("Medium", ZPageSizeMedium, ZObjectSizeLimitMedium), - _live(0), - _garbage(0) {} + _large("Large", 0 /* page_size */, 0 /* object_size_limit */) {} void ZRelocationSetSelector::register_live_page(ZPage* page) { const uint8_t type = page->type(); - const size_t live = page->live_bytes(); - const size_t garbage = page->size() - live; if (type == ZPageTypeSmall) { - _small.register_live_page(page, garbage); + _small.register_live_page(page); } else if (type == ZPageTypeMedium) { - _medium.register_live_page(page, garbage); + _medium.register_live_page(page); + } else { + _large.register_live_page(page); } - - _live += live; - _garbage += garbage; } void ZRelocationSetSelector::register_garbage_page(ZPage* page) { - _garbage += page->size(); + const uint8_t type = page->type(); + + if (type == ZPageTypeSmall) { + _small.register_garbage_page(page); + } else if (type == ZPageTypeMedium) { + _medium.register_garbage_page(page); + } else { + _large.register_garbage_page(page); + } } void ZRelocationSetSelector::select(ZRelocationSet* relocation_set) { @@ -190,7 +212,7 @@ // bytes in ascending order. Relocating pages in this order allows // us to start reclaiming memory more quickly. - // Select pages from each group + // Select pages from each group, except large _medium.select(); _small.select(); @@ -199,14 +221,10 @@ _small.selected(), _small.nselected()); } -size_t ZRelocationSetSelector::live() const { - return _live; -} - -size_t ZRelocationSetSelector::garbage() const { - return _garbage; -} - -size_t ZRelocationSetSelector::relocating() const { - return _small.relocating() + _medium.relocating(); +ZRelocationSetSelectorStats ZRelocationSetSelector::stats() const { + ZRelocationSetSelectorStats stats; + stats._small = _small.stats(); + stats._medium = _medium.stats(); + stats._large = _large.stats(); + return stats; } --- old/src/hotspot/share/gc/z/zRelocationSetSelector.hpp 2020-01-21 12:41:09.830684859 +0100 +++ new/src/hotspot/share/gc/z/zRelocationSetSelector.hpp 2020-01-21 12:41:09.307674247 +0100 @@ -30,17 +30,55 @@ class ZPage; class ZRelocationSet; +class ZRelocationSetSelectorGroupStats { + friend class ZRelocationSetSelectorGroup; + +private: + size_t _npages; + size_t _total; + size_t _live; + size_t _garbage; + size_t _empty; + size_t _compacting_from; + size_t _compacting_to; + +public: + ZRelocationSetSelectorGroupStats(); + + size_t npages() const; + size_t total() const; + size_t live() const; + size_t garbage() const; + size_t empty() const; + size_t compacting_from() const; + size_t compacting_to() const; +}; + +class ZRelocationSetSelectorStats { + friend class ZRelocationSetSelector; + +private: + ZRelocationSetSelectorGroupStats _small; + ZRelocationSetSelectorGroupStats _medium; + ZRelocationSetSelectorGroupStats _large; + +public: + const ZRelocationSetSelectorGroupStats& small() const; + const ZRelocationSetSelectorGroupStats& medium() const; + const ZRelocationSetSelectorGroupStats& large() const; +}; + class ZRelocationSetSelectorGroup { private: - const char* const _name; - const size_t _page_size; - const size_t _object_size_limit; - const size_t _fragmentation_limit; - - ZArray _registered_pages; - ZPage** _sorted_pages; - size_t _nselected; - size_t _relocating; + const char* const _name; + const size_t _page_size; + const size_t _object_size_limit; + const size_t _fragmentation_limit; + + ZArray _registered_pages; + ZPage** _sorted_pages; + size_t _nselected; + ZRelocationSetSelectorGroupStats _stats; void semi_sort(); @@ -50,20 +88,21 @@ size_t object_size_limit); ~ZRelocationSetSelectorGroup(); - void register_live_page(ZPage* page, size_t garbage); + void register_live_page(ZPage* page); + void register_garbage_page(ZPage* page); void select(); ZPage* const* selected() const; size_t nselected() const; - size_t relocating() const; + + const ZRelocationSetSelectorGroupStats& stats() const; }; class ZRelocationSetSelector : public StackObj { private: ZRelocationSetSelectorGroup _small; ZRelocationSetSelectorGroup _medium; - size_t _live; - size_t _garbage; + ZRelocationSetSelectorGroup _large; public: ZRelocationSetSelector(); @@ -72,9 +111,7 @@ void register_garbage_page(ZPage* page); void select(ZRelocationSet* relocation_set); - size_t live() const; - size_t garbage() const; - size_t relocating() const; + ZRelocationSetSelectorStats stats() const; }; #endif // SHARE_GC_Z_ZRELOCATIONSETSELECTOR_HPP --- old/src/hotspot/share/gc/z/zStat.cpp 2020-01-21 12:41:10.576699995 +0100 +++ new/src/hotspot/share/gc/z/zStat.cpp 2020-01-21 12:41:09.994688187 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ #include "gc/z/zLargePages.inline.hpp" #include "gc/z/zNMethodTable.hpp" #include "gc/z/zNUMA.hpp" +#include "gc/z/zRelocationSetSelector.inline.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zTracer.inline.hpp" #include "gc/z/zUtils.hpp" @@ -41,12 +42,13 @@ #include "utilities/debug.hpp" #include "utilities/ticks.hpp" -#define ZSIZE_FMT SIZE_FORMAT "M(%.0f%%)" -#define ZSIZE_ARGS(size) ((size) / M), (percent_of(size, ZStatHeap::max_capacity())) - -#define ZTABLE_ARGS_NA "%9s", "-" -#define ZTABLE_ARGS(size) SIZE_FORMAT_W(8) "M (%.0f%%)", \ - ((size) / M), (percent_of(size, ZStatHeap::max_capacity())) +#define ZSIZE_FMT SIZE_FORMAT "M(%.0f%%)" +#define ZSIZE_ARGS_WITH_MAX(size, max) ((size) / M), (percent_of(size, max)) +#define ZSIZE_ARGS(size) ZSIZE_ARGS_WITH_MAX(size, ZStatHeap::max_capacity()) + +#define ZTABLE_ARGS_NA "%9s", "-" +#define ZTABLE_ARGS(size) SIZE_FORMAT_W(8) "M (%.0f%%)", \ + ((size) / M), (percent_of(size, ZStatHeap::max_capacity())) // // Stat sampler/counter data @@ -641,10 +643,10 @@ ZStatLoad::print(); ZStatMMU::print(); ZStatMark::print(); - ZStatRelocation::print(); ZStatNMethods::print(); ZStatMetaspace::print(); ZStatReferences::print(); + ZStatRelocation::print(); ZStatHeap::print(); log_info(gc)("Garbage Collection (%s) " ZSIZE_FMT "->" ZSIZE_FMT, @@ -1126,23 +1128,35 @@ // // Stat relocation // -size_t ZStatRelocation::_relocating; -bool ZStatRelocation::_success; +ZRelocationSetSelectorStats ZStatRelocation::_stats; +bool ZStatRelocation::_success; -void ZStatRelocation::set_at_select_relocation_set(size_t relocating) { - _relocating = relocating; +void ZStatRelocation::set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats) { + _stats = stats; } void ZStatRelocation::set_at_relocate_end(bool success) { _success = success; } +void ZStatRelocation::print(const char* name, const ZRelocationSetSelectorGroupStats& group) { + const size_t total = _stats.small().total() + _stats.medium().total() + _stats.large().total(); + + log_info(gc, reloc)("%s Pages: " SIZE_FORMAT " / " ZSIZE_FMT ", Empty: " ZSIZE_FMT ", Compacting: " ZSIZE_FMT "->" ZSIZE_FMT, + name, + group.npages(), + ZSIZE_ARGS_WITH_MAX(group.total(), total), + ZSIZE_ARGS_WITH_MAX(group.empty(), total), + ZSIZE_ARGS_WITH_MAX(group.compacting_from(), total), + ZSIZE_ARGS_WITH_MAX(group.compacting_to(), total)); +} + void ZStatRelocation::print() { - if (_success) { - log_info(gc, reloc)("Relocation: Successful, " SIZE_FORMAT "M relocated", _relocating / M); - } else { - log_info(gc, reloc)("Relocation: Incomplete"); - } + print("Small", _stats.small()); + print("Medium", _stats.medium()); + print("Large", _stats.large()); + + log_info(gc, reloc)("Relocation: %s", _success ? "Successful" : "Incomplete"); } // @@ -1278,9 +1292,10 @@ _at_mark_end.free = free(used); } -void ZStatHeap::set_at_select_relocation_set(size_t live, - size_t garbage, - size_t reclaimed) { +void ZStatHeap::set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats, size_t reclaimed) { + const size_t live = stats.small().live() + stats.medium().live() + stats.large().live(); + const size_t garbage = stats.small().garbage() + stats.medium().garbage() + stats.large().garbage(); + _at_mark_end.live = live; _at_mark_end.garbage = garbage; --- old/src/hotspot/share/gc/z/zStat.hpp 2020-01-21 12:41:11.298714645 +0100 +++ new/src/hotspot/share/gc/z/zStat.hpp 2020-01-21 12:41:10.778704094 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,8 @@ #include "utilities/ticks.hpp" class ZPage; +class ZRelocationSetSelectorGroupStats; +class ZRelocationSetSelectorStats; class ZStatSampler; class ZStatSamplerHistory; struct ZStatCounterData; @@ -418,11 +420,13 @@ // class ZStatRelocation : public AllStatic { private: - static size_t _relocating; - static bool _success; + static ZRelocationSetSelectorStats _stats; + static bool _success; + + static void print(const char* name, const ZRelocationSetSelectorGroupStats& group); public: - static void set_at_select_relocation_set(size_t relocating); + static void set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats); static void set_at_relocate_end(bool success); static void print(); @@ -540,8 +544,7 @@ static void set_at_mark_end(size_t capacity, size_t allocated, size_t used); - static void set_at_select_relocation_set(size_t live, - size_t garbage, + static void set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats, size_t reclaimed); static void set_at_relocate_start(size_t capacity, size_t allocated, --- /dev/null 2020-01-07 09:26:22.747784373 +0100 +++ new/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp 2020-01-21 12:41:11.471718155 +0100 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP +#define SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP + +#include "gc/z/zRelocationSetSelector.hpp" + +inline size_t ZRelocationSetSelectorGroupStats::npages() const { + return _npages; +} + +inline size_t ZRelocationSetSelectorGroupStats::total() const { + return _total; +} + +inline size_t ZRelocationSetSelectorGroupStats::live() const { + return _live; +} + +inline size_t ZRelocationSetSelectorGroupStats::garbage() const { + return _garbage; +} + +inline size_t ZRelocationSetSelectorGroupStats::empty() const { + return _empty; +} + +inline size_t ZRelocationSetSelectorGroupStats::compacting_from() const { + return _compacting_from; +} + +inline size_t ZRelocationSetSelectorGroupStats::compacting_to() const { + return _compacting_to; +} + +inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::small() const { + return _small; +} + +inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::medium() const { + return _medium; +} + +inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::large() const { + return _large; +} + +inline ZPage* const* ZRelocationSetSelectorGroup::selected() const { + return _sorted_pages; +} + +inline size_t ZRelocationSetSelectorGroup::nselected() const { + return _nselected; +} + +inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorGroup::stats() const { + return _stats; +} + +#endif // SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP