authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-26 00:24:29-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:55-07:00
log9a738c0be54c9bda0e57de9da84f86fc73bd5198
treeae754aeda344d8d9c359ccddb565155f45468d5e
parentf37c0a459382fa033cefc9bb139277436a78b25e

Module: intern the values of decls when they are marked alive

I'm not sure if this is the right place for this to happen, and it should become obsolete when comptime mutation is rewritten and the remaining legacy value tags are remove, so keeping this as a separate revertable commit.

7 files changed, 29 insertions(+), 27 deletions(-)

src/Module.zig+19-17
......@@ -6603,47 +6603,49 @@ fn reportRetryableFileError(
66036603 gop.value_ptr.* = err_msg;
66046604}
66056605
6606pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void {
6606pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void {
66076607 switch (mod.intern_pool.indexToKey(val.toIntern())) {
6608 .variable => |variable| mod.markDeclIndexAlive(variable.decl),
6609 .extern_func => |extern_func| mod.markDeclIndexAlive(extern_func.decl),
6610 .func => |func| mod.markDeclIndexAlive(mod.funcPtr(func.index).owner_decl),
6608 .variable => |variable| try mod.markDeclIndexAlive(variable.decl),
6609 .extern_func => |extern_func| try mod.markDeclIndexAlive(extern_func.decl),
6610 .func => |func| try mod.markDeclIndexAlive(mod.funcPtr(func.index).owner_decl),
66116611 .error_union => |error_union| switch (error_union.val) {
66126612 .err_name => {},
6613 .payload => |payload| mod.markReferencedDeclsAlive(payload.toValue()),
6613 .payload => |payload| try mod.markReferencedDeclsAlive(payload.toValue()),
66146614 },
66156615 .ptr => |ptr| {
66166616 switch (ptr.addr) {
6617 .decl => |decl| mod.markDeclIndexAlive(decl),
6618 .mut_decl => |mut_decl| mod.markDeclIndexAlive(mut_decl.decl),
6617 .decl => |decl| try mod.markDeclIndexAlive(decl),
6618 .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl),
66196619 .int, .comptime_field => {},
6620 .eu_payload, .opt_payload => |parent| mod.markReferencedDeclsAlive(parent.toValue()),
6621 .elem, .field => |base_index| mod.markReferencedDeclsAlive(base_index.base.toValue()),
6620 .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(parent.toValue()),
6621 .elem, .field => |base_index| try mod.markReferencedDeclsAlive(base_index.base.toValue()),
66226622 }
6623 if (ptr.len != .none) mod.markReferencedDeclsAlive(ptr.len.toValue());
6623 if (ptr.len != .none) try mod.markReferencedDeclsAlive(ptr.len.toValue());
66246624 },
6625 .opt => |opt| if (opt.val != .none) mod.markReferencedDeclsAlive(opt.val.toValue()),
6625 .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(opt.val.toValue()),
66266626 .aggregate => |aggregate| for (aggregate.storage.values()) |elem|
6627 mod.markReferencedDeclsAlive(elem.toValue()),
6627 try mod.markReferencedDeclsAlive(elem.toValue()),
66286628 .un => |un| {
6629 mod.markReferencedDeclsAlive(un.tag.toValue());
6630 mod.markReferencedDeclsAlive(un.val.toValue());
6629 try mod.markReferencedDeclsAlive(un.tag.toValue());
6630 try mod.markReferencedDeclsAlive(un.val.toValue());
66316631 },
66326632 else => {},
66336633 }
66346634}
66356635
6636pub fn markDeclAlive(mod: *Module, decl: *Decl) void {
6636pub fn markDeclAlive(mod: *Module, decl: *Decl) Allocator.Error!void {
66376637 if (decl.alive) return;
66386638 decl.alive = true;
66396639
6640 decl.val = (try decl.val.intern(decl.ty, mod)).toValue();
6641
66406642 // This is the first time we are marking this Decl alive. We must
66416643 // therefore recurse into its value and mark any Decl it references
66426644 // as also alive, so that any Decl referenced does not get garbage collected.
6643 mod.markReferencedDeclsAlive(decl.val);
6645 try mod.markReferencedDeclsAlive(decl.val);
66446646}
66456647
6646fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) void {
6648fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {
66476649 return mod.markDeclAlive(mod.declPtr(decl_index));
66486650}
66496651
src/Sema.zig+1-1
......@@ -5807,7 +5807,7 @@ pub fn analyzeExport(
58075807 }
58085808
58095809 // This decl is alive no matter what, since it's being exported
5810 mod.markDeclAlive(exported_decl);
5810 try mod.markDeclAlive(exported_decl);
58115811 try sema.maybeQueueFuncBodyAnalysis(exported_decl_index);
58125812
58135813 const gpa = sema.gpa;
src/arch/wasm/CodeGen.zig+2-2
......@@ -3019,7 +3019,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue {
30193019fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue {
30203020 const mod = func.bin_file.base.options.module.?;
30213021 const decl = mod.declPtr(decl_index);
3022 mod.markDeclAlive(decl);
3022 try mod.markDeclAlive(decl);
30233023 const ptr_ty = try mod.singleMutPtrType(decl.ty);
30243024 return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset);
30253025}
......@@ -3035,7 +3035,7 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind
30353035 return WValue{ .imm32 = 0xaaaaaaaa };
30363036 }
30373037
3038 mod.markDeclAlive(decl);
3038 try mod.markDeclAlive(decl);
30393039 const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index);
30403040 const atom = func.bin_file.getAtom(atom_index);
30413041
src/codegen.zig+2-2
......@@ -673,7 +673,7 @@ fn lowerDeclRef(
673673 return Result.ok;
674674 }
675675
676 mod.markDeclAlive(decl);
676 try mod.markDeclAlive(decl);
677677
678678 const vaddr = try bin_file.getDeclVAddr(decl_index, .{
679679 .parent_atom_index = reloc_info.parent_atom_index,
......@@ -782,7 +782,7 @@ fn genDeclRef(
782782 }
783783 }
784784
785 mod.markDeclAlive(decl);
785 try mod.markDeclAlive(decl);
786786
787787 const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded;
788788
src/codegen/c.zig+1-1
......@@ -1923,7 +1923,7 @@ pub const DeclGen = struct {
19231923 fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void {
19241924 const mod = dg.module;
19251925 const decl = mod.declPtr(decl_index);
1926 mod.markDeclAlive(decl);
1926 try mod.markDeclAlive(decl);
19271927
19281928 if (mod.decl_exports.get(decl_index)) |exports| {
19291929 try writer.writeAll(exports.items[export_index].options.name);
src/codegen/llvm.zig+3-3
......@@ -3252,7 +3252,7 @@ pub const DeclGen = struct {
32523252 else => unreachable,
32533253 };
32543254 const fn_decl = dg.module.declPtr(fn_decl_index);
3255 dg.module.markDeclAlive(fn_decl);
3255 try dg.module.markDeclAlive(fn_decl);
32563256 return dg.resolveLlvmFunction(fn_decl_index);
32573257 },
32583258 .int => |int| {
......@@ -3831,7 +3831,7 @@ pub const DeclGen = struct {
38313831 ) Error!*llvm.Value {
38323832 const mod = dg.module;
38333833 const decl = mod.declPtr(decl_index);
3834 mod.markDeclAlive(decl);
3834 try mod.markDeclAlive(decl);
38353835 const ptr_ty = try mod.singleMutPtrType(decl.ty);
38363836 return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index);
38373837 }
......@@ -4006,7 +4006,7 @@ pub const DeclGen = struct {
40064006 return self.lowerPtrToVoid(tv.ty);
40074007 }
40084008
4009 mod.markDeclAlive(decl);
4009 try mod.markDeclAlive(decl);
40104010
40114011 const llvm_decl_val = if (is_fn_body)
40124012 try self.resolveLlvmFunction(decl_index)
src/codegen/spirv.zig+1-1
......@@ -256,7 +256,7 @@ pub const DeclGen = struct {
256256 /// Note: Function does not actually generate the decl.
257257 fn resolveDecl(self: *DeclGen, decl_index: Module.Decl.Index) !SpvModule.Decl.Index {
258258 const decl = self.module.declPtr(decl_index);
259 self.module.markDeclAlive(decl);
259 try self.module.markDeclAlive(decl);
260260
261261 const entry = try self.decl_link.getOrPut(decl_index);
262262 if (!entry.found_existing) {