| ... | ... | @@ -244,7 +244,6 @@ unnamed_const_atoms: UnnamedConstTable = .{}, |
| 244 | 244 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?MatchingSection) = .{}, |
| 245 | 245 | |
| 246 | 246 | gc_roots: std.AutoHashMapUnmanaged(*Atom, void) = .{}, |
| 247 | | gc_sections: std.AutoHashMapUnmanaged(MatchingSection, void) = .{}, |
| 248 | 247 | |
| 249 | 248 | const Entry = struct { |
| 250 | 249 | target: SymbolWithLoc, |
| ... | ... | @@ -3296,7 +3295,6 @@ pub fn deinit(self: *MachO) void { |
| 3296 | 3295 | self.locals_free_list.deinit(self.base.allocator); |
| 3297 | 3296 | self.unresolved.deinit(self.base.allocator); |
| 3298 | 3297 | self.gc_roots.deinit(self.base.allocator); |
| 3299 | | self.gc_sections.deinit(self.base.allocator); |
| 3300 | 3298 | |
| 3301 | 3299 | for (self.objects.items) |*object| { |
| 3302 | 3300 | object.deinit(self.base.allocator); |
| ... | ... | @@ -5333,35 +5331,6 @@ fn pruneAndSortSectionsInSegment(self: *MachO, maybe_seg_id: *?u16, indices: []* |
| 5333 | 5331 | for (indices) |maybe_index| { |
| 5334 | 5332 | const old_idx = maybe_index.* orelse continue; |
| 5335 | 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 | 5334 | if (sect.size == 0) { |
| 5366 | 5335 | log.debug("pruning section {s},{s}", .{ sect.segName(), sect.sectName() }); |
| 5367 | 5336 | maybe_index.* = null; |
| ... | ... | @@ -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 | 5527 | atoms_it = self.atoms.iterator(); |
| 5554 | 5528 | while (atoms_it.next()) |entry| { |
| 5555 | 5529 | const match = entry.key_ptr.*; |
| ... | ... | @@ -5602,18 +5576,22 @@ fn gcAtoms(self: *MachO) !void { |
| 5602 | 5576 | // account any padding that might have been left here. |
| 5603 | 5577 | sect.size -= atom.size; |
| 5604 | 5578 | |
| 5579 | _ = try gc_sections.put(match, {}); |
| 5580 | |
| 5605 | 5581 | if (atom.prev) |prev| { |
| 5606 | 5582 | prev.next = atom.next; |
| 5607 | 5583 | } |
| 5608 | 5584 | if (atom.next) |next| { |
| 5609 | 5585 | next.prev = atom.prev; |
| 5610 | 5586 | } else { |
| 5611 | | // TODO I think a null would be better here. |
| 5612 | | // The section will be GCed in the next step. |
| 5613 | | entry.value_ptr.* = if (atom.prev) |prev| prev else undefined; |
| 5587 | if (atom.prev) |prev| { |
| 5588 | entry.value_ptr.* = prev; |
| 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 | 5597 | if (orig_prev) |prev| { |
| ... | ... | @@ -5621,6 +5599,34 @@ fn gcAtoms(self: *MachO) !void { |
| 5621 | 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 | 5632 | fn updateSectionOrdinals(self: *MachO) !void { |