codegen: pin call-target CodeInstances that are not cache-reachable
The linking metadata of an emitted module holds raw pointers to its
call-target CodeInstances, and JuliaOJIT::linkCallTarget dereferences
them when the module is materialized. Compiler.add_codeinsts_to_jit!
maintains the rooting invariant by cache-inserting the CIs it compiles,
but callees with invalid ABI sparams are skipped without rooting while
the caller still records them as call targets. Upstream the pending
window is a few statements (materialization happens within the same
jl_compile_method_internal call); under tiered batching, materialization
is deferred to the compiled code's first call, so the collected CI is
dereferenced on a JIT dispatcher thread arbitrarily later. Observed at
test/core.jl's issue-#47476 tests (exactly the invalid-sparams shape) on
both macOS architectures:
https://buildkite.com/julialang/julia-pr/builds/316#019f4d6f-5f10-406d-9aff-2bdb6bc7717f
Pin such CIs as global roots at emission. TODO: scope the root to the
pending materialization instead.
This commit was written with the assistance of generative AI (Claude).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>