| ... | ... | @@ -47,9 +47,6 @@ offset_table_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 47 | 47 | /// This is ment for bookkeeping so we can safely cleanup all codegen memory |
| 48 | 48 | /// when calling `deinit` |
| 49 | 49 | symbols: 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. |
| 52 | | symbols_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 53 | 50 | |
| 54 | 51 | pub const FnData = struct { |
| 55 | 52 | /// Generated code for the type of the function |
| ... | ... | @@ -95,6 +92,19 @@ pub const DeclBlock = struct { |
| 95 | 92 | .next = null, |
| 96 | 93 | .data = undefined, |
| 97 | 94 | }; |
| 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 | } |
| 98 | 108 | }; |
| 99 | 109 | |
| 100 | 110 | 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 { |
| 131 | 141 | } |
| 132 | 142 | |
| 133 | 143 | pub 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 | | } |
| 138 | 144 | for (self.symbols.items) |decl| { |
| 139 | 145 | decl.fn_link.wasm.functype.deinit(self.base.allocator); |
| 140 | 146 | decl.fn_link.wasm.code.deinit(self.base.allocator); |
| ... | ... | @@ -146,7 +152,6 @@ pub fn deinit(self: *Wasm) void { |
| 146 | 152 | self.offset_table.deinit(self.base.allocator); |
| 147 | 153 | self.offset_table_free_list.deinit(self.base.allocator); |
| 148 | 154 | self.symbols.deinit(self.base.allocator); |
| 149 | | self.symbols_free_list.deinit(self.base.allocator); |
| 150 | 155 | } |
| 151 | 156 | |
| 152 | 157 | pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void { |
| ... | ... | @@ -158,12 +163,8 @@ pub fn allocateDeclIndexes(self: *Wasm, decl: *Module.Decl) !void { |
| 158 | 163 | const block = &decl.link.wasm; |
| 159 | 164 | block.init = true; |
| 160 | 165 | |
| 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); |
| 167 | 168 | |
| 168 | 169 | if (self.offset_table_free_list.popOrNull()) |index| { |
| 169 | 170 | block.offset_index = index; |
| ... | ... | @@ -241,12 +242,7 @@ pub fn updateDecl(self: *Wasm, module: *Module, decl: *Module.Decl) !void { |
| 241 | 242 | |
| 242 | 243 | // If we're updating an existing decl, unplug it first |
| 243 | 244 | // 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(); |
| 250 | 246 | |
| 251 | 247 | if (self.last_block) |last| { |
| 252 | 248 | if (last != block) { |
| ... | ... | @@ -278,16 +274,15 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { |
| 278 | 274 | self.last_block = block.prev; |
| 279 | 275 | } |
| 280 | 276 | |
| 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(); |
| 288 | 278 | |
| 289 | 279 | 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 | |
| 291 | 286 | block.init = false; |
| 292 | 287 | |
| 293 | 288 | decl.fn_link.wasm.functype.deinit(self.base.allocator); |