< prev index next >
src/hotspot/share/gc/z/zRelocationSetSelector.cpp
Print this page
*** 23,57 ****
#include "precompiled.hpp"
#include "gc/z/zArray.inline.hpp"
#include "gc/z/zPage.inline.hpp"
#include "gc/z/zRelocationSet.hpp"
! #include "gc/z/zRelocationSetSelector.hpp"
#include "logging/log.hpp"
#include "runtime/globals.hpp"
#include "utilities/debug.hpp"
ZRelocationSetSelectorGroup::ZRelocationSetSelectorGroup(const char* name,
size_t page_size,
size_t object_size_limit) :
_name(name),
_page_size(page_size),
_object_size_limit(object_size_limit),
_fragmentation_limit(page_size * (ZFragmentationLimit / 100)),
_registered_pages(),
_sorted_pages(NULL),
_nselected(0),
! _relocating(0) {}
ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() {
FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages);
}
! void ZRelocationSetSelectorGroup::register_live_page(ZPage* page, size_t garbage) {
if (garbage > _fragmentation_limit) {
_registered_pages.add(page);
}
}
void ZRelocationSetSelectorGroup::semi_sort() {
// Semi-sort registered pages by live bytes in ascending order
const size_t npartitions_shift = 11;
--- 23,85 ----
#include "precompiled.hpp"
#include "gc/z/zArray.inline.hpp"
#include "gc/z/zPage.inline.hpp"
#include "gc/z/zRelocationSet.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) :
_name(name),
_page_size(page_size),
_object_size_limit(object_size_limit),
_fragmentation_limit(page_size * (ZFragmentationLimit / 100)),
_registered_pages(),
_sorted_pages(NULL),
_nselected(0),
! _stats() {}
ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() {
FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages);
}
! 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() {
// Semi-sort registered pages by live bytes in ascending order
const size_t npartitions_shift = 11;
*** 62,72 ****
// Partition slots/fingers
size_t partitions[npartitions];
// Allocate destination array
! _sorted_pages = REALLOC_C_HEAP_ARRAY(ZPage*, _sorted_pages, npages, mtGC);
debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*)));
// Calculate partition slots
memset(partitions, 0, sizeof(partitions));
ZArrayIterator<ZPage*> iter1(&_registered_pages);
--- 90,101 ----
// Partition slots/fingers
size_t partitions[npartitions];
// Allocate destination array
! 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
memset(partitions, 0, sizeof(partitions));
ZArrayIterator<ZPage*> iter1(&_registered_pages);
*** 103,113 ****
// a candidate relocation set and calculate the maximum space requirement for
// their live objects.
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();
for (size_t from = 1; from <= npages; from++) {
--- 132,141 ----
*** 128,212 ****
const size_t diff_to = to - selected_to;
const double diff_reclaimable = 100 - percent_of(diff_to, diff_from);
if (diff_reclaimable > ZFragmentationLimit) {
selected_from = from;
selected_to = to;
- selected_from_size = from_size;
}
log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): "
SIZE_FORMAT "->" SIZE_FORMAT ", %.1f%% relative defragmentation, %s",
_name, from, to, diff_reclaimable, (selected_from == from) ? "Selected" : "Rejected");
}
// 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;
! }
!
! size_t ZRelocationSetSelectorGroup::relocating() const {
! return _relocating;
}
ZRelocationSetSelector::ZRelocationSetSelector() :
_small("Small", ZPageSizeSmall, ZObjectSizeLimitSmall),
_medium("Medium", ZPageSizeMedium, ZObjectSizeLimitMedium),
! _live(0),
! _garbage(0) {}
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);
} else if (type == ZPageTypeMedium) {
! _medium.register_live_page(page, garbage);
}
-
- _live += live;
- _garbage += garbage;
}
void ZRelocationSetSelector::register_garbage_page(ZPage* page) {
! _garbage += page->size();
}
void ZRelocationSetSelector::select(ZRelocationSet* relocation_set) {
// Select pages to relocate. The resulting relocation set will be
// sorted such that medium pages comes first, followed by small
// pages. Pages within each page group will be semi-sorted by live
// bytes in ascending order. Relocating pages in this order allows
// us to start reclaiming memory more quickly.
! // Select pages from each group
_medium.select();
_small.select();
// Populate relocation set
relocation_set->populate(_medium.selected(), _medium.nselected(),
_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();
- }
--- 156,222 ----
const size_t diff_to = to - selected_to;
const double diff_reclaimable = 100 - percent_of(diff_to, diff_from);
if (diff_reclaimable > ZFragmentationLimit) {
selected_from = from;
selected_to = to;
}
log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): "
SIZE_FORMAT "->" SIZE_FORMAT ", %.1f%% relative defragmentation, %s",
_name, from, to, diff_reclaimable, (selected_from == from) ? "Selected" : "Rejected");
}
// Finalize selection
_nselected = selected_from;
! // Update statistics
! _stats._compacting_from = selected_from * _page_size;
! _stats._compacting_to = selected_to * _page_size;
! 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),
! _large("Large", 0 /* page_size */, 0 /* object_size_limit */) {}
void ZRelocationSetSelector::register_live_page(ZPage* page) {
const uint8_t type = page->type();
if (type == ZPageTypeSmall) {
! _small.register_live_page(page);
} else if (type == ZPageTypeMedium) {
! _medium.register_live_page(page);
! } else {
! _large.register_live_page(page);
}
}
void ZRelocationSetSelector::register_garbage_page(ZPage* page) {
! 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) {
// Select pages to relocate. The resulting relocation set will be
// sorted such that medium pages comes first, followed by small
// pages. Pages within each page group will be semi-sorted by live
// bytes in ascending order. Relocating pages in this order allows
// us to start reclaiming memory more quickly.
! // Select pages from each group, except large
_medium.select();
_small.select();
// Populate relocation set
relocation_set->populate(_medium.selected(), _medium.nselected(),
_small.selected(), _small.nselected());
}
< prev index next >