diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 10 | ||||
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 17 | ||||
| -rw-r--r-- | src/codegen.zig | 15 | ||||
| -rw-r--r-- | src/codegen/c.zig | 15 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 26 | ||||
| -rw-r--r-- | src/value.zig | 49 |
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, |
