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,...@@ -13,9 +13,9 @@ file: File,
13/// Byte index inside `file` where `memory` starts. Page-aligned.13/// Byte index inside `file` where `memory` starts. Page-aligned.
14offset: u64,14offset: u64,
15/// Memory that may or may not remain consistent with file contents. Use `read`15/// Memory that may or may not remain consistent with file contents. Use `read`
16/// and `write` to ensure synchronization points. Pointer is page-aligned but16/// and `write` to ensure synchronization points. Length has no alignment
17/// length is not.17/// requirement.
18memory: []u8,18memory: []align(std.heap.page_size_min) u8,
19/// Tells whether it is memory-mapped or file operations. On Windows this also19/// Tells whether it is memory-mapped or file operations. On Windows this also
20/// has a section handle.20/// has a section handle.
21section: ?Section,21section: ?Section,
lib/std/Io/Threaded.zig+13-9
...@@ -16198,7 +16198,7 @@ fn fileMemoryMapCreate(...@@ -16198,7 +16198,7 @@ fn fileMemoryMapCreate(
16198 return .{16198 return .{
16199 .file = file,16199 .file = file,
16200 .offset = offset,16200 .offset = offset,
16201 .memory = memory,16201 .memory = @alignCast(memory),
16202 .section = null,16202 .section = null,
16203 };16203 };
16204}16204}
...@@ -16283,7 +16283,7 @@ fn createFileMap(...@@ -16283,7 +16283,7 @@ fn createFileMap(
16283 return .{16283 return .{
16284 .file = file,16284 .file = file,
16285 .offset = offset,16285 .offset = offset,
16286 .memory = contents_ptr.?[0..contents_len],16286 .memory = @alignCast(contents_ptr.?[0..contents_len]),
16287 .section = section,16287 .section = section,
16288 };16288 };
16289 } else if (have_mmap) {16289 } else if (have_mmap) {
...@@ -16297,6 +16297,8 @@ fn createFileMap(...@@ -16297,6 +16297,8 @@ fn createFileMap(
16297 .POPULATE = populate,16297 .POPULATE = populate,
16298 };16298 };
1629916299
16300 const page_align = std.heap.page_size_min;
16301
16300 const contents = while (true) {16302 const contents = while (true) {
16301 const syscall: Syscall = try .start();16303 const syscall: Syscall = try .start();
16302 const casted_offset = std.math.cast(i64, offset) orelse return error.Unseekable;16304 const casted_offset = std.math.cast(i64, offset) orelse return error.Unseekable;
...@@ -16304,13 +16306,13 @@ fn createFileMap(...@@ -16304,13 +16306,13 @@ fn createFileMap(
16304 syscall.finish();16306 syscall.finish();
16305 const err: posix.E = if (builtin.link_libc) e: {16307 const err: posix.E = if (builtin.link_libc) e: {
16306 if (rc != std.c.MAP_FAILED) {16308 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];
16308 }16310 }
16309 break :e @enumFromInt(posix.system._errno().*);16311 break :e @enumFromInt(posix.system._errno().*);
16310 } else e: {16312 } else e: {
16311 const err = posix.errno(rc);16313 const err = posix.errno(rc);
16312 if (err == .SUCCESS) {16314 if (err == .SUCCESS) {
16313 break @as([*]u8, @ptrFromInt(rc))[0..aligned_len];16315 break @as([*]align(page_align) u8, @ptrFromInt(rc))[0..aligned_len];
16314 }16316 }
16315 break :e err;16317 break :e err;
16316 };16318 };
...@@ -16375,6 +16377,7 @@ fn fileMemoryMapSetLength(...@@ -16375,6 +16377,7 @@ fn fileMemoryMapSetLength(
16375 const t: *Threaded = @ptrCast(@alignCast(userdata));16377 const t: *Threaded = @ptrCast(@alignCast(userdata));
16376 const page_size = std.heap.pageSize();16378 const page_size = std.heap.pageSize();
16377 const alignment: Alignment = .fromByteUnits(page_size);16379 const alignment: Alignment = .fromByteUnits(page_size);
16380 const page_align = std.heap.page_size_min;
1637816381
16379 if (mm.section) |section| {16382 if (mm.section) |section| {
16380 if (alignment.forward(new_len) == alignment.forward(mm.memory.len)) {16383 if (alignment.forward(new_len) == alignment.forward(mm.memory.len)) {
...@@ -16395,11 +16398,11 @@ fn fileMemoryMapSetLength(...@@ -16395,11 +16398,11 @@ fn fileMemoryMapSetLength(
16395 const rc = posix.system.mremap(mm.memory.ptr, mm.memory.len, new_len, flags, addr_hint);16398 const rc = posix.system.mremap(mm.memory.ptr, mm.memory.len, new_len, flags, addr_hint);
16396 syscall.finish();16399 syscall.finish();
16397 const err: posix.E = if (builtin.link_libc) e: {16400 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];
16399 break :e @enumFromInt(posix.system._errno().*);16402 break :e @enumFromInt(posix.system._errno().*);
16400 } else e: {16403 } else e: {
16401 const err = posix.errno(rc);16404 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];
16403 break :e err;16406 break :e err;
16404 };16407 };
16405 switch (err) {16408 switch (err) {
...@@ -16418,10 +16421,11 @@ fn fileMemoryMapSetLength(...@@ -16418,10 +16421,11 @@ fn fileMemoryMapSetLength(
16418 } else {16421 } else {
16419 const gpa = t.allocator;16422 const gpa = t.allocator;
16420 if (gpa.rawRemap(mm.memory, alignment, new_len, @returnAddress())) |new_ptr| {16423 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]);
16422 } else {16425 } else {
16423 const new_ptr = gpa.rawAlloc(new_len, alignment, @returnAddress()) orelse16426 const new_ptr: [*]align(page_align) u8 = @alignCast(
16424 return error.OutOfMemory;16427 gpa.rawAlloc(new_len, alignment, @returnAddress()) orelse return error.OutOfMemory,
16428 );
16425 const copy_len = @min(new_len, mm.memory.len);16429 const copy_len = @min(new_len, mm.memory.len);
16426 @memcpy(new_ptr[0..copy_len], mm.memory[0..copy_len]);16430 @memcpy(new_ptr[0..copy_len], mm.memory[0..copy_len]);
16427 mm.memory = new_ptr[0..new_len];16431 mm.memory = new_ptr[0..new_len];