diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-07-22 11:47:30 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-07-22 12:06:02 +0200 |
| commit | 96fa29b90f16ea12a4fea944636f5c5de73160fc (patch) | |
| tree | 9388aa40d136c7d90f27da061d796cc79c326234 /src | |
| parent | 7e5a2673ac8b76dbd8cbcfadb829083238182666 (diff) | |
| download | zig-96fa29b90f16ea12a4fea944636f5c5de73160fc.tar.gz zig-96fa29b90f16ea12a4fea944636f5c5de73160fc.zip | |
macho: write sections in parallel in -r mode
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO/file.zig | 7 | ||||
| -rw-r--r-- | src/link/MachO/relocatable.zig | 73 |
2 files changed, 64 insertions, 16 deletions
diff --git a/src/link/MachO/file.zig b/src/link/MachO/file.zig index 4c585c7609..26b5957058 100644 --- a/src/link/MachO/file.zig +++ b/src/link/MachO/file.zig @@ -302,6 +302,13 @@ pub const File = union(enum) { }; } + pub fn writeAtomsRelocatable(file: File, macho_file: *MachO) !void { + return switch (file) { + .dylib, .internal => unreachable, + inline else => |x| x.writeAtomsRelocatable(macho_file), + }; + } + pub fn calcSymtabSize(file: File, macho_file: *MachO) void { return switch (file) { inline else => |x| x.calcSymtabSize(macho_file), diff --git a/src/link/MachO/relocatable.zig b/src/link/MachO/relocatable.zig index 99b2aa7820..1ee40921ce 100644 --- a/src/link/MachO/relocatable.zig +++ b/src/link/MachO/relocatable.zig @@ -605,33 +605,74 @@ fn writeSections(macho_file: *MachO) !void { try macho_file.strtab.resize(gpa, cmd.strsize); macho_file.strtab.items[0] = 0; - for (macho_file.objects.items) |index| { - try macho_file.getFile(index).?.object.writeAtomsRelocatable(macho_file); - macho_file.getFile(index).?.writeSymtab(macho_file, macho_file); + const tp = macho_file.base.comp.thread_pool; + var wg: WaitGroup = .{}; + { + wg.reset(); + defer wg.wait(); + + for (macho_file.objects.items) |index| { + tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, macho_file.getFile(index).? }); + tp.spawnWg(&wg, File.writeSymtab, .{ macho_file.getFile(index).?, macho_file, macho_file }); + } + + if (macho_file.getZigObject()) |zo| { + tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, zo.asFile() }); + tp.spawnWg(&wg, File.writeSymtab, .{ zo.asFile(), macho_file, macho_file }); + } + + if (macho_file.eh_frame_sect_index) |_| { + tp.spawnWg(&wg, writeEhFrameWorker, .{macho_file}); + } + + if (macho_file.unwind_info_sect_index) |_| { + for (macho_file.objects.items) |index| { + tp.spawnWg(&wg, writeCompactUnwindWorker, .{ macho_file, macho_file.getFile(index).?.object }); + } + } } + if (macho_file.has_errors.swap(false, .seq_cst)) return error.FlushFailure; + if (macho_file.getZigObject()) |zo| { try zo.writeRelocs(macho_file); - try zo.writeAtomsRelocatable(macho_file); - zo.writeSymtab(macho_file, macho_file); - } - - if (macho_file.eh_frame_sect_index) |_| { - try writeEhFrame(macho_file); } +} - if (macho_file.unwind_info_sect_index) |_| { - for (macho_file.objects.items) |index| { - try macho_file.getFile(index).?.object.writeCompactUnwindRelocatable(macho_file); - } - } +fn writeAtomsWorker(macho_file: *MachO, file: File) void { + const tracy = trace(@src()); + defer tracy.end(); + file.writeAtomsRelocatable(macho_file) catch |err| { + macho_file.reportParseError2(file.getIndex(), "failed to write atoms: {s}", .{ + @errorName(err), + }) catch {}; + _ = macho_file.has_errors.swap(true, .seq_cst); + }; } -fn writeEhFrame(macho_file: *MachO) !void { +fn writeEhFrameWorker(macho_file: *MachO) void { + const tracy = trace(@src()); + defer tracy.end(); const sect_index = macho_file.eh_frame_sect_index.?; const buffer = macho_file.sections.items(.out)[sect_index]; const relocs = macho_file.sections.items(.relocs)[sect_index]; - try eh_frame.writeRelocs(macho_file, buffer.items, relocs.items); + eh_frame.writeRelocs(macho_file, buffer.items, relocs.items) catch |err| { + macho_file.reportUnexpectedError("failed to write '__LD,__eh_frame' section: {s}", .{ + @errorName(err), + }) catch {}; + _ = macho_file.has_errors.swap(true, .seq_cst); + }; +} + +fn writeCompactUnwindWorker(macho_file: *MachO, object: *Object) void { + const tracy = trace(@src()); + defer tracy.end(); + object.writeCompactUnwindRelocatable(macho_file) catch |err| { + macho_file.reportUnexpectedError("failed to write '__LD,__eh_frame' section: {s}", .{ + @errorName(err), + }) catch {}; + _ = macho_file.has_errors.swap(true, .seq_cst); + }; } fn writeSectionsToFile(macho_file: *MachO) !void { |
