Skip to content

Make PageAllocator use next_mmap_addr_hint on Windows #17377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
squeek502 opened this issue Oct 3, 2023 · 3 comments
Open

Make PageAllocator use next_mmap_addr_hint on Windows #17377

squeek502 opened this issue Oct 3, 2023 · 3 comments
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. enhancement Solving this issue will likely involve adding new logic or components to the codebase. os-windows standard library This issue involves writing Zig code for the standard library.
Milestone

Comments

@squeek502
Copy link
Collaborator

squeek502 commented Oct 3, 2023

This is a TODO in the code currently:

zig/lib/std/heap.zig

Lines 31 to 32 in 412d863

/// TODO Utilize this on Windows.
pub var next_mmap_addr_hint: ?[*]align(mem.page_size) u8 = null;

On non-Windows systems, PageAllocator uses this to make the addresses returned always increase to avoid memory addresses being re-used. This is useful/necessary for the GeneralPurposeAllocator to behave as documented:

//! * Do not re-use memory slots, so that memory safety is upheld. For small
//! allocations, this is handled here; for larger ones it is handled in the
//! backing allocator (by default `std.heap.page_allocator`).

I'm converting this into an issue to better track progress towards addressing this on Windows.

Right now, VirtualAlloc is used in PageAllocator, but if the function VirtualAlloc2 was used instead (on >= Windows 10), it would allow the use of next_mmap_addr_hint via LowestStartingAddress

@dweiller has tried to make a binding for VirtualAlloc2 for unrelated reasons but ran into some problems. Relevant Discord links:

I'm having problems trying to cross compile (from linux) a dll using VirtualAlloc2(). My investigations online have pointed to a few issues people have had with the microsoft docs (at least at one point) indicating incorrect dependencies and mingw not exporting it (mingw-w64/mingw-w64#27). I don't really understand what the files in lib/libc/mingw/lib{32,-common} are used for though I gather they define the symbols exported by some libraries and I see that zig only includes VirtualAlloc2FromApp() in them, with VirtualAlloc2() only present in libs/libc/include/any-windows-any/memoryapi.h, which may be one issue (the github link above links to a change to mingw on Jul 28 2023 that adds VirtualAlloc2 to api-ms-win-core-memory-l1-1-6.def). However, attempting to switch to using VirtualAlloc2FromApp results in the same error reported by Zig which is:

error: lld-link: undefined symbol: VirtualAlloc2

This is with -target x86_64-windows-gnu -lkernel32 -ladvapi32 - I'm not 100% confident these linker flags are correct.

My response:

mostly guessing:

looks like the fix for mingw-w64/mingw-w64#27 isn't in the latest tagged mingw release either, so it might take even longer for the fix to make its way into zig

@squeek502 squeek502 added enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library. os-windows labels Oct 3, 2023
@Vexu Vexu added this to the 0.14.0 milestone Mar 26, 2024
@andrewrk andrewrk added the contributor friendly This issue is limited in scope and/or knowledge of Zig internals. label Feb 10, 2025
@andrewrk
Copy link
Member

VirtualAlloc2 is from kernel32. I think you are looking for NtAllocateVirtualMemory.

Related:

@Trevor-Strong
Copy link

NtAllocateVirtualMemory is just the NT version of VirtualAlloc/VirtualAllocEx. VitualAlloc2 is a wrapper around a different system call, which seems to be NtAllocateVirtualMemoryEx

@alichraghi
Copy link
Contributor

alichraghi commented Feb 12, 2025

for anyone having trouble finding NtAllocateVirtualMemoryEx definition in win32 api docs:

pub const MEM_EXTENDED_PARAMETER = extern struct {
    BitFields: ULONG64,
    Value: extern union {
        ULong64: DWORD64,
        Pointer: PVOID,
        Size: SIZE_T,
        Handle: HANDLE,
        ULong: DWORD,
    },
};

pub extern "ntdll" fn NtAllocateVirtualMemoryEx(
    ProcessHandle: HANDLE,
    BaseAddress: *?PVOID,
    RegionSize: *SIZE_T,
    AllocationType: ULONG,
    PageProtection: ULONG,
    ExtendedParameters: ?*MEM_EXTENDED_PARAMETER,
    ExtendedParameterCount: ULONG,
) callconv(.winapi) NTSTATUS;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. enhancement Solving this issue will likely involve adding new logic or components to the codebase. os-windows standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

No branches or pull requests

5 participants