authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-29 20:34:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-29 20:34:33-07:00
log8ab4a003c8f22a3fd8f84bdb2fc27d8c20d3bf2f
tree28db2ba140f4017ef0f314d47a52c8dd517301a9
parent474ade88b58b6fd7239049ec445129eabafa3cbd

stage2: properly free Decl name

Two problems solved: * The Decl name may be allocated with gpa or it may be a reference to the ZIR string table. * The main update() function was freeing the ZIR when we still had Decl objects referencing it.

2 files changed, 18 insertions(+), 2 deletions(-)

src/Compilation.zig+6-1
......@@ -1646,10 +1646,15 @@ pub fn update(self: *Compilation) !void {
16461646
16471647 // If there are any errors, we anticipate the source files being loaded
16481648 // to report error messages. Otherwise we unload all source files to save memory.
1649 // The ZIR needs to stay loaded in memory because (1) Decl objects contain references
1650 // to it, and (2) generic instantiations, comptime calls, inline calls will need
1651 // to reference the ZIR.
16491652 if (self.totalErrorCount() == 0 and !self.keep_source_files_loaded) {
16501653 if (self.bin_file.options.module) |module| {
16511654 for (module.import_table.items()) |entry| {
1652 entry.value.unload(self.gpa);
1655 const file = entry.value;
1656 file.unloadTree(self.gpa);
1657 file.unloadSource(self.gpa);
16531658 }
16541659 }
16551660 }
src/Module.zig+12-1
......@@ -263,9 +263,20 @@ pub const Decl = struct {
263263 false,
264264 );
265265
266 pub fn clearName(decl: *Decl, gpa: *Allocator) void {
267 // name could be allocated in the ZIR or it could be owned by gpa.
268 const file = decl.namespace.file_scope;
269 const string_table_start = @ptrToInt(file.zir.string_bytes.ptr);
270 const string_table_end = string_table_start + file.zir.string_bytes.len;
271 if (@ptrToInt(decl.name) < string_table_start or @ptrToInt(decl.name) >= string_table_end) {
272 gpa.free(mem.spanZ(decl.name));
273 }
274 decl.name = undefined;
275 }
276
266277 pub fn destroy(decl: *Decl, module: *Module) void {
267278 const gpa = module.gpa;
268 gpa.free(mem.spanZ(decl.name));
279 decl.clearName(gpa);
269280 if (decl.has_tv) {
270281 if (decl.val.castTag(.function)) |payload| {
271282 const func = payload.data;