split up map_or_reserve_memory_aligned_va2 into map_memory_aligned_va2 and reserve_memory_aligned_va2

This commit is contained in:
Robert Toyonaga 2026-04-07 18:17:50 -04:00
parent d431181f5c
commit 35986bdcf6

View File

@ -3284,6 +3284,10 @@ static bool is_VirtualAlloc2_supported() {
return os::win32::VirtualAlloc2 != nullptr;
}
static bool is_MapViewOfFile3_supported() {
return os::win32::MapViewOfFile3 != nullptr;
}
// Multiple threads can race in this code but it's not possible to unmap small sections of
// virtual space to get requested alignment, like posix-like os's.
// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
@ -3326,8 +3330,9 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi
return aligned_base;
}
// VirtualAlloc2 and MapViewOfFile3 support alignment natively.
static char* map_or_reserve_memory_aligned_va2(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
// MapViewOfFile3 supports alignment natively.
static char* map_memory_aligned_va2(size_t size, size_t alignment, int file_desc, MemTag mem_tag) {
assert(file_desc != -1,"file descriptor should not be -1");
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
@ -3342,46 +3347,66 @@ static char* map_or_reserve_memory_aligned_va2(size_t size, size_t alignment, in
char* aligned_base = nullptr;
if (file_desc != -1 && os::win32::MapViewOfFile3 != nullptr) {
// File-backed aligned mapping.
HANDLE fh = (HANDLE)_get_osfhandle(file_desc);
HANDLE fileMapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,(DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), nullptr);
if (fileMapping != nullptr) {
aligned_base = (char*)os::win32::MapViewOfFile3(
fileMapping,
GetCurrentProcess(),
nullptr, // let the system choose an aligned address
0, // offset
size,
0, // no special allocation type flags
PAGE_READWRITE,
&param, 1);
CloseHandle(fileMapping);
}
} else if (file_desc == -1) {
// Anonymous aligned reservation.
aligned_base = (char*)os::win32::VirtualAlloc2(
// File-backed aligned mapping.
HANDLE fh = (HANDLE)_get_osfhandle(file_desc);
HANDLE fileMapping = CreateFileMapping(fh, nullptr, PAGE_READWRITE,(DWORD)(size >> 32), (DWORD)(size & 0xFFFFFFFF), nullptr);
if (fileMapping != nullptr) {
aligned_base = (char*)os::win32::MapViewOfFile3(
fileMapping,
GetCurrentProcess(),
nullptr, // let the system choose an aligned address
0, // offset
size,
MEM_RESERVE,
0, // no special allocation type flags
PAGE_READWRITE,
&param, 1);
CloseHandle(fileMapping);
}
if (aligned_base != nullptr) {
assert(is_aligned(aligned_base, alignment), "Result must be aligned");
if (file_desc == -1) {
MemTracker::record_virtual_memory_reserve(aligned_base, size, CALLER_PC, mem_tag);
} else {
MemTracker::record_virtual_memory_reserve_and_commit(aligned_base, size, CALLER_PC, mem_tag);
}
MemTracker::record_virtual_memory_reserve_and_commit(aligned_base, size, CALLER_PC, mem_tag);
return aligned_base;
}
log_trace(os)("Aligned allocation via VirtualAlloc2/MapViewOfFile3 failed, falling back to retry loop. GetLastError->%lu.", GetLastError());
return map_or_reserve_memory_aligned(size, alignment, file_desc, mem_tag);
}
// VirtualAlloc2 supports alignment natively.
static char* reserve_memory_aligned_va2(size_t size, size_t alignment, MemTag mem_tag) {
assert(is_aligned(alignment, os::vm_allocation_granularity()),
"Alignment must be a multiple of allocation granularity");
assert(is_aligned(size, os::vm_allocation_granularity()),
"Size must be a multiple of allocation granularity");
MEM_ADDRESS_REQUIREMENTS requirements = {0};
requirements.Alignment = alignment;
MEM_EXTENDED_PARAMETER param = {0};
param.Type = MemExtendedParameterAddressRequirements;
param.Pointer = &requirements;
char* aligned_base = nullptr;
// Anonymous aligned reservation.
aligned_base = (char*)os::win32::VirtualAlloc2(
GetCurrentProcess(),
nullptr, // let the system choose an aligned address
size,
MEM_RESERVE,
PAGE_READWRITE,
&param, 1);
if (aligned_base != nullptr) {
assert(is_aligned(aligned_base, alignment), "Result must be aligned");
MemTracker::record_virtual_memory_reserve(aligned_base, size, CALLER_PC, mem_tag);
return aligned_base;
}
log_trace(os)("Aligned allocation via VirtualAlloc2 failed, falling back to retry loop. GetLastError->%lu.", GetLastError());
return map_or_reserve_memory_aligned(size, alignment, -1, mem_tag);
}
size_t os::commit_memory_limit() {
BOOL is_in_job_object = false;
BOOL res = IsProcessInJob(GetCurrentProcess(), nullptr, &is_in_job_object);
@ -3430,14 +3455,14 @@ size_t os::reserve_memory_limit() {
char* os::reserve_memory_aligned(size_t size, size_t alignment, MemTag mem_tag, bool exec) {
// exec can be ignored
if (is_VirtualAlloc2_supported()) {
return map_or_reserve_memory_aligned_va2(size, alignment, -1/* file_desc */, mem_tag);
return reserve_memory_aligned_va2(size, alignment, mem_tag);
}
return map_or_reserve_memory_aligned(size, alignment, -1/* file_desc */, mem_tag);
}
char* os::map_memory_to_file_aligned(size_t size, size_t alignment, int fd, MemTag mem_tag) {
if (is_VirtualAlloc2_supported()) {
return map_or_reserve_memory_aligned_va2(size, alignment, fd, mem_tag);
if (is_MapViewOfFile3_supported()) {
return map_memory_aligned_va2(size, alignment, fd, mem_tag);
}
return map_or_reserve_memory_aligned(size, alignment, fd, mem_tag);
}
@ -3461,12 +3486,6 @@ static os::PlaceholderRegion reserve_placeholder_memory_helper(size_t bytes, boo
nullptr, 0);
if (res != nullptr) {
if (addr != nullptr && res != addr) {
// Got a different address than requested; release and fail.
virtualFree(res, 0, MEM_RELEASE);
log_warning(os)("VirtualAlloc2 placeholder at requested " PTR_FORMAT " returned different address " PTR_FORMAT ", released.", p2i(addr), p2i(res));
return os::PlaceholderRegion();
}
log_trace(os)("VirtualAlloc2 placeholder of size (%zu) returned " PTR_FORMAT ".", bytes, p2i(res));
return os::PlaceholderRegion(res, bytes);
} else {