authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-04-09 09:24:52+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2021-04-09 09:24:52+02:00
logeaaf75c1579e0202efb1b8b71155ea147d52c56a
treef94dff606589b1d8685543048ace9866e2bca8aa
parentff5774d93d9d952a74fab3666d4480f534c770db
signature Commit is signed but in an unrecognized format.

Fix memory cleanup and update unplugging to avoid infinite loop


1 files changed, 23 insertions(+), 28 deletions(-)

src/link/Wasm.zig+23-28
......@@ -47,9 +47,6 @@ offset_table_free_list: std.ArrayListUnmanaged(u32) = .{},
4747/// This is ment for bookkeeping so we can safely cleanup all codegen memory
4848/// when calling `deinit`
4949symbols: std.ArrayListUnmanaged(*Module.Decl) = .{},
50/// Contains indexes into `symbols` that are no longer used and can be populated instead,
51/// removing the need to search for a symbol and remove it when it's dereferenced.
52symbols_free_list: std.ArrayListUnmanaged(u32) = .{},
5350
5451pub const FnData = struct {
5552 /// Generated code for the type of the function
......@@ -95,6 +92,19 @@ pub const DeclBlock = struct {
9592 .next = null,
9693 .data = undefined,
9794 };
95
96 /// Unplugs the `DeclBlock` from the chain
97 fn unplug(self: *DeclBlock) void {
98 if (self.prev) |prev| {
99 prev.next = self.next;
100 }
101
102 if (self.next) |next| {
103 next.prev = self.prev;
104 }
105 self.next = null;
106 self.prev = null;
107 }
98108};
99109
100110pub 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 {
131141}
132142
133143pub fn deinit(self: *Wasm) void {
134 while (self.symbols_free_list.popOrNull()) |idx| {
135 //dead decl's so remove them from symbol list before trying to clean them up
136 _ = self.symbols.swapRemove(idx);
137 }
138144 for (self.symbols.items) |decl| {
139145 decl.fn_link.wasm.functype.deinit(self.base.allocator);
140146 decl.fn_link.wasm.code.deinit(self.base.allocator);
......@@ -146,7 +152,6 @@ pub fn deinit(self: *Wasm) void {
146152 self.offset_table.deinit(self.base.allocator);
147153 self.offset_table_free_list.deinit(self.base.allocator);
148154 self.symbols.deinit(self.base.allocator);
149 self.symbols_free_list.deinit(self.base.allocator);
150155}
151156
152157pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
......@@ -158,12 +163,8 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void {
158163 const block = &decl.link.wasm;
159164 block.init = true;
160165
161 if (self.symbols_free_list.popOrNull()) |index| {
162 block.symbol_index = index;
163 } else {
164 block.symbol_index = @intCast(u32, self.symbols.items.len);
165 _ = self.symbols.addOneAssumeCapacity();
166 }
166 block.symbol_index = @intCast(u32, self.symbols.items.len);
167 self.symbols.appendAssumeCapacity(decl);
167168
168169 if (self.offset_table_free_list.popOrNull()) |index| {
169170 block.offset_index = index;
......@@ -241,12 +242,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void {
241242
242243 // If we're updating an existing decl, unplug it first
243244 // to avoid infinite loops due to earlier links
244 if (block.prev) |prev| {
245 prev.next = block.next;
246 }
247 if (block.next) |next| {
248 next.prev = block.prev;
249 }
245 block.unplug();
250246
251247 if (self.last_block) |last| {
252248 if (last != block) {
......@@ -278,16 +274,15 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void {
278274 self.last_block = block.prev;
279275 }
280276
281 if (block.prev) |prev| {
282 prev.next = block.next;
283 }
284
285 if (block.next) |next| {
286 next.prev = block.prev;
287 }
277 block.unplug();
288278
289279 self.offset_table_free_list.append(self.base.allocator, decl.link.wasm.offset_index) catch {};
290 self.symbols_free_list.append(self.base.allocator, decl.link.wasm.symbol_index) catch {};
280 _ = self.symbols.swapRemove(block.symbol_index);
281
282 // update symbol_index as we swap removed the last symbol into the removed's position
283 if (block.symbol_index < self.symbols.items.len)
284 self.symbols.items[block.symbol_index].link.wasm.symbol_index = block.symbol_index;
285
291286 block.init = false;
292287
293288 decl.fn_link.wasm.functype.deinit(self.base.allocator);