-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow external absint to hold custom data in codeinst.inferred
#53300
Conversation
Does #53219 resolve this? It removes the need to handle code-instances in this location. #52964 does require that |
In JuliaDebug/Cthulhu.jl#540 I continued using the external code cache instead of using the internal code cache (but the external code cache no longer participates in invalidation logic) |
Probably. I'm looking into it.
Cthulhu has traditionally created a new cache for each instance of |
0ec75bb
to
e52761e
Compare
I think it's fine to have non-CodeInfo objects in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting on resolution of #53219, since that already addresses the .inferred
field issue here, and then this will need to be rebased
Yeah I'll work on the PR first and then we only need the test cases from this PR. |
I know it might sound like I'm flip-flopping, but I want to move forward with this PR as is. This is because, as things stand post-#52233, virtually all external abstract interpreters utilizing the external code cache with custom data are rendered inoperative on assertion builds. Given that the code in question will be eliminated by #53219 anyway in the future, I think this PR doesn't make any harm and merging this for now alone can be justified with the added test cases. |
Leverages JuliaLang/julia#52233 to use the internal code cache that comes with the inherent invalidation support. Still requires: - JuliaLang/julia#53300 (or JuliaLang/julia#53219) - JuliaLang/julia#53318
Leverages JuliaLang/julia#52233 to use the internal code cache that comes with the inherent invalidation support. Still requires: - JuliaLang/julia#53300 (or JuliaLang/julia#53219) - JuliaLang/julia#53318
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are currently more places that make assumptions about the content of this field.
If the relocatability flag on the codeinstance is 0x0 we do not safe it as part of a package image. This is determined here
julia/base/compiler/typeinfer.jl
Lines 314 to 328 in 288912a
relocatability = 0x0 | |
if const_flags == 0x3 && may_discard_trees(interp) | |
inferred_result = nothing | |
relocatability = 0x1 | |
else | |
inferred_result = transform_result_for_cache(interp, result.linfo, valid_worlds, result) | |
if isa(inferred_result, String) | |
t = @_gc_preserve_begin inferred_result | |
relocatability = unsafe_load(unsafe_convert(Ptr{UInt8}, inferred_result), Core.sizeof(inferred_result)) | |
@_gc_preserve_end t | |
elseif inferred_result === nothing | |
relocatability = 0x1 | |
end | |
end | |
# relocatability = isa(inferred_result, String) ? inferred_result[end] : UInt8(0) |
and checked here
Line 233 in a7b68cf
if (!ci->relocatability) |
Even if I force relocatability to 0x1 we hit an assertion later
Line 993 in a7b68cf
assert(jl_is_string(data)); |
Line 189 in a7b68cf
jl_ir_flag_inferred(inferred) && |
While we could thread everything through this does raise the question that we store inferred normally in a compressed format, using jl_compress_ir which of course doesn't know how to handle custom results.
For me this indicates that using analysis_results
over additional data in inferred should be preferred. Or we need to figure out how to compress custom data.
Leverages JuliaLang/julia#52233 to use the internal code cache that comes with the inherent invalidation support. Still requires: - JuliaLang/julia#53300 (or JuliaLang/julia#53219) - JuliaLang/julia#53318
Leverages JuliaLang/julia#52233 to use the internal code cache that comes with the inherent invalidation support. Still requires: - JuliaLang/julia#53300 (or JuliaLang/julia#53219) - JuliaLang/julia#53318
5bd972a
to
31bebd3
Compare
It has been possible for external abstract interpreters to keep custom data in `codeinst.inferred` (together /w overloading `inlining_policy`). After #52233, when such external absint uses `InternalCodeCache`, this data is passed to `jl_ir_flag_inferred`, leading to segfaults in assertion builds. This commit resolves the issue by omitting `jl_ir_flag_inferred` checks when the `cache_owner` is external. Nonetheless, a better resolution might be necessary. It suggests that the current design of `code_owner` and `InternalCodeCache` for the external cache system is somewhat flawed. A conceivable approach could involve: - Adding a layer similar to `inlining_policy` in `CC.get(::WorldView{InternalCodeCache})` to enable safe redirection of custom data to the native interpreter's implementation. - Prohibiting custom data in the `inferred` field and directing such data to be kept in `analysis_results`.
31bebd3
to
610f27a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still not a big fan of using .inferred
for these purposes,
but I am okay with this change to unblock current uses of AbstractInterpreter.
@aviatesk do you want to add an explicit serialization test, where you override relocatability
?
Yeah, since |
To address Valentin's comment: it looks like this doesn't really express an opinion specifically on whether it is acceptable to use this field, but simply attempts to address the possibility of a missing type assert, which would be valid to check there regardless of whether we later state that other content should be put here Thinking more broadly, I wonder if we should restructure this layering of types to instead look like this, so that there is a more bright line distinction in the types what is volatile and what is constant: struct MethodInstance #= mostly unchanged =# end
mutable struct CodeCache # renamed from CodeInstance to indicate this is volatile
parent::MethodInstance # for show reflection
#= most fields from existing CodeInstance =#
...
@atomic inferred::Union{CodeInfo, CompressedCodeInfo}
end
struct CodeInfo # partially kept as-is, but extended to allow external stmt representations
#= fields from existing CodeInstance that are properties of the whole function =#
...
parent::MethodInstance # for show reflection
stmts::Union{StmtInfo, OpaqueExternalObjects, Nothing} # custom info goes here
end
struct StmtInfo # split from CodeInfo
#= fields from existing CodeInstance that are arrays of per stmt info =#
...
end |
) It has been possible for external abstract interpreters to keep custom data in `codeinst.inferred` (together /w overloading `inlining_policy`). After #52233, when such external absint uses `InternalCodeCache`, this data is passed to `jl_ir_flag_inferred`, leading to segfaults in assertion builds. This commit resolves the issue by omitting `jl_ir_flag_inferred` checks when the `cache_owner` is external. Nonetheless, a better resolution might be necessary. It suggests that the current design of `code_owner` and `InternalCodeCache` for the external cache system is somewhat flawed. A conceivable approach could involve: - Adding a layer similar to `inlining_policy` in `CC.get(::WorldView{InternalCodeCache})` to enable safe redirection of custom data to the native interpreter's implementation. - Prohibiting custom data in the `inferred` field and directing such data to be kept in `analysis_results`. (cherry picked from commit 93876c9)
While experimenting with precompilation for external absints on builds just after #53300 was merged, I found that the test case for `CustomAbstractInterpreterCaching2.jl` fails if the test case for `CustomAbstractInterpreterCaching1.jl` isn't run in the same session beforehand. That is probably because of the previous lack of support for proper `CodeInstance` caching. To address this, I've changed the tests to run in separate processes in this commit. Note that it appears that a recent refactor concerning `CodeInstance` might have resolved this issue, so the new test cases runs successfully on master. However, I suspect the fix hasn't been applied to v1.11 yet, we would need more research.
While experimenting with precompilation for external absints on builds just after #53300 was merged, I found that the test case for `CustomAbstractInterpreterCaching2.jl` fails if the test case for `CustomAbstractInterpreterCaching1.jl` isn't run in the same session beforehand. That is probably because of the previous lack of support for proper `CodeInstance` caching. To address this, I've changed the tests to run in separate processes in this commit. Note that it appears that a recent refactor concerning `CodeInstance` might have resolved this issue, so the new test cases runs successfully on master. However, I suspect the fix hasn't been applied to v1.11 yet, we would need more research.
While experimenting with precompilation for external absints on builds just after #53300 was merged, I found that the test case for `CustomAbstractInterpreterCaching2.jl` fails if the test case for `CustomAbstractInterpreterCaching1.jl` isn't run in the same session beforehand. That is probably because of the previous lack of support for proper `CodeInstance` caching. To address this, I've changed the tests to run in separate processes in this commit. Note that it appears that a recent refactor concerning `CodeInstance` might have resolved this issue, so the new test cases runs successfully on master. However, I suspect the fix hasn't been applied to v1.11 yet, we would need more research.
As mentioned in #53478, the precompilation support for external abstract interpreters in v1.11 isn't perfect, and directly cherry-picking the refined test cases from #53478 into the v1.11 backport branch leads to a test failure (note that this particular problem has likely been fixed in the master branch, probably thanks to #53300). To address this, this commit does more than just cherry-pick the test case, and it also modifies the `CodeInstance(::AbstractInterpreter, ::InferenceResult)` constructor to allow precompilation for external abstract interpreters in v1.11.
Backported PRs: - [x] #53361 <!-- 🤖 [master] Bump the SparseArrays stdlib from c9f7293 to cb602d7 --> - [x] #53300 <!-- allow external absint to hold custom data in `codeinst.inferred` --> - [x] #53342 <!-- Add `Base.wrap` to docs --> - [x] #53372 <!-- Silence warnings in `test/file.jl` --> - [x] #53357 <!-- 🤖 [master] Bump the Pkg stdlib from 6dd0e7c9e to 76070d295 --> - [x] #53373 <!-- fix sysimage-native-code=no option with pkgimages --> - [x] #53333 <!-- More consistent return value for annotations, take 2 --> - [x] #53354 <!-- fix code coverage bug in tail position and `else` --> - [x] #53407 <!-- fix sysimage-native-code=yes option --> - [x] #53388 <!-- Fix documentation: thread pool of main thread --> - [x] #53355 <!-- Fix synchronization issues on the GC scheduler. --> - [x] #53429 <!-- Subtype: skip slow-path in `local_∀_∃_subtype` if inputs contain no ∃ typevar. --> - [x] #53437 <!-- Add debug variant of loader_trampolines.o --> - [x] #53284 <!-- Add annotate! method for AnnotatedIOBuffer --> - [x] #53466 <!-- [MozillaCACerts_jll] Update to v2023-12-12 --> - [x] #53467 <!-- [LibGit2_jll] Update to v1.7.2 --> - [x] #53326 <!-- RFC: when loading code for internal purposes, load stdlib files directly, bypassing DEPOT_PATH, LOAD_PATH, and stale checks --> - [x] #53332 - [x] #53320 <!-- Add `Sys.isreadable, Sys.iswriteable`, update `ispath` --> - [x] #53476 Contains multiple commits, manual intervention needed: - [ ] #53285 <!-- Add update mechanism for Terminfo, and common user-alias data --> Non-merged PRs with backport label: - [ ] #53424 <!-- yet more atomics & cache-line fixes on work-stealing queue --> - [ ] #53408 <!-- task splitting: change additive accumulation to multiplicative --> - [ ] #53403 <!-- Move parallel precompilation to Base --> - [ ] #53402 <!-- Add `jl_getaffinity` and `jl_setaffinity` --> - [ ] #53391 <!-- Default to the medium code model in x86 linux --> - [ ] #53125 <!-- coverage: count coverage where explicitly requested by inference only --> - [ ] #52694 <!-- Reinstate similar for AbstractQ for backward compatibility -->
…iaLang#53300) It has been possible for external abstract interpreters to keep custom data in `codeinst.inferred` (together /w overloading `inlining_policy`). After JuliaLang#52233, when such external absint uses `InternalCodeCache`, this data is passed to `jl_ir_flag_inferred`, leading to segfaults in assertion builds. This commit resolves the issue by omitting `jl_ir_flag_inferred` checks when the `cache_owner` is external. Nonetheless, a better resolution might be necessary. It suggests that the current design of `code_owner` and `InternalCodeCache` for the external cache system is somewhat flawed. A conceivable approach could involve: - Adding a layer similar to `inlining_policy` in `CC.get(::WorldView{InternalCodeCache})` to enable safe redirection of custom data to the native interpreter's implementation. - Prohibiting custom data in the `inferred` field and directing such data to be kept in `analysis_results`.
While experimenting with precompilation for external absints on builds just after #53300 was merged, I found that the test case for `CustomAbstractInterpreterCaching2.jl` fails if the test case for `CustomAbstractInterpreterCaching1.jl` isn't run in the same session beforehand. That is probably because of the previous lack of support for proper `CodeInstance` caching. To address this, I've changed the tests to run in separate processes in this commit. Note that it appears that a recent refactor concerning `CodeInstance` might have resolved this issue, so the new test cases runs successfully on master. However, I suspect the fix hasn't been applied to v1.11 yet, we would need more research.
As mentioned in #53478, the precompilation support for external abstract interpreters in v1.11 isn't perfect, and directly cherry-picking the refined test cases from #53478 into the v1.11 backport branch leads to a test failure (note that this particular problem has likely been fixed in the master branch, probably thanks to #53300). To address this, this commit does more than just cherry-pick the test case, and it also modifies the `CodeInstance(::AbstractInterpreter, ::InferenceResult)` constructor to allow precompilation for external abstract interpreters in v1.11.
) While experimenting with precompilation for external absints on builds just after #53300 was merged, I found that the test case for `CustomAbstractInterpreterCaching2.jl` fails if the test case for `CustomAbstractInterpreterCaching1.jl` isn't run in the same session beforehand. That is probably because of the previous lack of support for proper `CodeInstance` caching. To address this, I've changed the tests to run in separate processes in this commit. Note that it appears that a recent refactor concerning `CodeInstance` might have resolved this issue, so the new test cases runs successfully on master. However, I suspect the fix hasn't been applied to v1.11 yet, we would need more research.
It has been possible for external abstract interpreters to keep custom data in
codeinst.inferred
(together /w overloadinginlining_policy
). After #52233, when such external absint usesInternalCodeCache
, this data is passed tojl_ir_flag_inferred
, leading to segfaults in assertion builds.This commit resolves the issue by omitting
jl_ir_flag_inferred
checks when thecache_owner
is external. Nonetheless, a better resolution might be necessary. It suggests that the current design ofcode_owner
andInternalCodeCache
for the external cache system is somewhat flawed. A conceivable approach could involve:inlining_policy
inCC.get(::WorldView{InternalCodeCache})
to enable safe redirection of custom data to the native interpreter's implementation.inferred
field and directing such data to be kept inanalysis_results
.