mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 01:24:49 +01:00
std.heap.PageAllocator: fix not respecting alignments
in remap and resize, alignments larger than page size were incorrectly ignored.
This commit is contained in:
parent
0a61eca22c
commit
5c59a46238
2 changed files with 21 additions and 24 deletions
|
|
@ -1,19 +1,17 @@
|
|||
const std = @import("../std.zig");
|
||||
const builtin = @import("builtin");
|
||||
const native_os = builtin.os.tag;
|
||||
|
||||
const std = @import("../std.zig");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Alignment = std.mem.Alignment;
|
||||
const mem = std.mem;
|
||||
const maxInt = std.math.maxInt;
|
||||
const assert = std.debug.assert;
|
||||
const native_os = builtin.os.tag;
|
||||
const windows = std.os.windows;
|
||||
const ntdll = windows.ntdll;
|
||||
const ntdll = std.os.windows.ntdll;
|
||||
const posix = std.posix;
|
||||
const page_size_min = std.heap.page_size_min;
|
||||
|
||||
const SUCCESS = @import("../os/windows/ntstatus.zig").NTSTATUS.SUCCESS;
|
||||
const MEM_RESERVE_PLACEHOLDER = windows.MEM_RESERVE_PLACEHOLDER;
|
||||
const MEM_PRESERVE_PLACEHOLDER = windows.MEM_PRESERVE_PLACEHOLDER;
|
||||
|
||||
pub const vtable: Allocator.VTable = .{
|
||||
.alloc = alloc,
|
||||
.resize = resize,
|
||||
|
|
@ -21,7 +19,7 @@ pub const vtable: Allocator.VTable = .{
|
|||
.free = free,
|
||||
};
|
||||
|
||||
pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
|
||||
pub fn map(n: usize, alignment: Alignment) ?[*]u8 {
|
||||
const page_size = std.heap.pageSize();
|
||||
if (n >= maxInt(usize) - page_size) return null;
|
||||
const alignment_bytes = alignment.toByteUnits();
|
||||
|
|
@ -33,11 +31,11 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
|
|||
const current_process = windows.GetCurrentProcess();
|
||||
var status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true, .RESERVE = true }, .{ .READWRITE = true });
|
||||
|
||||
if (status == SUCCESS and mem.isAligned(@intFromPtr(base_addr), alignment_bytes)) {
|
||||
if (status == .SUCCESS and mem.isAligned(@intFromPtr(base_addr), alignment_bytes)) {
|
||||
return @ptrCast(base_addr);
|
||||
}
|
||||
|
||||
if (status == SUCCESS) {
|
||||
if (status == .SUCCESS) {
|
||||
var region_size: windows.SIZE_T = 0;
|
||||
_ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&base_addr), ®ion_size, .{ .RELEASE = true });
|
||||
}
|
||||
|
|
@ -50,7 +48,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
|
|||
|
||||
status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .RESERVE = true, .RESERVE_PLACEHOLDER = true }, .{ .NOACCESS = true });
|
||||
|
||||
if (status != SUCCESS) return null;
|
||||
if (status != .SUCCESS) return null;
|
||||
|
||||
const placeholder_addr = @intFromPtr(base_addr);
|
||||
const aligned_addr = mem.alignForward(usize, placeholder_addr, alignment_bytes);
|
||||
|
|
@ -75,7 +73,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
|
|||
|
||||
status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true }, .{ .READWRITE = true });
|
||||
|
||||
if (status == SUCCESS) {
|
||||
if (status == .SUCCESS) {
|
||||
return @ptrCast(base_addr);
|
||||
}
|
||||
|
||||
|
|
@ -116,31 +114,29 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 {
|
|||
return result_ptr;
|
||||
}
|
||||
|
||||
fn alloc(context: *anyopaque, n: usize, alignment: mem.Alignment, ra: usize) ?[*]u8 {
|
||||
fn alloc(context: *anyopaque, n: usize, alignment: Alignment, ra: usize) ?[*]u8 {
|
||||
_ = context;
|
||||
_ = ra;
|
||||
assert(n > 0);
|
||||
return map(n, alignment);
|
||||
}
|
||||
|
||||
fn resize(context: *anyopaque, memory: []u8, alignment: mem.Alignment, new_len: usize, return_address: usize) bool {
|
||||
fn resize(context: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, return_address: usize) bool {
|
||||
_ = context;
|
||||
_ = alignment;
|
||||
_ = return_address;
|
||||
return realloc(memory, new_len, false) != null;
|
||||
return realloc(memory, alignment, new_len, false) != null;
|
||||
}
|
||||
|
||||
fn remap(context: *anyopaque, memory: []u8, alignment: mem.Alignment, new_len: usize, return_address: usize) ?[*]u8 {
|
||||
fn remap(context: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, return_address: usize) ?[*]u8 {
|
||||
_ = context;
|
||||
_ = alignment;
|
||||
_ = return_address;
|
||||
return realloc(memory, new_len, true);
|
||||
return realloc(memory, alignment, new_len, true);
|
||||
}
|
||||
|
||||
fn free(context: *anyopaque, memory: []u8, alignment: mem.Alignment, return_address: usize) void {
|
||||
fn free(context: *anyopaque, memory: []u8, alignment: Alignment, return_address: usize) void {
|
||||
_ = context;
|
||||
_ = alignment;
|
||||
_ = return_address;
|
||||
_ = alignment;
|
||||
return unmap(@alignCast(memory));
|
||||
}
|
||||
|
||||
|
|
@ -155,9 +151,10 @@ pub fn unmap(memory: []align(page_size_min) u8) void {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn realloc(uncasted_memory: []u8, new_len: usize, may_move: bool) ?[*]u8 {
|
||||
pub fn realloc(uncasted_memory: []u8, alignment: Alignment, new_len: usize, may_move: bool) ?[*]u8 {
|
||||
const memory: []align(page_size_min) u8 = @alignCast(uncasted_memory);
|
||||
const page_size = std.heap.pageSize();
|
||||
if (alignment.toByteUnits() > page_size) return null;
|
||||
const new_size_aligned = mem.alignForward(usize, new_len, page_size);
|
||||
|
||||
if (native_os == .windows) {
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ fn resize(context: *anyopaque, memory: []u8, alignment: mem.Alignment, new_len:
|
|||
const new_class = sizeClassIndex(new_len, alignment);
|
||||
if (class >= size_class_count) {
|
||||
if (new_class < size_class_count) return false;
|
||||
return PageAllocator.realloc(memory, new_len, false) != null;
|
||||
return PageAllocator.realloc(memory, alignment, new_len, false) != null;
|
||||
}
|
||||
return new_class == class;
|
||||
}
|
||||
|
|
@ -191,7 +191,7 @@ fn remap(context: *anyopaque, memory: []u8, alignment: mem.Alignment, new_len: u
|
|||
const new_class = sizeClassIndex(new_len, alignment);
|
||||
if (class >= size_class_count) {
|
||||
if (new_class < size_class_count) return null;
|
||||
return PageAllocator.realloc(memory, new_len, true);
|
||||
return PageAllocator.realloc(memory, alignment, new_len, true);
|
||||
}
|
||||
return if (new_class == class) memory.ptr else null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue