authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-03 06:02:38-04:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-03 18:02:53+02:00
log562170681a3d0c8502892f8975f369c4b269fe1a
treef4515c71cbd4d8d204fc8b957f0fda024f443fe2
parentf0d13489f819ecd1c0d1c23914127c225f507241

link: cleanup lazy symbols

We now only update one lazy symbol in flushModule. Updating the rest from updateDecl is TBD.

5 files changed, 158 insertions(+), 163 deletions(-)

src/Module.zig+1-1
...@@ -555,7 +555,7 @@ pub const Decl = struct {...@@ -555,7 +555,7 @@ pub const Decl = struct {
555 _,555 _,
556556
557 pub fn init(oi: ?Index) OptionalIndex {557 pub fn init(oi: ?Index) OptionalIndex {
558 return oi orelse .none;558 return @intToEnum(OptionalIndex, @enumToInt(oi orelse return .none));
559 }559 }
560560
561 pub fn unwrap(oi: OptionalIndex) ?Index {561 pub fn unwrap(oi: OptionalIndex) ?Index {
src/link.zig+12-14
...@@ -1106,23 +1106,21 @@ pub const File = struct {...@@ -1106,23 +1106,21 @@ pub const File = struct {
1106 };1106 };
11071107
1108 pub const LazySymbol = struct {1108 pub const LazySymbol = struct {
1109 kind: enum { code, const_data },1109 pub const Kind = enum { code, const_data };
1110 ty: Type,
11111110
1112 pub const Context = struct {1111 kind: Kind,
1113 mod: *Module,1112 ty: Type,
11141113
1115 pub fn hash(ctx: @This(), sym: LazySymbol) u32 {1114 pub fn initDecl(kind: Kind, decl: Module.Decl.OptionalIndex, mod: *Module) LazySymbol {
1116 var hasher = std.hash.Wyhash.init(0);1115 return .{ .kind = kind, .ty = if (decl.unwrap()) |decl_index|
1117 std.hash.autoHash(&hasher, sym.kind);1116 mod.declPtr(decl_index).val.castTag(.ty).?.data
1118 sym.ty.hashWithHasher(&hasher, ctx.mod);1117 else
1119 return @truncate(u32, hasher.final());1118 Type.anyerror };
1120 }1119 }
11211120
1122 pub fn eql(ctx: @This(), lhs: LazySymbol, rhs: LazySymbol, _: usize) bool {1121 pub fn getDecl(self: LazySymbol) Module.Decl.OptionalIndex {
1123 return lhs.kind == rhs.kind and lhs.ty.eql(rhs.ty, ctx.mod);1122 return Module.Decl.OptionalIndex.init(self.ty.getOwnerDeclOrNull());
1124 }1123 }
1125 };
1126 };1124 };
11271125
1128 pub const C = @import("link/C.zig");1126 pub const C = @import("link/C.zig");
src/link/Coff.zig+48-51
...@@ -145,16 +145,11 @@ const Section = struct {...@@ -145,16 +145,11 @@ const Section = struct {
145 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},145 free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
146};146};
147147
148const LazySymbolTable = std.ArrayHashMapUnmanaged(148const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
149 link.File.LazySymbol,
150 LazySymbolMetadata,
151 link.File.LazySymbol.Context,
152 true,
153);
154149
155const LazySymbolMetadata = struct {150const LazySymbolMetadata = struct {
156 atom: Atom.Index,151 text_atom: ?Atom.Index = null,
157 section: u16,152 rdata_atom: ?Atom.Index = null,
158 alignment: u32,153 alignment: u32,
159};154};
160155
...@@ -1176,10 +1171,28 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !...@@ -1176,10 +1171,28 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !
1176 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));1171 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
1177}1172}
11781173
1179fn updateLazySymbol(1174fn updateLazySymbol(self: *Coff, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void {
1175 const mod = self.base.options.module.?;
1176 if (metadata.text_atom) |atom| try self.updateLazySymbolAtom(
1177 link.File.LazySymbol.initDecl(.code, decl, mod),
1178 atom,
1179 self.text_section_index.?,
1180 metadata.alignment,
1181 );
1182 if (metadata.rdata_atom) |atom| try self.updateLazySymbolAtom(
1183 link.File.LazySymbol.initDecl(.const_data, decl, mod),
1184 atom,
1185 self.rdata_section_index.?,
1186 metadata.alignment,
1187 );
1188}
1189
1190fn updateLazySymbolAtom(
1180 self: *Coff,1191 self: *Coff,
1181 lazy_sym: link.File.LazySymbol,1192 sym: link.File.LazySymbol,
1182 lazy_metadata: LazySymbolMetadata,1193 atom_index: Atom.Index,
1194 section_index: u16,
1195 required_alignment: u32,
1183) !void {1196) !void {
1184 const gpa = self.base.allocator;1197 const gpa = self.base.allocator;
1185 const mod = self.base.options.module.?;1198 const mod = self.base.options.module.?;
...@@ -1188,16 +1201,15 @@ fn updateLazySymbol(...@@ -1188,16 +1201,15 @@ fn updateLazySymbol(
1188 defer code_buffer.deinit();1201 defer code_buffer.deinit();
11891202
1190 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{1203 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
1191 @tagName(lazy_sym.kind),1204 @tagName(sym.kind),
1192 lazy_sym.ty.fmt(mod),1205 sym.ty.fmt(mod),
1193 });1206 });
1194 defer gpa.free(name);1207 defer gpa.free(name);
11951208
1196 const atom_index = lazy_metadata.atom;
1197 const atom = self.getAtomPtr(atom_index);1209 const atom = self.getAtomPtr(atom_index);
1198 const local_sym_index = atom.getSymbolIndex().?;1210 const local_sym_index = atom.getSymbolIndex().?;
11991211
1200 const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl|1212 const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl|
1201 mod.declPtr(owner_decl).srcLoc()1213 mod.declPtr(owner_decl).srcLoc()
1202 else1214 else
1203 Module.SrcLoc{1215 Module.SrcLoc{
...@@ -1205,14 +1217,9 @@ fn updateLazySymbol(...@@ -1205,14 +1217,9 @@ fn updateLazySymbol(
1205 .parent_decl_node = undefined,1217 .parent_decl_node = undefined,
1206 .lazy = .unneeded,1218 .lazy = .unneeded,
1207 };1219 };
1208 const res = try codegen.generateLazySymbol(1220 const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{
1209 &self.base,1221 .parent_atom_index = local_sym_index,
1210 src,1222 });
1211 lazy_sym,
1212 &code_buffer,
1213 .none,
1214 .{ .parent_atom_index = local_sym_index },
1215 );
1216 const code = switch (res) {1223 const code = switch (res) {
1217 .ok => code_buffer.items,1224 .ok => code_buffer.items,
1218 .fail => |em| {1225 .fail => |em| {
...@@ -1221,11 +1228,10 @@ fn updateLazySymbol(...@@ -1221,11 +1228,10 @@ fn updateLazySymbol(
1221 },1228 },
1222 };1229 };
12231230
1224 const required_alignment = lazy_metadata.alignment;
1225 const code_len = @intCast(u32, code.len);1231 const code_len = @intCast(u32, code.len);
1226 const symbol = atom.getSymbolPtr(self);1232 const symbol = atom.getSymbolPtr(self);
1227 try self.setSymbolName(symbol, name);1233 try self.setSymbolName(symbol, name);
1228 symbol.section_number = @intToEnum(coff.SectionNumber, lazy_metadata.section + 1);1234 symbol.section_number = @intToEnum(coff.SectionNumber, section_index + 1);
1229 symbol.type = .{ .complex_type = .NULL, .base_type = .NULL };1235 symbol.type = .{ .complex_type = .NULL, .base_type = .NULL };
12301236
1231 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);1237 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
...@@ -1250,24 +1256,18 @@ fn updateLazySymbol(...@@ -1250,24 +1256,18 @@ fn updateLazySymbol(
12501256
1251pub fn getOrCreateAtomForLazySymbol(1257pub fn getOrCreateAtomForLazySymbol(
1252 self: *Coff,1258 self: *Coff,
1253 lazy_sym: link.File.LazySymbol,1259 sym: link.File.LazySymbol,
1254 alignment: u32,1260 alignment: u32,
1255) !Atom.Index {1261) !Atom.Index {
1256 const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{1262 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
1257 .mod = self.base.options.module.?,
1258 });
1259 errdefer _ = self.lazy_syms.pop();1263 errdefer _ = self.lazy_syms.pop();
1260 if (!gop.found_existing) {1264 if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment };
1261 gop.value_ptr.* = .{1265 const atom = switch (sym.kind) {
1262 .atom = try self.createAtom(),1266 .code => &gop.value_ptr.text_atom,
1263 .section = switch (lazy_sym.kind) {1267 .const_data => &gop.value_ptr.rdata_atom,
1264 .code => self.text_section_index.?,1268 };
1265 .const_data => self.rdata_section_index.?,1269 if (atom.* == null) atom.* = try self.createAtom();
1266 },1270 return atom.*.?;
1267 .alignment = alignment,
1268 };
1269 }
1270 return gop.value_ptr.atom;
1271}1271}
12721272
1273pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {1273pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index {
...@@ -1600,17 +1600,13 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1600,17 +1600,13 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
1600 sub_prog_node.activate();1600 sub_prog_node.activate();
1601 defer sub_prog_node.end();1601 defer sub_prog_node.end();
16021602
1603 {1603 // Most lazy symbols can be updated when the corresponding decl is,
1604 var lazy_it = self.lazy_syms.iterator();1604 // so we only have to worry about the one without an associated decl.
1605 while (lazy_it.next()) |lazy_entry| {1605 if (self.lazy_syms.get(.none)) |metadata| {
1606 self.updateLazySymbol(1606 self.updateLazySymbol(.none, metadata) catch |err| switch (err) {
1607 lazy_entry.key_ptr.*,1607 error.CodegenFail => return error.FlushFailure,
1608 lazy_entry.value_ptr.*,1608 else => |e| return e,
1609 ) catch |err| switch (err) {1609 };
1610 error.CodegenFail => return error.FlushFailure,
1611 else => |e| return e,
1612 };
1613 }
1614 }1610 }
16151611
1616 const gpa = self.base.allocator;1612 const gpa = self.base.allocator;
...@@ -2489,6 +2485,7 @@ const Module = @import("../Module.zig");...@@ -2489,6 +2485,7 @@ const Module = @import("../Module.zig");
2489const Object = @import("Coff/Object.zig");2485const Object = @import("Coff/Object.zig");
2490const Relocation = @import("Coff/Relocation.zig");2486const Relocation = @import("Coff/Relocation.zig");
2491const StringTable = @import("strtab.zig").StringTable;2487const StringTable = @import("strtab.zig").StringTable;
2488const Type = @import("../type.zig").Type;
2492const TypedValue = @import("../TypedValue.zig");2489const TypedValue = @import("../TypedValue.zig");
24932490
2494pub const base_tag: link.File.Tag = .coff;2491pub const base_tag: link.File.Tag = .coff;
src/link/Elf.zig+48-44
...@@ -64,8 +64,8 @@ const Section = struct {...@@ -64,8 +64,8 @@ const Section = struct {
64};64};
6565
66const LazySymbolMetadata = struct {66const LazySymbolMetadata = struct {
67 atom: Atom.Index,67 text_atom: ?Atom.Index = null,
68 shdr: u16,68 rodata_atom: ?Atom.Index = null,
69 alignment: u32,69 alignment: u32,
70};70};
7171
...@@ -208,7 +208,7 @@ relocs: RelocTable = .{},...@@ -208,7 +208,7 @@ relocs: RelocTable = .{},
208208
209const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc));209const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc));
210const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));210const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));
211const LazySymbolTable = std.ArrayHashMapUnmanaged(File.LazySymbol, LazySymbolMetadata, File.LazySymbol.Context, true);211const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
212212
213/// When allocating, the ideal_capacity is calculated by213/// When allocating, the ideal_capacity is calculated by
214/// actual_capacity + (actual_capacity / ideal_factor)214/// actual_capacity + (actual_capacity / ideal_factor)
...@@ -1065,17 +1065,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1065,17 +1065,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1065 sub_prog_node.activate();1065 sub_prog_node.activate();
1066 defer sub_prog_node.end();1066 defer sub_prog_node.end();
10671067
1068 {1068 // Most lazy symbols can be updated when the corresponding decl is,
1069 var lazy_it = self.lazy_syms.iterator();1069 // so we only have to worry about the one without an associated decl.
1070 while (lazy_it.next()) |lazy_entry| {1070 if (self.lazy_syms.get(.none)) |metadata| {
1071 self.updateLazySymbol(1071 self.updateLazySymbol(.none, metadata) catch |err| switch (err) {
1072 lazy_entry.key_ptr.*,1072 error.CodegenFail => return error.FlushFailure,
1073 lazy_entry.value_ptr.*,1073 else => |e| return e,
1074 ) catch |err| switch (err) {1074 };
1075 error.CodegenFail => return error.FlushFailure,
1076 else => |e| return e,
1077 };
1078 }
1079 }1075 }
10801076
1081 // TODO This linker code currently assumes there is only 1 compilation unit and it1077 // TODO This linker code currently assumes there is only 1 compilation unit and it
...@@ -2424,22 +2420,16 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {...@@ -2424,22 +2420,16 @@ pub fn freeDecl(self: *Elf, decl_index: Module.Decl.Index) void {
2424 }2420 }
2425}2421}
24262422
2427pub fn getOrCreateAtomForLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, alignment: u32) !Atom.Index {2423pub fn getOrCreateAtomForLazySymbol(self: *Elf, sym: File.LazySymbol, alignment: u32) !Atom.Index {
2428 const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{2424 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
2429 .mod = self.base.options.module.?,
2430 });
2431 errdefer _ = self.lazy_syms.pop();2425 errdefer _ = self.lazy_syms.pop();
2432 if (!gop.found_existing) {2426 if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment };
2433 gop.value_ptr.* = .{2427 const atom = switch (sym.kind) {
2434 .atom = try self.createAtom(),2428 .code => &gop.value_ptr.text_atom,
2435 .shdr = switch (lazy_sym.kind) {2429 .const_data => &gop.value_ptr.rodata_atom,
2436 .code => self.text_section_index.?,2430 };
2437 .const_data => self.rodata_section_index.?,2431 if (atom.* == null) atom.* = try self.createAtom();
2438 },2432 return atom.*.?;
2439 .alignment = alignment,
2440 };
2441 }
2442 return gop.value_ptr.atom;
2443}2433}
24442434
2445pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {2435pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index {
...@@ -2708,7 +2698,29 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v...@@ -2708,7 +2698,29 @@ pub fn updateDecl(self: *Elf, module: *Module, decl_index: Module.Decl.Index) !v
2708 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));2698 return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
2709}2699}
27102700
2711fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void {2701fn updateLazySymbol(self: *Elf, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void {
2702 const mod = self.base.options.module.?;
2703 if (metadata.text_atom) |atom| try self.updateLazySymbolAtom(
2704 File.LazySymbol.initDecl(.code, decl, mod),
2705 atom,
2706 self.text_section_index.?,
2707 metadata.alignment,
2708 );
2709 if (metadata.rodata_atom) |atom| try self.updateLazySymbolAtom(
2710 File.LazySymbol.initDecl(.const_data, decl, mod),
2711 atom,
2712 self.rodata_section_index.?,
2713 metadata.alignment,
2714 );
2715}
2716
2717fn updateLazySymbolAtom(
2718 self: *Elf,
2719 sym: File.LazySymbol,
2720 atom_index: Atom.Index,
2721 shdr_index: u16,
2722 required_alignment: u32,
2723) !void {
2712 const gpa = self.base.allocator;2724 const gpa = self.base.allocator;
2713 const mod = self.base.options.module.?;2725 const mod = self.base.options.module.?;
27142726
...@@ -2717,19 +2729,18 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy...@@ -2717,19 +2729,18 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy
27172729
2718 const name_str_index = blk: {2730 const name_str_index = blk: {
2719 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{2731 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{}", .{
2720 @tagName(lazy_sym.kind),2732 @tagName(sym.kind),
2721 lazy_sym.ty.fmt(mod),2733 sym.ty.fmt(mod),
2722 });2734 });
2723 defer gpa.free(name);2735 defer gpa.free(name);
2724 break :blk try self.shstrtab.insert(gpa, name);2736 break :blk try self.shstrtab.insert(gpa, name);
2725 };2737 };
2726 const name = self.shstrtab.get(name_str_index).?;2738 const name = self.shstrtab.get(name_str_index).?;
27272739
2728 const atom_index = lazy_metadata.atom;
2729 const atom = self.getAtom(atom_index);2740 const atom = self.getAtom(atom_index);
2730 const local_sym_index = atom.getSymbolIndex().?;2741 const local_sym_index = atom.getSymbolIndex().?;
27312742
2732 const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl|2743 const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl|
2733 mod.declPtr(owner_decl).srcLoc()2744 mod.declPtr(owner_decl).srcLoc()
2734 else2745 else
2735 Module.SrcLoc{2746 Module.SrcLoc{
...@@ -2737,14 +2748,9 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy...@@ -2737,14 +2748,9 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy
2737 .parent_decl_node = undefined,2748 .parent_decl_node = undefined,
2738 .lazy = .unneeded,2749 .lazy = .unneeded,
2739 };2750 };
2740 const res = try codegen.generateLazySymbol(2751 const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{
2741 &self.base,2752 .parent_atom_index = local_sym_index,
2742 src,2753 });
2743 lazy_sym,
2744 &code_buffer,
2745 .none,
2746 .{ .parent_atom_index = local_sym_index },
2747 );
2748 const code = switch (res) {2754 const code = switch (res) {
2749 .ok => code_buffer.items,2755 .ok => code_buffer.items,
2750 .fail => |em| {2756 .fail => |em| {
...@@ -2753,7 +2759,6 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy...@@ -2753,7 +2759,6 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy
2753 },2759 },
2754 };2760 };
27552761
2756 const shdr_index = lazy_metadata.shdr;
2757 const phdr_index = self.sections.items(.phdr_index)[shdr_index];2762 const phdr_index = self.sections.items(.phdr_index)[shdr_index];
2758 const local_sym = atom.getSymbolPtr(self);2763 const local_sym = atom.getSymbolPtr(self);
2759 local_sym.* = .{2764 local_sym.* = .{
...@@ -2764,7 +2769,6 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy...@@ -2764,7 +2769,6 @@ fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySy
2764 .st_value = 0,2769 .st_value = 0,
2765 .st_size = 0,2770 .st_size = 0,
2766 };2771 };
2767 const required_alignment = lazy_metadata.alignment;
2768 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);2772 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);
2769 errdefer self.freeAtom(atom_index);2773 errdefer self.freeAtom(atom_index);
2770 log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr });2774 log.debug("allocated text block for {s} at 0x{x}", .{ name, vaddr });
src/link/MachO.zig+49-53
...@@ -232,16 +232,11 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) {...@@ -232,16 +232,11 @@ const is_hot_update_compatible = switch (builtin.target.os.tag) {
232 else => false,232 else => false,
233};233};
234234
235const LazySymbolTable = std.ArrayHashMapUnmanaged(235const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata);
236 link.File.LazySymbol,
237 LazySymbolMetadata,
238 link.File.LazySymbol.Context,
239 true,
240);
241236
242const LazySymbolMetadata = struct {237const LazySymbolMetadata = struct {
243 atom: Atom.Index,238 text_atom: ?Atom.Index = null,
244 section: u8,239 data_const_atom: ?Atom.Index = null,
245 alignment: u32,240 alignment: u32,
246};241};
247242
...@@ -513,17 +508,13 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -513,17 +508,13 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
513 sub_prog_node.activate();508 sub_prog_node.activate();
514 defer sub_prog_node.end();509 defer sub_prog_node.end();
515510
516 {511 // Most lazy symbols can be updated when the corresponding decl is,
517 var lazy_it = self.lazy_syms.iterator();512 // so we only have to worry about the one without an associated decl.
518 while (lazy_it.next()) |lazy_entry| {513 if (self.lazy_syms.get(.none)) |metadata| {
519 self.updateLazySymbol(514 self.updateLazySymbol(.none, metadata) catch |err| switch (err) {
520 lazy_entry.key_ptr.*,515 error.CodegenFail => return error.FlushFailure,
521 lazy_entry.value_ptr.*,516 else => |e| return e,
522 ) catch |err| switch (err) {517 };
523 error.CodegenFail => return error.FlushFailure,
524 else => |e| return e,
525 };
526 }
527 }518 }
528519
529 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;520 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
...@@ -2309,7 +2300,29 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)...@@ -2309,7 +2300,29 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index)
2309 try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));2300 try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
2310}2301}
23112302
2312fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void {2303fn updateLazySymbol(self: *MachO, decl: Module.Decl.OptionalIndex, metadata: LazySymbolMetadata) !void {
2304 const mod = self.base.options.module.?;
2305 if (metadata.text_atom) |atom| try self.updateLazySymbolAtom(
2306 File.LazySymbol.initDecl(.code, decl, mod),
2307 atom,
2308 self.text_section_index.?,
2309 metadata.alignment,
2310 );
2311 if (metadata.data_const_atom) |atom| try self.updateLazySymbolAtom(
2312 File.LazySymbol.initDecl(.const_data, decl, mod),
2313 atom,
2314 self.data_const_section_index.?,
2315 metadata.alignment,
2316 );
2317}
2318
2319fn updateLazySymbolAtom(
2320 self: *MachO,
2321 sym: File.LazySymbol,
2322 atom_index: Atom.Index,
2323 section_index: u8,
2324 required_alignment: u32,
2325) !void {
2313 const gpa = self.base.allocator;2326 const gpa = self.base.allocator;
2314 const mod = self.base.options.module.?;2327 const mod = self.base.options.module.?;
23152328
...@@ -2318,19 +2331,18 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy...@@ -2318,19 +2331,18 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy
23182331
2319 const name_str_index = blk: {2332 const name_str_index = blk: {
2320 const name = try std.fmt.allocPrint(gpa, "___lazy_{s}_{}", .{2333 const name = try std.fmt.allocPrint(gpa, "___lazy_{s}_{}", .{
2321 @tagName(lazy_sym.kind),2334 @tagName(sym.kind),
2322 lazy_sym.ty.fmt(mod),2335 sym.ty.fmt(mod),
2323 });2336 });
2324 defer gpa.free(name);2337 defer gpa.free(name);
2325 break :blk try self.strtab.insert(gpa, name);2338 break :blk try self.strtab.insert(gpa, name);
2326 };2339 };
2327 const name = self.strtab.get(name_str_index).?;2340 const name = self.strtab.get(name_str_index).?;
23282341
2329 const atom_index = lazy_metadata.atom;
2330 const atom = self.getAtomPtr(atom_index);2342 const atom = self.getAtomPtr(atom_index);
2331 const local_sym_index = atom.getSymbolIndex().?;2343 const local_sym_index = atom.getSymbolIndex().?;
23322344
2333 const src = if (lazy_sym.ty.getOwnerDeclOrNull()) |owner_decl|2345 const src = if (sym.ty.getOwnerDeclOrNull()) |owner_decl|
2334 mod.declPtr(owner_decl).srcLoc()2346 mod.declPtr(owner_decl).srcLoc()
2335 else2347 else
2336 Module.SrcLoc{2348 Module.SrcLoc{
...@@ -2338,14 +2350,9 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy...@@ -2338,14 +2350,9 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy
2338 .parent_decl_node = undefined,2350 .parent_decl_node = undefined,
2339 .lazy = .unneeded,2351 .lazy = .unneeded,
2340 };2352 };
2341 const res = try codegen.generateLazySymbol(2353 const res = try codegen.generateLazySymbol(&self.base, src, sym, &code_buffer, .none, .{
2342 &self.base,2354 .parent_atom_index = local_sym_index,
2343 src,2355 });
2344 lazy_sym,
2345 &code_buffer,
2346 .none,
2347 .{ .parent_atom_index = local_sym_index },
2348 );
2349 const code = switch (res) {2356 const code = switch (res) {
2350 .ok => code_buffer.items,2357 .ok => code_buffer.items,
2351 .fail => |em| {2358 .fail => |em| {
...@@ -2354,11 +2361,10 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy...@@ -2354,11 +2361,10 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy
2354 },2361 },
2355 };2362 };
23562363
2357 const required_alignment = lazy_metadata.alignment;
2358 const symbol = atom.getSymbolPtr(self);2364 const symbol = atom.getSymbolPtr(self);
2359 symbol.n_strx = name_str_index;2365 symbol.n_strx = name_str_index;
2360 symbol.n_type = macho.N_SECT;2366 symbol.n_type = macho.N_SECT;
2361 symbol.n_sect = lazy_metadata.section + 1;2367 symbol.n_sect = section_index + 1;
2362 symbol.n_desc = 0;2368 symbol.n_desc = 0;
23632369
2364 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);2370 const vaddr = try self.allocateAtom(atom_index, code.len, required_alignment);
...@@ -2381,26 +2387,16 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy...@@ -2381,26 +2387,16 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy
2381 try self.writeAtom(atom_index, code);2387 try self.writeAtom(atom_index, code);
2382}2388}
23832389
2384pub fn getOrCreateAtomForLazySymbol(2390pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol, alignment: u32) !Atom.Index {
2385 self: *MachO,2391 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl());
2386 lazy_sym: File.LazySymbol,
2387 alignment: u32,
2388) !Atom.Index {
2389 const gop = try self.lazy_syms.getOrPutContext(self.base.allocator, lazy_sym, .{
2390 .mod = self.base.options.module.?,
2391 });
2392 errdefer _ = self.lazy_syms.pop();2392 errdefer _ = self.lazy_syms.pop();
2393 if (!gop.found_existing) {2393 if (!gop.found_existing) gop.value_ptr.* = .{ .alignment = alignment };
2394 gop.value_ptr.* = .{2394 const atom = switch (sym.kind) {
2395 .atom = try self.createAtom(),2395 .code => &gop.value_ptr.text_atom,
2396 .section = switch (lazy_sym.kind) {2396 .const_data => &gop.value_ptr.data_const_atom,
2397 .code => self.text_section_index.?,2397 };
2398 .const_data => self.data_const_section_index.?,2398 if (atom.* == null) atom.* = try self.createAtom();
2399 },2399 return atom.*.?;
2400 .alignment = alignment,
2401 };
2402 }
2403 return gop.value_ptr.atom;
2404}2400}
24052401
2406pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index {2402pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index {