authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-12 14:58:49-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-12 16:30:27-08:00
log0957761d5c26ef23c04333120974323109a38f93
treef4add6adfe3577d18345e3c3b1105a1d781dd6d2
parent6296924214fe8f0c08c7fcf30ecce5974133d1b4

std.heap.BrkAllocator: fix incorrect assumptions


1 files changed, 12 insertions(+), 14 deletions(-)

lib/std/heap/BrkAllocator.zig+12-14
...@@ -10,7 +10,6 @@ const Allocator = std.mem.Allocator;...@@ -10,7 +10,6 @@ const Allocator = std.mem.Allocator;
10const Alignment = std.mem.Alignment;10const Alignment = std.mem.Alignment;
11const assert = std.debug.assert;11const assert = std.debug.assert;
12const math = std.math;12const math = std.math;
13const page_size_max = std.heap.page_size_max;
1413
15comptime {14comptime {
16 if (!builtin.single_threaded) @compileError("unsupported");15 if (!builtin.single_threaded) @compileError("unsupported");
...@@ -36,14 +35,9 @@ pub const Error = Allocator.Error;...@@ -36,14 +35,9 @@ pub const Error = Allocator.Error;
3635
37const max_usize = math.maxInt(usize);36const max_usize = math.maxInt(usize);
38const ushift = math.Log2Int(usize);37const ushift = math.Log2Int(usize);
39const bigpage_size = 64 * 1024;38const bigpage_size: comptime_int = @max(64 * 1024, std.heap.page_size_max);
40const pages_per_bigpage = bigpage_size / page_size_max;
41const bigpage_count = max_usize / bigpage_size;39const bigpage_count = max_usize / bigpage_size;
4240
43comptime {
44 assert(bigpage_size >= page_size_max);
45}
46
47/// Because of storing free list pointers, the minimum size class is 3.41/// Because of storing free list pointers, the minimum size class is 3.
48const min_class = math.log2(math.ceilPowerOfTwoAssert(usize, 1 + @sizeOf(usize)));42const min_class = math.log2(math.ceilPowerOfTwoAssert(usize, 1 + @sizeOf(usize)));
49const size_class_count = math.log2(bigpage_size) - min_class;43const size_class_count = math.log2(bigpage_size) - min_class;
...@@ -70,7 +64,7 @@ fn alloc(ctx: *anyopaque, len: usize, alignment: Alignment, return_address: usiz...@@ -70,7 +64,7 @@ fn alloc(ctx: *anyopaque, len: usize, alignment: Alignment, return_address: usiz
70 }64 }
7165
72 const next_addr = global.next_addrs[class];66 const next_addr = global.next_addrs[class];
73 if (next_addr % page_size_max == 0) {67 if (next_addr % bigpage_size == 0) {
74 const addr = allocBigPages(1);68 const addr = allocBigPages(1);
75 if (addr == 0) return null;69 if (addr == 0) return null;
76 //std.debug.print("allocated fresh slot_size={d} class={d} addr=0x{x}\n", .{70 //std.debug.print("allocated fresh slot_size={d} class={d} addr=0x{x}\n", .{
...@@ -172,15 +166,19 @@ fn allocBigPages(n: usize) usize {...@@ -172,15 +166,19 @@ fn allocBigPages(n: usize) usize {
172 }166 }
173167
174 if (builtin.cpu.arch.isWasm()) {168 if (builtin.cpu.arch.isWasm()) {
169 comptime assert(std.heap.page_size_max == std.heap.page_size_min);
170 const page_size = std.heap.page_size_max;
171 const pages_per_bigpage = bigpage_size / page_size;
175 const page_index = @wasmMemoryGrow(0, pow2_pages * pages_per_bigpage);172 const page_index = @wasmMemoryGrow(0, pow2_pages * pages_per_bigpage);
176 if (page_index == -1) return 0;173 if (page_index == -1) return 0;
177 return @as(usize, @intCast(page_index)) * page_size_max;174 return @as(usize, @intCast(page_index)) * page_size;
178 } else if (builtin.os.tag == .linux) {175 } else if (builtin.os.tag == .linux) {
179 const start_brk = s: {176 const prev_brk = global.prev_brk;
180 const start_brk = global.prev_brk;177 const start_brk = if (prev_brk == 0)
181 break :s if (start_brk == 0) std.os.linux.brk(0) else start_brk;178 std.mem.alignForward(usize, std.os.linux.brk(0), bigpage_size)
182 };179 else
183 const end_brk = start_brk + pow2_pages * pages_per_bigpage * page_size_max;180 prev_brk;
181 const end_brk = start_brk + pow2_pages * bigpage_size;
184 const new_prev_brk = std.os.linux.brk(end_brk);182 const new_prev_brk = std.os.linux.brk(end_brk);
185 global.prev_brk = new_prev_brk;183 global.prev_brk = new_prev_brk;
186 if (new_prev_brk != end_brk) return 0;184 if (new_prev_brk != end_brk) return 0;