8268127: Shenandoah: Heap size may be too small for region to align to large page size

Reviewed-by: rkennke, shade
This commit is contained in:
Zhengyu Gu 2021-06-08 20:31:22 +00:00
parent 7a37816548
commit 5ad4a91c3d
3 changed files with 33 additions and 13 deletions

View File

@ -54,11 +54,13 @@ void ShenandoahArguments::initialize() {
FLAG_SET_DEFAULT(ShenandoahVerifyOptoBarriers, false);
#endif
if (UseLargePages && (MaxHeapSize / os::large_page_size()) < ShenandoahHeapRegion::MIN_NUM_REGIONS) {
warning("Large pages size (" SIZE_FORMAT "K) is too large to afford page-sized regions, disabling uncommit",
os::large_page_size() / K);
FLAG_SET_DEFAULT(ShenandoahUncommit, false);
if (UseLargePages) {
size_t large_page_size = os::large_page_size();
if ((align_up(MaxHeapSize, large_page_size) / large_page_size) < ShenandoahHeapRegion::MIN_NUM_REGIONS) {
warning("Large pages size (" SIZE_FORMAT "K) is too large to afford page-sized regions, disabling uncommit",
os::large_page_size() / K);
FLAG_SET_DEFAULT(ShenandoahUncommit, false);
}
}
// Enable NUMA by default. While Shenandoah is not NUMA-aware, enabling NUMA makes
@ -177,7 +179,7 @@ size_t ShenandoahArguments::conservative_max_heap_alignment() {
void ShenandoahArguments::initialize_alignments() {
// Need to setup sizes early to get correct alignments.
ShenandoahHeapRegion::setup_sizes(MaxHeapSize);
MaxHeapSize = ShenandoahHeapRegion::setup_sizes(MaxHeapSize);
// This is expected by our algorithm for ShenandoahHeap::heap_region_containing().
size_t align = ShenandoahHeapRegion::region_size_bytes();

View File

@ -467,7 +467,7 @@ size_t ShenandoahHeapRegion::block_size(const HeapWord* p) const {
}
}
void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
size_t ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
// Absolute minimums we should not ever break.
static const size_t MIN_REGION_SIZE = 256*K;
@ -542,14 +542,29 @@ void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
region_size = ShenandoahRegionSize;
}
// Make sure region size is at least one large page, if enabled.
// The heap sizes would be rounded by heap initialization code by
// page size, so we need to round up the region size too, to cover
// the heap exactly.
// Make sure region size and heap size are page aligned.
// If large pages are used, we ensure that region size is aligned to large page size if
// heap size is large enough to accommodate minimal number of regions. Otherwise, we align
// region size to regular page size.
// Figure out page size to use, and aligns up heap to page size
int page_size = os::vm_page_size();
if (UseLargePages) {
region_size = MAX2(region_size, os::large_page_size());
size_t large_page_size = os::large_page_size();
max_heap_size = align_up(max_heap_size, large_page_size);
if ((max_heap_size / align_up(region_size, large_page_size)) >= MIN_NUM_REGIONS) {
page_size = (int)large_page_size;
} else {
// Should have been checked during argument initialization
assert(!ShenandoahUncommit, "Uncommit requires region size aligns to large page size");
}
} else {
max_heap_size = align_up(max_heap_size, page_size);
}
// Align region size to page size
region_size = align_up(region_size, page_size);
int region_size_log = log2i(region_size);
// Recalculate the region size to make sure it's a power of
// 2. This means that region_size is the largest power of 2 that's
@ -612,6 +627,8 @@ void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
guarantee(MaxTLABSizeBytes == 0, "we should only set it once");
MaxTLABSizeBytes = MaxTLABSizeWords * HeapWordSize;
assert (MaxTLABSizeBytes > MinTLABSize, "should be larger");
return max_heap_size;
}
void ShenandoahHeapRegion::do_commit() {

View File

@ -251,7 +251,8 @@ public:
static const size_t MIN_NUM_REGIONS = 10;
static void setup_sizes(size_t max_heap_size);
// Return adjusted max heap size
static size_t setup_sizes(size_t max_heap_size);
double empty_time() {
return _empty_time;