authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-14 19:30:37-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-15 14:18:20-08:00
logeb163361d9d7b61ee0b93b6f49efd24943c6027d
tree8cd0e0f390dcd7a45b688fc8e4250bea4d77bb1a
parent482189843220d4bd21ab4fdb737c20ee57580769

std.Io.File.MemoryMap: add some alignment type safety


2 files changed, 16 insertions(+), 12 deletions(-)

lib/std/Io/File/MemoryMap.zig+3-3
......@@ -13,9 +13,9 @@ file: File,
1313/// Byte index inside `file` where `memory` starts. Page-aligned.
1414offset: u64,
1515/// Memory that may or may not remain consistent with file contents. Use `read`
16/// and `write` to ensure synchronization points. Pointer is page-aligned but
17/// length is not.
18memory: []u8,
16/// and `write` to ensure synchronization points. Length has no alignment
17/// requirement.
18memory: []align(std.heap.page_size_min) u8,
1919/// Tells whether it is memory-mapped or file operations. On Windows this also
2020/// has a section handle.
2121section: ?Section,
lib/std/Io/Threaded.zig+13-9
......@@ -16198,7 +16198,7 @@ fn fileMemoryMapCreate(
1619816198 return .{
1619916199 .file = file,
1620016200 .offset = offset,
16201 .memory = memory,
16201 .memory = @alignCast(memory),
1620216202 .section = null,
1620316203 };
1620416204}
......@@ -16283,7 +16283,7 @@ fn createFileMap(
1628316283 return .{
1628416284 .file = file,
1628516285 .offset = offset,
16286 .memory = contents_ptr.?[0..contents_len],
16286 .memory = @alignCast(contents_ptr.?[0..contents_len]),
1628716287 .section = section,
1628816288 };
1628916289 } else if (have_mmap) {
......@@ -16297,6 +16297,8 @@ fn createFileMap(
1629716297 .POPULATE = populate,
1629816298 };
1629916299
16300 const page_align = std.heap.page_size_min;
16301
1630016302 const contents = while (true) {
1630116303 const syscall: Syscall = try .start();
1630216304 const casted_offset = std.math.cast(i64, offset) orelse return error.Unseekable;
......@@ -16304,13 +16306,13 @@ fn createFileMap(
1630416306 syscall.finish();
1630516307 const err: posix.E = if (builtin.link_libc) e: {
1630616308 if (rc != std.c.MAP_FAILED) {
16307 break @as([*]u8, @ptrCast(@alignCast(rc)))[0..aligned_len];
16309 break @as([*]align(page_align) u8, @ptrCast(@alignCast(rc)))[0..aligned_len];
1630816310 }
1630916311 break :e @enumFromInt(posix.system._errno().*);
1631016312 } else e: {
1631116313 const err = posix.errno(rc);
1631216314 if (err == .SUCCESS) {
16313 break @as([*]u8, @ptrFromInt(rc))[0..aligned_len];
16315 break @as([*]align(page_align) u8, @ptrFromInt(rc))[0..aligned_len];
1631416316 }
1631516317 break :e err;
1631616318 };
......@@ -16375,6 +16377,7 @@ fn fileMemoryMapSetLength(
1637516377 const t: *Threaded = @ptrCast(@alignCast(userdata));
1637616378 const page_size = std.heap.pageSize();
1637716379 const alignment: Alignment = .fromByteUnits(page_size);
16380 const page_align = std.heap.page_size_min;
1637816381
1637916382 if (mm.section) |section| {
1638016383 if (alignment.forward(new_len) == alignment.forward(mm.memory.len)) {
......@@ -16395,11 +16398,11 @@ fn fileMemoryMapSetLength(
1639516398 const rc = posix.system.mremap(mm.memory.ptr, mm.memory.len, new_len, flags, addr_hint);
1639616399 syscall.finish();
1639716400 const err: posix.E = if (builtin.link_libc) e: {
16398 if (rc != std.c.MAP_FAILED) break @as([*]u8, @ptrCast(@alignCast(rc)))[0..new_len];
16401 if (rc != std.c.MAP_FAILED) break @as([*]align(page_align) u8, @ptrCast(@alignCast(rc)))[0..new_len];
1639916402 break :e @enumFromInt(posix.system._errno().*);
1640016403 } else e: {
1640116404 const err = posix.errno(rc);
16402 if (err == .SUCCESS) break @as([*]u8, @ptrFromInt(rc))[0..new_len];
16405 if (err == .SUCCESS) break @as([*]align(page_align) u8, @ptrFromInt(rc))[0..new_len];
1640316406 break :e err;
1640416407 };
1640516408 switch (err) {
......@@ -16418,10 +16421,11 @@ fn fileMemoryMapSetLength(
1641816421 } else {
1641916422 const gpa = t.allocator;
1642016423 if (gpa.rawRemap(mm.memory, alignment, new_len, @returnAddress())) |new_ptr| {
16421 mm.memory = new_ptr[0..new_len];
16424 mm.memory = @alignCast(new_ptr[0..new_len]);
1642216425 } else {
16423 const new_ptr = gpa.rawAlloc(new_len, alignment, @returnAddress()) orelse
16424 return error.OutOfMemory;
16426 const new_ptr: [*]align(page_align) u8 = @alignCast(
16427 gpa.rawAlloc(new_len, alignment, @returnAddress()) orelse return error.OutOfMemory,
16428 );
1642516429 const copy_len = @min(new_len, mm.memory.len);
1642616430 @memcpy(new_ptr[0..copy_len], mm.memory[0..copy_len]);
1642716431 mm.memory = new_ptr[0..new_len];