| author | |
| committer | |
| log | 562170681a3d0c8502892f8975f369c4b269fe1a |
| tree | f4515c71cbd4d8d204fc8b957f0fda024f443fe2 |
| parent | f0d13489f819ecd1c0d1c23914127c225f507241 |
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 | _, |
| 556 | 556 | ||
| 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 | } |
| 560 | 560 | ||
| 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 | }; |
| 1107 | 1107 | ||
| 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, | ||
| 1111 | 1110 | ||
| 1112 | pub const Context = struct { | 1111 | kind: Kind, |
| 1113 | mod: *Module, | 1112 | ty: Type, |
| 1114 | 1113 | ||
| 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 | } |
| 1121 | 1120 | ||
| 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 | }; |
| 1127 | 1125 | ||
| 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 | }; |
| 147 | 147 | ||
| 148 | const LazySymbolTable = std.ArrayHashMapUnmanaged( | 148 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); |
| 149 | link.File.LazySymbol, | ||
| 150 | LazySymbolMetadata, | ||
| 151 | link.File.LazySymbol.Context, | ||
| 152 | true, | ||
| 153 | ); | ||
| 154 | 149 | ||
| 155 | const LazySymbolMetadata = struct { | 150 | const 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 | }; |
| 160 | 155 | ||
| ... | @@ -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 | } |
| 1178 | 1173 | ||
| 1179 | fn updateLazySymbol( | 1174 | fn 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 | |||
| 1190 | fn 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(); |
| 1189 | 1202 | ||
| 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); |
| 1195 | 1208 | ||
| 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().?; |
| 1199 | 1211 | ||
| 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 | else | 1214 | 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 | }; |
| 1223 | 1230 | ||
| 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 }; |
| 1230 | 1236 | ||
| 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( |
| 1250 | 1256 | ||
| 1251 | pub fn getOrCreateAtomForLazySymbol( | 1257 | pub 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 | } |
| 1272 | 1272 | ||
| 1273 | pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index { | 1273 | pub 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(); |
| 1602 | 1602 | ||
| 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 | } |
| 1615 | 1611 | ||
| 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"); |
| 2489 | const Object = @import("Coff/Object.zig"); | 2485 | const Object = @import("Coff/Object.zig"); |
| 2490 | const Relocation = @import("Coff/Relocation.zig"); | 2486 | const Relocation = @import("Coff/Relocation.zig"); |
| 2491 | const StringTable = @import("strtab.zig").StringTable; | 2487 | const StringTable = @import("strtab.zig").StringTable; |
| 2488 | const Type = @import("../type.zig").Type; | ||
| 2492 | const TypedValue = @import("../TypedValue.zig"); | 2489 | const TypedValue = @import("../TypedValue.zig"); |
| 2493 | 2490 | ||
| 2494 | pub const base_tag: link.File.Tag = .coff; | 2491 | pub 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 | }; |
| 65 | 65 | ||
| 66 | const LazySymbolMetadata = struct { | 66 | const 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 | }; |
| 71 | 71 | ||
| ... | @@ -208,7 +208,7 @@ relocs: RelocTable = .{}, | ... | @@ -208,7 +208,7 @@ relocs: RelocTable = .{}, |
| 208 | 208 | ||
| 209 | const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc)); | 209 | const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Reloc)); |
| 210 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); | 210 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 211 | const LazySymbolTable = std.ArrayHashMapUnmanaged(File.LazySymbol, LazySymbolMetadata, File.LazySymbol.Context, true); | 211 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); |
| 212 | 212 | ||
| 213 | /// When allocating, the ideal_capacity is calculated by | 213 | /// 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(); |
| 1067 | 1067 | ||
| 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 | } |
| 1080 | 1076 | ||
| 1081 | // TODO This linker code currently assumes there is only 1 compilation unit and it | 1077 | // 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 | } |
| 2426 | 2422 | ||
| 2427 | pub fn getOrCreateAtomForLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, alignment: u32) !Atom.Index { | 2423 | pub 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 | } |
| 2444 | 2434 | ||
| 2445 | pub fn getOrCreateAtomForDecl(self: *Elf, decl_index: Module.Decl.Index) !Atom.Index { | 2435 | pub 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 | } |
| 2710 | 2700 | ||
| 2711 | fn updateLazySymbol(self: *Elf, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void { | 2701 | fn 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 | |||
| 2717 | fn 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.?; |
| 2714 | 2726 | ||
| ... | @@ -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 |
| 2717 | 2729 | ||
| 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).?; |
| 2727 | 2739 | ||
| 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().?; |
| 2731 | 2742 | ||
| 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 | else | 2745 | 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 | }; |
| 2755 | 2761 | ||
| 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 | }; |
| 234 | 234 | ||
| 235 | const LazySymbolTable = std.ArrayHashMapUnmanaged( | 235 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); |
| 236 | link.File.LazySymbol, | ||
| 237 | LazySymbolMetadata, | ||
| 238 | link.File.LazySymbol.Context, | ||
| 239 | true, | ||
| 240 | ); | ||
| 241 | 236 | ||
| 242 | const LazySymbolMetadata = struct { | 237 | const 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 | }; |
| 247 | 242 | ||
| ... | @@ -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(); |
| 515 | 510 | ||
| 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 | } |
| 528 | 519 | ||
| 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 | } |
| 2311 | 2302 | ||
| 2312 | fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: LazySymbolMetadata) !void { | 2303 | fn 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 | |||
| 2319 | fn 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.?; |
| 2315 | 2328 | ||
| ... | @@ -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 |
| 2318 | 2331 | ||
| 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).?; |
| 2328 | 2341 | ||
| 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().?; |
| 2332 | 2344 | ||
| 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 | else | 2347 | 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 | }; |
| 2356 | 2363 | ||
| 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; |
| 2363 | 2369 | ||
| 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 | } |
| 2383 | 2389 | ||
| 2384 | pub fn getOrCreateAtomForLazySymbol( | 2390 | pub 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 | } |
| 2405 | 2401 | ||
| 2406 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { | 2402 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { |