Skip to content
This repository was archived by the owner on Sep 2, 2022. It is now read-only.

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,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
Expand Down Expand Up @@ -184,7 +186,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();
Expand Down
30 changes: 23 additions & 7 deletions src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
#include "gc/shared/space.inline.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/resourceArea.hpp"
Expand Down Expand Up @@ -465,7 +464,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;

Expand Down Expand Up @@ -540,14 +539,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 = log2_long((jlong) 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
Expand Down Expand Up @@ -610,6 +624,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() {
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ class ShenandoahHeapRegion {

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;
Expand Down