Skip to content

Commit 232f1a7

Browse files
committed
Choose large page size based on MaxHeapSize
1 parent 5bfc5e5 commit 232f1a7

File tree

11 files changed

+102
-87
lines changed

11 files changed

+102
-87
lines changed

src/hotspot/share/gc/parallel/parallelArguments.cpp

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,21 @@
3838
#include "utilities/powerOfTwo.hpp"
3939

4040
size_t ParallelArguments::conservative_max_heap_alignment() {
41-
return compute_heap_alignment();
41+
// The card marking array and the offset arrays for old generations are
42+
// committed in os pages as well. Make sure they are entirely full (to
43+
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
44+
// byte entry and the os page size is 4096, the maximum heap size should
45+
// be 512*4096 = 2MB aligned.
46+
47+
size_t alignment = CardTable::ct_max_alignment_constraint();
48+
49+
if (UseLargePages) {
50+
// In presence of large pages we have to make sure that our
51+
// alignment is large page aware.
52+
alignment = lcm(os::large_page_size(), alignment);
53+
}
54+
55+
return alignment;
4256
}
4357

4458
void ParallelArguments::initialize() {
@@ -98,43 +112,53 @@ void ParallelArguments::initialize() {
98112
FullGCForwarding::initialize_flags(heap_reserved_size_bytes());
99113
}
100114

115+
static size_t num_young_spaces() {
116+
// When using NUMA, we create one MutableNUMASpace for each NUMA node
117+
const size_t num_eden_spaces = UseNUMA ? os::numa_get_groups_num() : 1;
118+
119+
// The young generation must have room for eden + two survivors
120+
return num_eden_spaces + 2;
121+
}
122+
123+
static size_t num_old_spaces() {
124+
return 1;
125+
}
126+
101127
void ParallelArguments::initialize_alignments() {
102128
// Initialize card size before initializing alignments
103129
CardTable::initialize_card_size();
130+
const size_t card_table_alignment = CardTable::ct_max_alignment_constraint();
104131
SpaceAlignment = ParallelScavengeHeap::default_space_alignment();
105-
HeapAlignment = compute_heap_alignment();
106-
}
107132

108-
void ParallelArguments::initialize_heap_flags_and_sizes_one_pass() {
109-
// Do basic sizing work
110-
GenArguments::initialize_heap_flags_and_sizes();
111-
}
133+
if (UseLargePages) {
134+
const size_t total_spaces = num_young_spaces() + num_old_spaces();
135+
const size_t page_size = os::page_size_for_region_unaligned(MaxHeapSize, total_spaces);
136+
ParallelScavengeHeap::set_desired_page_size(page_size);
112137

113-
void ParallelArguments::initialize_heap_flags_and_sizes() {
114-
initialize_heap_flags_and_sizes_one_pass();
138+
if (page_size == os::vm_page_size()) {
139+
log_warning(gc, heap)("MaxHeapSize (%zu) must be large enough for %zu * page-size; Disabling UseLargePages for heap",
140+
MaxHeapSize, total_spaces);
141+
}
115142

116-
if (!UseLargePages) {
117-
ParallelScavengeHeap::set_desired_page_size(os::vm_page_size());
118-
return;
119-
}
143+
if (page_size > SpaceAlignment) {
144+
SpaceAlignment = page_size;
145+
}
120146

121-
// If using large-page, need to update SpaceAlignment so that spaces are page-size aligned.
122-
const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
123-
const size_t page_sz = os::page_size_for_region_aligned(MinHeapSize, min_pages);
124-
ParallelScavengeHeap::set_desired_page_size(page_sz);
147+
HeapAlignment = lcm(page_size, card_table_alignment);
125148

126-
if (page_sz == os::vm_page_size()) {
127-
log_warning(gc, heap)("MinHeapSize (%zu) must be large enough for 4 * page-size; Disabling UseLargePages for heap", MinHeapSize);
128-
return;
149+
} else {
150+
assert(is_aligned(SpaceAlignment, os::vm_page_size()), "");
151+
ParallelScavengeHeap::set_desired_page_size(os::vm_page_size());
152+
HeapAlignment = card_table_alignment;
129153
}
154+
}
130155

131-
// Space is largepage-aligned.
132-
size_t new_alignment = page_sz;
133-
if (new_alignment != SpaceAlignment) {
134-
SpaceAlignment = new_alignment;
135-
// Redo everything from the start
136-
initialize_heap_flags_and_sizes_one_pass();
137-
}
156+
size_t ParallelArguments::young_gen_size_lower_bound() {
157+
return num_young_spaces() * SpaceAlignment;
158+
}
159+
160+
size_t ParallelArguments::old_gen_size_lower_bound() {
161+
return num_old_spaces() * SpaceAlignment;
138162
}
139163

140164
size_t ParallelArguments::heap_reserved_size_bytes() {

src/hotspot/share/gc/parallel/parallelArguments.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,12 @@ class CollectedHeap;
3333
class ParallelArguments : public GenArguments {
3434
private:
3535
virtual void initialize_alignments();
36-
virtual void initialize_heap_flags_and_sizes();
37-
38-
void initialize_heap_flags_and_sizes_one_pass();
3936

4037
virtual void initialize();
4138
virtual size_t conservative_max_heap_alignment();
4239
virtual CollectedHeap* create_heap();
40+
virtual size_t young_gen_size_lower_bound();
41+
virtual size_t old_gen_size_lower_bound();
4342

4443
public:
4544
static size_t heap_reserved_size_bytes();

src/hotspot/share/gc/serial/serialArguments.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,49 @@
2727
#include "gc/shared/fullGCForwarding.hpp"
2828
#include "gc/shared/gcArguments.hpp"
2929

30+
static size_t compute_heap_alignment() {
31+
// The card marking array and the offset arrays for old generations are
32+
// committed in os pages as well. Make sure they are entirely full (to
33+
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
34+
// byte entry and the os page size is 4096, the maximum heap size should
35+
// be 512*4096 = 2MB aligned.
36+
37+
size_t alignment = CardTable::ct_max_alignment_constraint();
38+
39+
if (UseLargePages) {
40+
// In presence of large pages we have to make sure that our
41+
// alignment is large page aware.
42+
alignment = lcm(os::large_page_size(), alignment);
43+
}
44+
45+
return alignment;
46+
}
47+
48+
size_t SerialArguments::conservative_max_heap_alignment() {
49+
return MAX2((size_t)Generation::GenGrain, compute_heap_alignment());
50+
}
51+
3052
void SerialArguments::initialize() {
3153
GCArguments::initialize();
3254
FullGCForwarding::initialize_flags(MaxHeapSize);
3355
}
3456

57+
void SerialArguments::initialize_alignments() {
58+
// Initialize card size before initializing alignments
59+
CardTable::initialize_card_size();
60+
SpaceAlignment = (size_t)Generation::GenGrain;
61+
HeapAlignment = compute_heap_alignment();
62+
}
63+
3564
CollectedHeap* SerialArguments::create_heap() {
3665
return new SerialHeap();
3766
}
67+
68+
size_t SerialArguments::young_gen_size_lower_bound() {
69+
// The young generation must be aligned and have room for eden + two survivors
70+
return 3 * SpaceAlignment;
71+
}
72+
73+
size_t SerialArguments::old_gen_size_lower_bound() {
74+
return SpaceAlignment;
75+
}

src/hotspot/share/gc/serial/serialArguments.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ class CollectedHeap;
3131

3232
class SerialArguments : public GenArguments {
3333
private:
34+
size_t conservative_max_heap_alignment();
3435
virtual void initialize();
36+
virtual void initialize_alignments();
3537
virtual CollectedHeap* create_heap();
38+
virtual size_t young_gen_size_lower_bound();
39+
virtual size_t old_gen_size_lower_bound();
3640
};
3741

3842
#endif // SHARE_GC_SERIAL_SERIALARGUMENTS_HPP

src/hotspot/share/gc/shared/gcArguments.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,6 @@ void GCArguments::initialize_heap_sizes() {
6262
initialize_size_info();
6363
}
6464

65-
size_t GCArguments::compute_heap_alignment() {
66-
// The card marking array and the offset arrays for old generations are
67-
// committed in os pages as well. Make sure they are entirely full (to
68-
// avoid partial page problems), e.g. if 512 bytes heap corresponds to 1
69-
// byte entry and the os page size is 4096, the maximum heap size should
70-
// be 512*4096 = 2MB aligned.
71-
72-
size_t alignment = CardTable::ct_max_alignment_constraint();
73-
74-
if (UseLargePages) {
75-
// In presence of large pages we have to make sure that our
76-
// alignment is large page aware.
77-
alignment = lcm(os::large_page_size(), alignment);
78-
}
79-
80-
return alignment;
81-
}
82-
8365
#ifdef ASSERT
8466
void GCArguments::assert_flags() {
8567
assert(InitialHeapSize <= MaxHeapSize, "Ergonomics decided on incompatible initial and maximum heap sizes");

src/hotspot/share/gc/shared/gcArguments.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class GCArguments {
4545

4646
public:
4747
virtual void initialize();
48+
49+
// Return the (conservative) maximum heap alignment
4850
virtual size_t conservative_max_heap_alignment() = 0;
4951

5052
// Used by heap size heuristics to determine max
@@ -59,8 +61,6 @@ class GCArguments {
5961
}
6062

6163
void initialize_heap_sizes();
62-
63-
static size_t compute_heap_alignment();
6464
};
6565

6666
#endif // SHARE_GC_SHARED_GCARGUMENTS_HPP

src/hotspot/share/gc/shared/genArguments.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,6 @@ size_t MaxOldSize = 0;
4242
// See more in JDK-8346005
4343
size_t OldSize = ScaleForWordSize(4*M);
4444

45-
size_t GenArguments::conservative_max_heap_alignment() { return (size_t)Generation::GenGrain; }
46-
47-
static size_t young_gen_size_lower_bound() {
48-
// The young generation must be aligned and have room for eden + two survivors
49-
return 3 * SpaceAlignment;
50-
}
51-
52-
static size_t old_gen_size_lower_bound() {
53-
return SpaceAlignment;
54-
}
55-
5645
size_t GenArguments::scale_by_NewRatio_aligned(size_t base_size, size_t alignment) {
5746
return align_down_bounded(base_size / (NewRatio + 1), alignment);
5847
}
@@ -64,13 +53,6 @@ static size_t bound_minus_alignment(size_t desired_size,
6453
return MIN2(desired_size, max_minus);
6554
}
6655

67-
void GenArguments::initialize_alignments() {
68-
// Initialize card size before initializing alignments
69-
CardTable::initialize_card_size();
70-
SpaceAlignment = (size_t)Generation::GenGrain;
71-
HeapAlignment = compute_heap_alignment();
72-
}
73-
7456
void GenArguments::initialize_heap_flags_and_sizes() {
7557
GCArguments::initialize_heap_flags_and_sizes();
7658

src/hotspot/share/gc/shared/genArguments.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,17 @@ extern size_t OldSize;
3838
class GenArguments : public GCArguments {
3939
friend class TestGenCollectorPolicy; // Testing
4040
private:
41-
virtual void initialize_alignments();
4241
virtual void initialize_size_info();
4342

44-
// Return the (conservative) maximum heap alignment
45-
virtual size_t conservative_max_heap_alignment();
46-
4743
DEBUG_ONLY(void assert_flags();)
4844
DEBUG_ONLY(void assert_size_info();)
4945

5046
static size_t scale_by_NewRatio_aligned(size_t base_size, size_t alignment);
5147

5248
protected:
5349
virtual void initialize_heap_flags_and_sizes();
50+
virtual size_t young_gen_size_lower_bound() = 0;
51+
virtual size_t old_gen_size_lower_bound() = 0;
5452
};
5553

5654
#endif // SHARE_GC_SHARED_GENARGUMENTS_HPP

src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ static JVMFlag::Error MaxSizeForHeapAlignment(const char* name, size_t value, bo
250250
} else
251251
#endif
252252
{
253-
heap_alignment = GCArguments::compute_heap_alignment();
253+
heap_alignment = Arguments::conservative_max_heap_alignment();
254254
}
255255

256256
return MaxSizeForAlignment(name, value, heap_alignment, verbose);

src/hotspot/share/runtime/arguments.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,10 +1478,9 @@ void Arguments::set_conservative_max_heap_alignment() {
14781478
// the alignments imposed by several sources: any requirements from the heap
14791479
// itself and the maximum page size we may run the VM with.
14801480
size_t heap_alignment = GCConfig::arguments()->conservative_max_heap_alignment();
1481-
_conservative_max_heap_alignment = MAX4(heap_alignment,
1481+
_conservative_max_heap_alignment = MAX3(heap_alignment,
14821482
os::vm_allocation_granularity(),
1483-
os::max_page_size(),
1484-
GCArguments::compute_heap_alignment());
1483+
os::max_page_size());
14851484
}
14861485

14871486
jint Arguments::set_ergonomics_flags() {

0 commit comments

Comments
 (0)