| ... | ... | @@ -1,19 +1,17 @@ |
| 1 | | const std = @import("../std.zig"); |
| 2 | 1 | const builtin = @import("builtin"); |
| 2 | const native_os = builtin.os.tag; |
| 3 | |
| 4 | const std = @import("../std.zig"); |
| 3 | 5 | const Allocator = std.mem.Allocator; |
| 6 | const Alignment = std.mem.Alignment; |
| 4 | 7 | const mem = std.mem; |
| 5 | 8 | const maxInt = std.math.maxInt; |
| 6 | 9 | const assert = std.debug.assert; |
| 7 | | const native_os = builtin.os.tag; |
| 8 | 10 | const windows = std.os.windows; |
| 9 | | const ntdll = windows.ntdll; |
| 11 | const ntdll = std.os.windows.ntdll; |
| 10 | 12 | const posix = std.posix; |
| 11 | 13 | const page_size_min = std.heap.page_size_min; |
| 12 | 14 | |
| 13 | | const SUCCESS = @import("../os/windows/ntstatus.zig").NTSTATUS.SUCCESS; |
| 14 | | const MEM_RESERVE_PLACEHOLDER = windows.MEM_RESERVE_PLACEHOLDER; |
| 15 | | const MEM_PRESERVE_PLACEHOLDER = windows.MEM_PRESERVE_PLACEHOLDER; |
| 16 | | |
| 17 | 15 | pub const vtable: Allocator.VTable = .{ |
| 18 | 16 | .alloc = alloc, |
| 19 | 17 | .resize = resize, |
| ... | ... | @@ -21,7 +19,7 @@ pub const vtable: Allocator.VTable = .{ |
| 21 | 19 | .free = free, |
| 22 | 20 | }; |
| 23 | 21 | |
| 24 | | pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 { |
| 22 | pub fn map(n: usize, alignment: Alignment) ?[*]u8 { |
| 25 | 23 | const page_size = std.heap.pageSize(); |
| 26 | 24 | if (n >= maxInt(usize) - page_size) return null; |
| 27 | 25 | const alignment_bytes = alignment.toByteUnits(); |
| ... | ... | @@ -33,11 +31,11 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 { |
| 33 | 31 | const current_process = windows.GetCurrentProcess(); |
| 34 | 32 | var status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true, .RESERVE = true }, .{ .READWRITE = true }); |
| 35 | 33 | |
| 36 | | if (status == SUCCESS and mem.isAligned(@intFromPtr(base_addr), alignment_bytes)) { |
| 34 | if (status == .SUCCESS and mem.isAligned(@intFromPtr(base_addr), alignment_bytes)) { |
| 37 | 35 | return @ptrCast(base_addr); |
| 38 | 36 | } |
| 39 | 37 | |
| 40 | | if (status == SUCCESS) { |
| 38 | if (status == .SUCCESS) { |
| 41 | 39 | var region_size: windows.SIZE_T = 0; |
| 42 | 40 | _ = ntdll.NtFreeVirtualMemory(current_process, @ptrCast(&base_addr), &region_size, .{ .RELEASE = true }); |
| 43 | 41 | } |
| ... | ... | @@ -50,7 +48,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 { |
| 50 | 48 | |
| 51 | 49 | status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .RESERVE = true, .RESERVE_PLACEHOLDER = true }, .{ .NOACCESS = true }); |
| 52 | 50 | |
| 53 | | if (status != SUCCESS) return null; |
| 51 | if (status != .SUCCESS) return null; |
| 54 | 52 | |
| 55 | 53 | const placeholder_addr = @intFromPtr(base_addr); |
| 56 | 54 | const aligned_addr = mem.alignForward(usize, placeholder_addr, alignment_bytes); |
| ... | ... | @@ -75,7 +73,7 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 { |
| 75 | 73 | |
| 76 | 74 | status = ntdll.NtAllocateVirtualMemory(current_process, @ptrCast(&base_addr), 0, &size, .{ .COMMIT = true }, .{ .READWRITE = true }); |
| 77 | 75 | |
| 78 | | if (status == SUCCESS) { |
| 76 | if (status == .SUCCESS) { |
| 79 | 77 | return @ptrCast(base_addr); |
| 80 | 78 | } |
| 81 | 79 | |
| ... | ... | @@ -116,31 +114,29 @@ pub fn map(n: usize, alignment: mem.Alignment) ?[*]u8 { |
| 116 | 114 | return result_ptr; |
| 117 | 115 | } |
| 118 | 116 | |
| 119 | | fn alloc(context: *anyopaque, n: usize, alignment: mem.Alignment, ra: usize) ?[*]u8 { |
| 117 | fn alloc(context: *anyopaque, n: usize, alignment: Alignment, ra: usize) ?[*]u8 { |
| 120 | 118 | _ = context; |
| 121 | 119 | _ = ra; |
| 122 | 120 | assert(n > 0); |
| 123 | 121 | return map(n, alignment); |
| 124 | 122 | } |
| 125 | 123 | |
| 126 | | fn resize(context: *anyopaque, memory: []u8, alignment: mem.Alignment, new_len: usize, return_address: usize) bool { |
| 124 | fn resize(context: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, return_address: usize) bool { |
| 127 | 125 | _ = context; |
| 128 | | _ = alignment; |
| 129 | 126 | _ = return_address; |
| 130 | | return realloc(memory, new_len, false) != null; |
| 127 | return realloc(memory, alignment, new_len, false) != null; |
| 131 | 128 | } |
| 132 | 129 | |
| 133 | | fn remap(context: *anyopaque, memory: []u8, alignment: mem.Alignment, new_len: usize, return_address: usize) ?[*]u8 { |
| 130 | fn remap(context: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, return_address: usize) ?[*]u8 { |
| 134 | 131 | _ = context; |
| 135 | | _ = alignment; |
| 136 | 132 | _ = return_address; |
| 137 | | return realloc(memory, new_len, true); |
| 133 | return realloc(memory, alignment, new_len, true); |
| 138 | 134 | } |
| 139 | 135 | |
| 140 | | fn free(context: *anyopaque, memory: []u8, alignment: mem.Alignment, return_address: usize) void { |
| 136 | fn free(context: *anyopaque, memory: []u8, alignment: Alignment, return_address: usize) void { |
| 141 | 137 | _ = context; |
| 142 | | _ = alignment; |
| 143 | 138 | _ = return_address; |
| 139 | _ = alignment; |
| 144 | 140 | return unmap(@alignCast(memory)); |
| 145 | 141 | } |
| 146 | 142 | |
| ... | ... | @@ -155,9 +151,10 @@ pub fn unmap(memory: []align(page_size_min) u8) void { |
| 155 | 151 | } |
| 156 | 152 | } |
| 157 | 153 | |
| 158 | | pub fn realloc(uncasted_memory: []u8, new_len: usize, may_move: bool) ?[*]u8 { |
| 154 | pub fn realloc(uncasted_memory: []u8, alignment: Alignment, new_len: usize, may_move: bool) ?[*]u8 { |
| 159 | 155 | const memory: []align(page_size_min) u8 = @alignCast(uncasted_memory); |
| 160 | 156 | const page_size = std.heap.pageSize(); |
| 157 | if (alignment.toByteUnits() > page_size) return null; |
| 161 | 158 | const new_size_aligned = mem.alignForward(usize, new_len, page_size); |
| 162 | 159 | |
| 163 | 160 | if (native_os == .windows) { |