Skip to content

Commit af2fbd5

Browse files
committed
8367413: Fix potential truncation error in Arguments::set_heap_size()
Reviewed-by: ayang, lkorinth
1 parent 991f8e6 commit af2fbd5

File tree

1 file changed

+67
-55
lines changed

1 file changed

+67
-55
lines changed

src/hotspot/share/runtime/arguments.cpp

Lines changed: 67 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "classfile/stringTable.hpp"
3232
#include "classfile/symbolTable.hpp"
3333
#include "compiler/compilerDefinitions.hpp"
34+
#include "gc/shared/gc_globals.hpp"
3435
#include "gc/shared/gcArguments.hpp"
3536
#include "gc/shared/gcConfig.hpp"
3637
#include "gc/shared/genArguments.hpp"
@@ -1506,49 +1507,59 @@ size_t Arguments::limit_heap_by_allocatable_memory(size_t limit) {
15061507
// Use static initialization to get the default before parsing
15071508
static const size_t DefaultHeapBaseMinAddress = HeapBaseMinAddress;
15081509

1510+
static size_t clamp_by_size_t_max(uint64_t value) {
1511+
return (size_t)MIN2(value, (uint64_t)std::numeric_limits<size_t>::max());
1512+
}
1513+
15091514
void Arguments::set_heap_size() {
1510-
julong phys_mem;
1511-
1512-
// If the user specified one of these options, they
1513-
// want specific memory sizing so do not limit memory
1514-
// based on compressed oops addressability.
1515-
// Also, memory limits will be calculated based on
1516-
// available os physical memory, not our MaxRAM limit,
1517-
// unless MaxRAM is also specified.
1518-
bool override_coop_limit = (!FLAG_IS_DEFAULT(MaxRAMPercentage) ||
1519-
!FLAG_IS_DEFAULT(MinRAMPercentage) ||
1520-
!FLAG_IS_DEFAULT(InitialRAMPercentage) ||
1521-
!FLAG_IS_DEFAULT(MaxRAM));
1522-
if (override_coop_limit) {
1523-
if (FLAG_IS_DEFAULT(MaxRAM)) {
1524-
phys_mem = static_cast<julong>(os::physical_memory());
1525-
FLAG_SET_ERGO(MaxRAM, (uint64_t)phys_mem);
1515+
uint64_t physical_memory;
1516+
1517+
// Check if the user has configured any limit on the amount of RAM we may use.
1518+
bool has_ram_limit = !FLAG_IS_DEFAULT(MaxRAMPercentage) ||
1519+
!FLAG_IS_DEFAULT(MinRAMPercentage) ||
1520+
!FLAG_IS_DEFAULT(InitialRAMPercentage) ||
1521+
!FLAG_IS_DEFAULT(MaxRAM);
1522+
1523+
if (has_ram_limit) {
1524+
if (!FLAG_IS_DEFAULT(MaxRAM)) {
1525+
// The user has configured MaxRAM, use that instead of physical memory
1526+
// reported by the OS.
1527+
physical_memory = MaxRAM;
15261528
} else {
1527-
phys_mem = (julong)MaxRAM;
1529+
// The user has configured a limit, make sure MaxRAM reflects the physical
1530+
// memory limit that heap sizing takes into account.
1531+
physical_memory = os::physical_memory();
1532+
FLAG_SET_ERGO(MaxRAM, physical_memory);
15281533
}
15291534
} else {
1530-
phys_mem = FLAG_IS_DEFAULT(MaxRAM) ? MIN2(static_cast<julong>(os::physical_memory()), (julong)MaxRAM)
1531-
: (julong)MaxRAM;
1535+
// If the user did not specify any limit, choose the lowest of the available
1536+
// physical memory and MaxRAM. MaxRAM is typically set to 128GB on 64-bit
1537+
// architecture.
1538+
physical_memory = MIN2(os::physical_memory(), MaxRAM);
15321539
}
15331540

1534-
// If the maximum heap size has not been set with -Xmx,
1535-
// then set it as fraction of the size of physical memory,
1536-
// respecting the maximum and minimum sizes of the heap.
1541+
// If the maximum heap size has not been set with -Xmx, then set it as
1542+
// fraction of the size of physical memory, respecting the maximum and
1543+
// minimum sizes of the heap.
15371544
if (FLAG_IS_DEFAULT(MaxHeapSize)) {
1538-
julong reasonable_max = (julong)(((double)phys_mem * MaxRAMPercentage) / 100);
1539-
const julong reasonable_min = (julong)(((double)phys_mem * MinRAMPercentage) / 100);
1545+
uint64_t min_memory = (uint64_t)(((double)physical_memory * MinRAMPercentage) / 100);
1546+
uint64_t max_memory = (uint64_t)(((double)physical_memory * MaxRAMPercentage) / 100);
1547+
1548+
const size_t reasonable_min = clamp_by_size_t_max(min_memory);
1549+
size_t reasonable_max = clamp_by_size_t_max(max_memory);
1550+
15401551
if (reasonable_min < MaxHeapSize) {
15411552
// Small physical memory, so use a minimum fraction of it for the heap
15421553
reasonable_max = reasonable_min;
15431554
} else {
15441555
// Not-small physical memory, so require a heap at least
15451556
// as large as MaxHeapSize
1546-
reasonable_max = MAX2(reasonable_max, (julong)MaxHeapSize);
1557+
reasonable_max = MAX2(reasonable_max, MaxHeapSize);
15471558
}
15481559

15491560
if (!FLAG_IS_DEFAULT(ErgoHeapSizeLimit) && ErgoHeapSizeLimit != 0) {
15501561
// Limit the heap size to ErgoHeapSizeLimit
1551-
reasonable_max = MIN2(reasonable_max, (julong)ErgoHeapSizeLimit);
1562+
reasonable_max = MIN2(reasonable_max, ErgoHeapSizeLimit);
15521563
}
15531564

15541565
reasonable_max = limit_heap_by_allocatable_memory(reasonable_max);
@@ -1558,9 +1569,9 @@ void Arguments::set_heap_size() {
15581569
// so be sure that the maximum size is consistent. Done
15591570
// after call to limit_heap_by_allocatable_memory because that
15601571
// method might reduce the allocation size.
1561-
reasonable_max = MAX2(reasonable_max, (julong)InitialHeapSize);
1572+
reasonable_max = MAX2(reasonable_max, InitialHeapSize);
15621573
} else if (!FLAG_IS_DEFAULT(MinHeapSize)) {
1563-
reasonable_max = MAX2(reasonable_max, (julong)MinHeapSize);
1574+
reasonable_max = MAX2(reasonable_max, MinHeapSize);
15641575
}
15651576

15661577
#ifdef _LP64
@@ -1569,70 +1580,71 @@ void Arguments::set_heap_size() {
15691580
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) {
15701581
if (HeapBaseMinAddress < DefaultHeapBaseMinAddress) {
15711582
// matches compressed oops printing flags
1572-
log_debug(gc, heap, coops)("HeapBaseMinAddress must be at least %zu"
1573-
" (%zuG) which is greater than value given %zu",
1583+
log_debug(gc, heap, coops)("HeapBaseMinAddress must be at least %zu "
1584+
"(%zuG) which is greater than value given %zu",
15741585
DefaultHeapBaseMinAddress,
15751586
DefaultHeapBaseMinAddress/G,
15761587
HeapBaseMinAddress);
15771588
FLAG_SET_ERGO(HeapBaseMinAddress, DefaultHeapBaseMinAddress);
15781589
}
15791590
}
15801591
}
1592+
15811593
if (UseCompressedOops) {
1582-
// Limit the heap size to the maximum possible when using compressed oops
1583-
julong max_coop_heap = (julong)max_heap_for_compressed_oops();
1594+
size_t heap_end = HeapBaseMinAddress + MaxHeapSize;
1595+
size_t max_coop_heap = max_heap_for_compressed_oops();
15841596

1585-
if (HeapBaseMinAddress + MaxHeapSize < max_coop_heap) {
1586-
// Heap should be above HeapBaseMinAddress to get zero based compressed oops
1587-
// but it should be not less than default MaxHeapSize.
1597+
// Limit the heap size to the maximum possible when using compressed oops
1598+
if (heap_end < max_coop_heap) {
1599+
// Heap should be above HeapBaseMinAddress to get zero based compressed
1600+
// oops but it should be not less than default MaxHeapSize.
15881601
max_coop_heap -= HeapBaseMinAddress;
15891602
}
15901603

1591-
// If user specified flags prioritizing os physical
1592-
// memory limits, then disable compressed oops if
1593-
// limits exceed max_coop_heap and UseCompressedOops
1594-
// was not specified.
1604+
// If the user has configured any limit on the amount of RAM we may use,
1605+
// then disable compressed oops if the calculated max exceeds max_coop_heap
1606+
// and UseCompressedOops was not specified.
15951607
if (reasonable_max > max_coop_heap) {
1596-
if (FLAG_IS_ERGO(UseCompressedOops) && override_coop_limit) {
1597-
aot_log_info(aot)("UseCompressedOops disabled due to"
1598-
" max heap %zu > compressed oop heap %zu. "
1599-
"Please check the setting of MaxRAMPercentage %5.2f."
1600-
,(size_t)reasonable_max, (size_t)max_coop_heap, MaxRAMPercentage);
1608+
if (FLAG_IS_ERGO(UseCompressedOops) && has_ram_limit) {
1609+
aot_log_info(aot)("UseCompressedOops disabled due to "
1610+
"max heap %zu > compressed oop heap %zu. "
1611+
"Please check the setting of MaxRAMPercentage %5.2f.",
1612+
reasonable_max, max_coop_heap, MaxRAMPercentage);
16011613
FLAG_SET_ERGO(UseCompressedOops, false);
16021614
} else {
1603-
reasonable_max = MIN2(reasonable_max, max_coop_heap);
1615+
reasonable_max = max_coop_heap;
16041616
}
16051617
}
16061618
}
16071619
#endif // _LP64
16081620

1609-
log_trace(gc, heap)(" Maximum heap size %zu", (size_t) reasonable_max);
1610-
FLAG_SET_ERGO(MaxHeapSize, (size_t)reasonable_max);
1621+
log_trace(gc, heap)(" Maximum heap size %zu", reasonable_max);
1622+
FLAG_SET_ERGO(MaxHeapSize, reasonable_max);
16111623
}
16121624

16131625
// If the minimum or initial heap_size have not been set or requested to be set
16141626
// ergonomically, set them accordingly.
16151627
if (InitialHeapSize == 0 || MinHeapSize == 0) {
1616-
julong reasonable_minimum = (julong)(OldSize + NewSize);
1617-
1618-
reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize);
1619-
1628+
size_t reasonable_minimum = clamp_by_size_t_max((uint64_t)OldSize + (uint64_t)NewSize);
1629+
reasonable_minimum = MIN2(reasonable_minimum, MaxHeapSize);
16201630
reasonable_minimum = limit_heap_by_allocatable_memory(reasonable_minimum);
16211631

16221632
if (InitialHeapSize == 0) {
1623-
julong reasonable_initial = (julong)(((double)phys_mem * InitialRAMPercentage) / 100);
1633+
uint64_t initial_memory = (uint64_t)(((double)physical_memory * InitialRAMPercentage) / 100);
1634+
size_t reasonable_initial = clamp_by_size_t_max(initial_memory);
16241635
reasonable_initial = limit_heap_by_allocatable_memory(reasonable_initial);
16251636

1626-
reasonable_initial = MAX3(reasonable_initial, reasonable_minimum, (julong)MinHeapSize);
1627-
reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize);
1637+
reasonable_initial = MAX3(reasonable_initial, reasonable_minimum, MinHeapSize);
1638+
reasonable_initial = MIN2(reasonable_initial, MaxHeapSize);
16281639

16291640
FLAG_SET_ERGO(InitialHeapSize, (size_t)reasonable_initial);
16301641
log_trace(gc, heap)(" Initial heap size %zu", InitialHeapSize);
16311642
}
1643+
16321644
// If the minimum heap size has not been set (via -Xms or -XX:MinHeapSize),
16331645
// synchronize with InitialHeapSize to avoid errors with the default value.
16341646
if (MinHeapSize == 0) {
1635-
FLAG_SET_ERGO(MinHeapSize, MIN2((size_t)reasonable_minimum, InitialHeapSize));
1647+
FLAG_SET_ERGO(MinHeapSize, MIN2(reasonable_minimum, InitialHeapSize));
16361648
log_trace(gc, heap)(" Minimum heap size %zu", MinHeapSize);
16371649
}
16381650
}

0 commit comments

Comments
 (0)