authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-26 14:20:08+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-27 20:53:06+02:00
log1a80315836f77e38eee3e4c0a646b82febbc3604
tree74ea13fa37e13af5e4ade0f18d9f3ee7231bae3a
parentb4815b31310a36e3c1fabd83d010b44b693c9782

dwarf: rename DebugInfoAtom into Atom; free all allocated memory


3 files changed, 39 insertions(+), 30 deletions(-)

src/link/Dwarf.zig+37-28
......@@ -31,10 +31,11 @@ dbg_line_fn_free_list: std.AutoHashMapUnmanaged(*SrcFn, void) = .{},
3131dbg_line_fn_first: ?*SrcFn = null,
3232dbg_line_fn_last: ?*SrcFn = null,
3333
34/// A list of `TextBlock` whose corresponding .debug_info tags have surplus capacity. /// This is the same concept as `text_block_free_list`; see those doc comments.
35dbg_info_decl_free_list: std.AutoHashMapUnmanaged(*DebugInfoAtom, void) = .{},
36dbg_info_decl_first: ?*DebugInfoAtom = null,
37dbg_info_decl_last: ?*DebugInfoAtom = null,
34/// A list of `Atom`s whose corresponding .debug_info tags have surplus capacity.
35/// This is the same concept as `text_block_free_list`; see those doc comments.
36atom_free_list: std.AutoHashMapUnmanaged(*Atom, void) = .{},
37atom_first: ?*Atom = null,
38atom_last: ?*Atom = null,
3839
3940abbrev_table_offset: ?u64 = null,
4041
......@@ -43,11 +44,16 @@ strtab: std.ArrayListUnmanaged(u8) = .{},
4344
4445deferred_error_sets_relocs: std.ArrayListUnmanaged(u32) = .{},
4546
46pub const DebugInfoAtom = struct {
47/// List of atoms that are owned directly by the DWARF module.
48/// TODO convert links in DebugInfoAtom into indices and make
49/// sure every atom is owned by this module.
50managed_atoms: std.ArrayListUnmanaged(*Atom) = .{},
51
52pub const Atom = struct {
4753 /// Previous/next linked list pointers.
4854 /// This is the linked list node for this Decl's corresponding .debug_info tag.
49 prev: ?*DebugInfoAtom,
50 next: ?*DebugInfoAtom,
55 prev: ?*Atom,
56 next: ?*Atom,
5157 /// Offset into .debug_info pointing to the tag for this Decl.
5258 off: u32,
5359 /// Size of the .debug_info tag for this Decl, not including padding.
......@@ -119,9 +125,14 @@ pub fn init(allocator: Allocator, tag: File.Tag, target: std.Target) Dwarf {
119125pub fn deinit(self: *Dwarf) void {
120126 const gpa = self.allocator;
121127 self.dbg_line_fn_free_list.deinit(gpa);
122 self.dbg_info_decl_free_list.deinit(gpa);
128 self.atom_free_list.deinit(gpa);
123129 self.strtab.deinit(gpa);
124130 self.deferred_error_sets_relocs.deinit(gpa);
131
132 for (self.managed_atoms.items) |atom| {
133 gpa.destroy(atom);
134 }
135 self.managed_atoms.deinit(gpa);
125136}
126137
127138pub const DeclDebugBuffers = struct {
......@@ -568,10 +579,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void
568579 var dbg_info_buffer = std.ArrayList(u8).init(arena);
569580 try self.addDbgInfoErrorSet(arena, module, ty, &dbg_info_buffer);
570581
571 // TODO seems like we need to store DebugInfoAtoms in Dwarf object
572 // In other words, I have turned Dwarf into a linker...
573 // FIXME memory leak!!!
574 const atom = try gpa.create(DebugInfoAtom);
582 const atom = try gpa.create(Atom);
575583 errdefer gpa.destroy(atom);
576584 atom.* = .{
577585 .prev = null,
......@@ -579,6 +587,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void
579587 .off = 0,
580588 .len = 0,
581589 };
590 try self.managed_atoms.append(gpa, atom);
582591 try self.updateDeclDebugInfoAllocation(file, atom, @intCast(u32, dbg_info_buffer.items.len));
583592 try self.writeDeclDebugInfo(file, atom, dbg_info_buffer.items);
584593
......@@ -620,7 +629,7 @@ pub fn commitErrorSetDebugInfo(self: *Dwarf, file: *File, module: *Module) !void
620629 }
621630}
622631
623fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom, len: u32) !void {
632fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u32) !void {
624633 const tracy = trace(@src());
625634 defer tracy.end();
626635
......@@ -630,14 +639,14 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom
630639 const gpa = self.allocator;
631640
632641 atom.len = len;
633 if (self.dbg_info_decl_last) |last| blk: {
642 if (self.atom_last) |last| blk: {
634643 if (atom == last) break :blk;
635644 if (atom.next) |next| {
636645 // Update existing Decl - non-last item.
637646 if (atom.off + atom.len + min_nop_size > next.off) {
638647 // It grew too big, so we move it to a new location.
639648 if (atom.prev) |prev| {
640 self.dbg_info_decl_free_list.put(gpa, prev, {}) catch {};
649 self.atom_free_list.put(gpa, prev, {}) catch {};
641650 prev.next = atom.next;
642651 }
643652 next.prev = atom.prev;
......@@ -663,7 +672,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom
663672 // TODO Look at the free list before appending at the end.
664673 atom.prev = last;
665674 last.next = atom;
666 self.dbg_info_decl_last = atom;
675 self.atom_last = atom;
667676
668677 atom.off = last.off + padToIdeal(last.len);
669678 }
......@@ -672,20 +681,20 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *DebugInfoAtom
672681 // TODO Look at the free list before appending at the end.
673682 atom.prev = last;
674683 last.next = atom;
675 self.dbg_info_decl_last = atom;
684 self.atom_last = atom;
676685
677686 atom.off = last.off + padToIdeal(last.len);
678687 }
679688 } else {
680689 // This is the first Decl of the .debug_info
681 self.dbg_info_decl_first = atom;
682 self.dbg_info_decl_last = atom;
690 self.atom_first = atom;
691 self.atom_last = atom;
683692
684693 atom.off = @intCast(u32, padToIdeal(self.dbgInfoHeaderBytes()));
685694 }
686695}
687696
688fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *DebugInfoAtom, dbg_info_buf: []const u8) !void {
697fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []const u8) !void {
689698 const tracy = trace(@src());
690699 defer tracy.end();
691700
......@@ -694,7 +703,7 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *DebugInfoAtom, dbg_info_
694703 // probably need to edit that logic too.
695704 const gpa = self.allocator;
696705
697 const last_decl = self.dbg_info_decl_last.?;
706 const last_decl = self.atom_last.?;
698707 // +1 for a trailing zero to end the children of the decl tag.
699708 const needed_size = last_decl.off + last_decl.len + 1;
700709 const prev_padding_size: u32 = if (atom.prev) |prev| atom.off - (prev.off + prev.len) else 0;
......@@ -819,13 +828,13 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl)
819828 }
820829}
821830
822pub fn freeAtom(self: *Dwarf, atom: *DebugInfoAtom) void {
823 if (self.dbg_info_decl_first == atom) {
824 self.dbg_info_decl_first = atom.next;
831pub fn freeAtom(self: *Dwarf, atom: *Atom) void {
832 if (self.atom_first == atom) {
833 self.atom_first = atom.next;
825834 }
826 if (self.dbg_info_decl_last == atom) {
835 if (self.atom_last == atom) {
827836 // TODO shrink the .debug_info section size here
828 self.dbg_info_decl_last = atom.prev;
837 self.atom_last = atom.prev;
829838 }
830839
831840 if (atom.prev) |prev| {
......@@ -1964,12 +1973,12 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
19641973}
19651974
19661975fn getDebugInfoOff(self: Dwarf) ?u32 {
1967 const first = self.dbg_info_decl_first orelse return null;
1976 const first = self.atom_first orelse return null;
19681977 return first.off;
19691978}
19701979
19711980fn getDebugInfoEnd(self: Dwarf) ?u32 {
1972 const last = self.dbg_info_decl_last orelse return null;
1981 const last = self.atom_last orelse return null;
19731982 return last.off + last.len;
19741983}
19751984
src/link/Elf.zig+1-1
......@@ -207,7 +207,7 @@ pub const TextBlock = struct {
207207 prev: ?*TextBlock,
208208 next: ?*TextBlock,
209209
210 dbg_info_atom: Dwarf.DebugInfoAtom,
210 dbg_info_atom: Dwarf.Atom,
211211
212212 pub const empty = TextBlock{
213213 .local_sym_index = 0,
src/link/MachO/Atom.zig+1-1
......@@ -72,7 +72,7 @@ stab: ?Stab = null,
7272next: ?*Atom,
7373prev: ?*Atom,
7474
75dbg_info_atom: Dwarf.DebugInfoAtom,
75dbg_info_atom: Dwarf.Atom,
7676
7777dirty: bool = true,
7878