Commit b3ecdb21ee

Andrew Kelley <andrew@ziglang.org>
2024-12-08 06:41:44
switch to ArrayListUnmanaged for machine code
1 parent bf20a4a
src/arch/aarch64/CodeGen.zig
@@ -323,7 +323,7 @@ pub fn generate(
     func_index: InternPool.Index,
     air: Air,
     liveness: Liveness,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const zcu = pt.zcu;
src/arch/aarch64/Emit.zig
@@ -20,7 +20,7 @@ debug_output: link.File.DebugInfoOutput,
 target: *const std.Target,
 err_msg: ?*ErrorMsg = null,
 src_loc: Zcu.LazySrcLoc,
-code: *std.ArrayList(u8),
+code: *std.ArrayListUnmanaged(u8),
 
 prev_di_line: u32,
 prev_di_column: u32,
@@ -424,8 +424,10 @@ fn lowerBranches(emit: *Emit) !void {
 }
 
 fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
+    const comp = emit.bin_file.comp;
+    const gpa = comp.gpa;
     const endian = emit.target.cpu.arch.endian();
-    std.mem.writeInt(u32, try emit.code.addManyAsArray(4), instruction.toU32(), endian);
+    std.mem.writeInt(u32, try emit.code.addManyAsArray(gpa, 4), instruction.toU32(), endian);
 }
 
 fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
src/arch/arm/CodeGen.zig
@@ -332,7 +332,7 @@ pub fn generate(
     func_index: InternPool.Index,
     air: Air,
     liveness: Liveness,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const zcu = pt.zcu;
src/arch/arm/Emit.zig
@@ -24,7 +24,7 @@ debug_output: link.File.DebugInfoOutput,
 target: *const std.Target,
 err_msg: ?*ErrorMsg = null,
 src_loc: Zcu.LazySrcLoc,
-code: *std.ArrayList(u8),
+code: *std.ArrayListUnmanaged(u8),
 
 prev_di_line: u32,
 prev_di_column: u32,
@@ -342,8 +342,10 @@ fn lowerBranches(emit: *Emit) !void {
 }
 
 fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
+    const comp = emit.bin_file.comp;
+    const gpa = comp.gpa;
     const endian = emit.target.cpu.arch.endian();
-    std.mem.writeInt(u32, try emit.code.addManyAsArray(4), instruction.toU32(), endian);
+    std.mem.writeInt(u32, try emit.code.addManyAsArray(gpa, 4), instruction.toU32(), endian);
 }
 
 fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
