From 35986bdcf6cb08c634796a8d91c075fe9c9f0e85 Mon Sep 17 00:00:00 2001 From: Robert Toyonaga Date: Tue, 7 Apr 2026 18:17:50 -0400 Subject: [PATCH] split up map_or_reserve_memory_aligned_va2 into map_memory_aligned_va2 and reserve_memory_aligned_va2 --- src/hotspot/os/windows/os_windows.cpp | 91 ++++++++++++++++----------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 53a4e85cf71..ff86100930a 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -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, - ¶m, 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, ¶m, 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, + ¶m, 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 {