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.
This commit is contained in:
Jacob Young 2023-05-26 00:24:29 -04:00 committed by Andrew Kelley
parent f37c0a4593
commit 9a738c0be5
7 changed files with 29 additions and 27 deletions

View File

@ -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));
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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) {