Skip to content

Commit 5ad4a91

Browse files
committed
8268127: Shenandoah: Heap size may be too small for region to align to large page size
Reviewed-by: rkennke, shade
1 parent 7a37816 commit 5ad4a91

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,13 @@ void ShenandoahArguments::initialize() {
5454

5555
FLAG_SET_DEFAULT(ShenandoahVerifyOptoBarriers, false);
5656
#endif
57-
58-
if (UseLargePages && (MaxHeapSize / os::large_page_size()) < ShenandoahHeapRegion::MIN_NUM_REGIONS) {
59-
warning("Large pages size (" SIZE_FORMAT "K) is too large to afford page-sized regions, disabling uncommit",
60-
os::large_page_size() / K);
61-
FLAG_SET_DEFAULT(ShenandoahUncommit, false);
57+
if (UseLargePages) {
58+
size_t large_page_size = os::large_page_size();
59+
if ((align_up(MaxHeapSize, large_page_size) / large_page_size) < ShenandoahHeapRegion::MIN_NUM_REGIONS) {
60+
warning("Large pages size (" SIZE_FORMAT "K) is too large to afford page-sized regions, disabling uncommit",
61+
os::large_page_size() / K);
62+
FLAG_SET_DEFAULT(ShenandoahUncommit, false);
63+
}
6264
}
6365

6466
// Enable NUMA by default. While Shenandoah is not NUMA-aware, enabling NUMA makes
@@ -177,7 +179,7 @@ size_t ShenandoahArguments::conservative_max_heap_alignment() {
177179

178180
void ShenandoahArguments::initialize_alignments() {
179181
// Need to setup sizes early to get correct alignments.
180-
ShenandoahHeapRegion::setup_sizes(MaxHeapSize);
182+
MaxHeapSize = ShenandoahHeapRegion::setup_sizes(MaxHeapSize);
181183

182184
// This is expected by our algorithm for ShenandoahHeap::heap_region_containing().
183185
size_t align = ShenandoahHeapRegion::region_size_bytes();

src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ size_t ShenandoahHeapRegion::block_size(const HeapWord* p) const {
467467
}
468468
}
469469

470-
void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
470+
size_t ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
471471
// Absolute minimums we should not ever break.
472472
static const size_t MIN_REGION_SIZE = 256*K;
473473

@@ -542,14 +542,29 @@ void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
542542
region_size = ShenandoahRegionSize;
543543
}
544544

545-
// Make sure region size is at least one large page, if enabled.
546-
// The heap sizes would be rounded by heap initialization code by
547-
// page size, so we need to round up the region size too, to cover
548-
// the heap exactly.
545+
// Make sure region size and heap size are page aligned.
546+
// If large pages are used, we ensure that region size is aligned to large page size if
547+
// heap size is large enough to accommodate minimal number of regions. Otherwise, we align
548+
// region size to regular page size.
549+
550+
// Figure out page size to use, and aligns up heap to page size
551+
int page_size = os::vm_page_size();
549552
if (UseLargePages) {
550-
region_size = MAX2(region_size, os::large_page_size());
553+
size_t large_page_size = os::large_page_size();
554+
max_heap_size = align_up(max_heap_size, large_page_size);
555+
if ((max_heap_size / align_up(region_size, large_page_size)) >= MIN_NUM_REGIONS) {
556+
page_size = (int)large_page_size;
557+
} else {
558+
// Should have been checked during argument initialization
559+
assert(!ShenandoahUncommit, "Uncommit requires region size aligns to large page size");
560+
}
561+
} else {
562+
max_heap_size = align_up(max_heap_size, page_size);
551563
}
552564

565+
// Align region size to page size
566+
region_size = align_up(region_size, page_size);
567+
553568
int region_size_log = log2i(region_size);
554569
// Recalculate the region size to make sure it's a power of
555570
// 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) {
612627
guarantee(MaxTLABSizeBytes == 0, "we should only set it once");
613628
MaxTLABSizeBytes = MaxTLABSizeWords * HeapWordSize;
614629
assert (MaxTLABSizeBytes > MinTLABSize, "should be larger");
630+
631+
return max_heap_size;
615632
}
616633

617634
void ShenandoahHeapRegion::do_commit() {

src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ class ShenandoahHeapRegion {
251251

252252
static const size_t MIN_NUM_REGIONS = 10;
253253

254-
static void setup_sizes(size_t max_heap_size);
254+
// Return adjusted max heap size
255+
static size_t setup_sizes(size_t max_heap_size);
255256

256257
double empty_time() {
257258
return _empty_time;

0 commit comments

Comments
 (0)