diff --git a/src/Compilation.zig b/src/Compilation.zig index e4de593fd0..82ede40a9d 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1646,10 +1646,15 @@ pub fn update(self: *Compilation) !void { // If there are any errors, we anticipate the source files being loaded // to report error messages. Otherwise we unload all source files to save memory. + // The ZIR needs to stay loaded in memory because (1) Decl objects contain references + // to it, and (2) generic instantiations, comptime calls, inline calls will need + // to reference the ZIR. if (self.totalErrorCount() == 0 and !self.keep_source_files_loaded) { if (self.bin_file.options.module) |module| { for (module.import_table.items()) |entry| { - entry.value.unload(self.gpa); + const file = entry.value; + file.unloadTree(self.gpa); + file.unloadSource(self.gpa); } } } diff --git a/src/Module.zig b/src/Module.zig index a212fb44e4..76a740bdc0 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -263,9 +263,20 @@ pub const Decl = struct { false, ); + pub fn clearName(decl: *Decl, gpa: *Allocator) void { + // name could be allocated in the ZIR or it could be owned by gpa. + const file = decl.namespace.file_scope; + const string_table_start = @ptrToInt(file.zir.string_bytes.ptr); + const string_table_end = string_table_start + file.zir.string_bytes.len; + if (@ptrToInt(decl.name) < string_table_start or @ptrToInt(decl.name) >= string_table_end) { + gpa.free(mem.spanZ(decl.name)); + } + decl.name = undefined; + } + pub fn destroy(decl: *Decl, module: *Module) void { const gpa = module.gpa; - gpa.free(mem.spanZ(decl.name)); + decl.clearName(gpa); if (decl.has_tv) { if (decl.val.castTag(.function)) |payload| { const func = payload.data;