| ... | @@ -243,8 +243,6 @@ unnamed_const_atoms: UnnamedConstTable = .{}, | ... | @@ -243,8 +243,6 @@ unnamed_const_atoms: UnnamedConstTable = .{}, |
| 243 | /// TODO consolidate this. | 243 | /// TODO consolidate this. |
| 244 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?MatchingSection) = .{}, | 244 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?MatchingSection) = .{}, |
| 245 | | 245 | |
| 246 | gc_roots: std.AutoHashMapUnmanaged(*Atom, void) = .{}, | | |
| 247 | | | |
| 248 | const Entry = struct { | 246 | const Entry = struct { |
| 249 | target: SymbolWithLoc, | 247 | target: SymbolWithLoc, |
| 250 | atom: *Atom, | 248 | atom: *Atom, |
| ... | @@ -631,7 +629,8 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -631,7 +629,8 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 631 | const tracy = trace(@src()); | 629 | const tracy = trace(@src()); |
| 632 | defer tracy.end(); | 630 | defer tracy.end(); |
| 633 | | 631 | |
| 634 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); | 632 | const gpa = self.base.allocator; |
| | 633 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| 635 | defer arena_allocator.deinit(); | 634 | defer arena_allocator.deinit(); |
| 636 | const arena = arena_allocator.allocator(); | 635 | const arena = arena_allocator.allocator(); |
| 637 | | 636 | |
| ... | @@ -676,6 +675,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -676,6 +675,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 676 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; | 675 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; |
| 677 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe; | 676 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe; |
| 678 | const stack_size = self.base.options.stack_size_override orelse 0; | 677 | const stack_size = self.base.options.stack_size_override orelse 0; |
| | 678 | const dead_strip = self.base.options.gc_sections orelse false; |
| 679 | | 679 | |
| 680 | const id_symlink_basename = "zld.id"; | 680 | const id_symlink_basename = "zld.id"; |
| 681 | | 681 | |
| ... | @@ -707,7 +707,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -707,7 +707,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 707 | man.hash.addOptional(self.base.options.search_strategy); | 707 | man.hash.addOptional(self.base.options.search_strategy); |
| 708 | man.hash.addOptional(self.base.options.headerpad_size); | 708 | man.hash.addOptional(self.base.options.headerpad_size); |
| 709 | man.hash.add(self.base.options.headerpad_max_install_names); | 709 | man.hash.add(self.base.options.headerpad_max_install_names); |
| 710 | man.hash.add(self.base.options.gc_sections orelse false); | 710 | man.hash.add(dead_strip); |
| 711 | man.hash.add(self.base.options.dead_strip_dylibs); | 711 | man.hash.add(self.base.options.dead_strip_dylibs); |
| 712 | man.hash.addListOfBytes(self.base.options.lib_dirs); | 712 | man.hash.addListOfBytes(self.base.options.lib_dirs); |
| 713 | man.hash.addListOfBytes(self.base.options.framework_dirs); | 713 | man.hash.addListOfBytes(self.base.options.framework_dirs); |
| ... | @@ -790,14 +790,14 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -790,14 +790,14 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 790 | .mode = link.determineMode(self.base.options), | 790 | .mode = link.determineMode(self.base.options), |
| 791 | }); | 791 | }); |
| 792 | // Index 0 is always a null symbol. | 792 | // Index 0 is always a null symbol. |
| 793 | try self.locals.append(self.base.allocator, .{ | 793 | try self.locals.append(gpa, .{ |
| 794 | .n_strx = 0, | 794 | .n_strx = 0, |
| 795 | .n_type = 0, | 795 | .n_type = 0, |
| 796 | .n_sect = 0, | 796 | .n_sect = 0, |
| 797 | .n_desc = 0, | 797 | .n_desc = 0, |
| 798 | .n_value = 0, | 798 | .n_value = 0, |
| 799 | }); | 799 | }); |
| 800 | try self.strtab.buffer.append(self.base.allocator, 0); | 800 | try self.strtab.buffer.append(gpa, 0); |
| 801 | try self.populateMissingMetadata(); | 801 | try self.populateMissingMetadata(); |
| 802 | | 802 | |
| 803 | var lib_not_found = false; | 803 | var lib_not_found = false; |
| ... | @@ -964,10 +964,10 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -964,10 +964,10 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 964 | .cmdsize = cmdsize, | 964 | .cmdsize = cmdsize, |
| 965 | .path = @sizeOf(macho.rpath_command), | 965 | .path = @sizeOf(macho.rpath_command), |
| 966 | }); | 966 | }); |
| 967 | rpath_cmd.data = try self.base.allocator.alloc(u8, cmdsize - rpath_cmd.inner.path); | 967 | rpath_cmd.data = try gpa.alloc(u8, cmdsize - rpath_cmd.inner.path); |
| 968 | mem.set(u8, rpath_cmd.data, 0); | 968 | mem.set(u8, rpath_cmd.data, 0); |
| 969 | mem.copy(u8, rpath_cmd.data, rpath); | 969 | mem.copy(u8, rpath_cmd.data, rpath); |
| 970 | try self.load_commands.append(self.base.allocator, .{ .rpath = rpath_cmd }); | 970 | try self.load_commands.append(gpa, .{ .rpath = rpath_cmd }); |
| 971 | try rpath_table.putNoClobber(rpath, {}); | 971 | try rpath_table.putNoClobber(rpath, {}); |
| 972 | self.load_commands_dirty = true; | 972 | self.load_commands_dirty = true; |
| 973 | } | 973 | } |
| ... | @@ -975,11 +975,11 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -975,11 +975,11 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 975 | // code signature and entitlements | 975 | // code signature and entitlements |
| 976 | if (self.base.options.entitlements) |path| { | 976 | if (self.base.options.entitlements) |path| { |
| 977 | if (self.code_signature) |*csig| { | 977 | if (self.code_signature) |*csig| { |
| 978 | try csig.addEntitlements(self.base.allocator, path); | 978 | try csig.addEntitlements(gpa, path); |
| 979 | csig.code_directory.ident = self.base.options.emit.?.sub_path; | 979 | csig.code_directory.ident = self.base.options.emit.?.sub_path; |
| 980 | } else { | 980 | } else { |
| 981 | var csig = CodeSignature.init(self.page_size); | 981 | var csig = CodeSignature.init(self.page_size); |
| 982 | try csig.addEntitlements(self.base.allocator, path); | 982 | try csig.addEntitlements(gpa, path); |
| 983 | csig.code_directory.ident = self.base.options.emit.?.sub_path; | 983 | csig.code_directory.ident = self.base.options.emit.?.sub_path; |
| 984 | self.code_signature = csig; | 984 | self.code_signature = csig; |
| 985 | } | 985 | } |
| ... | @@ -1033,10 +1033,8 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -1033,10 +1033,8 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1033 | try argv.append("-headerpad_max_install_names"); | 1033 | try argv.append("-headerpad_max_install_names"); |
| 1034 | } | 1034 | } |
| 1035 | | 1035 | |
| 1036 | if (self.base.options.gc_sections) |is_set| { | 1036 | if (dead_strip) { |
| 1037 | if (is_set) { | 1037 | try argv.append("-dead_strip"); |
| 1038 | try argv.append("-dead_strip"); | | |
| 1039 | } | | |
| 1040 | } | 1038 | } |
| 1041 | | 1039 | |
| 1042 | if (self.base.options.dead_strip_dylibs) { | 1040 | if (self.base.options.dead_strip_dylibs) { |
| ... | @@ -1120,7 +1118,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -1120,7 +1118,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1120 | var dependent_libs = std.fifo.LinearFifo(struct { | 1118 | var dependent_libs = std.fifo.LinearFifo(struct { |
| 1121 | id: Dylib.Id, | 1119 | id: Dylib.Id, |
| 1122 | parent: u16, | 1120 | parent: u16, |
| 1123 | }, .Dynamic).init(self.base.allocator); | 1121 | }, .Dynamic).init(gpa); |
| 1124 | defer dependent_libs.deinit(); | 1122 | defer dependent_libs.deinit(); |
| 1125 | try self.parseInputFiles(positionals.items, self.base.options.sysroot, &dependent_libs); | 1123 | try self.parseInputFiles(positionals.items, self.base.options.sysroot, &dependent_libs); |
| 1126 | try self.parseAndForceLoadStaticArchives(must_link_archives.keys()); | 1124 | try self.parseAndForceLoadStaticArchives(must_link_archives.keys()); |
| ... | @@ -1153,11 +1151,21 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -1153,11 +1151,21 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1153 | | 1151 | |
| 1154 | try self.createTentativeDefAtoms(); | 1152 | try self.createTentativeDefAtoms(); |
| 1155 | | 1153 | |
| 1156 | for (self.objects.items) |*object, object_id| { | 1154 | if (dead_strip) { |
| 1157 | try object.splitIntoAtomsOneShot(self, @intCast(u32, object_id)); | 1155 | var gc_roots = std.AutoHashMap(*Atom, void).init(gpa); |
| | 1156 | defer gc_roots.deinit(); |
| | 1157 | |
| | 1158 | for (self.objects.items) |*object, object_id| { |
| | 1159 | try object.splitIntoAtomsOneShot(self, @intCast(u32, object_id), &gc_roots); |
| | 1160 | } |
| | 1161 | |
| | 1162 | try self.gcAtoms(&gc_roots); |
| | 1163 | } else { |
| | 1164 | for (self.objects.items) |*object, object_id| { |
| | 1165 | try object.splitIntoAtomsOneShot(self, @intCast(u32, object_id), null); |
| | 1166 | } |
| 1158 | } | 1167 | } |
| 1159 | | 1168 | |
| 1160 | try self.gcAtoms(); | | |
| 1161 | try self.pruneAndSortSections(); | 1169 | try self.pruneAndSortSections(); |
| 1162 | try self.allocateSegments(); | 1170 | try self.allocateSegments(); |
| 1163 | try self.allocateSymbols(); | 1171 | try self.allocateSymbols(); |
| ... | @@ -1184,7 +1192,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -1184,7 +1192,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1184 | try self.writeLinkeditSegment(); | 1192 | try self.writeLinkeditSegment(); |
| 1185 | | 1193 | |
| 1186 | if (self.code_signature) |*csig| { | 1194 | if (self.code_signature) |*csig| { |
| 1187 | csig.clear(self.base.allocator); | 1195 | csig.clear(gpa); |
| 1188 | csig.code_directory.ident = self.base.options.emit.?.sub_path; | 1196 | csig.code_directory.ident = self.base.options.emit.?.sub_path; |
| 1189 | // Preallocate space for the code signature. | 1197 | // Preallocate space for the code signature. |
| 1190 | // We need to do this at this stage so that we have the load commands with proper values | 1198 | // We need to do this at this stage so that we have the load commands with proper values |
| ... | @@ -3294,7 +3302,6 @@ pub fn deinit(self: *MachO) void { | ... | @@ -3294,7 +3302,6 @@ pub fn deinit(self: *MachO) void { |
| 3294 | self.locals.deinit(self.base.allocator); | 3302 | self.locals.deinit(self.base.allocator); |
| 3295 | self.locals_free_list.deinit(self.base.allocator); | 3303 | self.locals_free_list.deinit(self.base.allocator); |
| 3296 | self.unresolved.deinit(self.base.allocator); | 3304 | self.unresolved.deinit(self.base.allocator); |
| 3297 | self.gc_roots.deinit(self.base.allocator); | | |
| 3298 | | 3305 | |
| 3299 | for (self.objects.items) |*object| { | 3306 | for (self.objects.items) |*object| { |
| 3300 | object.deinit(self.base.allocator); | 3307 | object.deinit(self.base.allocator); |
| ... | @@ -5447,9 +5454,8 @@ fn pruneAndSortSections(self: *MachO) !void { | ... | @@ -5447,9 +5454,8 @@ fn pruneAndSortSections(self: *MachO) !void { |
| 5447 | self.sections_order_dirty = false; | 5454 | self.sections_order_dirty = false; |
| 5448 | } | 5455 | } |
| 5449 | | 5456 | |
| 5450 | fn gcAtoms(self: *MachO) !void { | 5457 | fn gcAtoms(self: *MachO, gc_roots: *std.AutoHashMap(*Atom, void)) !void { |
| 5451 | const dead_strip = self.base.options.gc_sections orelse return; | 5458 | assert(self.base.options.gc_sections.?); |
| 5452 | if (!dead_strip) return; | | |
| 5453 | | 5459 | |
| 5454 | const gpa = self.base.allocator; | 5460 | const gpa = self.base.allocator; |
| 5455 | | 5461 | |
| ... | @@ -5461,7 +5467,7 @@ fn gcAtoms(self: *MachO) !void { | ... | @@ -5461,7 +5467,7 @@ fn gcAtoms(self: *MachO) !void { |
| 5461 | log.debug("skipping {s}", .{self.getSymbolName(global)}); | 5467 | log.debug("skipping {s}", .{self.getSymbolName(global)}); |
| 5462 | continue; | 5468 | continue; |
| 5463 | }; | 5469 | }; |
| 5464 | _ = try self.gc_roots.getOrPut(gpa, gc_root); | 5470 | _ = try gc_roots.getOrPut(gc_root); |
| 5465 | } | 5471 | } |
| 5466 | | 5472 | |
| 5467 | // Add any atom targeting an import as GC root | 5473 | // Add any atom targeting an import as GC root |
| ... | @@ -5474,7 +5480,7 @@ fn gcAtoms(self: *MachO) !void { | ... | @@ -5474,7 +5480,7 @@ fn gcAtoms(self: *MachO) !void { |
| 5474 | if ((try rel.getTargetAtom(self)) == null) { | 5480 | if ((try rel.getTargetAtom(self)) == null) { |
| 5475 | const target_sym = self.getSymbol(rel.target); | 5481 | const target_sym = self.getSymbol(rel.target); |
| 5476 | if (target_sym.undf()) { | 5482 | if (target_sym.undf()) { |
| 5477 | _ = try self.gc_roots.getOrPut(gpa, atom); | 5483 | _ = try gc_roots.getOrPut(atom); |
| 5478 | break; | 5484 | break; |
| 5479 | } | 5485 | } |
| 5480 | } | 5486 | } |
| ... | @@ -5488,14 +5494,14 @@ fn gcAtoms(self: *MachO) !void { | ... | @@ -5488,14 +5494,14 @@ fn gcAtoms(self: *MachO) !void { |
| 5488 | | 5494 | |
| 5489 | var stack = std.ArrayList(*Atom).init(gpa); | 5495 | var stack = std.ArrayList(*Atom).init(gpa); |
| 5490 | defer stack.deinit(); | 5496 | defer stack.deinit(); |
| 5491 | try stack.ensureUnusedCapacity(self.gc_roots.count()); | 5497 | try stack.ensureUnusedCapacity(gc_roots.count()); |
| 5492 | | 5498 | |
| 5493 | var retained = std.AutoHashMap(*Atom, void).init(gpa); | 5499 | var retained = std.AutoHashMap(*Atom, void).init(gpa); |
| 5494 | defer retained.deinit(); | 5500 | defer retained.deinit(); |
| 5495 | try retained.ensureUnusedCapacity(self.gc_roots.count()); | 5501 | try retained.ensureUnusedCapacity(gc_roots.count()); |
| 5496 | | 5502 | |
| 5497 | log.debug("GC roots:", .{}); | 5503 | log.debug("GC roots:", .{}); |
| 5498 | var gc_roots_it = self.gc_roots.keyIterator(); | 5504 | var gc_roots_it = gc_roots.keyIterator(); |
| 5499 | while (gc_roots_it.next()) |gc_root| { | 5505 | while (gc_roots_it.next()) |gc_root| { |
| 5500 | self.logAtom(gc_root.*); | 5506 | self.logAtom(gc_root.*); |
| 5501 | | 5507 | |