From 567c6ffb1e6cbd49e4e87ecf71cdc4093eafe4c6 Mon Sep 17 00:00:00 2001 From: Cody Tapscott Date: Thu, 5 Feb 2026 20:55:52 -0500 Subject: [PATCH] codegen: Mark resolved `const` `GlobalRef` as method root This allows `--trim` to safely* prune bindings without dropping the root required for the generated machine code. * uninferred GlobalRefs can lead to missing bindings at runtime, but these do not directly trigger UB / crash and they are relatively rare --- src/codegen.cpp | 4 ++++ test/trimming/trimmability.jl | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/codegen.cpp b/src/codegen.cpp index 5bf292bc44427..4e2a796dd2eb7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3505,6 +3505,10 @@ static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t * undef_var_error_ifnot(ctx, ConstantInt::get(getInt1Ty(ctx.builder.getContext()), 0), name, (jl_value_t*)mod); return jl_cgval_t(); } + if (jl_generating_output()) { + // root is required to allow bindings to be pruned, especially by `--trim` + jl_temporary_root(ctx, constval); + } return mark_julia_const(ctx, constval); } if (rkp.kind != PARTITION_KIND_GLOBAL) { diff --git a/test/trimming/trimmability.jl b/test/trimming/trimmability.jl index 209a27343d18d..0fd9eedc6999d 100644 --- a/test/trimming/trimmability.jl +++ b/test/trimming/trimmability.jl @@ -19,6 +19,13 @@ area(c::Circle) = pi*c.radius^2 sum_areas(v::Vector{Shape}) = sum(area, v) +mutable struct Foo; x::Int; end +const storage = Foo[] +function add_one(x::Cint)::Cint + push!(storage, Foo(x)) + return x + 1 +end + function @main(args::Vector{String})::Cint println(Core.stdout, str()) println(Core.stdout, PROGRAM_FILE) @@ -38,6 +45,12 @@ function @main(args::Vector{String})::Cint d = mapreduce(x -> x^2, +, sorted_arr) # e = reduce(xor, rand(Int, 10)) + for i = 1:10 + # https://github.com/JuliaLang/julia/issues/60846 + add_one(Cint(i)) + GC.gc() + end + try sock = connect("localhost", 4900) if isopen(sock)