authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-18 14:52:12-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-18 14:52:12-07:00
log9b177a7d21250b82cd18677c5c71ab04e431120d
tree0cd3ebe9366309a0bf3eef1e17c0815a5afabf9e
parent0346aef2da921a424e0763ed345adc207b4e684b
parente2c3920fb178a7e785036238a7c8207539b08902

Merge pull request 'Rework StackFallbackAllocator' (#31841) into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31841 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

24 files changed, 366 insertions(+), 304 deletions(-)

lib/compiler/aro/aro/CodeGen.zig+3-2
...@@ -54,8 +54,9 @@ return_label: Ir.Ref = undefined,...@@ -54,8 +54,9 @@ return_label: Ir.Ref = undefined,
54compound_assign_dummy: ?Ir.Ref = null,54compound_assign_dummy: ?Ir.Ref = null,
5555
56fn fail(c: *CodeGen, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {56fn fail(c: *CodeGen, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {
57 var sf = std.heap.stackFallback(1024, c.comp.gpa);57 var bfa_buf: [u8]1024 = undefined;
58 const allocator = sf.get();58 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, c.comp.gpa);
59 const allocator = bfa.allocator();
59 var buf: std.ArrayList(u8) = .empty;60 var buf: std.ArrayList(u8) = .empty;
60 defer buf.deinit(allocator);61 defer buf.deinit(allocator);
6162
lib/compiler/aro/aro/Compilation.zig+15-12
...@@ -1761,8 +1761,9 @@ fn addToSearchPath(comp: *Compilation, include: Include, verbose: bool) !void {...@@ -1761,8 +1761,9 @@ fn addToSearchPath(comp: *Compilation, include: Include, verbose: bool) !void {
1761 try comp.search_path.append(comp.gpa, include);1761 try comp.search_path.append(comp.gpa, include);
1762}1762}
1763fn removeDuplicateSearchPaths(comp: *Compilation, start: usize, verbose: bool) !void {1763fn removeDuplicateSearchPaths(comp: *Compilation, start: usize, verbose: bool) !void {
1764 var sf = std.heap.stackFallback(1024, comp.gpa);1764 var bfa_buf: [1024]u8 = undefined;
1765 const allocator = sf.get();1765 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, comp.gpa);
1766 const allocator = bfa.allocator();
1766 var seen_includes: std.StringHashMapUnmanaged(void) = .empty;1767 var seen_includes: std.StringHashMapUnmanaged(void) = .empty;
1767 defer seen_includes.deinit(allocator);1768 defer seen_includes.deinit(allocator);
1768 var seen_frameworks: std.StringHashMapUnmanaged(void) = .empty;1769 var seen_frameworks: std.StringHashMapUnmanaged(void) = .empty;
...@@ -1976,10 +1977,11 @@ const FindInclude = struct {...@@ -1976,10 +1977,11 @@ const FindInclude = struct {
1976 ) Allocator.Error!?Result {1977 ) Allocator.Error!?Result {
1977 const comp = find.comp;1978 const comp = find.comp;
19781979
1979 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);1980 var bfa_buf: [path_buf_stack_limit]u8 = undefined;
1980 const sfa = stack_fallback.get();1981 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, comp.gpa);
1981 const header_path = try std.fmt.allocPrint(sfa, format, args);1982 const bfa = bfa_state.allocator();
1982 defer sfa.free(header_path);1983 const header_path = try std.fmt.allocPrint(bfa, format, args);
1984 defer bfa.free(header_path);
1983 find.comp.normalizePath(header_path);1985 find.comp.normalizePath(header_path);
19841986
1985 const source = comp.addSourceFromPathExtra(header_path, kind) catch |err| switch (err) {1987 const source = comp.addSourceFromPathExtra(header_path, kind) catch |err| switch (err) {
...@@ -2068,14 +2070,15 @@ pub fn findEmbed(...@@ -2068,14 +2070,15 @@ pub fn findEmbed(
2068 }2070 }
2069 }2071 }
20702072
2071 var stack_fallback = std.heap.stackFallback(path_buf_stack_limit, comp.gpa);2073 var bfa_buf: [path_buf_stack_limit]u8 = undefined;
2072 const sf_allocator = stack_fallback.get();2074 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, comp.gpa);
2075 const bfa = bfa_state.allocator();
20732076
2074 switch (include_type) {2077 switch (include_type) {
2075 .quotes, .cli => {2078 .quotes, .cli => {
2076 const dir = std.fs.path.dirname(comp.getSource(includer_token_source).path) orelse ".";2079 const dir = std.fs.path.dirname(comp.getSource(includer_token_source).path) orelse ".";
2077 const path = try std.fs.path.join(sf_allocator, &.{ dir, filename });2080 const path = try std.fs.path.join(bfa, &.{ dir, filename });
2078 defer sf_allocator.free(path);2081 defer bfa.free(path);
2079 comp.normalizePath(path);2082 comp.normalizePath(path);
2080 if (comp.getPathContents(path, limit)) |some| {2083 if (comp.getPathContents(path, limit)) |some| {
2081 errdefer comp.gpa.free(some);2084 errdefer comp.gpa.free(some);
...@@ -2089,8 +2092,8 @@ pub fn findEmbed(...@@ -2089,8 +2092,8 @@ pub fn findEmbed(
2089 .angle_brackets => {},2092 .angle_brackets => {},
2090 }2093 }
2091 for (comp.embed_dirs.items) |embed_dir| {2094 for (comp.embed_dirs.items) |embed_dir| {
2092 const path = try std.fs.path.join(sf_allocator, &.{ embed_dir, filename });2095 const path = try std.fs.path.join(bfa, &.{ embed_dir, filename });
2093 defer sf_allocator.free(path);2096 defer bfa.free(path);
2094 comp.normalizePath(path);2097 comp.normalizePath(path);
2095 if (comp.getPathContents(path, limit)) |some| {2098 if (comp.getPathContents(path, limit)) |some| {
2096 errdefer comp.gpa.free(some);2099 errdefer comp.gpa.free(some);
lib/compiler/aro/aro/Driver.zig+9-6
...@@ -947,8 +947,9 @@ fn addImacros(d: *Driver, path: []const u8) !void {...@@ -947,8 +947,9 @@ fn addImacros(d: *Driver, path: []const u8) !void {
947}947}
948948
949pub fn err(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void {949pub fn err(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void {
950 var sf = std.heap.stackFallback(1024, d.comp.gpa);950 var bfa_buf: [1024]u8 = undefined;
951 var allocating: std.Io.Writer.Allocating = .init(sf.get());951 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, d.comp.gpa);
952 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
952 defer allocating.deinit();953 defer allocating.deinit();
953954
954 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;955 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;
...@@ -956,8 +957,9 @@ pub fn err(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void {...@@ -956,8 +957,9 @@ pub fn err(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void {
956}957}
957958
958pub fn warn(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void {959pub fn warn(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void {
959 var sf = std.heap.stackFallback(1024, d.comp.gpa);960 var bfa_buf: [1024]u8 = undefined;
960 var allocating: std.Io.Writer.Allocating = .init(sf.get());961 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, d.comp.gpa);
962 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
961 defer allocating.deinit();963 defer allocating.deinit();
962964
963 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;965 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;
...@@ -1101,8 +1103,9 @@ fn parseTarget(d: *Driver, arch_os_abi: []const u8, opt_cpu_features: ?[]const u...@@ -1101,8 +1103,9 @@ fn parseTarget(d: *Driver, arch_os_abi: []const u8, opt_cpu_features: ?[]const u
1101}1103}
11021104
1103pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {1105pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalError, OutOfMemory } {
1104 var sf = std.heap.stackFallback(1024, d.comp.gpa);1106 var bfa_buf: [1024]u8 = undefined;
1105 var allocating: std.Io.Writer.Allocating = .init(sf.get());1107 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, d.comp.gpa);
1108 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
1106 defer allocating.deinit();1109 defer allocating.deinit();
11071110
1108 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;1111 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;
lib/compiler/aro/aro/Parser.zig+18-12
...@@ -215,8 +215,9 @@ fn checkIdentifierCodepointWarnings(p: *Parser, codepoint: u21, loc: Source.Loca...@@ -215,8 +215,9 @@ fn checkIdentifierCodepointWarnings(p: *Parser, codepoint: u21, loc: Source.Loca
215 assert(codepoint >= 0x80);215 assert(codepoint >= 0x80);
216216
217 const prev_total = p.diagnostics.total;217 const prev_total = p.diagnostics.total;
218 var sf = std.heap.stackFallback(1024, p.comp.gpa);218 var bfa_buf: [1024]u8 = undefined;
219 var allocating: std.Io.Writer.Allocating = .init(sf.get());219 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, p.comp.gpa);
220 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
220 defer allocating.deinit();221 defer allocating.deinit();
221222
222 if (!char_info.isC99IdChar(codepoint)) {223 if (!char_info.isC99IdChar(codepoint)) {
...@@ -429,8 +430,9 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype)...@@ -429,8 +430,9 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype)
429 if (diagnostic.suppress_unless_version) |some| if (!p.comp.langopts.standard.atLeast(some)) return;430 if (diagnostic.suppress_unless_version) |some| if (!p.comp.langopts.standard.atLeast(some)) return;
430 if (p.diagnostics.effectiveKind(diagnostic) == .off) return;431 if (p.diagnostics.effectiveKind(diagnostic) == .off) return;
431432
432 var sf = std.heap.stackFallback(1024, p.comp.gpa);433 var bfa_buf: [1024]u8 = undefined;
433 var allocating: std.Io.Writer.Allocating = .init(sf.get());434 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, p.comp.gpa);
435 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
434 defer allocating.deinit();436 defer allocating.deinit();
435437
436 p.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;438 p.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;
...@@ -1537,8 +1539,9 @@ fn staticAssert(p: *Parser) Error!bool {...@@ -1537,8 +1539,9 @@ fn staticAssert(p: *Parser) Error!bool {
1537 }1539 }
1538 } else {1540 } else {
1539 if (!res.val.toBool(p.comp)) {1541 if (!res.val.toBool(p.comp)) {
1540 var sf = std.heap.stackFallback(1024, gpa);1542 var bfa_buf: [1024]u8 = undefined;
1541 var allocating: std.Io.Writer.Allocating = .init(sf.get());1543 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
1544 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
1542 defer allocating.deinit();1545 defer allocating.deinit();
15431546
1544 if (p.staticAssertMessage(res_node, str, &allocating) catch return error.OutOfMemory) |message| {1547 if (p.staticAssertMessage(res_node, str, &allocating) catch return error.OutOfMemory) |message| {
...@@ -4837,8 +4840,9 @@ fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, asm_tok: TokenIndex...@@ -4837,8 +4840,9 @@ fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, asm_tok: TokenIndex
4837 const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names4840 const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names
4838 const bytes_needed = expected_items * @sizeOf(Tree.Node.AsmStmt.Operand) + expected_items * 2 * @sizeOf(Node.Index);4841 const bytes_needed = expected_items * @sizeOf(Tree.Node.AsmStmt.Operand) + expected_items * 2 * @sizeOf(Node.Index);
48394842
4840 var stack_fallback = std.heap.stackFallback(bytes_needed, gpa);4843 var bfa_buf: [bytes_needed]u8 = undefined;
4841 const allocator = stack_fallback.get();4844 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
4845 const allocator = bfa.allocator();
48424846
4843 var operands: std.ArrayList(Tree.Node.AsmStmt.Operand) = .empty;4847 var operands: std.ArrayList(Tree.Node.AsmStmt.Operand) = .empty;
4844 defer operands.deinit(allocator);4848 defer operands.deinit(allocator);
...@@ -9922,8 +9926,9 @@ fn primaryExpr(p: *Parser) Error!?Result {...@@ -9922,8 +9926,9 @@ fn primaryExpr(p: *Parser) Error!?Result {
9922 if (p.func.pretty_ident) |some| {9926 if (p.func.pretty_ident) |some| {
9923 qt = some.qt;9927 qt = some.qt;
9924 } else if (p.func.qt) |func_qt| {9928 } else if (p.func.qt) |func_qt| {
9925 var sf = std.heap.stackFallback(1024, gpa);9929 var bfa_buf: [1024]u8 = undefined;
9926 var allocating: std.Io.Writer.Allocating = .init(sf.get());9930 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
9931 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
9927 defer allocating.deinit();9932 defer allocating.deinit();
99289933
9929 func_qt.printNamed(p.tokSlice(p.func.name), p.comp, &allocating.writer) catch return error.OutOfMemory;9934 func_qt.printNamed(p.tokSlice(p.func.name), p.comp, &allocating.writer) catch return error.OutOfMemory;
...@@ -10212,8 +10217,9 @@ fn charLiteral(p: *Parser) Error!?Result {...@@ -10212,8 +10217,9 @@ fn charLiteral(p: *Parser) Error!?Result {
10212 };10217 };
1021310218
10214 const max_chars_expected = 4;10219 const max_chars_expected = 4;
10215 var sf = std.heap.stackFallback(max_chars_expected * @sizeOf(u32), gpa);10220 var bfa_buf: [max_chars_expected]u32 = undefined;
10216 const allocator = sf.get();10221 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), gpa);
10222 const allocator = bfa.allocator();
10217 var chars: std.ArrayList(u32) = .empty;10223 var chars: std.ArrayList(u32) = .empty;
10218 defer chars.deinit(allocator);10224 defer chars.deinit(allocator);
1021910225
lib/compiler/aro/aro/Pragma.zig+3-2
...@@ -212,8 +212,9 @@ pub const Diagnostic = struct {...@@ -212,8 +212,9 @@ pub const Diagnostic = struct {
212};212};
213213
214pub fn err(pp: *Preprocessor, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) Compilation.Error!void {214pub fn err(pp: *Preprocessor, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) Compilation.Error!void {
215 var sf = std.heap.stackFallback(1024, pp.comp.gpa);215 var buf: [1024]u8 = undefined;
216 var allocating: std.Io.Writer.Allocating = .init(sf.get());216 var bfa: std.heap.BufferFirstAllocator = .init(&buf, pp.comp.gpa);
217 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
217 defer allocating.deinit();218 defer allocating.deinit();
218219
219 Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;220 Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;
lib/compiler/aro/aro/Preprocessor.zig+9-6
...@@ -1023,8 +1023,9 @@ fn err(pp: *Preprocessor, loc: anytype, diagnostic: Diagnostic, args: anytype) C...@@ -1023,8 +1023,9 @@ fn err(pp: *Preprocessor, loc: anytype, diagnostic: Diagnostic, args: anytype) C
1023 defer pp.diagnostics.state.suppress_system_headers = old_suppress_system;1023 defer pp.diagnostics.state.suppress_system_headers = old_suppress_system;
1024 if (diagnostic.show_in_system_headers) pp.diagnostics.state.suppress_system_headers = false;1024 if (diagnostic.show_in_system_headers) pp.diagnostics.state.suppress_system_headers = false;
10251025
1026 var sf = std.heap.stackFallback(1024, pp.comp.gpa);1026 var bfa_buf: [1024]u8 = undefined;
1027 var allocating: std.Io.Writer.Allocating = .init(sf.get());1027 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, pp.comp.gpa);
1028 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
1028 defer allocating.deinit();1029 defer allocating.deinit();
10291030
1030 Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;1031 Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;
...@@ -1052,8 +1053,9 @@ fn err(pp: *Preprocessor, loc: anytype, diagnostic: Diagnostic, args: anytype) C...@@ -1052,8 +1053,9 @@ fn err(pp: *Preprocessor, loc: anytype, diagnostic: Diagnostic, args: anytype) C
1052}1053}
10531054
1054fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) Compilation.Error {1055fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anytype) Compilation.Error {
1055 var sf = std.heap.stackFallback(1024, pp.comp.gpa);1056 var bfa_buf: [1024]u8 = undefined;
1056 var allocating: std.Io.Writer.Allocating = .init(sf.get());1057 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, pp.comp.gpa);
1058 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
1057 defer allocating.deinit();1059 defer allocating.deinit();
10581060
1059 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;1061 Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory;
...@@ -1074,8 +1076,9 @@ fn fatalNotFound(pp: *Preprocessor, tok: TokenWithExpansionLocs, filename: []con...@@ -1074,8 +1076,9 @@ fn fatalNotFound(pp: *Preprocessor, tok: TokenWithExpansionLocs, filename: []con
1074 pp.diagnostics.state.fatal_errors = true;1076 pp.diagnostics.state.fatal_errors = true;
1075 defer pp.diagnostics.state.fatal_errors = old;1077 defer pp.diagnostics.state.fatal_errors = old;
10761078
1077 var sf = std.heap.stackFallback(1024, pp.comp.gpa);1079 var bfa_buf: [1024]u8 = undefined;
1078 const allocator = sf.get();1080 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, pp.comp.gpa);
1081 const allocator = bfa.allocator();
1079 var buf: std.ArrayList(u8) = .empty;1082 var buf: std.ArrayList(u8) = .empty;
1080 defer buf.deinit(allocator);1083 defer buf.deinit(allocator);
10811084
lib/compiler/aro/aro/pragmas/message.zig+3-2
...@@ -44,8 +44,9 @@ fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pra...@@ -44,8 +44,9 @@ fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pra
4444
45 const diagnostic: Pragma.Diagnostic = .pragma_message;45 const diagnostic: Pragma.Diagnostic = .pragma_message;
4646
47 var sf = std.heap.stackFallback(1024, pp.comp.gpa);47 var bfa_buf: [1024]u8 = undefined;
48 var allocating: std.Io.Writer.Allocating = .init(sf.get());48 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, pp.comp.gpa);
49 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
49 defer allocating.deinit();50 defer allocating.deinit();
5051
51 Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, .{str}) catch return error.OutOfMemory;52 Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, .{str}) catch return error.OutOfMemory;
lib/compiler/aro/aro/text_literal.zig+3-2
...@@ -315,8 +315,9 @@ pub const Parser = struct {...@@ -315,8 +315,9 @@ pub const Parser = struct {
315 if (p.errored) return;315 if (p.errored) return;
316 if (p.comp.diagnostics.effectiveKind(diagnostic) == .off) return;316 if (p.comp.diagnostics.effectiveKind(diagnostic) == .off) return;
317317
318 var sf = std.heap.stackFallback(1024, p.comp.gpa);318 var bfa_buf: [1024]u8 = undefined;
319 var allocating: std.Io.Writer.Allocating = .init(sf.get());319 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, p.comp.gpa);
320 var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
320 defer allocating.deinit();321 defer allocating.deinit();
321322
322 formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;323 formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;
lib/compiler/aro/assembly_backend/x86_64.zig+3-2
...@@ -68,8 +68,9 @@ fn serializeFloat(comptime T: type, value: T, w: *std.Io.Writer) !void {...@@ -68,8 +68,9 @@ fn serializeFloat(comptime T: type, value: T, w: *std.Io.Writer) !void {
68pub fn todo(c: *AsmCodeGen, msg: []const u8, tok: Tree.TokenIndex) Error {68pub fn todo(c: *AsmCodeGen, msg: []const u8, tok: Tree.TokenIndex) Error {
69 const loc: Source.Location = c.tree.tokens.items(.loc)[tok];69 const loc: Source.Location = c.tree.tokens.items(.loc)[tok];
7070
71 var sf = std.heap.stackFallback(1024, c.comp.gpa);71 var bfa_buf: [u8]1024 = undefined;
72 const allocator = sf.get();72 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, c.comp.gpa);
73 const allocator = bfa.allocator();
73 var buf: std.ArrayList(u8) = .empty;74 var buf: std.ArrayList(u8) = .empty;
74 defer buf.deinit(allocator);75 defer buf.deinit(allocator);
7576
lib/std/debug.zig+3-2
...@@ -1197,8 +1197,9 @@ fn printSourceAtAddress(...@@ -1197,8 +1197,9 @@ fn printSourceAtAddress(
11971197
1198 // Initialize the symbol array with space for at least one element, allocating this on the stack1198 // Initialize the symbol array with space for at least one element, allocating this on the stack
1199 // in the common case where only one element is needed1199 // in the common case where only one element is needed
1200 var symbol_fallback_allocator = std.heap.stackFallback(@sizeOf(Symbol) + @alignOf(Symbol) - 1, getDebugInfoAllocator());1200 var buf: [1]Symbol = undefined;
1201 const symbol_allocator = symbol_fallback_allocator.get();1201 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&buf), getDebugInfoAllocator());
1202 const symbol_allocator = bfa.allocator();
1202 var symbols = std.ArrayList(Symbol).initCapacity(symbol_allocator, 1) catch unreachable;1203 var symbols = std.ArrayList(Symbol).initCapacity(symbol_allocator, 1) catch unreachable;
1203 defer symbols.deinit(symbol_allocator);1204 defer symbols.deinit(symbol_allocator);
12041205
lib/std/fs/path.zig+6-4
...@@ -894,8 +894,9 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error!...@@ -894,8 +894,9 @@ pub fn resolve(allocator: Allocator, paths: []const []const u8) Allocator.Error!
894pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {894pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) Allocator.Error![]u8 {
895 // Avoid heap allocation when paths.len is <= @bitSizeOf(usize) * 2895 // Avoid heap allocation when paths.len is <= @bitSizeOf(usize) * 2
896 // (we use `* 3` because stackFallback uses 1 usize as a length)896 // (we use `* 3` because stackFallback uses 1 usize as a length)
897 var bit_set_allocator_state = std.heap.stackFallback(@sizeOf(usize) * 3, allocator);897 var buf: [3]usize = undefined;
898 const bit_set_allocator = bit_set_allocator_state.get();898 var bit_set_allocator_state: std.heap.BufferFirstAllocator = .init(@ptrCast(&buf), allocator);
899 const bit_set_allocator = bit_set_allocator_state.allocator();
899 var relevant_paths = try std.bit_set.DynamicBitSetUnmanaged.initEmpty(bit_set_allocator, paths.len);900 var relevant_paths = try std.bit_set.DynamicBitSetUnmanaged.initEmpty(bit_set_allocator, paths.len);
900 defer relevant_paths.deinit(bit_set_allocator);901 defer relevant_paths.deinit(bit_set_allocator);
901902
...@@ -1642,7 +1643,8 @@ fn windowsResolveAgainstCwd(...@@ -1642,7 +1643,8 @@ fn windowsResolveAgainstCwd(
1642 parsed: WindowsPath2(u8),1643 parsed: WindowsPath2(u8),
1643) ![]u8 {1644) ![]u8 {
1644 // Space for 256 WTF-16 code units; potentially 3 WTF-8 bytes per WTF-16 code unit1645 // Space for 256 WTF-16 code units; potentially 3 WTF-8 bytes per WTF-16 code unit
1645 var temp_allocator_state = std.heap.stackFallback(256 * 3, gpa);1646 var buf: [256 * 3]u8 = undefined;
1647 var temp_allocator_state: std.heap.BufferFirstAllocator = .init(&buf, gpa);
1646 return switch (parsed.kind) {1648 return switch (parsed.kind) {
1647 .drive_absolute,1649 .drive_absolute,
1648 .unc_absolute,1650 .unc_absolute,
...@@ -1668,7 +1670,7 @@ fn windowsResolveAgainstCwd(...@@ -1668,7 +1670,7 @@ fn windowsResolveAgainstCwd(
1668 }1670 }
1669 },1671 },
1670 .drive_relative => blk: {1672 .drive_relative => blk: {
1671 const temp_allocator = temp_allocator_state.get();1673 const temp_allocator = temp_allocator_state.allocator();
1672 const drive_cwd = drive_cwd: {1674 const drive_cwd = drive_cwd: {
1673 const parsed_cwd = parsePathWindows(u8, cwd);1675 const parsed_cwd = parsePathWindows(u8, cwd);
16741676
lib/std/heap.zig+2-126
...@@ -12,6 +12,7 @@ const Alignment = std.mem.Alignment;...@@ -12,6 +12,7 @@ const Alignment = std.mem.Alignment;
12pub const ArenaAllocator = @import("heap/ArenaAllocator.zig");12pub const ArenaAllocator = @import("heap/ArenaAllocator.zig");
13pub const SmpAllocator = @import("heap/SmpAllocator.zig");13pub const SmpAllocator = @import("heap/SmpAllocator.zig");
14pub const FixedBufferAllocator = @import("heap/FixedBufferAllocator.zig");14pub const FixedBufferAllocator = @import("heap/FixedBufferAllocator.zig");
15pub const BufferFirstAllocator = @import("heap/BufferFirstAllocator.zig");
15pub const PageAllocator = @import("heap/PageAllocator.zig");16pub const PageAllocator = @import("heap/PageAllocator.zig");
16pub const WasmAllocator = if (builtin.single_threaded) BrkAllocator else @compileError("unimplemented");17pub const WasmAllocator = if (builtin.single_threaded) BrkAllocator else @compileError("unimplemented");
17pub const BrkAllocator = @import("heap/BrkAllocator.zig");18pub const BrkAllocator = @import("heap/BrkAllocator.zig");
...@@ -367,113 +368,6 @@ pub const brk_allocator: Allocator = .{...@@ -367,113 +368,6 @@ pub const brk_allocator: Allocator = .{
367 .vtable = &BrkAllocator.vtable,368 .vtable = &BrkAllocator.vtable,
368};369};
369370
370/// Returns a `StackFallbackAllocator` allocating using either a
371/// `FixedBufferAllocator` on an array of size `size` and falling back to
372/// `fallback_allocator` if that fails.
373pub fn stackFallback(comptime size: usize, fallback_allocator: Allocator) StackFallbackAllocator(size) {
374 return StackFallbackAllocator(size){
375 .buffer = undefined,
376 .fallback_allocator = fallback_allocator,
377 .fixed_buffer_allocator = undefined,
378 };
379}
380
381/// An allocator that attempts to allocate using a
382/// `FixedBufferAllocator` using an array of size `size`. If the
383/// allocation fails, it will fall back to using
384/// `fallback_allocator`. Easily created with `stackFallback`.
385pub fn StackFallbackAllocator(comptime size: usize) type {
386 return struct {
387 const Self = @This();
388
389 buffer: [size]u8,
390 fallback_allocator: Allocator,
391 fixed_buffer_allocator: FixedBufferAllocator,
392 get_called: if (std.debug.runtime_safety) bool else void =
393 if (std.debug.runtime_safety) false else {},
394
395 /// This function both fetches a `Allocator` interface to this
396 /// allocator *and* resets the internal buffer allocator.
397 pub fn get(self: *Self) Allocator {
398 if (std.debug.runtime_safety) {
399 assert(!self.get_called); // `get` called multiple times; instead use `const allocator = stackFallback(N).get();`
400 self.get_called = true;
401 }
402 self.fixed_buffer_allocator = FixedBufferAllocator.init(self.buffer[0..]);
403 return .{
404 .ptr = self,
405 .vtable = &.{
406 .alloc = alloc,
407 .resize = resize,
408 .remap = remap,
409 .free = free,
410 },
411 };
412 }
413
414 /// Unlike most std allocators `StackFallbackAllocator` modifies
415 /// its internal state before returning an implementation of
416 /// the`Allocator` interface and therefore also doesn't use
417 /// the usual `.allocator()` method.
418 pub const allocator = @compileError("use 'const allocator = stackFallback(N).get();' instead");
419
420 fn alloc(
421 ctx: *anyopaque,
422 len: usize,
423 alignment: Alignment,
424 ra: usize,
425 ) ?[*]u8 {
426 const self: *Self = @ptrCast(@alignCast(ctx));
427 return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, alignment, ra) orelse
428 return self.fallback_allocator.rawAlloc(len, alignment, ra);
429 }
430
431 fn resize(
432 ctx: *anyopaque,
433 buf: []u8,
434 alignment: Alignment,
435 new_len: usize,
436 ra: usize,
437 ) bool {
438 const self: *Self = @ptrCast(@alignCast(ctx));
439 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
440 return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, alignment, new_len, ra);
441 } else {
442 return self.fallback_allocator.rawResize(buf, alignment, new_len, ra);
443 }
444 }
445
446 fn remap(
447 context: *anyopaque,
448 memory: []u8,
449 alignment: Alignment,
450 new_len: usize,
451 return_address: usize,
452 ) ?[*]u8 {
453 const self: *Self = @ptrCast(@alignCast(context));
454 if (self.fixed_buffer_allocator.ownsPtr(memory.ptr)) {
455 return FixedBufferAllocator.remap(&self.fixed_buffer_allocator, memory, alignment, new_len, return_address);
456 } else {
457 return self.fallback_allocator.rawRemap(memory, alignment, new_len, return_address);
458 }
459 }
460
461 fn free(
462 ctx: *anyopaque,
463 buf: []u8,
464 alignment: Alignment,
465 ra: usize,
466 ) void {
467 const self: *Self = @ptrCast(@alignCast(ctx));
468 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
469 return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, alignment, ra);
470 } else {
471 return self.fallback_allocator.rawFree(buf, alignment, ra);
472 }
473 }
474 };
475}
476
477test c_allocator {371test c_allocator {
478 if (builtin.link_libc) {372 if (builtin.link_libc) {
479 try testAllocator(c_allocator);373 try testAllocator(c_allocator);
...@@ -524,25 +418,6 @@ test ArenaAllocator {...@@ -524,25 +418,6 @@ test ArenaAllocator {
524 try testAllocatorAlignedShrink(allocator);418 try testAllocatorAlignedShrink(allocator);
525}419}
526420
527test "StackFallbackAllocator" {
528 {
529 var stack_allocator = stackFallback(4096, std.testing.allocator);
530 try testAllocator(stack_allocator.get());
531 }
532 {
533 var stack_allocator = stackFallback(4096, std.testing.allocator);
534 try testAllocatorAligned(stack_allocator.get());
535 }
536 {
537 var stack_allocator = stackFallback(4096, std.testing.allocator);
538 try testAllocatorLargeAlignment(stack_allocator.get());
539 }
540 {
541 var stack_allocator = stackFallback(4096, std.testing.allocator);
542 try testAllocatorAlignedShrink(stack_allocator.get());
543 }
544}
545
546/// This one should not try alignments that exceed what C malloc can handle.421/// This one should not try alignments that exceed what C malloc can handle.
547pub fn testAllocator(base_allocator: mem.Allocator) !void {422pub fn testAllocator(base_allocator: mem.Allocator) !void {
548 var validationAllocator = mem.validationWrap(base_allocator);423 var validationAllocator = mem.validationWrap(base_allocator);
...@@ -1011,6 +886,7 @@ test {...@@ -1011,6 +886,7 @@ test {
1011 _ = ArenaAllocator;886 _ = ArenaAllocator;
1012 _ = DebugAllocator(.{});887 _ = DebugAllocator(.{});
1013 _ = FixedBufferAllocator;888 _ = FixedBufferAllocator;
889 _ = BufferFirstAllocator;
1014 if (builtin.single_threaded) {890 if (builtin.single_threaded) {
1015 if (builtin.cpu.arch.isWasm() or (builtin.os.tag == .linux and !builtin.link_libc)) {891 if (builtin.cpu.arch.isWasm() or (builtin.os.tag == .linux and !builtin.link_libc)) {
1016 _ = brk_allocator;892 _ = brk_allocator;
lib/std/heap/BufferFirstAllocator.zig created+165
...@@ -0,0 +1,165 @@
1//! An allocator that attempts to allocate from the given buffer, falling back to
2//! `fallback_allocator` if this fails.
3
4const std = @import("../std.zig");
5const heap = std.heap;
6const testing = std.testing;
7
8const Alignment = std.mem.Alignment;
9const Allocator = std.mem.Allocator;
10const FixedBufferAllocator = std.heap.FixedBufferAllocator;
11
12const BufferFirstAllocator = @This();
13
14fallback_allocator: Allocator,
15fixed_buffer_allocator: FixedBufferAllocator,
16
17pub fn init(buffer: []u8, fallback_allocator: Allocator) BufferFirstAllocator {
18 return .{
19 .fallback_allocator = fallback_allocator,
20 .fixed_buffer_allocator = .init(buffer),
21 };
22}
23
24pub fn allocator(self: *BufferFirstAllocator) Allocator {
25 return .{
26 .ptr = self,
27 .vtable = &.{
28 .alloc = alloc,
29 .resize = resize,
30 .remap = remap,
31 .free = free,
32 },
33 };
34}
35
36fn alloc(
37 ctx: *anyopaque,
38 len: usize,
39 alignment: Alignment,
40 ra: usize,
41) ?[*]u8 {
42 const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
43 return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, alignment, ra) orelse
44 return self.fallback_allocator.rawAlloc(len, alignment, ra);
45}
46
47fn resize(
48 ctx: *anyopaque,
49 buf: []u8,
50 alignment: Alignment,
51 new_len: usize,
52 ra: usize,
53) bool {
54 const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
55 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
56 return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, alignment, new_len, ra);
57 } else {
58 return self.fallback_allocator.rawResize(buf, alignment, new_len, ra);
59 }
60}
61
62fn remap(
63 context: *anyopaque,
64 memory: []u8,
65 alignment: Alignment,
66 new_len: usize,
67 return_address: usize,
68) ?[*]u8 {
69 const self: *BufferFirstAllocator = @ptrCast(@alignCast(context));
70 if (self.fixed_buffer_allocator.ownsPtr(memory.ptr)) {
71 return FixedBufferAllocator.remap(&self.fixed_buffer_allocator, memory, alignment, new_len, return_address);
72 } else {
73 return self.fallback_allocator.rawRemap(memory, alignment, new_len, return_address);
74 }
75}
76
77fn free(
78 ctx: *anyopaque,
79 buf: []u8,
80 alignment: Alignment,
81 ra: usize,
82) void {
83 const self: *BufferFirstAllocator = @ptrCast(@alignCast(ctx));
84 if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) {
85 return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, alignment, ra);
86 } else {
87 return self.fallback_allocator.rawFree(buf, alignment, ra);
88 }
89}
90
91test "BufferFirstAllocator" {
92 // Buffer first specific tests
93 {
94 var buffer: [10]u8 = undefined;
95 var bfa_state: BufferFirstAllocator = .init(&buffer, std.testing.allocator);
96 const bfa = bfa_state.allocator();
97
98 // We're under the limit, so we should be allocated in the buffer
99 const txt0 = "hellowrld";
100 const buf0 = try bfa.create(@TypeOf(txt0.*));
101 buf0.* = txt0.*;
102 try testing.expect(bfa_state.fixed_buffer_allocator.ownsPtr(buf0.ptr));
103
104 // We're now over the limit, so we should be allocated from the fallback
105 const txt1 = "test!";
106 const buf1 = try bfa.create(@TypeOf(txt1.*));
107 buf1.* = txt1.*;
108 try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf1.ptr));
109
110 // Free the allocation that took up space in the buffer
111 try testing.expectEqualStrings(txt0, buf0);
112 bfa.destroy(buf0);
113
114 // The next allocation would go in the buffer, but it's too big so it doesn't
115 const txt2 = "qwertyqwerty";
116 const buf2 = try bfa.create(@TypeOf(txt2.*));
117 buf2.* = txt2.*;
118 try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf2.ptr));
119
120 // The next allocation is smaller and fits in the buffer
121 const txt3 = "dvorak";
122 const buf3 = try bfa.create(@TypeOf(txt3.*));
123 buf3.* = txt3.*;
124 try testing.expect(bfa_state.fixed_buffer_allocator.ownsPtr(buf3.ptr));
125
126 // The remainder in the buffer is too small for the following allocation so it falls back
127 const txt4 = "moretext";
128 const buf4 = try bfa.create(@TypeOf(txt4.*));
129 buf4.* = txt4.*;
130 try testing.expect(!bfa_state.fixed_buffer_allocator.ownsPtr(buf4.ptr));
131
132 // Check equality on the remaining buffers and free them
133 try testing.expectEqualStrings(txt1, buf1);
134 bfa.destroy(buf1);
135 try testing.expectEqualStrings(txt2, buf2);
136 bfa.destroy(buf2);
137 try testing.expectEqualStrings(txt3, buf3);
138 bfa.destroy(buf3);
139 try testing.expectEqualStrings(txt4, buf4);
140 bfa.destroy(buf4);
141
142 try testing.expectEqual(0, bfa_state.fixed_buffer_allocator.end_index);
143 }
144
145 // Standard allocator tests
146 {
147 var buf: [4096]u8 = undefined;
148 {
149 var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
150 try heap.testAllocator(bfa.allocator());
151 }
152 {
153 var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
154 try heap.testAllocatorAligned(bfa.allocator());
155 }
156 {
157 var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
158 try heap.testAllocatorLargeAlignment(bfa.allocator());
159 }
160 {
161 var bfa: BufferFirstAllocator = .init(&buf, std.testing.allocator);
162 try heap.testAllocatorAlignedShrink(bfa.allocator());
163 }
164 }
165}
lib/std/zig/AstGen.zig+21-18
...@@ -1776,11 +1776,12 @@ fn structInitExpr(...@@ -1776,11 +1776,12 @@ fn structInitExpr(
1776 }1776 }
17771777
1778 {1778 {
1779 var sfba = std.heap.stackFallback(256, astgen.arena);1779 var bfa_buf: [256]u8 = undefined;
1780 const sfba_allocator = sfba.get();1780 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, astgen.arena);
1781 const bfa = bfa_state.allocator();
17811782
1782 var duplicate_names: std.array_hash_map.Auto(Zir.NullTerminatedString, ArrayList(Ast.TokenIndex)) = .empty;1783 var duplicate_names: std.array_hash_map.Auto(Zir.NullTerminatedString, ArrayList(Ast.TokenIndex)) = .empty;
1783 try duplicate_names.ensureTotalCapacity(sfba_allocator, @intCast(struct_init.ast.fields.len));1784 try duplicate_names.ensureTotalCapacity(bfa, @intCast(struct_init.ast.fields.len));
17841785
1785 // When there aren't errors, use this to avoid a second iteration.1786 // When there aren't errors, use this to avoid a second iteration.
1786 var any_duplicate = false;1787 var any_duplicate = false;
...@@ -1789,14 +1790,14 @@ fn structInitExpr(...@@ -1789,14 +1790,14 @@ fn structInitExpr(
1789 const name_token = tree.firstToken(field) - 2;1790 const name_token = tree.firstToken(field) - 2;
1790 const name_index = try astgen.identAsString(name_token);1791 const name_index = try astgen.identAsString(name_token);
17911792
1792 const gop = try duplicate_names.getOrPut(sfba_allocator, name_index);1793 const gop = try duplicate_names.getOrPut(bfa, name_index);
17931794
1794 if (gop.found_existing) {1795 if (gop.found_existing) {
1795 try gop.value_ptr.append(sfba_allocator, name_token);1796 try gop.value_ptr.append(bfa, name_token);
1796 any_duplicate = true;1797 any_duplicate = true;
1797 } else {1798 } else {
1798 gop.value_ptr.* = .empty;1799 gop.value_ptr.* = .empty;
1799 try gop.value_ptr.append(sfba_allocator, name_token);1800 try gop.value_ptr.append(bfa, name_token);
1800 }1801 }
1801 }1802 }
18021803
...@@ -8404,9 +8405,10 @@ fn tunnelThroughClosure(...@@ -8404,9 +8405,10 @@ fn tunnelThroughClosure(
84048405
8405 // Otherwise we need a tunnel. First, figure out the path of namespaces we8406 // Otherwise we need a tunnel. First, figure out the path of namespaces we
8406 // are tunneling through. This is usually only going to be one or two, so8407 // are tunneling through. This is usually only going to be one or two, so
8407 // use an SFBA to optimize for the common case.8408 // use an BFA to optimize for the common case.
8408 var sfba = std.heap.stackFallback(@sizeOf(usize) * 2, astgen.arena);8409 var bfa_buf: [2]usize = undefined;
8409 var intermediate_tunnels = try sfba.get().alloc(*Scope.Namespace, num_tunnels - 1);8410 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), astgen.arena);
8411 var intermediate_tunnels = try bfa.allocator().alloc(*Scope.Namespace, num_tunnels - 1);
84108412
8411 const root_ns = ns: {8413 const root_ns = ns: {
8412 var i: usize = num_tunnels - 1;8414 var i: usize = num_tunnels - 1;
...@@ -12926,17 +12928,18 @@ fn scanContainer(...@@ -12926,17 +12928,18 @@ fn scanContainer(
12926 next: ?*@This(),12928 next: ?*@This(),
12927 };12929 };
1292812930
12929 // The maps below are allocated into this SFBA to avoid using the GPA for small namespaces.12931 // The maps below are allocated into this BFA to avoid using the GPA for small namespaces.
12930 var sfba_state = std.heap.stackFallback(512, astgen.gpa);12932 var bfa_buf: [512]u8 = undefined;
12931 const sfba = sfba_state.get();12933 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, astgen.gpa);
12934 const bfa = bfa_state.allocator();
1293212935
12933 var names: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, NameEntry) = .empty;12936 var names: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, NameEntry) = .empty;
12934 var test_names: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, NameEntry) = .empty;12937 var test_names: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, NameEntry) = .empty;
12935 var decltest_names: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, NameEntry) = .empty;12938 var decltest_names: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, NameEntry) = .empty;
12936 defer {12939 defer {
12937 names.deinit(sfba);12940 names.deinit(bfa);
12938 test_names.deinit(sfba);12941 test_names.deinit(bfa);
12939 decltest_names.deinit(sfba);12942 decltest_names.deinit(bfa);
12940 }12943 }
1294112944
12942 var any_duplicates = false;12945 var any_duplicates = false;
...@@ -13008,7 +13011,7 @@ fn scanContainer(...@@ -13008,7 +13011,7 @@ fn scanContainer(
13008 else => {}, // unnamed test13011 else => {}, // unnamed test
13009 .string_literal => {13012 .string_literal => {
13010 const name = try astgen.strLitAsString(test_name_token);13013 const name = try astgen.strLitAsString(test_name_token);
13011 const gop = try test_names.getOrPut(sfba, name.index);13014 const gop = try test_names.getOrPut(bfa, name.index);
13012 if (gop.found_existing) {13015 if (gop.found_existing) {
13013 var e = gop.value_ptr;13016 var e = gop.value_ptr;
13014 while (e.next) |n| e = n;13017 while (e.next) |n| e = n;
...@@ -13021,7 +13024,7 @@ fn scanContainer(...@@ -13021,7 +13024,7 @@ fn scanContainer(
13021 },13024 },
13022 .identifier => {13025 .identifier => {
13023 const name = try astgen.identAsString(test_name_token);13026 const name = try astgen.identAsString(test_name_token);
13024 const gop = try decltest_names.getOrPut(sfba, name);13027 const gop = try decltest_names.getOrPut(bfa, name);
13025 if (gop.found_existing) {13028 if (gop.found_existing) {
13026 var e = gop.value_ptr;13029 var e = gop.value_ptr;
13027 while (e.next) |n| e = n;13030 while (e.next) |n| e = n;
...@@ -13048,7 +13051,7 @@ fn scanContainer(...@@ -13048,7 +13051,7 @@ fn scanContainer(
13048 }13051 }
1304913052
13050 {13053 {
13051 const gop = try names.getOrPut(sfba, name_str_index);13054 const gop = try names.getOrPut(bfa, name_str_index);
13052 const new_ent: NameEntry = .{13055 const new_ent: NameEntry = .{
13053 .tok = name_token,13056 .tok = name_token,
13054 .next = null,13057 .next = null,
lib/std/zig/ZonGen.zig+5-4
...@@ -427,10 +427,11 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator...@@ -427,10 +427,11 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator
427 });427 });
428428
429 // For short initializers, track the names on the stack rather than going through gpa.429 // For short initializers, track the names on the stack rather than going through gpa.
430 var sfba_state = std.heap.stackFallback(256, gpa);430 var bfa_buf: [256]u8 = undefined;
431 const sfba = sfba_state.get();431 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
432 const bfa = bfa_state.allocator();
432 var field_names: std.AutoHashMapUnmanaged(Zoir.NullTerminatedString, Ast.TokenIndex) = .empty;433 var field_names: std.AutoHashMapUnmanaged(Zoir.NullTerminatedString, Ast.TokenIndex) = .empty;
433 defer field_names.deinit(sfba);434 defer field_names.deinit(bfa);
434435
435 var reported_any_duplicate = false;436 var reported_any_duplicate = false;
436437
...@@ -438,7 +439,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator...@@ -438,7 +439,7 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator
438 const name_token = tree.firstToken(elem_node) - 2;439 const name_token = tree.firstToken(elem_node) - 2;
439 if (zg.identAsString(name_token)) |name_str| {440 if (zg.identAsString(name_token)) |name_str| {
440 zg.extra.items[extra_name_idx] = @intFromEnum(name_str);441 zg.extra.items[extra_name_idx] = @intFromEnum(name_str);
441 const gop = try field_names.getOrPut(sfba, name_str);442 const gop = try field_names.getOrPut(bfa, name_str);
442 if (gop.found_existing and !reported_any_duplicate) {443 if (gop.found_existing and !reported_any_duplicate) {
443 reported_any_duplicate = true;444 reported_any_duplicate = true;
444 const earlier_token = gop.value_ptr.*;445 const earlier_token = gop.value_ptr.*;
lib/std/zig/llvm/Builder.zig+12-12
...@@ -7638,9 +7638,9 @@ pub const Constant = enum(u32) {...@@ -7638,9 +7638,9 @@ pub const Constant = enum(u32) {
7638 std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10)7638 std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10)
7639 ]std.math.big.Limb,7639 ]std.math.big.Limb,
7640 };7640 };
7641 var stack align(@alignOf(ExpectedContents)) =7641 var bfa_buf: ExpectedContents = undefined;
7642 std.heap.stackFallback(@sizeOf(ExpectedContents), data.builder.gpa);7642 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), data.builder.gpa);
7643 const allocator = stack.get();7643 const allocator = bfa.allocator();
7644 const str = bigint.toStringAlloc(allocator, 10, undefined) catch return error.WriteFailed;7644 const str = bigint.toStringAlloc(allocator, 10, undefined) catch return error.WriteFailed;
7645 defer allocator.free(str);7645 defer allocator.free(str);
7646 try w.writeAll(str);7646 try w.writeAll(str);
...@@ -9209,9 +9209,9 @@ pub fn getIntrinsic(...@@ -9209,9 +9209,9 @@ pub fn getIntrinsic(
9209 fields: [expected_fields_len]Type,9209 fields: [expected_fields_len]Type,
9210 },9210 },
9211 };9211 };
9212 var stack align(@max(@alignOf(std.heap.StackFallbackAllocator(0)), @alignOf(ExpectedContents))) =9212 var bfa_buf: ExpectedContents = undefined;
9213 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);9213 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
9214 const allocator = stack.get();9214 const allocator = bfa.allocator();
92159215
9216 const name = name: {9216 const name = name: {
9217 {9217 {
...@@ -10607,9 +10607,9 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void...@@ -10607,9 +10607,9 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
10607 std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10)10607 std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10)
10608 ]std.math.big.Limb,10608 ]std.math.big.Limb,
10609 };10609 };
10610 var stack align(@alignOf(ExpectedContents)) =10610 var bfa_buf: ExpectedContents = undefined;
10611 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);10611 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
10612 const allocator = stack.get();10612 const allocator = bfa.allocator();
1061310613
10614 const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len];10614 const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len];
10615 const bigint: std.math.big.int.Const = .{10615 const bigint: std.math.big.int.Const = .{
...@@ -11129,9 +11129,9 @@ fn bigIntConstAssumeCapacity(...@@ -11129,9 +11129,9 @@ fn bigIntConstAssumeCapacity(
11129 const bits = type_item.data;11129 const bits = type_item.data;
1113011130
11131 const ExpectedContents = [64 / @sizeOf(std.math.big.Limb)]std.math.big.Limb;11131 const ExpectedContents = [64 / @sizeOf(std.math.big.Limb)]std.math.big.Limb;
11132 var stack align(@alignOf(ExpectedContents)) =11132 var bfa_buf: ExpectedContents = undefined;
11133 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);11133 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
11134 const allocator = stack.get();11134 const allocator = bfa.allocator();
1113511135
11136 var limbs: []std.math.big.Limb = &.{};11136 var limbs: []std.math.big.Limb = &.{};
11137 defer allocator.free(limbs);11137 defer allocator.free(limbs);
src/Air/Legalize.zig+24-21
...@@ -1122,14 +1122,15 @@ fn scalarizeShuffleOneBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro...@@ -1122,14 +1122,15 @@ fn scalarizeShuffleOneBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro
1122 //1122 //
1123 // So we must first compute `out_idxs` and `in_idxs`.1123 // So we must first compute `out_idxs` and `in_idxs`.
11241124
1125 var sfba_state = std.heap.stackFallback(512, gpa);1125 var bfa_buf: [512]u8 = undefined;
1126 const sfba = sfba_state.get();1126 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
1127 const bfa = bfa_state.allocator();
11271128
1128 const out_idxs_buf = try sfba.alloc(InternPool.Index, shuffle.mask.len);1129 const out_idxs_buf = try bfa.alloc(InternPool.Index, shuffle.mask.len);
1129 defer sfba.free(out_idxs_buf);1130 defer bfa.free(out_idxs_buf);
11301131
1131 const in_idxs_buf = try sfba.alloc(InternPool.Index, shuffle.mask.len);1132 const in_idxs_buf = try bfa.alloc(InternPool.Index, shuffle.mask.len);
1132 defer sfba.free(in_idxs_buf);1133 defer bfa.free(in_idxs_buf);
11331134
1134 var n: usize = 0;1135 var n: usize = 0;
1135 for (shuffle.mask, 0..) |mask, out_idx| switch (mask.unwrap()) {1136 for (shuffle.mask, 0..) |mask, out_idx| switch (mask.unwrap()) {
...@@ -1143,8 +1144,8 @@ fn scalarizeShuffleOneBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro...@@ -1143,8 +1144,8 @@ fn scalarizeShuffleOneBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro
11431144
1144 const init_val: Value = init: {1145 const init_val: Value = init: {
1145 const undef_val = try pt.undefValue(shuffle.result_ty.childType(zcu));1146 const undef_val = try pt.undefValue(shuffle.result_ty.childType(zcu));
1146 const elems = try sfba.alloc(InternPool.Index, shuffle.mask.len);1147 const elems = try bfa.alloc(InternPool.Index, shuffle.mask.len);
1147 defer sfba.free(elems);1148 defer bfa.free(elems);
1148 for (shuffle.mask, elems) |mask, *elem| elem.* = switch (mask.unwrap()) {1149 for (shuffle.mask, elems) |mask, *elem| elem.* = switch (mask.unwrap()) {
1149 .value => |ip_index| ip_index,1150 .value => |ip_index| ip_index,
1150 .elem => undef_val.toIntern(),1151 .elem => undef_val.toIntern(),
...@@ -1212,14 +1213,15 @@ fn scalarizeShuffleTwoBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro...@@ -1212,14 +1213,15 @@ fn scalarizeShuffleTwoBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro
1212 // %8 = br(%1, %7)1213 // %8 = br(%1, %7)
1213 // })1214 // })
12141215
1215 var sfba_state = std.heap.stackFallback(512, gpa);1216 var bfa_buf: [512]u8 = undefined;
1216 const sfba = sfba_state.get();1217 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
1218 const bfa = bfa_state.allocator();
12171219
1218 const out_idxs_buf = try sfba.alloc(InternPool.Index, shuffle.mask.len);1220 const out_idxs_buf = try bfa.alloc(InternPool.Index, shuffle.mask.len);
1219 defer sfba.free(out_idxs_buf);1221 defer bfa.free(out_idxs_buf);
12201222
1221 const in_idxs_buf = try sfba.alloc(InternPool.Index, shuffle.mask.len);1223 const in_idxs_buf = try bfa.alloc(InternPool.Index, shuffle.mask.len);
1222 defer sfba.free(in_idxs_buf);1224 defer bfa.free(in_idxs_buf);
12231225
1224 // Iterate `shuffle.mask` before doing anything, because modifying AIR invalidates it.1226 // Iterate `shuffle.mask` before doing anything, because modifying AIR invalidates it.
1225 const out_idxs_a, const in_idxs_a, const out_idxs_b, const in_idxs_b = idxs: {1227 const out_idxs_a, const in_idxs_a, const out_idxs_b, const in_idxs_b = idxs: {
...@@ -2394,9 +2396,9 @@ fn packedStoreBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.In...@@ -2394,9 +2396,9 @@ fn packedStoreBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.In
2394 }).toRef(),2396 }).toRef(),
2395 .rhs = Air.internedToRef((keep_mask: {2397 .rhs = Air.internedToRef((keep_mask: {
2396 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;2398 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;
2397 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =2399 var bfa_buf: ExpectedContents = undefined;
2398 std.heap.stackFallback(@sizeOf(ExpectedContents), zcu.gpa);2400 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), zcu.gpa);
2399 const gpa = stack.get();2401 const gpa = bfa.allocator();
24002402
2401 var mask_big_int: std.math.big.int.Mutable = .{2403 var mask_big_int: std.math.big.int.Mutable = .{
2402 .limbs = try gpa.alloc(2404 .limbs = try gpa.alloc(
...@@ -2489,11 +2491,12 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro...@@ -2489,11 +2491,12 @@ fn packedAggregateInitBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Erro
2489 const agg_ty = orig_ty_pl.ty.toType();2491 const agg_ty = orig_ty_pl.ty.toType();
2490 const agg_field_count = agg_ty.structFieldCount(zcu);2492 const agg_field_count = agg_ty.structFieldCount(zcu);
24912493
2492 var sfba_state = std.heap.stackFallback(@sizeOf([4 * 32 + 2]Air.Inst.Index), gpa);2494 var bfa_buf: [4 * 32 + 2]Air.Inst.Index = undefined;
2493 const sfba = sfba_state.get();2495 var bfa_state: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), gpa);
2496 const bfa = bfa_state.allocator();
24942497
2495 const inst_buf = try sfba.alloc(Air.Inst.Index, 4 * agg_field_count + 2);2498 const inst_buf = try bfa.alloc(Air.Inst.Index, 4 * agg_field_count + 2);
2496 defer sfba.free(inst_buf);2499 defer bfa.free(inst_buf);
24972500
2498 var main_block: Block = .init(inst_buf);2501 var main_block: Block = .init(inst_buf);
2499 try l.air_instructions.ensureUnusedCapacity(gpa, inst_buf.len);2502 try l.air_instructions.ensureUnusedCapacity(gpa, inst_buf.len);
src/Value.zig+6-5
...@@ -882,15 +882,16 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {...@@ -882,15 +882,16 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
882 else => unreachable,882 else => unreachable,
883 };883 };
884 // Avoid hitting gpa for accesses to small packed structs884 // Avoid hitting gpa for accesses to small packed structs
885 var sfba_state = std.heap.stackFallback(128, zcu.comp.gpa);885 var bfa_buf: [128]u8 = undefined;
886 const sfba = sfba_state.get();886 var bfa_state: std.heap.BufferFirstAllocator = .init(&bfa_buf, zcu.comp.gpa);
887 const buf = try sfba.alloc(u8, @intCast((ty.bitSize(zcu) + 7) / 8));887 const bfa = bfa_state.allocator();
888 defer sfba.free(buf);888 const buf = try bfa.alloc(u8, @intCast((ty.bitSize(zcu) + 7) / 8));
889 defer bfa.free(buf);
889 int_val.writeToPackedMemory(zcu, buf, 0) catch |err| switch (err) {890 int_val.writeToPackedMemory(zcu, buf, 0) catch |err| switch (err) {
890 error.ReinterpretDeclRef => unreachable, // it's an integer891 error.ReinterpretDeclRef => unreachable, // it's an integer
891 error.OutOfMemory => |e| return e,892 error.OutOfMemory => |e| return e,
892 };893 };
893 return Value.readFromPackedMemory(field_ty, pt, buf, field_bit_offset, sfba) catch |err| switch (err) {894 return Value.readFromPackedMemory(field_ty, pt, buf, field_bit_offset, bfa) catch |err| switch (err) {
894 error.IllDefinedMemoryLayout => unreachable, // it's a bitpack895 error.IllDefinedMemoryLayout => unreachable, // it's a bitpack
895 error.OutOfMemory => |e| return e,896 error.OutOfMemory => |e| return e,
896 };897 };
src/codegen/c.zig+3-2
...@@ -4841,8 +4841,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4841,8 +4841,9 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
4841 {4841 {
4842 const asm_source = unwrapped_asm.source;4842 const asm_source = unwrapped_asm.source;
48434843
4844 var stack = std.heap.stackFallback(256, f.dg.gpa);4844 var bfa_buf: [256]u8 = undefined;
4845 const allocator = stack.get();4845 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, f.dg.gpa);
4846 const allocator = bfa.allocator();
4846 const fixed_asm_source = try allocator.alloc(u8, asm_source.len);4847 const fixed_asm_source = try allocator.alloc(u8, asm_source.len);
4847 defer allocator.free(fixed_asm_source);4848 defer allocator.free(fixed_asm_source);
48484849
src/codegen/llvm.zig+15-25
...@@ -3605,11 +3605,9 @@ pub const Object = struct {...@@ -3605,11 +3605,9 @@ pub const Object = struct {
3605 vals: [Builder.expected_fields_len]Builder.Constant,3605 vals: [Builder.expected_fields_len]Builder.Constant,
3606 fields: [Builder.expected_fields_len]Builder.Type,3606 fields: [Builder.expected_fields_len]Builder.Type,
3607 };3607 };
3608 var stack align(@max(3608 var bfa_buf: ExpectedContents = undefined;
3609 @alignOf(std.heap.StackFallbackAllocator(0)),3609 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa);
3610 @alignOf(ExpectedContents),3610 const allocator = bfa.allocator();
3611 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), o.gpa);
3612 const allocator = stack.get();
3613 const vals = try allocator.alloc(Builder.Constant, elems.len);3611 const vals = try allocator.alloc(Builder.Constant, elems.len);
3614 defer allocator.free(vals);3612 defer allocator.free(vals);
3615 const fields = try allocator.alloc(Builder.Type, elems.len);3613 const fields = try allocator.alloc(Builder.Type, elems.len);
...@@ -3636,11 +3634,9 @@ pub const Object = struct {...@@ -3636,11 +3634,9 @@ pub const Object = struct {
3636 vals: [Builder.expected_fields_len]Builder.Constant,3634 vals: [Builder.expected_fields_len]Builder.Constant,
3637 fields: [Builder.expected_fields_len]Builder.Type,3635 fields: [Builder.expected_fields_len]Builder.Type,
3638 };3636 };
3639 var stack align(@max(3637 var bfa_buf: ExpectedContents = undefined;
3640 @alignOf(std.heap.StackFallbackAllocator(0)),3638 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa);
3641 @alignOf(ExpectedContents),3639 const allocator = bfa.allocator();
3642 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), o.gpa);
3643 const allocator = stack.get();
3644 const vals = try allocator.alloc(Builder.Constant, len_including_sentinel);3640 const vals = try allocator.alloc(Builder.Constant, len_including_sentinel);
3645 defer allocator.free(vals);3641 defer allocator.free(vals);
3646 const fields = try allocator.alloc(Builder.Type, len_including_sentinel);3642 const fields = try allocator.alloc(Builder.Type, len_including_sentinel);
...@@ -3668,11 +3664,9 @@ pub const Object = struct {...@@ -3668,11 +3664,9 @@ pub const Object = struct {
3668 switch (aggregate.storage) {3664 switch (aggregate.storage) {
3669 .bytes, .elems => {3665 .bytes, .elems => {
3670 const ExpectedContents = [Builder.expected_fields_len]Builder.Constant;3666 const ExpectedContents = [Builder.expected_fields_len]Builder.Constant;
3671 var stack align(@max(3667 var bfa_buf: ExpectedContents = undefined;
3672 @alignOf(std.heap.StackFallbackAllocator(0)),3668 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa);
3673 @alignOf(ExpectedContents),3669 const allocator = bfa.allocator();
3674 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), o.gpa);
3675 const allocator = stack.get();
3676 const vals = try allocator.alloc(Builder.Constant, vector_type.len);3670 const vals = try allocator.alloc(Builder.Constant, vector_type.len);
3677 defer allocator.free(vals);3671 defer allocator.free(vals);
36783672
...@@ -3701,11 +3695,9 @@ pub const Object = struct {...@@ -3701,11 +3695,9 @@ pub const Object = struct {
3701 vals: [Builder.expected_fields_len]Builder.Constant,3695 vals: [Builder.expected_fields_len]Builder.Constant,
3702 fields: [Builder.expected_fields_len]Builder.Type,3696 fields: [Builder.expected_fields_len]Builder.Type,
3703 };3697 };
3704 var stack align(@max(3698 var bfa_buf: ExpectedContents = undefined;
3705 @alignOf(std.heap.StackFallbackAllocator(0)),3699 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa);
3706 @alignOf(ExpectedContents),3700 const allocator = bfa.allocator();
3707 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), o.gpa);
3708 const allocator = stack.get();
3709 const vals = try allocator.alloc(Builder.Constant, llvm_len);3701 const vals = try allocator.alloc(Builder.Constant, llvm_len);
3710 defer allocator.free(vals);3702 defer allocator.free(vals);
3711 const fields = try allocator.alloc(Builder.Type, llvm_len);3703 const fields = try allocator.alloc(Builder.Type, llvm_len);
...@@ -3779,11 +3771,9 @@ pub const Object = struct {...@@ -3779,11 +3771,9 @@ pub const Object = struct {
3779 vals: [Builder.expected_fields_len]Builder.Constant,3771 vals: [Builder.expected_fields_len]Builder.Constant,
3780 fields: [Builder.expected_fields_len]Builder.Type,3772 fields: [Builder.expected_fields_len]Builder.Type,
3781 };3773 };
3782 var stack align(@max(3774 var bfa_buf: ExpectedContents = undefined;
3783 @alignOf(std.heap.StackFallbackAllocator(0)),3775 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), o.gpa);
3784 @alignOf(ExpectedContents),3776 const allocator = bfa.allocator();
3785 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), o.gpa);
3786 const allocator = stack.get();
3787 const vals = try allocator.alloc(Builder.Constant, llvm_len);3777 const vals = try allocator.alloc(Builder.Constant, llvm_len);
3788 defer allocator.free(vals);3778 defer allocator.free(vals);
3789 const fields = try allocator.alloc(Builder.Type, llvm_len);3779 const fields = try allocator.alloc(Builder.Type, llvm_len);
src/codegen/llvm/FuncGen.zig+6-10
...@@ -3530,11 +3530,9 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)...@@ -3530,11 +3530,9 @@ fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind)
3530 const inst_llvm_ty = try o.lowerType(inst_ty);3530 const inst_llvm_ty = try o.lowerType(inst_ty);
35313531
3532 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;3532 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;
3533 var stack align(@max(3533 var bfa_buf: ExpectedContents = undefined;
3534 @alignOf(std.heap.StackFallbackAllocator(0)),3534 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
3535 @alignOf(ExpectedContents),3535 const allocator = bfa.allocator();
3536 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
3537 const allocator = stack.get();
35383536
3539 const scalar_bits = scalar_ty.intInfo(zcu).bits;3537 const scalar_bits = scalar_ty.intInfo(zcu).bits;
3540 var smin_big_int: std.math.big.int.Mutable = .{3538 var smin_big_int: std.math.big.int.Mutable = .{
...@@ -3616,11 +3614,9 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo...@@ -3616,11 +3614,9 @@ fn airMod(self: *FuncGen, inst: Air.Inst.Index, fast: Builder.FastMathKind) Allo
3616 }3614 }
3617 if (scalar_ty.isSignedInt(zcu)) {3615 if (scalar_ty.isSignedInt(zcu)) {
3618 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;3616 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(256)]std.math.big.Limb;
3619 var stack align(@max(3617 var bfa_buf: ExpectedContents = undefined;
3620 @alignOf(std.heap.StackFallbackAllocator(0)),3618 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
3621 @alignOf(ExpectedContents),3619 const allocator = bfa.allocator();
3622 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
3623 const allocator = stack.get();
36243620
3625 const scalar_bits = scalar_ty.intInfo(zcu).bits;3621 const scalar_bits = scalar_ty.intInfo(zcu).bits;
3626 var smin_big_int: std.math.big.int.Mutable = .{3622 var smin_big_int: std.math.big.int.Mutable = .{
src/codegen/riscv64/CodeGen.zig+7-6
...@@ -671,11 +671,12 @@ fn restoreState(func: *Func, state: State, deaths: []const Air.Inst.Index, compt...@@ -671,11 +671,12 @@ fn restoreState(func: *Func, state: State, deaths: []const Air.Inst.Index, compt
671 for (deaths) |death| try func.processDeath(death);671 for (deaths) |death| try func.processDeath(death);
672672
673 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;673 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;
674 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =674 const stack_buf_len = if (opts.update_tracking) 0 else 1;
675 if (opts.update_tracking) {} else std.heap.stackFallback(@sizeOf(ExpectedContents), func.gpa);675 var bfa_buf: [stack_buf_len]ExpectedContents = undefined;
676 var bfa = if (opts.update_tracking) {} else std.heap.BufferFirstAllocator.init(@ptrCast(&bfa_buf), func.gpa);
676677
677 var reg_locks = if (opts.update_tracking) {} else try std.array_list.Managed(RegisterLock).initCapacity(678 var reg_locks = if (opts.update_tracking) {} else try std.array_list.Managed(RegisterLock).initCapacity(
678 stack.get(),679 bfa.allocator(),
679 @typeInfo(ExpectedContents).array.len,680 @typeInfo(ExpectedContents).array.len,
680 );681 );
681 defer if (!opts.update_tracking) {682 defer if (!opts.update_tracking) {
...@@ -4807,9 +4808,9 @@ fn airCall(func: *Func, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -4807,9 +4808,9 @@ fn airCall(func: *Func, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4807 const ExpectedContents = extern struct {4808 const ExpectedContents = extern struct {
4808 vals: [expected_num_args][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),4809 vals: [expected_num_args][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),
4809 };4810 };
4810 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =4811 var bfa_buf: ExpectedContents = undefined;
4811 std.heap.stackFallback(@sizeOf(ExpectedContents), func.gpa);4812 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), func.gpa);
4812 const allocator = stack.get();4813 const allocator = bfa.allocator();
48134814
4814 const arg_tys = try allocator.alloc(Type, arg_refs.len);4815 const arg_tys = try allocator.alloc(Type, arg_refs.len);
4815 defer allocator.free(arg_tys);4816 defer allocator.free(arg_tys);
src/codegen/x86_64/CodeGen.zig+22-21
...@@ -173820,9 +173820,9 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {...@@ -173820,9 +173820,9 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173820 var err_temp = try cg.tempInit(err_ty, err_mcv);173820 var err_temp = try cg.tempInit(err_ty, err_mcv);
173821173821
173822 const ExpectedContents = [32]Mir.Inst.Index;173822 const ExpectedContents = [32]Mir.Inst.Index;
173823 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =173823 var bfa_buf: ExpectedContents = undefined;
173824 std.heap.stackFallback(@sizeOf(ExpectedContents), cg.gpa);173824 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa);
173825 const allocator = stack.get();173825 const allocator = bfa.allocator();
173826173826
173827 const relocs = try allocator.alloc(Mir.Inst.Index, error_set_type.names.len);173827 const relocs = try allocator.alloc(Mir.Inst.Index, error_set_type.names.len);
173828 defer allocator.free(relocs);173828 defer allocator.free(relocs);
...@@ -174220,11 +174220,12 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co...@@ -174220,11 +174220,12 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co
174220 for (deaths) |death| try self.processDeath(death, .{ .emit_instructions = opts.emit_instructions });174220 for (deaths) |death| try self.processDeath(death, .{ .emit_instructions = opts.emit_instructions });
174221174221
174222 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;174222 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;
174223 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =174223 const bfa_buf_len = if (opts.update_tracking) 0 else 1;
174224 if (opts.update_tracking) {} else std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);174224 var bfa_buf: [bfa_buf_len]ExpectedContents = undefined;
174225 var stack = if (opts.update_tracking) {} else std.heap.BufferFirstAllocator.init(@ptrCast(&bfa_buf), self.gpa);
174225174226
174226 var reg_locks = if (opts.update_tracking) {} else try std.array_list.Managed(RegisterLock).initCapacity(174227 var reg_locks = if (opts.update_tracking) {} else try std.array_list.Managed(RegisterLock).initCapacity(
174227 stack.get(),174228 stack.allocator(),
174228 @typeInfo(ExpectedContents).array.len,174229 @typeInfo(ExpectedContents).array.len,
174229 );174230 );
174230 defer if (!opts.update_tracking) {174231 defer if (!opts.update_tracking) {
...@@ -175929,9 +175930,9 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif...@@ -175929,9 +175930,9 @@ fn airCall(self: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
175929 tys: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),175930 tys: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
175930 vals: [32][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),175931 vals: [32][@sizeOf(MCValue)]u8 align(@alignOf(MCValue)),
175931 };175932 };
175932 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =175933 var bfa_buf: [1]ExpectedContents = undefined;
175933 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);175934 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
175934 const allocator = stack.get();175935 const allocator = bfa.allocator();
175935175936
175936 const arg_tys = try allocator.alloc(Type, arg_refs.len);175937 const arg_tys = try allocator.alloc(Type, arg_refs.len);
175937 defer allocator.free(arg_tys);175938 defer allocator.free(arg_tys);
...@@ -175985,9 +175986,9 @@ fn genCall(self: *CodeGen, info: union(enum) {...@@ -175985,9 +175986,9 @@ fn genCall(self: *CodeGen, info: union(enum) {
175985 frame_indices: [32]FrameIndex,175986 frame_indices: [32]FrameIndex,
175986 reg_locks: [32][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),175987 reg_locks: [32][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),
175987 };175988 };
175988 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =175989 var bfa_buf: ExpectedContents = undefined;
175989 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);175990 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), self.gpa);
175990 const allocator = stack.get();175991 const allocator = bfa.allocator();
175991175992
175992 const var_args = try allocator.alloc(Type, args.len - fn_info.param_types.len);175993 const var_args = try allocator.alloc(Type, args.len - fn_info.param_types.len);
175993 defer allocator.free(var_args);175994 defer allocator.free(var_args);
...@@ -176588,9 +176589,9 @@ fn lowerSwitchBr(...@@ -176588,9 +176589,9 @@ fn lowerSwitchBr(
176588 bigint_limbs: [std.math.big.int.calcTwosCompLimbCount(1 << 10)]std.math.big.Limb,176589 bigint_limbs: [std.math.big.int.calcTwosCompLimbCount(1 << 10)]std.math.big.Limb,
176589 relocs: [1 << 6]Mir.Inst.Index,176590 relocs: [1 << 6]Mir.Inst.Index,
176590 };176591 };
176591 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =176592 var bfa_buf: ExpectedContents = undefined;
176592 std.heap.stackFallback(@sizeOf(ExpectedContents), cg.gpa);176593 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa);
176593 const allocator = stack.get();176594 const allocator = bfa.allocator();
176594176595
176595 const state = try cg.saveState();176596 const state = try cg.saveState();
176596176597
...@@ -181154,9 +181155,9 @@ fn resolveCallingConventionValues(...@@ -181154,9 +181155,9 @@ fn resolveCallingConventionValues(
181154 const ExpectedContents = extern struct {181155 const ExpectedContents = extern struct {
181155 param_types: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),181156 param_types: [32][@sizeOf(Type)]u8 align(@alignOf(Type)),
181156 };181157 };
181157 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =181158 var bfa_buf: ExpectedContents = undefined;
181158 std.heap.stackFallback(@sizeOf(ExpectedContents), cg.gpa);181159 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa);
181159 const allocator = stack.get();181160 const allocator = bfa.allocator();
181160181161
181161 const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len);181162 const param_types = try allocator.alloc(Type, fn_info.param_types.len + var_args.len);
181162 defer allocator.free(param_types);181163 defer allocator.free(param_types);
...@@ -188706,9 +188707,9 @@ const Select = struct {...@@ -188706,9 +188707,9 @@ const Select = struct {
188706 }188707 }
188707188708
188708 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(1 << 10)]std.math.big.Limb;188709 const ExpectedContents = [std.math.big.int.calcTwosCompLimbCount(1 << 10)]std.math.big.Limb;
188709 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =188710 var bfa_buf: ExpectedContents = undefined;
188710 std.heap.stackFallback(@sizeOf(ExpectedContents), cg.gpa);188711 var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa);
188711 const allocator = stack.get();188712 const allocator = bfa.allocator();
188712 var res_big_int: std.math.big.int.Mutable = .{188713 var res_big_int: std.math.big.int.Mutable = .{
188713 .limbs = try allocator.alloc(188714 .limbs = try allocator.alloc(
188714 std.math.big.Limb,188715 std.math.big.Limb,
src/link/Elf2.zig+3-2
...@@ -2690,8 +2690,9 @@ pub fn ensureUnusedRelocCapacity(elf: *Elf, loc_si: Symbol.Index, len: usize) !v...@@ -2690,8 +2690,9 @@ pub fn ensureUnusedRelocCapacity(elf: *Elf, loc_si: Symbol.Index, len: usize) !v
2690 const shndx = loc_si.shndx(elf);2690 const shndx = loc_si.shndx(elf);
2691 const sh = shndx.get(elf);2691 const sh = shndx.get(elf);
2692 if (sh.rela_si == .null) {2692 if (sh.rela_si == .null) {
2693 var stack = std.heap.stackFallback(32, gpa);2693 var bfa_buf: [32]u8 = undefined;
2694 const allocator = stack.get();2694 var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
2695 const allocator = bfa.allocator();
26952696
2696 const rela_name =2697 const rela_name =
2697 try std.fmt.allocPrint(allocator, ".rela{s}", .{elf.sectionName(sh.si)});2698 try std.fmt.allocPrint(allocator, ".rela{s}", .{elf.sectionName(sh.si)});