aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Module.zig10
-rw-r--r--src/arch/wasm/CodeGen.zig17
-rw-r--r--src/codegen.zig15
-rw-r--r--src/codegen/c.zig15
-rw-r--r--src/codegen/llvm.zig26
-rw-r--r--src/value.zig49
6 files changed, 67 insertions, 65 deletions
diff --git a/src/Module.zig b/src/Module.zig
index e93fe2549c..a464ac83de 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -783,6 +783,16 @@ pub const Decl = struct {
return decl.ty.abiAlignment(target);
}
}
+
+ pub fn markAlive(decl: *Decl) void {
+ if (decl.alive) return;
+ decl.alive = true;
+
+ // 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.
+ decl.val.markReferencedDeclsAlive();
+ }
};
/// This state is attached to every Decl when Module emit_h is non-null.
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 97b43b3067..7a8efdfcc2 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -1037,7 +1037,7 @@ fn lowerDeclRef(self: *Self, ty: Type, val: Value, decl: *Module.Decl) InnerErro
const offset = @intCast(u32, self.code.items.len);
const atom = &self.decl.link.wasm;
const target_sym_index = decl.link.wasm.sym_index;
- markDeclAlive(decl);
+ decl.markAlive();
if (decl.ty.zigTypeTag() == .Fn) {
// We found a function pointer, so add it to our table,
// as function pointers are not allowed to be stored inside the data section,
@@ -1935,7 +1935,7 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
try self.emitConstant(slice.data.len, Type.usize);
} else if (val.castTag(.decl_ref)) |payload| {
const decl = payload.data;
- markDeclAlive(decl);
+ decl.markAlive();
// Function pointers use a table index, rather than a memory address
if (decl.ty.zigTypeTag() == .Fn) {
const target_sym_index = decl.link.wasm.sym_index;
@@ -2101,19 +2101,6 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
}
}
-fn markDeclAlive(decl: *Decl) void {
- if (decl.alive) return;
- decl.alive = true;
-
- // 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.
-
- if (decl.val.pointerDecl()) |pointee| {
- return markDeclAlive(pointee);
- }
-}
-
fn emitUndefined(self: *Self, ty: Type) InnerError!void {
switch (ty.zigTypeTag()) {
.Int => switch (ty.intInfo(self.target).bits) {
diff --git a/src/codegen.zig b/src/codegen.zig
index 1d20c4bc74..65b0318e9e 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -464,7 +464,7 @@ fn lowerDeclRef(
}
if (decl.analysis != .complete) return error.AnalysisFail;
- markDeclAlive(decl);
+ decl.markAlive();
const vaddr = vaddr: {
if (bin_file.cast(link.File.MachO)) |macho_file| {
break :vaddr try macho_file.getDeclVAddrWithReloc(decl, code.items.len);
@@ -484,16 +484,3 @@ fn lowerDeclRef(
return Result{ .appended = {} };
}
-
-fn markDeclAlive(decl: *Module.Decl) void {
- if (decl.alive) return;
- decl.alive = true;
-
- // 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.
-
- if (decl.val.pointerDecl()) |pointee| {
- return markDeclAlive(pointee);
- }
-}
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 58bf919b1f..3f3147ca80 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -215,7 +215,7 @@ pub const DeclGen = struct {
val: Value,
decl: *Decl,
) error{ OutOfMemory, AnalysisFail }!void {
- markDeclAlive(decl);
+ decl.markAlive();
if (ty.isSlice()) {
try writer.writeByte('(');
@@ -253,19 +253,6 @@ pub const DeclGen = struct {
try dg.renderDeclName(decl, writer);
}
- fn markDeclAlive(decl: *Decl) void {
- if (decl.alive) return;
- decl.alive = true;
-
- // 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.
-
- if (decl.val.pointerDecl()) |pointee| {
- return markDeclAlive(pointee);
- }
- }
-
fn renderInt128(
writer: anytype,
int_val: anytype,
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 7858fa76fa..d8c9589213 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1224,7 +1224,7 @@ pub const DeclGen = struct {
.decl_ref => return lowerDeclRefValue(dg, tv, tv.val.castTag(.decl_ref).?.data),
.variable => {
const decl = tv.val.castTag(.variable).?.data.owner_decl;
- dg.markDeclAlive(decl);
+ decl.markAlive();
const val = try dg.resolveGlobalDecl(decl);
const llvm_var_type = try dg.llvmType(tv.ty);
const llvm_addrspace = dg.llvmAddressSpace(decl.@"addrspace");
@@ -1373,7 +1373,7 @@ pub const DeclGen = struct {
.function => tv.val.castTag(.function).?.data.owner_decl,
else => unreachable,
};
- dg.markDeclAlive(fn_decl);
+ fn_decl.markAlive();
return dg.resolveLlvmFunction(fn_decl);
},
.ErrorSet => {
@@ -1681,7 +1681,7 @@ pub const DeclGen = struct {
ptr_val: Value,
decl: *Module.Decl,
) Error!ParentPtr {
- dg.markDeclAlive(decl);
+ decl.markAlive();
var ptr_ty_payload: Type.Payload.ElemType = .{
.base = .{ .tag = .single_mut_pointer },
.data = decl.ty,
@@ -1763,7 +1763,7 @@ pub const DeclGen = struct {
return self.lowerPtrToVoid(tv.ty);
}
- self.markDeclAlive(decl);
+ decl.markAlive();
const llvm_val = if (decl.ty.zigTypeTag() == .Fn)
try self.resolveLlvmFunction(decl)
@@ -1774,24 +1774,6 @@ pub const DeclGen = struct {
return llvm_val.constBitCast(llvm_type);
}
- fn markDeclAlive(dg: *DeclGen, decl: *Module.Decl) void {
- if (decl.alive) return;
- decl.alive = true;
-
- log.debug("{*} ({s}) marked alive by {*} ({s})", .{
- decl, decl.name,
- dg.decl, dg.decl.name,
- });
-
- // 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.
-
- if (decl.val.pointerDecl()) |pointee| {
- return dg.markDeclAlive(pointee);
- }
- }
-
fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*const llvm.Value {
const target = dg.module.getTarget();
const alignment = ptr_ty.ptrAlignment(target);
diff --git a/src/value.zig b/src/value.zig
index 1993a853cd..1836a14ce0 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -1746,6 +1746,55 @@ pub const Value = extern union {
};
}
+ pub fn markReferencedDeclsAlive(val: Value) void {
+ switch (val.tag()) {
+ .decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.markAlive(),
+ .extern_fn, .decl_ref => return val.cast(Payload.Decl).?.data.markAlive(),
+ .function => return val.castTag(.function).?.data.owner_decl.markAlive(),
+ .variable => return val.castTag(.variable).?.data.owner_decl.markAlive(),
+
+ .repeated,
+ .eu_payload,
+ .eu_payload_ptr,
+ .opt_payload,
+ .opt_payload_ptr,
+ .empty_array_sentinel,
+ => return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data),
+
+ .array => {
+ for (val.cast(Payload.Array).?.data) |elem_val| {
+ markReferencedDeclsAlive(elem_val);
+ }
+ },
+ .slice => {
+ const slice = val.cast(Payload.Slice).?.data;
+ markReferencedDeclsAlive(slice.ptr);
+ markReferencedDeclsAlive(slice.len);
+ },
+
+ .elem_ptr => {
+ const elem_ptr = val.cast(Payload.ElemPtr).?.data;
+ return markReferencedDeclsAlive(elem_ptr.array_ptr);
+ },
+ .field_ptr => {
+ const field_ptr = val.cast(Payload.FieldPtr).?.data;
+ return markReferencedDeclsAlive(field_ptr.container_ptr);
+ },
+ .@"struct" => {
+ for (val.cast(Payload.Struct).?.data) |field_val| {
+ markReferencedDeclsAlive(field_val);
+ }
+ },
+ .@"union" => {
+ const data = val.cast(Payload.Union).?.data;
+ markReferencedDeclsAlive(data.tag);
+ markReferencedDeclsAlive(data.val);
+ },
+
+ else => {},
+ }
+ }
+
pub fn slicePtr(val: Value) Value {
return switch (val.tag()) {
.slice => val.castTag(.slice).?.data.ptr,