src/arch/riscv64/CodeGen.zig
@@ -757,7 +757,7 @@ pub fn generate(
     func_index: InternPool.Index,
     air: Air,
     liveness: Liveness,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const zcu = pt.zcu;
@@ -898,7 +898,7 @@ pub fn generateLazy(
     pt: Zcu.PerThread,
     src_loc: Zcu.LazySrcLoc,
     lazy_sym: link.File.LazySymbol,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const comp = bin_file.comp;
src/arch/riscv64/Emit.zig
@@ -3,7 +3,7 @@
 bin_file: *link.File,
 lower: Lower,
 debug_output: link.File.DebugInfoOutput,
-code: *std.ArrayList(u8),
+code: *std.ArrayListUnmanaged(u8),
 
 prev_di_line: u32,
 prev_di_column: u32,
@@ -18,6 +18,7 @@ pub const Error = Lower.Error || error{
 };
 
 pub fn emitMir(emit: *Emit) Error!void {
+    const gpa = emit.bin_file.comp.gpa;
     log.debug("mir instruction len: {}", .{emit.lower.mir.instructions.len});
     for (0..emit.lower.mir.instructions.len) |mir_i| {
         const mir_index: Mir.Inst.Index = @intCast(mir_i);
@@ -30,7 +31,7 @@ pub fn emitMir(emit: *Emit) Error!void {
         var lowered_relocs = lowered.relocs;
         for (lowered.insts, 0..) |lowered_inst, lowered_index| {
             const start_offset: u32 = @intCast(emit.code.items.len);
-            try lowered_inst.encode(emit.code.writer());
+            try lowered_inst.encode(emit.code.writer(gpa));
 
             while (lowered_relocs.len > 0 and
                 lowered_relocs[0].lowered_inst_index == lowered_index) : ({
@@ -56,13 +57,13 @@ pub fn emitMir(emit: *Emit) Error!void {
                     const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
                     const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
 
-                    try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
+                    try atom_ptr.addReloc(gpa, .{
                         .r_offset = start_offset,
                         .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
                         .r_addend = 0,
                     }, zo);
 
-                    try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
+                    try atom_ptr.addReloc(gpa, .{
                         .r_offset = start_offset + 4,
                         .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,
                         .r_addend = 0,
@@ -76,19 +77,19 @@ pub fn emitMir(emit: *Emit) Error!void {
 
                     const R_RISCV = std.elf.R_RISCV;
 
-                    try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
+                    try atom_ptr.addReloc(gpa, .{
                         .r_offset = start_offset,
                         .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_HI20),
                         .r_addend = 0,
                     }, zo);
 
-                    try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
+                    try atom_ptr.addReloc(gpa, .{
                         .r_offset = start_offset + 4,
                         .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_ADD),
                         .r_addend = 0,
                     }, zo);
 
-                    try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
+                    try atom_ptr.addReloc(gpa, .{
                         .r_offset = start_offset + 8,
                         .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_LO12_I),
                         .r_addend = 0,
@@ -101,7 +102,7 @@ pub fn emitMir(emit: *Emit) Error!void {
 
                     const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);
 
-                    try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
+                    try atom_ptr.addReloc(gpa, .{
                         .r_offset = start_offset,
                         .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
                         .r_addend = 0,
src/arch/sparc64/CodeGen.zig
@@ -54,7 +54,7 @@ liveness: Liveness,
 bin_file: *link.File,
 target: *const std.Target,
 func_index: InternPool.Index,
-code: *std.ArrayList(u8),
+code: *std.ArrayListUnmanaged(u8),
 debug_output: link.File.DebugInfoOutput,
 err_msg: ?*ErrorMsg,
 args: []MCValue,
@@ -265,7 +265,7 @@ pub fn generate(
     func_index: InternPool.Index,
     air: Air,
     liveness: Liveness,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const zcu = pt.zcu;
@@ -283,7 +283,7 @@ pub fn generate(
     }
     try branch_stack.append(.{});
 
-    var function = Self{
+    var function: Self = .{
         .gpa = gpa,
         .pt = pt,
         .air = air,
@@ -331,7 +331,7 @@ pub fn generate(
     };
     defer mir.deinit(gpa);
 
-    var emit = Emit{
+    var emit: Emit = .{
         .mir = mir,
         .bin_file = lf,
         .debug_output = debug_output,
src/arch/sparc64/Emit.zig
@@ -22,7 +22,7 @@ debug_output: link.File.DebugInfoOutput,
 target: *const std.Target,
 err_msg: ?*ErrorMsg = null,
 src_loc: Zcu.LazySrcLoc,
-code: *std.ArrayList(u8),
+code: *std.ArrayListUnmanaged(u8),
 
 prev_di_line: u32,
 prev_di_column: u32,
@@ -678,10 +678,13 @@ fn optimalBranchType(emit: *Emit, tag: Mir.Inst.Tag, offset: i64) !BranchType {
 }
 
 fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
+    const comp = emit.bin_file.comp;
+    const gpa = comp.gpa;
+
     // SPARCv9 instructions are always arranged in BE regardless of the
     // endianness mode the CPU is running in (Section 3.1 of the ISA specification).
     // This is to ease porting in case someone wants to do a LE SPARCv9 backend.
-    const endian = Endian.big;
+    const endian: Endian = .big;
 
-    std.mem.writeInt(u32, try emit.code.addManyAsArray(4), instruction.toU32(), endian);
+    std.mem.writeInt(u32, try emit.code.addManyAsArray(gpa, 4), instruction.toU32(), endian);
 }
src/arch/x86_64/CodeGen.zig
@@ -817,7 +817,7 @@ pub fn generate(
     func_index: InternPool.Index,
     air: Air,
     liveness: Liveness,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const zcu = pt.zcu;
@@ -970,7 +970,7 @@ pub fn generateLazy(
     pt: Zcu.PerThread,
     src_loc: Zcu.LazySrcLoc,
     lazy_sym: link.File.LazySymbol,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const comp = bin_file.comp;
src/arch/x86_64/Emit.zig
@@ -4,7 +4,7 @@ air: Air,
 lower: Lower,
 atom_index: u32,
 debug_output: link.File.DebugInfoOutput,
-code: *std.ArrayList(u8),
+code: *std.ArrayListUnmanaged(u8),
 
 prev_di_loc: Loc,
 /// Relative to the beginning of `code`.
@@ -18,6 +18,7 @@ pub const Error = Lower.Error || error{
 } || link.File.UpdateDebugInfoError;
 
 pub fn emitMir(emit: *Emit) Error!void {
+    const gpa = emit.lower.bin_file.comp.gpa;
     for (0..emit.lower.mir.instructions.len) |mir_i| {
         const mir_index: Mir.Inst.Index = @intCast(mir_i);
         try emit.code_offset_mapping.putNoClobber(
@@ -82,7 +83,7 @@ pub fn emitMir(emit: *Emit) Error!void {
                 }
                 continue;
             }
-            try lowered_inst.encode(emit.code.writer(), .{});
+            try lowered_inst.encode(emit.code.writer(gpa), .{});
             const end_offset: u32 = @intCast(emit.code.items.len);
             while (lowered_relocs.len > 0 and
                 lowered_relocs[0].lowered_inst_index == lowered_index) : ({
@@ -100,7 +101,7 @@ pub fn emitMir(emit: *Emit) Error!void {
                     const zo = elf_file.zigObjectPtr().?;
                     const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?;
                     const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);
-                    try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
+                    try atom_ptr.addReloc(gpa, .{
                         .r_offset = end_offset - 4,
                         .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
                         .r_addend = lowered_relocs[0].off - 4,
@@ -147,7 +148,7 @@ pub fn emitMir(emit: *Emit) Error!void {
                     const zo = elf_file.zigObjectPtr().?;
                     const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
                     const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
-                    try atom.addReloc(elf_file.base.comp.gpa, .{
+                    try atom.addReloc(gpa, .{
                         .r_offset = end_offset - 4,
                         .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
                         .r_addend = lowered_relocs[0].off - 4,
@@ -158,7 +159,7 @@ pub fn emitMir(emit: *Emit) Error!void {
                     const zo = elf_file.zigObjectPtr().?;
                     const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
                     const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
-                    try atom.addReloc(elf_file.base.comp.gpa, .{
+                    try atom.addReloc(gpa, .{
                         .r_offset = end_offset - 4,
                         .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
                         .r_addend = lowered_relocs[0].off,
@@ -173,7 +174,7 @@ pub fn emitMir(emit: *Emit) Error!void {
                             @intFromEnum(std.elf.R_X86_64.GOTPCREL)
                         else
                             @intFromEnum(std.elf.R_X86_64.PC32);
-                        try atom.addReloc(elf_file.base.comp.gpa, .{
+                        try atom.addReloc(gpa, .{
                             .r_offset = end_offset - 4,
                             .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
                             .r_addend = lowered_relocs[0].off - 4,
@@ -183,7 +184,7 @@ pub fn emitMir(emit: *Emit) Error!void {
                             @intFromEnum(std.elf.R_X86_64.TPOFF32)
                         else
                             @intFromEnum(std.elf.R_X86_64.@"32");
-                        try atom.addReloc(elf_file.base.comp.gpa, .{
+                        try atom.addReloc(gpa, .{
                             .r_offset = end_offset - 4,
                             .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
                             .r_addend = lowered_relocs[0].off,
src/link/Elf/ZigObject.zig
@@ -1431,8 +1431,8 @@ pub fn updateFunc(
     const sym_index = try self.getOrCreateMetadataForNav(zcu, func.owner_nav);
     self.atom(self.symbol(sym_index).ref.index).?.freeRelocs(self);
 
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
     defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
@@ -1561,8 +1561,8 @@ pub fn updateNav(
         const sym_index = try self.getOrCreateMetadataForNav(zcu, nav_index);
         self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
 
-        var code_buffer = std.ArrayList(u8).init(zcu.gpa);
-        defer code_buffer.deinit();
+        var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+        defer code_buffer.deinit(zcu.gpa);
 
         var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
         defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
@@ -1616,8 +1616,8 @@ fn updateLazySymbol(
     const gpa = zcu.gpa;
 
     var required_alignment: InternPool.Alignment = .none;
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     const name_str_index = blk: {
         const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
@@ -1706,8 +1706,8 @@ fn lowerConst(
 ) !LowerConstResult {
     const gpa = pt.zcu.gpa;
 
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     const name_off = try self.addString(gpa, name);
     const sym_index = try self.newSymbolWithAtom(gpa, name_off);
src/link/MachO/ZigObject.zig
@@ -789,8 +789,8 @@ pub fn updateFunc(
     const sym_index = try self.getOrCreateMetadataForNav(macho_file, func.owner_nav);
     self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
 
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
     defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
@@ -900,8 +900,8 @@ pub fn updateNav(
         const sym_index = try self.getOrCreateMetadataForNav(macho_file, nav_index);
         self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
 
-        var code_buffer = std.ArrayList(u8).init(zcu.gpa);
-        defer code_buffer.deinit();
+        var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+        defer code_buffer.deinit(zcu.gpa);
 
         var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null;
         defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
@@ -1201,8 +1201,8 @@ fn lowerConst(
 ) !LowerConstResult {
     const gpa = macho_file.base.comp.gpa;
 
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     const name_str = try self.addString(gpa, name);
     const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file);
@@ -1352,8 +1352,8 @@ fn updateLazySymbol(
     const gpa = zcu.gpa;
 
     var required_alignment: Atom.Alignment = .none;
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     const name_str = blk: {
         const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
src/link/Coff.zig
@@ -1119,8 +1119,8 @@ pub fn updateFunc(
 
     coff.navs.getPtr(func.owner_nav).?.section = coff.text_section_index.?;
 
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     codegen.generateFunction(
         &coff.base,
@@ -1167,8 +1167,8 @@ fn lowerConst(
 ) !LowerConstResult {
     const gpa = coff.base.comp.gpa;
 
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     const atom_index = try coff.createAtom();
     const sym = coff.getAtom(atom_index).getSymbolPtr(coff);
@@ -1237,8 +1237,8 @@ pub fn updateNav(
 
         coff.navs.getPtr(nav_index).?.section = coff.getNavOutputSection(nav_index);
 
-        var code_buffer = std.ArrayList(u8).init(gpa);
-        defer code_buffer.deinit();
+        var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+        defer code_buffer.deinit(gpa);
 
         try codegen.generateSymbol(
             &coff.base,
@@ -1267,8 +1267,8 @@ fn updateLazySymbolAtom(
     const gpa = comp.gpa;
 
     var required_alignment: InternPool.Alignment = .none;
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     const name = try allocPrint(gpa, "__lazy_{s}_{}", .{
         @tagName(sym.kind),
src/link/Dwarf.zig
@@ -1890,17 +1890,16 @@ pub const WipNav = struct {
         const bytes = if (ty.hasRuntimeBits(wip_nav.pt.zcu)) ty.abiSize(wip_nav.pt.zcu) else 0;
         try uleb128(diw, bytes);
         if (bytes == 0) return;
-        var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa);
-        defer wip_nav.debug_info = dim.moveToUnmanaged();
+        const old_len = wip_nav.debug_info.items.len;
         try codegen.generateSymbol(
             wip_nav.dwarf.bin_file,
             wip_nav.pt,
             src_loc,
             val,
-            &dim,
+            &wip_nav.debug_info,
             .{ .debug_output = .{ .dwarf = wip_nav } },
         );
-        assert(dim.items.len == wip_nav.debug_info.items.len + bytes);
+        assert(old_len + bytes == wip_nav.debug_info.items.len);
     }
 
     const AbbrevCodeForForm = struct {
src/link/Plan9.zig
@@ -404,8 +404,8 @@ pub fn updateFunc(
 
     const atom_idx = try self.seeNav(pt, func.owner_nav);
 
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
     var dbg_info_output: DebugInfoOutput = .{
         .dbg_line = std.ArrayList(u8).init(gpa),
         .start_line = null,
@@ -426,7 +426,7 @@ pub fn updateFunc(
         &code_buffer,
         .{ .plan9 = &dbg_info_output },
     );
-    const code = try code_buffer.toOwnedSlice();
+    const code = try code_buffer.toOwnedSlice(gpa);
     self.getAtomPtr(atom_idx).code = .{
         .code_ptr = null,
         .other = .{ .nav_index = func.owner_nav },
@@ -462,8 +462,8 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
     if (nav_init.typeOf(zcu).hasRuntimeBits(zcu)) {
         const atom_idx = try self.seeNav(pt, nav_index);
 
-        var code_buffer = std.ArrayList(u8).init(gpa);
-        defer code_buffer.deinit();
+        var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+        defer code_buffer.deinit(gpa);
         // TODO we need the symbol index for symbol in the table of locals for the containing atom
         try codegen.generateSymbol(
             &self.base,
@@ -1060,8 +1060,8 @@ fn updateLazySymbolAtom(
     const diags = &comp.link_diags;
 
     var required_alignment: InternPool.Alignment = .none;
-    var code_buffer = std.ArrayList(u8).init(gpa);
-    defer code_buffer.deinit();
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
 
     // create the symbol for the name
     const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
@@ -1401,16 +1401,16 @@ pub fn lowerUav(
     const got_index = self.allocateGotIndex();
     gop.value_ptr.* = index;
     // we need to free name latex
-    var code_buffer = std.ArrayList(u8).init(gpa);
+    var code_buffer: std.ArrayListUnmanaged(u8) = .empty;
+    defer code_buffer.deinit(gpa);
     try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index });
-    const code = code_buffer.items;
     const atom_ptr = self.getAtomPtr(index);
     atom_ptr.* = .{
         .type = .d,
         .offset = undefined,
         .sym_index = null,
         .got_index = got_index,
-        .code = Atom.CodePtr.fromSlice(code),
+        .code = Atom.CodePtr.fromSlice(try code_buffer.toOwnedSlice(gpa)),
     };
     _ = try atom_ptr.getOrCreateSymbolTableEntry(self);
     self.syms.items[atom_ptr.sym_index.?] = .{
src/link/Wasm.zig
@@ -1560,7 +1560,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
     const relocs_start: u32 = @intCast(wasm.relocations.len);
     wasm.string_bytes_lock.lock();
 
-    const res = try codegen.generateSymbol(
+    try codegen.generateSymbol(
         &wasm.base,
         pt,
         zcu.navSrcLoc(nav_index),
@@ -1573,15 +1573,9 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
     const relocs_len: u32 = @intCast(wasm.relocations.len - relocs_start);
     wasm.string_bytes_lock.unlock();
 
-    const code: Nav.Code = switch (res) {
-        .ok => .{
-            .off = code_start,
-            .len = code_len,
-        },
-        .fail => |em| {
-            try zcu.failed_codegen.put(gpa, nav_index, em);
-            return;
-        },
+    const code: Nav.Code = .{
+        .off = code_start,
+        .len = code_len,
     };
 
     const gop = try wasm.navs.getOrPut(gpa, nav_index);
src/codegen.zig
@@ -55,7 +55,7 @@ pub fn generateFunction(
     func_index: InternPool.Index,
     air: Air,
     liveness: Liveness,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const zcu = pt.zcu;
@@ -80,7 +80,7 @@ pub fn generateLazyFunction(
     pt: Zcu.PerThread,
     src_loc: Zcu.LazySrcLoc,
     lazy_sym: link.File.LazySymbol,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
 ) CodeGenError!void {
     const zcu = pt.zcu;
@@ -110,7 +110,7 @@ pub fn generateLazySymbol(
     lazy_sym: link.File.LazySymbol,
     // TODO don't use an "out" parameter like this; put it in the result instead
     alignment: *Alignment,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     debug_output: link.File.DebugInfoOutput,
     reloc_parent: link.File.RelocInfo.Parent,
 ) CodeGenError!void {
@@ -120,6 +120,7 @@ pub fn generateLazySymbol(
     defer tracy.end();
 
     const comp = bin_file.comp;
+    const gpa = comp.gpa;
     const zcu = pt.zcu;
     const ip = &zcu.intern_pool;
     const target = comp.root_mod.resolved_target.result;
@@ -140,7 +141,7 @@ pub fn generateLazySymbol(
         const err_names = ip.global_error_set.getNamesFromMainThread();
         var offset_index: u32 = @intCast(code.items.len);
         var string_index: u32 = @intCast(4 * (1 + err_names.len + @intFromBool(err_names.len > 0)));
-        try code.resize(offset_index + string_index);
+        try code.resize(gpa, offset_index + string_index);
         mem.writeInt(u32, code.items[offset_index..][0..4], @intCast(err_names.len), endian);
         if (err_names.len == 0) return .ok;
         offset_index += 4;
@@ -148,7 +149,7 @@ pub fn generateLazySymbol(
             const err_name = err_name_nts.toSlice(ip);
             mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian);
             offset_index += 4;
-            try code.ensureUnusedCapacity(err_name.len + 1);
+            try code.ensureUnusedCapacity(gpa, err_name.len + 1);
             code.appendSliceAssumeCapacity(err_name);
             code.appendAssumeCapacity(0);
             string_index += @intCast(err_name.len + 1);
@@ -160,7 +161,7 @@ pub fn generateLazySymbol(
         const tag_names = enum_ty.enumFields(zcu);
         for (0..tag_names.len) |tag_index| {
             const tag_name = tag_names.get(ip)[tag_index].toSlice(ip);
-            try code.ensureUnusedCapacity(tag_name.len + 1);
+            try code.ensureUnusedCapacity(gpa, tag_name.len + 1);
             code.appendSliceAssumeCapacity(tag_name);
             code.appendAssumeCapacity(0);
         }
@@ -182,13 +183,14 @@ pub fn generateSymbol(
     pt: Zcu.PerThread,
     src_loc: Zcu.LazySrcLoc,
     val: Value,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     reloc_parent: link.File.RelocInfo.Parent,
 ) GenerateSymbolError!void {
     const tracy = trace(@src());
     defer tracy.end();
 
     const zcu = pt.zcu;
+    const gpa = zcu.gpa;
     const ip = &zcu.intern_pool;
     const ty = val.typeOf(zcu);
 
@@ -199,7 +201,7 @@ pub fn generateSymbol(
 
     if (val.isUndefDeep(zcu)) {
         const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
-        try code.appendNTimes(0xaa, abi_size);
+        try code.appendNTimes(gpa, 0xaa, abi_size);
         return;
     }
 
@@ -231,7 +233,7 @@ pub fn generateSymbol(
             .@"unreachable",
             .generic_poison,
             => unreachable, // non-runtime values
-            .false, .true => try code.append(switch (simple_value) {
+            .false, .true => try code.append(gpa, switch (simple_value) {
                 .false => 0,
                 .true => 1,
                 else => unreachable,
@@ -247,11 +249,11 @@ pub fn generateSymbol(
             const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
             var space: Value.BigIntSpace = undefined;
             const int_val = val.toBigInt(&space, zcu);
-            int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
+            int_val.writeTwosComplement(try code.addManyAsSlice(gpa, abi_size), endian);
         },
         .err => |err| {
             const int = try pt.getErrorValue(err.name);
-            try code.writer().writeInt(u16, @intCast(int), endian);
+            try code.writer(gpa).writeInt(u16, @intCast(int), endian);
         },
         .error_union => |error_union| {
             const payload_ty = ty.errorUnionPayload(zcu);
@@ -261,7 +263,7 @@ pub fn generateSymbol(
             };
 
             if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
-                try code.writer().writeInt(u16, err_val, endian);
+                try code.writer(gpa).writeInt(u16, err_val, endian);
                 return;
             }
 
@@ -271,7 +273,7 @@ pub fn generateSymbol(
 
             // error value first when its type is larger than the error union's payload
             if (error_align.order(payload_align) == .gt) {
-                try code.writer().writeInt(u16, err_val, endian);
+                try code.writer(gpa).writeInt(u16, err_val, endian);
             }
 
             // emit payload part of the error union
@@ -286,20 +288,20 @@ pub fn generateSymbol(
                 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
 
                 if (padding > 0) {
-                    try code.appendNTimes(0, padding);
+                    try code.appendNTimes(gpa, 0, padding);
                 }
             }
 
             // Payload size is larger than error set, so emit our error set last
             if (error_align.compare(.lte, payload_align)) {
                 const begin = code.items.len;
-                try code.writer().writeInt(u16, err_val, endian);
+                try code.writer(gpa).writeInt(u16, err_val, endian);
                 const unpadded_end = code.items.len - begin;
                 const padded_end = abi_align.forward(unpadded_end);
                 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
 
                 if (padding > 0) {
-                    try code.appendNTimes(0, padding);
+                    try code.appendNTimes(gpa, 0, padding);
                 }
             }
         },
@@ -308,15 +310,15 @@ pub fn generateSymbol(
             try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent);
         },
         .float => |float| switch (float.storage) {
-            .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(2)),
-            .f32 => |f32_val| writeFloat(f32, f32_val, target, endian, try code.addManyAsArray(4)),
-            .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(8)),
+            .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(gpa, 2)),
+            .f32 => |f32_val| writeFloat(f32, f32_val, target, endian, try code.addManyAsArray(gpa, 4)),
+            .f64 => |f64_val| writeFloat(f64, f64_val, target, endian, try code.addManyAsArray(gpa, 8)),
             .f80 => |f80_val| {
-                writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(10));
+                writeFloat(f80, f80_val, target, endian, try code.addManyAsArray(gpa, 10));
                 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
-                try code.appendNTimes(0, abi_size - 10);
+                try code.appendNTimes(gpa, 0, abi_size - 10);
             },
-            .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)),
+            .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(gpa, 16)),
         },
         .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0),
         .slice => |slice| {
@@ -332,7 +334,7 @@ pub fn generateSymbol(
                 if (payload_val) |value| {
                     try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
                 } else {
-                    try code.appendNTimes(0, abi_size);
+                    try code.appendNTimes(gpa, 0, abi_size);
                 }
             } else {
                 const padding = abi_size - (math.cast(usize, payload_type.abiSize(zcu)) orelse return error.Overflow) - 1;
@@ -342,13 +344,13 @@ pub fn generateSymbol(
                     }));
                     try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent);
                 }
-                try code.writer().writeByte(@intFromBool(payload_val != null));
-                try code.appendNTimes(0, padding);
+                try code.writer(gpa).writeByte(@intFromBool(payload_val != null));
+                try code.appendNTimes(gpa, 0, padding);
             }
         },
         .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) {
             .array_type => |array_type| switch (aggregate.storage) {
-                .bytes => |bytes| try code.appendSlice(bytes.toSlice(array_type.lenIncludingSentinel(), ip)),
+                .bytes => |bytes| try code.appendSlice(gpa, bytes.toSlice(array_type.lenIncludingSentinel(), ip)),
                 .elems, .repeated_elem => {
                     var index: u64 = 0;
                     while (index < array_type.lenIncludingSentinel()) : (index += 1) {
@@ -366,7 +368,7 @@ pub fn generateSymbol(
             .vector_type => |vector_type| {
                 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
                 if (vector_type.child == .bool_type) {
-                    const bytes = try code.addManyAsSlice(abi_size);
+                    const bytes = try code.addManyAsSlice(gpa, abi_size);
                     @memset(bytes, 0xaa);
                     var index: usize = 0;
                     const len = math.cast(usize, vector_type.len) orelse return error.Overflow;
@@ -405,7 +407,7 @@ pub fn generateSymbol(
                     }
                 } else {
                     switch (aggregate.storage) {
-                        .bytes => |bytes| try code.appendSlice(bytes.toSlice(vector_type.len, ip)),
+                        .bytes => |bytes| try code.appendSlice(gpa, bytes.toSlice(vector_type.len, ip)),
                         .elems, .repeated_elem => {
                             var index: u64 = 0;
                             while (index < vector_type.len) : (index += 1) {
@@ -423,7 +425,7 @@ pub fn generateSymbol(
                     const padding = abi_size -
                         (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse
                         return error.Overflow);
-                    if (padding > 0) try code.appendNTimes(0, padding);
+                    if (padding > 0) try code.appendNTimes(gpa, 0, padding);
                 }
             },
             .tuple_type => |tuple| {
@@ -454,7 +456,7 @@ pub fn generateSymbol(
                         return error.Overflow;
 
                     if (padding > 0) {
-                        try code.appendNTimes(0, padding);
+                        try code.appendNTimes(gpa, 0, padding);
                     }
                 }
             },
@@ -464,7 +466,7 @@ pub fn generateSymbol(
                     .@"packed" => {
                         const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
                         const current_pos = code.items.len;
-                        try code.appendNTimes(0, abi_size);
+                        try code.appendNTimes(gpa, 0, abi_size);
                         var bits: u16 = 0;
 
                         for (struct_type.field_types.get(ip), 0..) |field_ty, index| {
@@ -482,8 +484,8 @@ pub fn generateSymbol(
                             if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .pointer) {
                                 const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(zcu)) orelse
                                     return error.Overflow;
-                                var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size);
-                                defer tmp_list.deinit();
+                                var tmp_list = try std.ArrayListUnmanaged(u8).initCapacity(gpa, field_size);
+                                defer tmp_list.deinit(gpa);
                                 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent);
                                 @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items);
                             } else {
@@ -515,7 +517,7 @@ pub fn generateSymbol(
                                 usize,
                                 offsets[field_index] - (code.items.len - struct_begin),
                             ) orelse return error.Overflow;
-                            if (padding > 0) try code.appendNTimes(0, padding);
+                            if (padding > 0) try code.appendNTimes(gpa, 0, padding);
 
                             try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent);
                         }
@@ -528,7 +530,7 @@ pub fn generateSymbol(
                             std.mem.alignForward(u64, size, @max(alignment, 1)) -
                                 (code.items.len - struct_begin),
                         ) orelse return error.Overflow;
-                        if (padding > 0) try code.appendNTimes(0, padding);
+                        if (padding > 0) try code.appendNTimes(gpa, 0, padding);
                     },
                 }
             },
@@ -551,13 +553,13 @@ pub fn generateSymbol(
                 const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
                 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
                 if (!field_ty.hasRuntimeBits(zcu)) {
-                    try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
+                    try code.appendNTimes(gpa, 0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
                 } else {
                     try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent);
 
                     const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;
                     if (padding > 0) {
-                        try code.appendNTimes(0, padding);
+                        try code.appendNTimes(gpa, 0, padding);
                     }
                 }
             } else {
@@ -568,7 +570,7 @@ pub fn generateSymbol(
                 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent);
 
                 if (layout.padding > 0) {
-                    try code.appendNTimes(0, layout.padding);
+                    try code.appendNTimes(gpa, 0, layout.padding);
                 }
             }
         },
@@ -581,7 +583,7 @@ fn lowerPtr(
     pt: Zcu.PerThread,
     src_loc: Zcu.LazySrcLoc,
     ptr_val: InternPool.Index,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     reloc_parent: link.File.RelocInfo.Parent,
     prev_offset: u64,
 ) GenerateSymbolError!void {
@@ -634,7 +636,7 @@ fn lowerUavRef(
     pt: Zcu.PerThread,
     src_loc: Zcu.LazySrcLoc,
     uav: InternPool.Key.Ptr.BaseAddr.Uav,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     reloc_parent: link.File.RelocInfo.Parent,
     offset: u64,
 ) GenerateSymbolError!void {
@@ -649,7 +651,7 @@ fn lowerUavRef(
     log.debug("lowerUavRef: ty = {}", .{uav_ty.fmt(pt)});
     const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
     if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) {
-        try code.appendNTimes(0xaa, ptr_width_bytes);
+        try code.appendNTimes(gpa, 0xaa, ptr_width_bytes);
         return;
     }
 
@@ -667,7 +669,7 @@ fn lowerUavRef(
                 .offset = @intCast(code.items.len),
                 .pointee = .{ .uav_index = uav.val },
             });
-            try code.appendNTimes(0, ptr_width_bytes);
+            try code.appendNTimes(gpa, 0, ptr_width_bytes);
             return;
         },
         else => {},
@@ -686,9 +688,9 @@ fn lowerUavRef(
     });
     const endian = target.cpu.arch.endian();
     switch (ptr_width_bytes) {
-        2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian),
-        4 => mem.writeInt(u32, try code.addManyAsArray(4), @intCast(vaddr), endian),
-        8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
+        2 => mem.writeInt(u16, try code.addManyAsArray(gpa, 2), @intCast(vaddr), endian),
+        4 => mem.writeInt(u32, try code.addManyAsArray(gpa, 4), @intCast(vaddr), endian),
+        8 => mem.writeInt(u64, try code.addManyAsArray(gpa, 8), vaddr, endian),
         else => unreachable,
     }
 }
@@ -698,7 +700,7 @@ fn lowerNavRef(
     pt: Zcu.PerThread,
     src_loc: Zcu.LazySrcLoc,
     nav_index: InternPool.Nav.Index,
-    code: *std.ArrayList(u8),
+    code: *std.ArrayListUnmanaged(u8),
     reloc_parent: link.File.RelocInfo.Parent,
     offset: u64,
 ) GenerateSymbolError!void {
@@ -712,7 +714,7 @@ fn lowerNavRef(
     const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));
     const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
     if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {
-        try code.appendNTimes(0xaa, ptr_width_bytes);
+        try code.appendNTimes(gpa, 0xaa, ptr_width_bytes);
         return;
     }
 
@@ -730,7 +732,7 @@ fn lowerNavRef(
                 .offset = @intCast(code.items.len),
                 .pointee = .{ .nav_index = nav_index },
             });
-            try code.appendNTimes(0, ptr_width_bytes);
+            try code.appendNTimes(gpa, 0, ptr_width_bytes);
             return;
         },
         else => {},
@@ -743,9 +745,9 @@ fn lowerNavRef(
     }) catch @panic("TODO rework getNavVAddr");
     const endian = target.cpu.arch.endian();
     switch (ptr_width_bytes) {
-        2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian),
-        4 => mem.writeInt(u32, try code.addManyAsArray(4), @intCast(vaddr), endian),
-        8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian),
+        2 => mem.writeInt(u16, try code.addManyAsArray(gpa, 2), @intCast(vaddr), endian),
+        4 => mem.writeInt(u32, try code.addManyAsArray(gpa, 4), @intCast(vaddr), endian),
+        8 => mem.writeInt(u64, try code.addManyAsArray(gpa, 8), vaddr, endian),
         else => unreachable,
     }
 }