aboutsummaryrefslogtreecommitdiff
path: root/src/link/Plan9.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2022-12-28 03:20:06 -0500
committerAndrew Kelley <andrew@ziglang.org>2022-12-28 14:24:27 -0500
commit74b14edea8b7d8ae7816feda2ee37a4ca016bc03 (patch)
tree2e5beb75cf5f179d947021a981ddc6210d0c9630 /src/link/Plan9.zig
parent70ac9fc7afe672d39cdcc2f1fa4df00d34f5a775 (diff)
downloadzig-74b14edea8b7d8ae7816feda2ee37a4ca016bc03.tar.gz
zig-74b14edea8b7d8ae7816feda2ee37a4ca016bc03.zip
link: fix memory leaks
* Fix linker memory leaks found while running `zig build test-cases`. * Add missing target to test manifest.
Diffstat (limited to 'src/link/Plan9.zig')
-rw-r--r--src/link/Plan9.zig22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig
index 2d221463c9..5423269bf0 100644
--- a/src/link/Plan9.zig
+++ b/src/link/Plan9.zig
@@ -201,7 +201,10 @@ fn putFn(self: *Plan9, decl_index: Module.Decl.Index, out: FnDeclOutput) !void {
const decl = mod.declPtr(decl_index);
const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope());
if (fn_map_res.found_existing) {
- try fn_map_res.value_ptr.functions.put(gpa, decl_index, out);
+ if (try fn_map_res.value_ptr.functions.fetchPut(gpa, decl_index, out)) |old_entry| {
+ gpa.free(old_entry.value.code);
+ gpa.free(old_entry.value.lineinfo);
+ }
} else {
const file = decl.getFileScope();
const arena = self.path_arena.allocator();
@@ -408,9 +411,11 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index)
return;
},
};
- var duped_code = try self.base.allocator.dupe(u8, code);
- errdefer self.base.allocator.free(duped_code);
- try self.data_decl_table.put(self.base.allocator, decl_index, duped_code);
+ try self.data_decl_table.ensureUnusedCapacity(self.base.allocator, 1);
+ const duped_code = try self.base.allocator.dupe(u8, code);
+ if (self.data_decl_table.fetchPutAssumeCapacity(decl_index, duped_code)) |old_entry| {
+ self.base.allocator.free(old_entry.value);
+ }
return self.updateFinish(decl);
}
/// called at the end of update{Decl,Func}
@@ -743,14 +748,19 @@ pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void {
if (is_fn) {
var symidx_and_submap = self.fn_decl_table.get(decl.getFileScope()).?;
var submap = symidx_and_submap.functions;
- _ = submap.swapRemove(decl_index);
+ if (submap.fetchSwapRemove(decl_index)) |removed_entry| {
+ self.base.allocator.free(removed_entry.value.code);
+ self.base.allocator.free(removed_entry.value.lineinfo);
+ }
if (submap.count() == 0) {
self.syms.items[symidx_and_submap.sym_index] = aout.Sym.undefined_symbol;
self.syms_index_free_list.append(self.base.allocator, symidx_and_submap.sym_index) catch {};
submap.deinit(self.base.allocator);
}
} else {
- _ = self.data_decl_table.swapRemove(decl_index);
+ if (self.data_decl_table.fetchSwapRemove(decl_index)) |removed_entry| {
+ self.base.allocator.free(removed_entry.value);
+ }
}
if (decl.link.plan9.got_index) |i| {
// TODO: if this catch {} is triggered, an assertion in flushModule will be triggered, because got_index_free_list will have the wrong length