From d2585e68a79b8e43166e797d6adc33282acac046 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 15 Jan 2026 13:48:27 -0800 Subject: [PATCH] std.Io.Threaded: use NtExtendSection in fileMemoryMapSetLength is this a good idea? not sure yet. reverting in the next commit --- lib/std/Io/Threaded.zig | 57 +++++++++++++++++++++++------------- lib/std/os/windows/ntdll.zig | 5 ++++ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index c7cccf08d496d7401e4c0286989919e18bf9c9ac..e0f5804abafe373c3dae01ed2df0585d3a6c0fae 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -16279,6 +16279,8 @@ fn createFileMap( .SUCCESS => {}, .CONFLICTING_ADDRESSES => return error.MappingAlreadyExists, .SECTION_PROTECTION => return error.PermissionDenied, + .ACCESS_DENIED => return error.AccessDenied, + .INVALID_VIEW_SIZE => |status| return windows.statusBug(status), else => |status| return windows.unexpectedStatus(status), } if (builtin.mode == .Debug) { @@ -16392,32 +16394,47 @@ fn fileMemoryMapSetLength( const new_len = options.len; if (mm.section) |section| { - if (alignment.forward(new_len) == alignment.forward(old_memory.len)) { + const aligned_old_len = alignment.forward(old_memory.len); + const aligned_new_len = alignment.forward(new_len); + if (aligned_new_len == aligned_old_len) { mm.memory.len = new_len; return; } switch (native_os) { .windows => { - var contents_ptr: ?[*]align(page_align) u8 = null; - var contents_len = new_len; - switch (windows.ntdll.NtMapViewOfSection( - section, - windows.current_process, - @ptrCast(&contents_ptr), - null, - 0, - null, - &contents_len, - .Unmap, - .{}, - .{ .READWRITE = true }, - )) { - .SUCCESS => {}, - .SECTION_PROTECTION => return error.PermissionDenied, - else => |status| return windows.unexpectedStatus(status), + if (aligned_new_len > aligned_old_len) { + var new_section_size: windows.LARGE_INTEGER = @intCast(aligned_new_len); + switch (windows.ntdll.NtExtendSection(section, &new_section_size)) { + .SUCCESS => {}, + else => |status| return windows.unexpectedStatus(status), + } + assert(new_section_size == aligned_new_len); + mm.memory.len = new_len; + } else { + _ = windows.ntdll.NtUnmapViewOfSection(windows.current_process, old_memory.ptr); + windows.CloseHandle(section); + var contents_len = aligned_new_len; + var contents_ptr: ?[*]align(std.heap.page_size_min) u8 = null; + switch (windows.ntdll.NtMapViewOfSection( + section, + windows.current_process, + @ptrCast(&contents_ptr), + null, + 0, + null, + &contents_len, + .Unmap, + .{}, + .{ .READWRITE = true }, + )) { + .SUCCESS => {}, + .SECTION_PROTECTION => return error.PermissionDenied, + .INVALID_VIEW_SIZE => |status| return windows.statusBug(status), + else => |status| return windows.unexpectedStatus(status), + } + assert(contents_len == aligned_new_len); + mm.memory = contents_ptr.?[0..new_len]; } - assert(contents_len == alignment.forward(new_len)); - mm.memory = contents_ptr.?[0..new_len]; }, .wasi => unreachable, .linux => { diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 0a424fa7b2f150384bff5bbdae61d84b5e5fabb2..1cc17c0be6f56ef03909df8af7742c15472c9b93 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -253,6 +253,11 @@ pub extern "ntdll" fn NtCreateSection( FileHandle: ?HANDLE, ) callconv(.winapi) NTSTATUS; +pub extern "ntdll" fn NtExtendSection( + SectionHandle: HANDLE, + NewSectionSize: *LARGE_INTEGER, +) callconv(.winapi) NTSTATUS; + pub extern "ntdll" fn NtAllocateVirtualMemory( ProcessHandle: HANDLE, BaseAddress: *PVOID, -- 2.54.0