authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-22 11:47:30+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-22 12:06:02+02:00
log96fa29b90f16ea12a4fea944636f5c5de73160fc
tree9388aa40d136c7d90f27da061d796cc79c326234
parent7e5a2673ac8b76dbd8cbcfadb829083238182666

macho: write sections in parallel in -r mode


2 files changed, 64 insertions(+), 16 deletions(-)

src/link/MachO/file.zig+7
...@@ -302,6 +302,13 @@ pub const File = union(enum) {...@@ -302,6 +302,13 @@ pub const File = union(enum) {
302 };302 };
303 }303 }
304304
305 pub fn writeAtomsRelocatable(file: File, macho_file: *MachO) !void {
306 return switch (file) {
307 .dylib, .internal => unreachable,
308 inline else => |x| x.writeAtomsRelocatable(macho_file),
309 };
310 }
311
305 pub fn calcSymtabSize(file: File, macho_file: *MachO) void {312 pub fn calcSymtabSize(file: File, macho_file: *MachO) void {
306 return switch (file) {313 return switch (file) {
307 inline else => |x| x.calcSymtabSize(macho_file),314 inline else => |x| x.calcSymtabSize(macho_file),
src/link/MachO/relocatable.zig+57-16
...@@ -605,33 +605,74 @@ fn writeSections(macho_file: *MachO) !void {...@@ -605,33 +605,74 @@ fn writeSections(macho_file: *MachO) !void {
605 try macho_file.strtab.resize(gpa, cmd.strsize);605 try macho_file.strtab.resize(gpa, cmd.strsize);
606 macho_file.strtab.items[0] = 0;606 macho_file.strtab.items[0] = 0;
607607
608 for (macho_file.objects.items) |index| {608 const tp = macho_file.base.comp.thread_pool;
609 try macho_file.getFile(index).?.object.writeAtomsRelocatable(macho_file);609 var wg: WaitGroup = .{};
610 macho_file.getFile(index).?.writeSymtab(macho_file, macho_file);610 {
611 wg.reset();
612 defer wg.wait();
613
614 for (macho_file.objects.items) |index| {
615 tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, macho_file.getFile(index).? });
616 tp.spawnWg(&wg, File.writeSymtab, .{ macho_file.getFile(index).?, macho_file, macho_file });
617 }
618
619 if (macho_file.getZigObject()) |zo| {
620 tp.spawnWg(&wg, writeAtomsWorker, .{ macho_file, zo.asFile() });
621 tp.spawnWg(&wg, File.writeSymtab, .{ zo.asFile(), macho_file, macho_file });
622 }
623
624 if (macho_file.eh_frame_sect_index) |_| {
625 tp.spawnWg(&wg, writeEhFrameWorker, .{macho_file});
626 }
627
628 if (macho_file.unwind_info_sect_index) |_| {
629 for (macho_file.objects.items) |index| {
630 tp.spawnWg(&wg, writeCompactUnwindWorker, .{ macho_file, macho_file.getFile(index).?.object });
631 }
632 }
611 }633 }
612634
635 if (macho_file.has_errors.swap(false, .seq_cst)) return error.FlushFailure;
636
613 if (macho_file.getZigObject()) |zo| {637 if (macho_file.getZigObject()) |zo| {
614 try zo.writeRelocs(macho_file);638 try zo.writeRelocs(macho_file);
615 try zo.writeAtomsRelocatable(macho_file);
616 zo.writeSymtab(macho_file, macho_file);
617 }
618
619 if (macho_file.eh_frame_sect_index) |_| {
620 try writeEhFrame(macho_file);
621 }639 }
640}
622641
623 if (macho_file.unwind_info_sect_index) |_| {642fn writeAtomsWorker(macho_file: *MachO, file: File) void {
624 for (macho_file.objects.items) |index| {643 const tracy = trace(@src());
625 try macho_file.getFile(index).?.object.writeCompactUnwindRelocatable(macho_file);644 defer tracy.end();
626 }645 file.writeAtomsRelocatable(macho_file) catch |err| {
627 }646 macho_file.reportParseError2(file.getIndex(), "failed to write atoms: {s}", .{
647 @errorName(err),
648 }) catch {};
649 _ = macho_file.has_errors.swap(true, .seq_cst);
650 };
628}651}
629652
630fn writeEhFrame(macho_file: *MachO) !void {653fn writeEhFrameWorker(macho_file: *MachO) void {
654 const tracy = trace(@src());
655 defer tracy.end();
631 const sect_index = macho_file.eh_frame_sect_index.?;656 const sect_index = macho_file.eh_frame_sect_index.?;
632 const buffer = macho_file.sections.items(.out)[sect_index];657 const buffer = macho_file.sections.items(.out)[sect_index];
633 const relocs = macho_file.sections.items(.relocs)[sect_index];658 const relocs = macho_file.sections.items(.relocs)[sect_index];
634 try eh_frame.writeRelocs(macho_file, buffer.items, relocs.items);659 eh_frame.writeRelocs(macho_file, buffer.items, relocs.items) catch |err| {
660 macho_file.reportUnexpectedError("failed to write '__LD,__eh_frame' section: {s}", .{
661 @errorName(err),
662 }) catch {};
663 _ = macho_file.has_errors.swap(true, .seq_cst);
664 };
665}
666
667fn writeCompactUnwindWorker(macho_file: *MachO, object: *Object) void {
668 const tracy = trace(@src());
669 defer tracy.end();
670 object.writeCompactUnwindRelocatable(macho_file) catch |err| {
671 macho_file.reportUnexpectedError("failed to write '__LD,__eh_frame' section: {s}", .{
672 @errorName(err),
673 }) catch {};
674 _ = macho_file.has_errors.swap(true, .seq_cst);
675 };
635}676}
636677
637fn writeSectionsToFile(macho_file: *MachO) !void {678fn writeSectionsToFile(macho_file: *MachO) !void {