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;
1010const Alignment = std.mem.Alignment;
1111const assert = std.debug.assert;
1212const math = std.math;
13const page_size_max = std.heap.page_size_max;
1413
1514comptime {
1615 if (!builtin.single_threaded) @compileError("unsupported");
......@@ -36,14 +35,9 @@ pub const Error = Allocator.Error;
3635
3736const max_usize = math.maxInt(usize);
3837const ushift = math.Log2Int(usize);
39const bigpage_size = 64 * 1024;
40const pages_per_bigpage = bigpage_size / page_size_max;
38const bigpage_size: comptime_int = @max(64 * 1024, std.heap.page_size_max);
4139const bigpage_count = max_usize / bigpage_size;
4240
43comptime {
44 assert(bigpage_size >= page_size_max);
45}
46
4741/// Because of storing free list pointers, the minimum size class is 3.
4842const min_class = math.log2(math.ceilPowerOfTwoAssert(usize, 1 + @sizeOf(usize)));
4943const size_class_count = math.log2(bigpage_size) - min_class;
......@@ -70,7 +64,7 @@ fn alloc(ctx: *anyopaque, len: usize, alignment: Alignment, return_address: usiz
7064 }
7165
7266 const next_addr = global.next_addrs[class];
73 if (next_addr % page_size_max == 0) {
67 if (next_addr % bigpage_size == 0) {
7468 const addr = allocBigPages(1);
7569 if (addr == 0) return null;
7670 //std.debug.print("allocated fresh slot_size={d} class={d} addr=0x{x}\n", .{
......@@ -172,15 +166,19 @@ fn allocBigPages(n: usize) usize {
172166 }
173167
174168 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;
175172 const page_index = @wasmMemoryGrow(0, pow2_pages * pages_per_bigpage);
176173 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;
178175 } else if (builtin.os.tag == .linux) {
179 const start_brk = s: {
180 const start_brk = global.prev_brk;
181 break :s if (start_brk == 0) std.os.linux.brk(0) else start_brk;
182 };
183 const end_brk = start_brk + pow2_pages * pages_per_bigpage * page_size_max;
176 const prev_brk = global.prev_brk;
177 const start_brk = if (prev_brk == 0)
178 std.mem.alignForward(usize, std.os.linux.brk(0), bigpage_size)
179 else
180 prev_brk;
181 const end_brk = start_brk + pow2_pages * bigpage_size;
184182 const new_prev_brk = std.os.linux.brk(end_brk);
185183 global.prev_brk = new_prev_brk;
186184 if (new_prev_brk != end_brk) return 0;