| ... | @@ -244,7 +244,6 @@ unnamed_const_atoms: UnnamedConstTable = .{}, | ... | @@ -244,7 +244,6 @@ unnamed_const_atoms: UnnamedConstTable = .{}, |
| 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) = .{}, | 246 | gc_roots: std.AutoHashMapUnmanaged(*Atom, void) = .{}, |
| 247 | gc_sections: std.AutoHashMapUnmanaged(MatchingSection, void) = .{}, | | |
| 248 | | 247 | |
| 249 | const Entry = struct { | 248 | const Entry = struct { |
| 250 | target: SymbolWithLoc, | 249 | target: SymbolWithLoc, |
| ... | @@ -3296,7 +3295,6 @@ pub fn deinit(self: *MachO) void { | ... | @@ -3296,7 +3295,6 @@ pub fn deinit(self: *MachO) void { |
| 3296 | self.locals_free_list.deinit(self.base.allocator); | 3295 | self.locals_free_list.deinit(self.base.allocator); |
| 3297 | self.unresolved.deinit(self.base.allocator); | 3296 | self.unresolved.deinit(self.base.allocator); |
| 3298 | self.gc_roots.deinit(self.base.allocator); | 3297 | self.gc_roots.deinit(self.base.allocator); |
| 3299 | self.gc_sections.deinit(self.base.allocator); | | |
| 3300 | | 3298 | |
| 3301 | for (self.objects.items) |*object| { | 3299 | for (self.objects.items) |*object| { |
| 3302 | object.deinit(self.base.allocator); | 3300 | object.deinit(self.base.allocator); |
| ... | @@ -5333,35 +5331,6 @@ fn pruneAndSortSectionsInSegment(self: *MachO, maybe_seg_id: *?u16, indices: []* | ... | @@ -5333,35 +5331,6 @@ fn pruneAndSortSectionsInSegment(self: *MachO, maybe_seg_id: *?u16, indices: []* |
| 5333 | for (indices) |maybe_index| { | 5331 | for (indices) |maybe_index| { |
| 5334 | const old_idx = maybe_index.* orelse continue; | 5332 | const old_idx = maybe_index.* orelse continue; |
| 5335 | const sect = &sections[old_idx]; | 5333 | const sect = &sections[old_idx]; |
| 5336 | | | |
| 5337 | // Recalculate section alignment and size if required. | | |
| 5338 | const match = MatchingSection{ | | |
| 5339 | .seg = seg_id, | | |
| 5340 | .sect = old_idx, | | |
| 5341 | }; | | |
| 5342 | if (self.gc_sections.get(match)) |_| blk: { | | |
| 5343 | sect.@"align" = 0; | | |
| 5344 | sect.size = 0; | | |
| 5345 | | | |
| 5346 | var atom = self.atoms.get(match) orelse break :blk; | | |
| 5347 | | | |
| 5348 | while (atom.prev) |prev| { | | |
| 5349 | atom = prev; | | |
| 5350 | } | | |
| 5351 | | | |
| 5352 | while (true) { | | |
| 5353 | const atom_alignment = try math.powi(u32, 2, atom.alignment); | | |
| 5354 | const aligned_end_addr = mem.alignForwardGeneric(u64, sect.size, atom_alignment); | | |
| 5355 | const padding = aligned_end_addr - sect.size; | | |
| 5356 | sect.size += padding + atom.size; | | |
| 5357 | sect.@"align" = @maximum(sect.@"align", atom.alignment); | | |
| 5358 | | | |
| 5359 | if (atom.next) |next| { | | |
| 5360 | atom = next; | | |
| 5361 | } else break; | | |
| 5362 | } | | |
| 5363 | } | | |
| 5364 | | | |
| 5365 | if (sect.size == 0) { | 5334 | if (sect.size == 0) { |
| 5366 | log.debug("pruning section {s},{s}", .{ sect.segName(), sect.sectName() }); | 5335 | log.debug("pruning section {s},{s}", .{ sect.segName(), sect.sectName() }); |
| 5367 | maybe_index.* = null; | 5336 | maybe_index.* = null; |
| ... | @@ -5550,6 +5519,11 @@ fn gcAtoms(self: *MachO) !void { | ... | @@ -5550,6 +5519,11 @@ fn gcAtoms(self: *MachO) !void { |
| 5550 | } | 5519 | } |
| 5551 | } | 5520 | } |
| 5552 | | 5521 | |
| | 5522 | // Any section that ends up here will be updated, that is, |
| | 5523 | // its size and alignment recalculated. |
| | 5524 | var gc_sections = std.AutoHashMap(MatchingSection, void).init(gpa); |
| | 5525 | defer gc_sections.deinit(); |
| | 5526 | |
| 5553 | atoms_it = self.atoms.iterator(); | 5527 | atoms_it = self.atoms.iterator(); |
| 5554 | while (atoms_it.next()) |entry| { | 5528 | while (atoms_it.next()) |entry| { |
| 5555 | const match = entry.key_ptr.*; | 5529 | const match = entry.key_ptr.*; |
| ... | @@ -5602,18 +5576,22 @@ fn gcAtoms(self: *MachO) !void { | ... | @@ -5602,18 +5576,22 @@ fn gcAtoms(self: *MachO) !void { |
| 5602 | // account any padding that might have been left here. | 5576 | // account any padding that might have been left here. |
| 5603 | sect.size -= atom.size; | 5577 | sect.size -= atom.size; |
| 5604 | | 5578 | |
| | 5579 | _ = try gc_sections.put(match, {}); |
| | 5580 | |
| 5605 | if (atom.prev) |prev| { | 5581 | if (atom.prev) |prev| { |
| 5606 | prev.next = atom.next; | 5582 | prev.next = atom.next; |
| 5607 | } | 5583 | } |
| 5608 | if (atom.next) |next| { | 5584 | if (atom.next) |next| { |
| 5609 | next.prev = atom.prev; | 5585 | next.prev = atom.prev; |
| 5610 | } else { | 5586 | } else { |
| 5611 | // TODO I think a null would be better here. | 5587 | if (atom.prev) |prev| { |
| 5612 | // The section will be GCed in the next step. | 5588 | entry.value_ptr.* = prev; |
| 5613 | entry.value_ptr.* = if (atom.prev) |prev| prev else undefined; | 5589 | } else { |
| | 5590 | // The section will be GCed in the next step. |
| | 5591 | entry.value_ptr.* = undefined; |
| | 5592 | sect.size = 0; |
| | 5593 | } |
| 5614 | } | 5594 | } |
| 5615 | | | |
| 5616 | _ = try self.gc_sections.getOrPut(gpa, match); | | |
| 5617 | } | 5595 | } |
| 5618 | | 5596 | |
| 5619 | if (orig_prev) |prev| { | 5597 | if (orig_prev) |prev| { |
| ... | @@ -5621,6 +5599,34 @@ fn gcAtoms(self: *MachO) !void { | ... | @@ -5621,6 +5599,34 @@ fn gcAtoms(self: *MachO) !void { |
| 5621 | } else break; | 5599 | } else break; |
| 5622 | } | 5600 | } |
| 5623 | } | 5601 | } |
| | 5602 | |
| | 5603 | var gc_sections_it = gc_sections.iterator(); |
| | 5604 | while (gc_sections_it.next()) |entry| { |
| | 5605 | const match = entry.key_ptr.*; |
| | 5606 | const sect = self.getSectionPtr(match); |
| | 5607 | if (sect.size == 0) continue; // Pruning happens automatically in next step. |
| | 5608 | |
| | 5609 | sect.@"align" = 0; |
| | 5610 | sect.size = 0; |
| | 5611 | |
| | 5612 | var atom = self.atoms.get(match).?; |
| | 5613 | |
| | 5614 | while (atom.prev) |prev| { |
| | 5615 | atom = prev; |
| | 5616 | } |
| | 5617 | |
| | 5618 | while (true) { |
| | 5619 | const atom_alignment = try math.powi(u32, 2, atom.alignment); |
| | 5620 | const aligned_end_addr = mem.alignForwardGeneric(u64, sect.size, atom_alignment); |
| | 5621 | const padding = aligned_end_addr - sect.size; |
| | 5622 | sect.size += padding + atom.size; |
| | 5623 | sect.@"align" = @maximum(sect.@"align", atom.alignment); |
| | 5624 | |
| | 5625 | if (atom.next) |next| { |
| | 5626 | atom = next; |
| | 5627 | } else break; |
| | 5628 | } |
| | 5629 | } |
| 5624 | } | 5630 | } |
| 5625 | | 5631 | |
| 5626 | fn updateSectionOrdinals(self: *MachO) !void { | 5632 | fn updateSectionOrdinals(self: *MachO) !void { |