Don't re-infer compiled CodeInstance from external images - #61479
Merged
Conversation
vtjnash
reviewed
Apr 2, 2026
xal-0
force-pushed
the
precompile-external-linkage
branch
from
April 10, 2026 18:10
7288214 to
b3736c0
Compare
vtjnash
reviewed
Jun 25, 2026
| } | ||
|
|
||
| // Check the global cache for an equivalent CodeInstance with a world age range | ||
| // containing the world age range of the given CodeInstance. |
Member
There was a problem hiding this comment.
IIUC, this function also is supposed to check for the JL_CI_FLAGS_FROM_IMAGE marker. Not required (and generally the cache structure will be expected to surface it first anyways), but defensive?
vtjnash
approved these changes
Jun 25, 2026
998cb27 introduced a regression that, when invoking a CodeInstance from an external image, would result in the generation of a tojlinvoke trampoline for every invoke but the first (in the order `compile!` infers them). ```julia module P2 function what(x) try show(x) catch e rethrow() end end what(1) # calls julia_rethrow_88_gfthunk what(:a) # calls julia_rethrow_88_gfthunk what('a') # calls jlpkg_rethrow_0 end # module P2 ``` After inferring the first use of `rethrow` in this example, `compile!` would find no source for the CodeInstance and infer it again, with `source_mode=SOURCE_MODE_GET_SOURCE`. It then inserts the resulting new CodeInstance into the `code_cache`. Before 998cb27, this went into the InternalCodeCache, which would insert it after any CodeInstances with the `invoke` field set. Now, it is inserted into the OverlayCodeCache, which takes priority over the InternalCodeCache. For the two remaining specializations of `what`, this new CodeInstance is used for the invoke. Since it's a waste to re-infer this CodeInstance when we have `external_linkage`, it makes more sense to thread this through to `compile!` and skip any CodeInstances that are from the image. Thanks to @mlechu for helping track down this issue and providing the MWE.
xal-0
force-pushed
the
precompile-external-linkage
branch
from
August 31, 2026 17:30
b3736c0 to
d6a2f9c
Compare
37 tasks
KristofferC
pushed a commit
that referenced
this pull request
Sep 1, 2026
998cb27 introduced a regression that, when invoking a CodeInstance
from an external image, would result in the generation of a tojlinvoke
trampoline for every invoke but the first (in the order `compile!`
infers them).
```julia
module P2
function what(x)
try
show(x)
catch e
rethrow()
end
end
what(1) # calls julia_rethrow_88_gfthunk
what(:a) # calls julia_rethrow_88_gfthunk
what('a') # calls jlpkg_rethrow_0
end # module P2
```
After inferring the first use of `rethrow` in this example, `compile!` would
find no source for the CodeInstance and infer it again, with
`source_mode=SOURCE_MODE_GET_SOURCE`. It then inserts the resulting new
CodeInstance into the `code_cache`. Before 998cb27, this went into the
InternalCodeCache, which would insert it after any CodeInstances with the
`invoke` field set. Now, it is inserted into the OverlayCodeCache, which takes
priority over the InternalCodeCache. For the two remaining specializations of
`what`, this new CodeInstance is used for the invoke.
Since it's a waste to re-infer this CodeInstance when we have
`external_linkage`, it makes more sense to thread this through to `compile!`
and skip any CodeInstances that are from the image.
Thanks to mlechu for helping track down this issue and providing the
MWE.
(cherry picked from commit 21a70e4)
Backport note: the `src/aotcompile.cpp` hunk (`jl_get_ci_equiv_range` in
`aot_link_output`) was dropped — it depends on the `jl_codegen_output_t`
link-step refactor and `emit_pkg_plt_thunk` infrastructure that does not
exist on 1.13, where from-image `CodeInstance`s are linked externally at
codegen time in `emit_invoke` instead. The `collectinvokes!` condition was
adapted to 1.13's simpler enqueue logic.
IanButterworth
added a commit
to IanButterworth/Julia-TTFX-Snippets
that referenced
this pull request
Sep 1, 2026
…build Both dev arms are official binaries carrying the JuliaLang/julia#61479 fix: nightly 1.14.0-DEV.3081 and `juliaup add pr62959` (1.13.0-rc3.53) labelled 1.13. The 1.13 arm additionally has JuliaLang/julia#62891, so it precompiles with all 15 cores on Apple Silicon where earlier arms used 5. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VzpF8n8QdxxtrbpjgEgW6J
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


998cb27 introduced a regression that, when invoking a CodeInstance from an external image, would result in the generation of a tojlinvoke trampoline for every invoke but the first (in the order
compile!infers them).After inferring the first use of
rethrowin this example,compile!would find no source for the CodeInstance and infer it again, withsource_mode=SOURCE_MODE_GET_SOURCE. It then inserts the resulting new CodeInstance into thecode_cache. Before 998cb27, this went into the InternalCodeCache, which would insert it after any CodeInstances with theinvokefield set. Now, it is inserted into the OverlayCodeCache, which takes priority over the InternalCodeCache. For the two remaining specializations ofwhat, this new CodeInstance is used for the invoke.Since it's a waste to re-infer this CodeInstance when we have
external_linkage, it makes more sense to thread this through tocompile!and skip any CodeInstances that are from the image.Thanks to @mlechu for helping track down this issue and providing the MWE.