authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-28 19:02:16+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:52:43+01:00
log202ed7330fdc55cce22bfa9d9b5da03776e871b4
treeb0ef3791a3e10ea9e2b553cf2457f0a0fc079a27
parent196ba706a05046b2209529744d2df47215819691
signaturelock-open Commit is signed but in an unrecognized format.

fix memory leaks


2 files changed, 42 insertions(+), 19 deletions(-)

src/link/Wasm.zig+8-13
...@@ -33,7 +33,6 @@ const Object = @import("Wasm/Object.zig");...@@ -33,7 +33,6 @@ const Object = @import("Wasm/Object.zig");
33const Symbol = @import("Wasm/Symbol.zig");33const Symbol = @import("Wasm/Symbol.zig");
34const Type = @import("../type.zig").Type;34const Type = @import("../type.zig").Type;
35const TypedValue = @import("../TypedValue.zig");35const TypedValue = @import("../TypedValue.zig");
36const Value = @import("../value.zig").Value;
37const ZigObject = @import("Wasm/ZigObject.zig");36const ZigObject = @import("Wasm/ZigObject.zig");
3837
39pub const Atom = @import("Wasm/Atom.zig");38pub const Atom = @import("Wasm/Atom.zig");
...@@ -72,7 +71,7 @@ files: std.MultiArrayList(File.Entry) = .{},...@@ -72,7 +71,7 @@ files: std.MultiArrayList(File.Entry) = .{},
72/// to support existing code.71/// to support existing code.
73/// TODO: Allow setting this through a flag?72/// TODO: Allow setting this through a flag?
74host_name: []const u8 = "env",73host_name: []const u8 = "env",
75/// List of all symbols generated by Zig code.74/// List of symbols generated by the linker.
76synthetic_symbols: std.ArrayListUnmanaged(Symbol) = .{},75synthetic_symbols: std.ArrayListUnmanaged(Symbol) = .{},
77/// Maps atoms to their segment index76/// Maps atoms to their segment index
78atoms: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{},77atoms: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{},
...@@ -179,10 +178,6 @@ undefs: std.AutoArrayHashMapUnmanaged(u32, SymbolLoc) = .{},...@@ -179,10 +178,6 @@ undefs: std.AutoArrayHashMapUnmanaged(u32, SymbolLoc) = .{},
179/// Undefined (and synthetic) symbols do not have an Atom and therefore cannot be mapped.178/// Undefined (and synthetic) symbols do not have an Atom and therefore cannot be mapped.
180symbol_atom: std.AutoHashMapUnmanaged(SymbolLoc, Atom.Index) = .{},179symbol_atom: std.AutoHashMapUnmanaged(SymbolLoc, Atom.Index) = .{},
181180
182/// List of atom indexes of functions that are generated by the backend,
183/// rather than by the linker.
184synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{},
185
186pub const Alignment = types.Alignment;181pub const Alignment = types.Alignment;
187182
188pub const Segment = struct {183pub const Segment = struct {
...@@ -259,7 +254,7 @@ pub const InitFuncLoc = struct {...@@ -259,7 +254,7 @@ pub const InitFuncLoc = struct {
259 /// our own ctors.254 /// our own ctors.
260 file: File.Index,255 file: File.Index,
261 /// Symbol index within the corresponding object file.256 /// Symbol index within the corresponding object file.
262 index: u32,257 index: Symbol.Index,
263 /// The priority in which the constructor must be called.258 /// The priority in which the constructor must be called.
264 priority: u32,259 priority: u32,
265260
...@@ -270,7 +265,7 @@ pub const InitFuncLoc = struct {...@@ -270,7 +265,7 @@ pub const InitFuncLoc = struct {
270265
271 /// Turns the given `InitFuncLoc` into a `SymbolLoc`266 /// Turns the given `InitFuncLoc` into a `SymbolLoc`
272 fn getSymbolLoc(loc: InitFuncLoc) SymbolLoc {267 fn getSymbolLoc(loc: InitFuncLoc) SymbolLoc {
273 return .{ .file = loc.file, .index = @enumFromInt(loc.index) };268 return .{ .file = loc.file, .index = loc.index };
274 }269 }
275270
276 /// Returns true when `lhs` has a higher priority (e.i. value closer to 0) than `rhs`.271 /// Returns true when `lhs` has a higher priority (e.i. value closer to 0) than `rhs`.
...@@ -1411,9 +1406,9 @@ pub fn deinit(wasm: *Wasm) void {...@@ -1411,9 +1406,9 @@ pub fn deinit(wasm: *Wasm) void {
1411 archive.deinit(gpa);1406 archive.deinit(gpa);
1412 }1407 }
14131408
1414 for (wasm.synthetic_functions.items) |atom_index| {1409 if (wasm.findGlobalSymbol("__wasm_init_tls")) |loc| {
1415 const atom = wasm.getAtomPtr(atom_index);1410 const atom = wasm.symbol_atom.get(loc).?;
1416 atom.deinit(gpa);1411 wasm.getAtomPtr(atom).deinit(gpa);
1417 }1412 }
14181413
1419 wasm.synthetic_symbols.deinit(gpa);1414 wasm.synthetic_symbols.deinit(gpa);
...@@ -1441,7 +1436,7 @@ pub fn deinit(wasm: *Wasm) void {...@@ -1441,7 +1436,7 @@ pub fn deinit(wasm: *Wasm) void {
1441 wasm.exports.deinit(gpa);1436 wasm.exports.deinit(gpa);
14421437
1443 wasm.string_table.deinit(gpa);1438 wasm.string_table.deinit(gpa);
1444 wasm.synthetic_functions.deinit(gpa);1439 wasm.files.deinit(gpa);
1445}1440}
14461441
1447pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {1442pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
...@@ -1763,7 +1758,7 @@ fn setupInitFunctions(wasm: *Wasm) !void {...@@ -1763,7 +1758,7 @@ fn setupInitFunctions(wasm: *Wasm) !void {
1763 }1758 }
1764 log.debug("appended init func '{s}'\n", .{object.string_table.get(symbol.name)});1759 log.debug("appended init func '{s}'\n", .{object.string_table.get(symbol.name)});
1765 wasm.init_funcs.appendAssumeCapacity(.{1760 wasm.init_funcs.appendAssumeCapacity(.{
1766 .index = init_func.symbol_index,1761 .index = @enumFromInt(init_func.symbol_index),
1767 .file = file_index,1762 .file = file_index,
1768 .priority = init_func.priority,1763 .priority = init_func.priority,
1769 });1764 });
src/link/Wasm/ZigObject.zig+34-6
...@@ -37,12 +37,16 @@ segment_free_list: std.ArrayListUnmanaged(u32) = .{},...@@ -37,12 +37,16 @@ segment_free_list: std.ArrayListUnmanaged(u32) = .{},
37string_table: StringTable = .{},37string_table: StringTable = .{},
38/// Map for storing anonymous declarations. Each anonymous decl maps to its Atom's index.38/// Map for storing anonymous declarations. Each anonymous decl maps to its Atom's index.
39anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},39anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
40/// List of atom indexes of functions that are generated by the backend.
41synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{},
40/// Represents the symbol index of the error name table42/// Represents the symbol index of the error name table
41/// When this is `null`, no code references an error using runtime `@errorName`.43/// When this is `null`, no code references an error using runtime `@errorName`.
42/// During initializion, a symbol with corresponding atom will be created that is44/// During initializion, a symbol with corresponding atom will be created that is
43/// used to perform relocations to the pointer of this table.45/// used to perform relocations to the pointer of this table.
44/// The actual table is populated during `flush`.46/// The actual table is populated during `flush`.
45error_table_symbol: Symbol.Index = .null,47error_table_symbol: Symbol.Index = .null,
48/// Atom index of the table of symbol names. This is stored so we can clean up the atom.
49error_names_atom: Atom.Index = .null,
46/// Amount of functions in the `import` sections.50/// Amount of functions in the `import` sections.
47imported_functions_count: u32 = 0,51imported_functions_count: u32 = 0,
48/// Amount of globals in the `import` section.52/// Amount of globals in the `import` section.
...@@ -150,9 +154,6 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {...@@ -150,9 +154,6 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {
150 gpa.free(segment_info.name);154 gpa.free(segment_info.name);
151 }155 }
152156
153 // For decls and anon decls we free the memory of its atoms.
154 // The memory of atoms parsed from object files is managed by
155 // the object file itself, and therefore we can skip those.
156 {157 {
157 var it = zig_object.decls_map.valueIterator();158 var it = zig_object.decls_map.valueIterator();
158 while (it.next()) |decl_info| {159 while (it.next()) |decl_info| {
...@@ -175,6 +176,31 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {...@@ -175,6 +176,31 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void {
175 atom.deinit(gpa);176 atom.deinit(gpa);
176 }177 }
177 }178 }
179 if (zig_object.findGlobalSymbol("__zig_errors_len")) |sym_index| {
180 const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index }).?;
181 wasm_file.getAtomPtr(atom_index).deinit(gpa);
182 }
183 if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol })) |atom_index| {
184 const atom = wasm_file.getAtomPtr(atom_index);
185 atom.deinit(gpa);
186 }
187 for (zig_object.synthetic_functions.items) |atom_index| {
188 const atom = wasm_file.getAtomPtr(atom_index);
189 atom.deinit(gpa);
190 }
191 zig_object.synthetic_functions.deinit(gpa);
192 for (zig_object.func_types.items) |*ty| {
193 ty.deinit(gpa);
194 }
195 if (zig_object.error_names_atom != .null) {
196 const atom = wasm_file.getAtomPtr(zig_object.error_names_atom);
197 atom.deinit(gpa);
198 }
199 zig_object.global_syms.deinit(gpa);
200 zig_object.func_types.deinit(gpa);
201 zig_object.atom_types.deinit(gpa);
202 zig_object.functions.deinit(gpa);
203 zig_object.imports.deinit(gpa);
178 zig_object.decls_map.deinit(gpa);204 zig_object.decls_map.deinit(gpa);
179 zig_object.anon_decls.deinit(gpa);205 zig_object.anon_decls.deinit(gpa);
180 zig_object.symbols.deinit(gpa);206 zig_object.symbols.deinit(gpa);
...@@ -602,7 +628,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -602,7 +628,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
602 const atom = wasm_file.getAtomPtr(atom_index);628 const atom = wasm_file.getAtomPtr(atom_index);
603629
604 const error_name = mod.intern_pool.stringToSlice(error_name_nts);630 const error_name = mod.intern_pool.stringToSlice(error_name_nts);
605 const len = @as(u32, @intCast(error_name.len + 1)); // names are 0-termianted631 const len: u32 = @intCast(error_name.len + 1); // names are 0-terminated
606632
607 const slice_ty = Type.slice_const_u8_sentinel_0;633 const slice_ty = Type.slice_const_u8_sentinel_0;
608 const offset = @as(u32, @intCast(atom.code.items.len));634 const offset = @as(u32, @intCast(atom.code.items.len));
...@@ -614,9 +640,9 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -614,9 +640,9 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
614 .index = @intFromEnum(names_atom.sym_index),640 .index = @intFromEnum(names_atom.sym_index),
615 .relocation_type = .R_WASM_MEMORY_ADDR_I32,641 .relocation_type = .R_WASM_MEMORY_ADDR_I32,
616 .offset = offset,642 .offset = offset,
617 .addend = @as(i32, @intCast(addend)),643 .addend = @intCast(addend),
618 });644 });
619 atom.size += @as(u32, @intCast(slice_ty.abiSize(mod)));645 atom.size += @intCast(slice_ty.abiSize(mod));
620 addend += len;646 addend += len;
621647
622 // as we updated the error name table, we now store the actual name within the names atom648 // as we updated the error name table, we now store the actual name within the names atom
...@@ -627,6 +653,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -627,6 +653,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void {
627 log.debug("Populated error name: '{s}'", .{error_name});653 log.debug("Populated error name: '{s}'", .{error_name});
628 }654 }
629 names_atom.size = addend;655 names_atom.size = addend;
656 zig_object.error_names_atom = names_atom_index;
630}657}
631658
632/// Either creates a new import, or updates one if existing.659/// Either creates a new import, or updates one if existing.
...@@ -1174,6 +1201,7 @@ pub fn createFunction(...@@ -1174,6 +1201,7 @@ pub fn createFunction(
1174 atom.code = function_body.moveToUnmanaged();1201 atom.code = function_body.moveToUnmanaged();
1175 atom.relocs = relocations.moveToUnmanaged();1202 atom.relocs = relocations.moveToUnmanaged();
11761203
1204 try zig_object.synthetic_functions.append(gpa, atom_index);
1177 return sym_index;1205 return sym_index;
1178}1206}
11791207