| ... | @@ -10,7 +10,6 @@ const Allocator = std.mem.Allocator; | ... | @@ -10,7 +10,6 @@ const Allocator = std.mem.Allocator; |
| 10 | const Alignment = std.mem.Alignment; | 10 | const Alignment = std.mem.Alignment; |
| 11 | const assert = std.debug.assert; | 11 | const assert = std.debug.assert; |
| 12 | const math = std.math; | 12 | const math = std.math; |
| 13 | const page_size_max = std.heap.page_size_max; | | |
| 14 | | 13 | |
| 15 | comptime { | 14 | comptime { |
| 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; |
| 36 | | 35 | |
| 37 | const max_usize = math.maxInt(usize); | 36 | const max_usize = math.maxInt(usize); |
| 38 | const ushift = math.Log2Int(usize); | 37 | const ushift = math.Log2Int(usize); |
| 39 | const bigpage_size = 64 * 1024; | 38 | const bigpage_size: comptime_int = @max(64 * 1024, std.heap.page_size_max); |
| 40 | const pages_per_bigpage = bigpage_size / page_size_max; | | |
| 41 | const bigpage_count = max_usize / bigpage_size; | 39 | const bigpage_count = max_usize / bigpage_size; |
| 42 | | 40 | |
| 43 | comptime { | | |
| 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. |
| 48 | const min_class = math.log2(math.ceilPowerOfTwoAssert(usize, 1 + @sizeOf(usize))); | 42 | const min_class = math.log2(math.ceilPowerOfTwoAssert(usize, 1 + @sizeOf(usize))); |
| 49 | const size_class_count = math.log2(bigpage_size) - min_class; | 43 | const 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 | } |
| 71 | | 65 | |
| 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 | } |
| 173 | | 167 | |
| 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; |