Skip to content

Commit 96fa29b

Browse files
committed
macho: write sections in parallel in -r mode
1 parent 7e5a267 commit 96fa29b

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

src/link/MachO/file.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,13 @@ pub const File = union(enum) {
302302
};
303303
}
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+
305312
pub fn calcSymtabSize(file: File, macho_file: *MachO) void {
306313
return switch (file) {
307314
inline else => |x| x.calcSymtabSize(macho_file),

src/link/MachO/relocatable.zig

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -605,33 +605,74 @@ fn writeSections(macho_file: *MachO) !void {
605605
try macho_file.strtab.resize(gpa, cmd.strsize);
606606
macho_file.strtab.items[0] = 0;
607607

608-
for (macho_file.objects.items) |index| {
609-
try macho_file.getFile(index).?.object.writeAtomsRelocatable(macho_file);
610-
macho_file.getFile(index).?.writeSymtab(macho_file, macho_file);
608+
const tp = macho_file.base.comp.thread_pool;
609+
var wg: WaitGroup = .{};
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+
}
611633
}
612634

635+
if (macho_file.has_errors.swap(false, .seq_cst)) return error.FlushFailure;
636+
613637
if (macho_file.getZigObject()) |zo| {
614638
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);
621639
}
640+
}
622641

623-
if (macho_file.unwind_info_sect_index) |_| {
624-
for (macho_file.objects.items) |index| {
625-
try macho_file.getFile(index).?.object.writeCompactUnwindRelocatable(macho_file);
626-
}
627-
}
642+
fn writeAtomsWorker(macho_file: *MachO, file: File) void {
643+
const tracy = trace(@src());
644+
defer tracy.end();
645+
file.writeAtomsRelocatable(macho_file) catch |err| {
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+
};
628651
}
629652

630-
fn writeEhFrame(macho_file: *MachO) !void {
653+
fn writeEhFrameWorker(macho_file: *MachO) void {
654+
const tracy = trace(@src());
655+
defer tracy.end();
631656
const sect_index = macho_file.eh_frame_sect_index.?;
632657
const buffer = macho_file.sections.items(.out)[sect_index];
633658
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+
667+
fn 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+
};
635676
}
636677

637678
fn writeSectionsToFile(macho_file: *MachO) !void {

0 commit comments

Comments
 (0)