From 9a738c0be54c9bda0e57de9da84f86fc73bd5198 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 26 May 2023 00:24:29 -0400 Subject: [PATCH] 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. --- src/Module.zig | 36 +++++++++++++++++++----------------- src/Sema.zig | 2 +- src/arch/wasm/CodeGen.zig | 4 ++-- src/codegen.zig | 4 ++-- src/codegen/c.zig | 2 +- src/codegen/llvm.zig | 6 +++--- src/codegen/spirv.zig | 2 +- 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index d3045631c5f78c96655c173649930ed3cd3df0fc..76e2142ae6dec2395589ef2e78ea5d3f5ab04735 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -6603,47 +6603,49 @@ fn reportRetryableFileError( gop.value_ptr.* = err_msg; } -pub fn markReferencedDeclsAlive(mod: *Module, val: Value) void { +pub fn markReferencedDeclsAlive(mod: *Module, val: Value) Allocator.Error!void { switch (mod.intern_pool.indexToKey(val.toIntern())) { - .variable => |variable| mod.markDeclIndexAlive(variable.decl), - .extern_func => |extern_func| mod.markDeclIndexAlive(extern_func.decl), - .func => |func| mod.markDeclIndexAlive(mod.funcPtr(func.index).owner_decl), + .variable => |variable| try mod.markDeclIndexAlive(variable.decl), + .extern_func => |extern_func| try mod.markDeclIndexAlive(extern_func.decl), + .func => |func| try mod.markDeclIndexAlive(mod.funcPtr(func.index).owner_decl), .error_union => |error_union| switch (error_union.val) { .err_name => {}, - .payload => |payload| mod.markReferencedDeclsAlive(payload.toValue()), + .payload => |payload| try mod.markReferencedDeclsAlive(payload.toValue()), }, .ptr => |ptr| { switch (ptr.addr) { - .decl => |decl| mod.markDeclIndexAlive(decl), - .mut_decl => |mut_decl| mod.markDeclIndexAlive(mut_decl.decl), + .decl => |decl| try mod.markDeclIndexAlive(decl), + .mut_decl => |mut_decl| try mod.markDeclIndexAlive(mut_decl.decl), .int, .comptime_field => {}, - .eu_payload, .opt_payload => |parent| mod.markReferencedDeclsAlive(parent.toValue()), - .elem, .field => |base_index| mod.markReferencedDeclsAlive(base_index.base.toValue()), + .eu_payload, .opt_payload => |parent| try mod.markReferencedDeclsAlive(parent.toValue()), + .elem, .field => |base_index| try mod.markReferencedDeclsAlive(base_index.base.toValue()), } - if (ptr.len != .none) mod.markReferencedDeclsAlive(ptr.len.toValue()); + if (ptr.len != .none) try mod.markReferencedDeclsAlive(ptr.len.toValue()); }, - .opt => |opt| if (opt.val != .none) mod.markReferencedDeclsAlive(opt.val.toValue()), + .opt => |opt| if (opt.val != .none) try mod.markReferencedDeclsAlive(opt.val.toValue()), .aggregate => |aggregate| for (aggregate.storage.values()) |elem| - mod.markReferencedDeclsAlive(elem.toValue()), + try mod.markReferencedDeclsAlive(elem.toValue()), .un => |un| { - mod.markReferencedDeclsAlive(un.tag.toValue()); - mod.markReferencedDeclsAlive(un.val.toValue()); + try mod.markReferencedDeclsAlive(un.tag.toValue()); + try mod.markReferencedDeclsAlive(un.val.toValue()); }, else => {}, } } -pub fn markDeclAlive(mod: *Module, decl: *Decl) void { +pub fn markDeclAlive(mod: *Module, decl: *Decl) Allocator.Error!void { if (decl.alive) return; decl.alive = true; + decl.val = (try decl.val.intern(decl.ty, mod)).toValue(); + // This is the first time we are marking this Decl alive. We must // therefore recurse into its value and mark any Decl it references // as also alive, so that any Decl referenced does not get garbage collected. - mod.markReferencedDeclsAlive(decl.val); + try mod.markReferencedDeclsAlive(decl.val); } -fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) void { +fn markDeclIndexAlive(mod: *Module, decl_index: Decl.Index) Allocator.Error!void { return mod.markDeclAlive(mod.declPtr(decl_index)); } diff --git a/src/Sema.zig b/src/Sema.zig index 5395bb63d11a52d684babef0be9b365654f2b22f..e9c4958918108c65093724efa727a011541e4f74 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5807,7 +5807,7 @@ pub fn analyzeExport( } // This decl is alive no matter what, since it's being exported - mod.markDeclAlive(exported_decl); + try mod.markDeclAlive(exported_decl); try sema.maybeQueueFuncBodyAnalysis(exported_decl_index); const gpa = sema.gpa; diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index b4e627e957a20dbdc7e75bd50df574c60eefb637..d9cb56404a08d22b262c68bb32ca228732ac88b2 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3019,7 +3019,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value) InnerError!WValue { fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.Index, offset: u32) InnerError!WValue { const mod = func.bin_file.base.options.module.?; const decl = mod.declPtr(decl_index); - mod.markDeclAlive(decl); + try mod.markDeclAlive(decl); const ptr_ty = try mod.singleMutPtrType(decl.ty); return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset); } @@ -3035,7 +3035,7 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind return WValue{ .imm32 = 0xaaaaaaaa }; } - mod.markDeclAlive(decl); + try mod.markDeclAlive(decl); const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index); const atom = func.bin_file.getAtom(atom_index); diff --git a/src/codegen.zig b/src/codegen.zig index f343f0441d42899a41d4b5d8bf331b98b1ba0db1..87aea6c245b24b0b03a660efb11a8b0659fbf829 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -673,7 +673,7 @@ fn lowerDeclRef( return Result.ok; } - mod.markDeclAlive(decl); + try mod.markDeclAlive(decl); const vaddr = try bin_file.getDeclVAddr(decl_index, .{ .parent_atom_index = reloc_info.parent_atom_index, @@ -782,7 +782,7 @@ fn genDeclRef( } } - mod.markDeclAlive(decl); + try mod.markDeclAlive(decl); const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded; diff --git a/src/codegen/c.zig b/src/codegen/c.zig index f97292e5102e15705459709d5f990a4bb575fd0d..2dcc332713d02be67c1e395282e36c0aac9a5992 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1923,7 +1923,7 @@ pub const DeclGen = struct { fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void { const mod = dg.module; const decl = mod.declPtr(decl_index); - mod.markDeclAlive(decl); + try mod.markDeclAlive(decl); if (mod.decl_exports.get(decl_index)) |exports| { try writer.writeAll(exports.items[export_index].options.name); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 46b126ad84db9d8fa54875dc3b04a8aa7142817b..936b1d847ada7e45fea505868031472fd8f6aa2e 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -3252,7 +3252,7 @@ pub const DeclGen = struct { else => unreachable, }; const fn_decl = dg.module.declPtr(fn_decl_index); - dg.module.markDeclAlive(fn_decl); + try dg.module.markDeclAlive(fn_decl); return dg.resolveLlvmFunction(fn_decl_index); }, .int => |int| { @@ -3831,7 +3831,7 @@ pub const DeclGen = struct { ) Error!*llvm.Value { const mod = dg.module; const decl = mod.declPtr(decl_index); - mod.markDeclAlive(decl); + try mod.markDeclAlive(decl); const ptr_ty = try mod.singleMutPtrType(decl.ty); return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); } @@ -4006,7 +4006,7 @@ pub const DeclGen = struct { return self.lowerPtrToVoid(tv.ty); } - mod.markDeclAlive(decl); + try mod.markDeclAlive(decl); const llvm_decl_val = if (is_fn_body) try self.resolveLlvmFunction(decl_index) diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 1a19bbdf91f7f6a11e1ea87995c0db95bc21284b..43b67414934f776fd22b110d7a73ad8f0a684b31 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -256,7 +256,7 @@ pub const DeclGen = struct { /// Note: Function does not actually generate the decl. fn resolveDecl(self: *DeclGen, decl_index: Module.Decl.Index) !SpvModule.Decl.Index { const decl = self.module.declPtr(decl_index); - self.module.markDeclAlive(decl); + try self.module.markDeclAlive(decl); const entry = try self.decl_link.getOrPut(decl_index); if (!entry.found_existing) { -- 2.54.0