diff options
| author | Luuk de Gram <luuk@degram.dev> | 2024-02-28 19:02:16 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2024-02-29 15:52:43 +0100 |
| commit | 202ed7330fdc55cce22bfa9d9b5da03776e871b4 (patch) | |
| tree | b0ef3791a3e10ea9e2b553cf2457f0a0fc079a27 /src/link | |
| parent | 196ba706a05046b2209529744d2df47215819691 (diff) | |
| download | zig-202ed7330fdc55cce22bfa9d9b5da03776e871b4.tar.gz zig-202ed7330fdc55cce22bfa9d9b5da03776e871b4.zip | |
fix memory leaks
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Wasm.zig | 21 | ||||
| -rw-r--r-- | src/link/Wasm/ZigObject.zig | 40 |
2 files changed, 42 insertions, 19 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 9a59484aa1..b9997cf883 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -33,7 +33,6 @@ const Object = @import("Wasm/Object.zig"); const Symbol = @import("Wasm/Symbol.zig"); const Type = @import("../type.zig").Type; const TypedValue = @import("../TypedValue.zig"); -const Value = @import("../value.zig").Value; const ZigObject = @import("Wasm/ZigObject.zig"); pub const Atom = @import("Wasm/Atom.zig"); @@ -72,7 +71,7 @@ files: std.MultiArrayList(File.Entry) = .{}, /// to support existing code. /// TODO: Allow setting this through a flag? host_name: []const u8 = "env", -/// List of all symbols generated by Zig code. +/// List of symbols generated by the linker. synthetic_symbols: std.ArrayListUnmanaged(Symbol) = .{}, /// Maps atoms to their segment index atoms: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{}, @@ -179,10 +178,6 @@ undefs: std.AutoArrayHashMapUnmanaged(u32, SymbolLoc) = .{}, /// Undefined (and synthetic) symbols do not have an Atom and therefore cannot be mapped. symbol_atom: std.AutoHashMapUnmanaged(SymbolLoc, Atom.Index) = .{}, -/// List of atom indexes of functions that are generated by the backend, -/// rather than by the linker. -synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{}, - pub const Alignment = types.Alignment; pub const Segment = struct { @@ -259,7 +254,7 @@ pub const InitFuncLoc = struct { /// our own ctors. file: File.Index, /// Symbol index within the corresponding object file. - index: u32, + index: Symbol.Index, /// The priority in which the constructor must be called. priority: u32, @@ -270,7 +265,7 @@ pub const InitFuncLoc = struct { /// Turns the given `InitFuncLoc` into a `SymbolLoc` fn getSymbolLoc(loc: InitFuncLoc) SymbolLoc { - return .{ .file = loc.file, .index = @enumFromInt(loc.index) }; + return .{ .file = loc.file, .index = loc.index }; } /// 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 { archive.deinit(gpa); } - for (wasm.synthetic_functions.items) |atom_index| { - const atom = wasm.getAtomPtr(atom_index); - atom.deinit(gpa); + if (wasm.findGlobalSymbol("__wasm_init_tls")) |loc| { + const atom = wasm.symbol_atom.get(loc).?; + wasm.getAtomPtr(atom).deinit(gpa); } wasm.synthetic_symbols.deinit(gpa); @@ -1441,7 +1436,7 @@ pub fn deinit(wasm: *Wasm) void { wasm.exports.deinit(gpa); wasm.string_table.deinit(gpa); - wasm.synthetic_functions.deinit(gpa); + wasm.files.deinit(gpa); } pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void { @@ -1763,7 +1758,7 @@ fn setupInitFunctions(wasm: *Wasm) !void { } log.debug("appended init func '{s}'\n", .{object.string_table.get(symbol.name)}); wasm.init_funcs.appendAssumeCapacity(.{ - .index = init_func.symbol_index, + .index = @enumFromInt(init_func.symbol_index), .file = file_index, .priority = init_func.priority, }); diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index 7d017e20c8..5b1c587a74 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -37,12 +37,16 @@ segment_free_list: std.ArrayListUnmanaged(u32) = .{}, string_table: StringTable = .{}, /// Map for storing anonymous declarations. Each anonymous decl maps to its Atom's index. anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{}, +/// List of atom indexes of functions that are generated by the backend. +synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{}, /// Represents the symbol index of the error name table /// When this is `null`, no code references an error using runtime `@errorName`. /// During initializion, a symbol with corresponding atom will be created that is /// used to perform relocations to the pointer of this table. /// The actual table is populated during `flush`. error_table_symbol: Symbol.Index = .null, +/// Atom index of the table of symbol names. This is stored so we can clean up the atom. +error_names_atom: Atom.Index = .null, /// Amount of functions in the `import` sections. imported_functions_count: u32 = 0, /// Amount of globals in the `import` section. @@ -150,9 +154,6 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void { gpa.free(segment_info.name); } - // For decls and anon decls we free the memory of its atoms. - // The memory of atoms parsed from object files is managed by - // the object file itself, and therefore we can skip those. { var it = zig_object.decls_map.valueIterator(); while (it.next()) |decl_info| { @@ -175,6 +176,31 @@ pub fn deinit(zig_object: *ZigObject, wasm_file: *Wasm) void { atom.deinit(gpa); } } + if (zig_object.findGlobalSymbol("__zig_errors_len")) |sym_index| { + const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index }).?; + wasm_file.getAtomPtr(atom_index).deinit(gpa); + } + if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = zig_object.error_table_symbol })) |atom_index| { + const atom = wasm_file.getAtomPtr(atom_index); + atom.deinit(gpa); + } + for (zig_object.synthetic_functions.items) |atom_index| { + const atom = wasm_file.getAtomPtr(atom_index); + atom.deinit(gpa); + } + zig_object.synthetic_functions.deinit(gpa); + for (zig_object.func_types.items) |*ty| { + ty.deinit(gpa); + } + if (zig_object.error_names_atom != .null) { + const atom = wasm_file.getAtomPtr(zig_object.error_names_atom); + atom.deinit(gpa); + } + zig_object.global_syms.deinit(gpa); + zig_object.func_types.deinit(gpa); + zig_object.atom_types.deinit(gpa); + zig_object.functions.deinit(gpa); + zig_object.imports.deinit(gpa); zig_object.decls_map.deinit(gpa); zig_object.anon_decls.deinit(gpa); zig_object.symbols.deinit(gpa); @@ -602,7 +628,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { const atom = wasm_file.getAtomPtr(atom_index); const error_name = mod.intern_pool.stringToSlice(error_name_nts); - const len = @as(u32, @intCast(error_name.len + 1)); // names are 0-termianted + const len: u32 = @intCast(error_name.len + 1); // names are 0-terminated const slice_ty = Type.slice_const_u8_sentinel_0; const offset = @as(u32, @intCast(atom.code.items.len)); @@ -614,9 +640,9 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm) !void { .index = @intFromEnum(names_atom.sym_index), .relocation_type = .R_WASM_MEMORY_ADDR_I32, .offset = offset, - .addend = @as(i32, @intCast(addend)), + .addend = @intCast(addend), }); - atom.size += @as(u32, @intCast(slice_ty.abiSize(mod))); + atom.size += @intCast(slice_ty.abiSize(mod)); addend += len; // 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 { log.debug("Populated error name: '{s}'", .{error_name}); } names_atom.size = addend; + zig_object.error_names_atom = names_atom_index; } /// Either creates a new import, or updates one if existing. @@ -1174,6 +1201,7 @@ pub fn createFunction( atom.code = function_body.moveToUnmanaged(); atom.relocs = relocations.moveToUnmanaged(); + try zig_object.synthetic_functions.append(gpa, atom_index); return sym_index; } |
