diff options
| author | Luuk de Gram <Luukdegram@users.noreply.github.com> | 2021-04-09 09:24:52 +0200 |
|---|---|---|
| committer | Luuk de Gram <Luukdegram@users.noreply.github.com> | 2021-04-09 09:24:52 +0200 |
| commit | eaaf75c1579e0202efb1b8b71155ea147d52c56a (patch) | |
| tree | f94dff606589b1d8685543048ace9866e2bca8aa /src/link | |
| parent | ff5774d93d9d952a74fab3666d4480f534c770db (diff) | |
| download | zig-eaaf75c1579e0202efb1b8b71155ea147d52c56a.tar.gz zig-eaaf75c1579e0202efb1b8b71155ea147d52c56a.zip | |
Fix memory cleanup and update unplugging to avoid infinite loop
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Wasm.zig | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 2186afb4a6..2dd15db1d4 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -47,9 +47,6 @@ offset_table_free_list: std.ArrayListUnmanaged(u32) = .{}, /// This is ment for bookkeeping so we can safely cleanup all codegen memory /// when calling `deinit` symbols: std.ArrayListUnmanaged(*Module.Decl) = .{}, -/// Contains indexes into `symbols` that are no longer used and can be populated instead, -/// removing the need to search for a symbol and remove it when it's dereferenced. -symbols_free_list: std.ArrayListUnmanaged(u32) = .{}, pub const FnData = struct { /// Generated code for the type of the function @@ -95,6 +92,19 @@ pub const DeclBlock = struct { .next = null, .data = undefined, }; + + /// Unplugs the `DeclBlock` from the chain + fn unplug(self: *DeclBlock) void { + if (self.prev) |prev| { + prev.next = self.next; + } + + if (self.next) |next| { + next.prev = self.prev; + } + self.next = null; + self.prev = null; + } }; pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Wasm { @@ -131,10 +141,6 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Wasm { } pub fn deinit(self: *Wasm) void { - while (self.symbols_free_list.popOrNull()) |idx| { - //dead decl's so remove them from symbol list before trying to clean them up - _ = self.symbols.swapRemove(idx); - } for (self.symbols.items) |decl| { decl.fn_link.wasm.functype.deinit(self.base.allocator); decl.fn_link.wasm.code.deinit(self.base.allocator); @@ -146,7 +152,6 @@ pub fn deinit(self: *Wasm) void { self.offset_table.deinit(self.base.allocator); self.offset_table_free_list.deinit(self.base.allocator); self.symbols.deinit(self.base.allocator); - self.symbols_free_list.deinit(self.base.allocator); } pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void { @@ -158,12 +163,8 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void { const block = &decl.link.wasm; block.init = true; - if (self.symbols_free_list.popOrNull()) |index| { - block.symbol_index = index; - } else { - block.symbol_index = @intCast(u32, self.symbols.items.len); - _ = self.symbols.addOneAssumeCapacity(); - } + block.symbol_index = @intCast(u32, self.symbols.items.len); + self.symbols.appendAssumeCapacity(decl); if (self.offset_table_free_list.popOrNull()) |index| { block.offset_index = index; @@ -241,12 +242,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void { // If we're updating an existing decl, unplug it first // to avoid infinite loops due to earlier links - if (block.prev) |prev| { - prev.next = block.next; - } - if (block.next) |next| { - next.prev = block.prev; - } + block.unplug(); if (self.last_block) |last| { if (last != block) { @@ -278,16 +274,15 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { self.last_block = block.prev; } - if (block.prev) |prev| { - prev.next = block.next; - } - - if (block.next) |next| { - next.prev = block.prev; - } + block.unplug(); self.offset_table_free_list.append(self.base.allocator, decl.link.wasm.offset_index) catch {}; - self.symbols_free_list.append(self.base.allocator, decl.link.wasm.symbol_index) catch {}; + _ = self.symbols.swapRemove(block.symbol_index); + + // update symbol_index as we swap removed the last symbol into the removed's position + if (block.symbol_index < self.symbols.items.len) + self.symbols.items[block.symbol_index].link.wasm.symbol_index = block.symbol_index; + block.init = false; decl.fn_link.wasm.functype.deinit(self.base.allocator); |
