Skip to content

CoreLogging: prevent some Annotated*-related instability#59467

Merged
oscardssmith merged 4 commits intoJuliaLang:masterfrom
nsajko:CoreLogging-handle_message-prevent_AnnotatedString-related_type-instability_by_adding_concrete_typeasserts
Sep 19, 2025
Merged

CoreLogging: prevent some Annotated*-related instability#59467
oscardssmith merged 4 commits intoJuliaLang:masterfrom
nsajko:CoreLogging-handle_message-prevent_AnnotatedString-related_type-instability_by_adding_concrete_typeasserts

Conversation

@nsajko
Copy link
Copy Markdown
Member

@nsajko nsajko commented Sep 2, 2025

Add some concrete typeasserts to increase the resistance of the sysimage to invalidation by helping inference within the method body.

@nsajko nsajko added logging The logging framework invalidations backport 1.11 Change should be backported to release-1.11 backport 1.12 Change should be backported to release-1.12 labels Sep 2, 2025
@nsajko
Copy link
Copy Markdown
Member Author

nsajko commented Sep 2, 2025

Some of the sysimage invalidation eliminated with this PR, appearing on master on running struct S <: AbstractString end; function Base.thisind(::S, ::Int) end:

{
    "method_instance": {
        "method": "chomp(s::AbstractString) @ Base strings/util.jl:338",
        "method_instance": "MethodInstance for chomp(::AbstractString)"
    },
    "children": [
        {
            "method_instance": {
                "method": "var\"#handle_message#6\"(kwargs::Base.Pairs{Symbol, V, Nothing, NT} where {V, NT<:NamedTuple}, ::typeof(Base.CoreLogging.handle_message), logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                "method_instance": "MethodInstance for Base.CoreLogging.var\"#handle_message#6\"(::Base.Pairs{Symbol, Union{}, Nothing, @NamedTuple{}}, ::typeof(Base.CoreLogging.handle_message), ::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)"
            },
            "children": [
                {
                    "method_instance": {
                        "method": "handle_message(logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line; kwargs...) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                        "method_instance": "MethodInstance for Base.CoreLogging.handle_message(::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)"
                    },
                    "children": [
                    ]
                }
            ]
        },
        {
            "method_instance": {
                "method": "var\"#handle_message#6\"(kwargs::Base.Pairs{Symbol, V, Nothing, NT} where {V, NT<:NamedTuple}, ::typeof(Base.CoreLogging.handle_message), logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                "method_instance": "MethodInstance for Base.CoreLogging.var\"#handle_message#6\"(::Base.Pairs{Symbol, V, Nothing, NT} where {V, NT<:NamedTuple}, ::typeof(Base.CoreLogging.handle_message), ::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)"
            },
            "children": [
                {
                    "method_instance": {
                        "method": "handle_message(logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line; kwargs...) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                        "method_instance": "MethodInstance for Base.CoreLogging.handle_message(::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)"
                    },
                    "children": [
                    ]
                },
                {
                    "method_instance": {
                        "method": "kwcall(::NamedTuple, ::typeof(Base.CoreLogging.handle_message), logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                        "method_instance": "MethodInstance for Core.kwcall(::NamedTuple, ::typeof(Base.CoreLogging.handle_message), ::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)"
                    },
                    "children": [
                        {
                            "method_instance": {
                                "method": "logging_error(logger, level, _module, group, id, filepath, line, err, real::Bool) @ Base.CoreLogging logging/logging.jl:496",
                                "method_instance": "MethodInstance for Base.CoreLogging.logging_error(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Bool)"
                            },
                            "children": [
                            ]
                        }
                    ]
                },
                {
                    "method_instance": {
                        "method": "kwcall(::NamedTuple, ::typeof(Base.CoreLogging.handle_message), logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                        "method_instance": "MethodInstance for Core.kwcall(::NamedTuple{(:exception,), <:Tuple{Tuple{Any, Vector{Union{Ptr{Nothing}, Base.InterpreterIP}}}}}, ::typeof(Base.CoreLogging.handle_message), ::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::LazyString, ::Any, ::Symbol, ::Any, ::Any, ::Any)"
                    },
                    "children": [
                        {
                            "method_instance": {
                                "method": "logging_error(logger, level, _module, group, id, filepath, line, err, real::Bool) @ Base.CoreLogging logging/logging.jl:496",
                                "method_instance": "MethodInstance for Base.CoreLogging.logging_error(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Bool)"
                            },
                            "children": [
                            ]
                        }
                    ]
                },
                {
                    "method_instance": {
                        "method": "kwcall(::NamedTuple, ::typeof(Base.CoreLogging.handle_message), logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                        "method_instance": "MethodInstance for Core.kwcall(::NamedTuple{(:exception,), <:Tuple{Tuple{Any, Vector{Union{Ptr{Nothing}, Base.InterpreterIP}}}}}, ::typeof(Base.CoreLogging.handle_message), ::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::String, ::Any, ::Symbol, ::Any, ::Any, ::Any)"
                    },
                    "children": [
                        {
                            "method_instance": {
                                "method": "logging_error(logger, level, _module, group, id, filepath, line, err, real::Bool) @ Base.CoreLogging logging/logging.jl:496",
                                "method_instance": "MethodInstance for Base.CoreLogging.logging_error(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Bool)"
                            },
                            "children": [
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

Another tree of invalidations with the same reproducer:

{
    "method_instance": {
        "method": "iterate(iter::Base.SplitIterator) @ Base strings/util.jl:741",
        "method_instance": "MethodInstance for iterate(::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:SubString)"
    },
    "children": [
        {
            "method_instance": {
                "method": "_collect(cont, itr, ::Base.HasEltype, isz::Base.SizeUnknown) @ Base array.jl:743",
                "method_instance": "MethodInstance for Base._collect(::UnitRange{Int64}, ::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:SubString, ::Base.HasEltype, ::Base.SizeUnknown)"
            },
            "children": [
                {
                    "method_instance": {
                        "method": "collect(itr) @ Base array.jl:734",
                        "method_instance": "MethodInstance for collect(::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:SubString)"
                    },
                    "children": [
                        {
                            "method_instance": {
                                "method": "var\"#split#431\"(limit::Integer, keepempty::Bool, ::typeof(split), str::T, splitter) where T<:AbstractString @ Base strings/util.jl:908",
                                "method_instance": "MethodInstance for Base.var\"#split#431\"(::Int64, ::Bool, ::typeof(split), ::SubString, ::Char)"
                            },
                            "children": [
                                {
                                    "method_instance": {
                                        "method": "split(str::T, splitter; limit, keepempty) where T<:AbstractString @ Base strings/util.jl:908",
                                        "method_instance": "MethodInstance for split(::SubString, ::Char)"
                                    },
                                    "children": [
                                        {
                                            "method_instance": {
                                                "method": "var\"#handle_message#6\"(kwargs::Base.Pairs{Symbol, V, Nothing, NT} where {V, NT<:NamedTuple}, ::typeof(Base.CoreLogging.handle_message), logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                                                "method_instance": "MethodInstance for Base.CoreLogging.var\"#handle_message#6\"(::Base.Pairs{Symbol, Union{}, Nothing, @NamedTuple{}}, ::typeof(Base.CoreLogging.handle_message), ::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)"
                                            },
                                            "children": [
                                            ]
                                        },
                                        {
                                            "method_instance": {
                                                "method": "var\"#handle_message#6\"(kwargs::Base.Pairs{Symbol, V, Nothing, NT} where {V, NT<:NamedTuple}, ::typeof(Base.CoreLogging.handle_message), logger::Base.CoreLogging.ConsoleLogger, level::Base.CoreLogging.LogLevel, message, _module, group, id, filepath, line) @ Base.CoreLogging logging/ConsoleLogger.jl:110",
                                                "method_instance": "MethodInstance for Base.CoreLogging.var\"#handle_message#6\"(::Base.Pairs{Symbol, V, Nothing, NT} where {V, NT<:NamedTuple}, ::typeof(Base.CoreLogging.handle_message), ::Base.CoreLogging.ConsoleLogger, ::Base.CoreLogging.LogLevel, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any)"
                                            },
                                            "children": [
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

@nsajko nsajko marked this pull request as ready for review September 2, 2025 18:32
Add some concrete `typeassert`s to increase the resistance of the
sysimage to invalidation by helping inference within the method body.
@nsajko nsajko force-pushed the CoreLogging-handle_message-prevent_AnnotatedString-related_type-instability_by_adding_concrete_typeasserts branch from ed264f4 to 1d26139 Compare September 2, 2025 20:10
@nsajko
Copy link
Copy Markdown
Member Author

nsajko commented Sep 5, 2025

bump

@nsajko
Copy link
Copy Markdown
Member Author

nsajko commented Sep 9, 2025

ping

Co-authored-by: Cody Tapscott <84105208+topolarity@users.noreply.github.com>
Copy link
Copy Markdown
Member

@topolarity topolarity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@topolarity topolarity added the merge me PR is reviewed. Merge when all tests are passing label Sep 17, 2025
…edString-related_type-instability_by_adding_concrete_typeasserts
@oscardssmith oscardssmith merged commit bb51d56 into JuliaLang:master Sep 19, 2025
7 checks passed
@oscardssmith oscardssmith removed the merge me PR is reviewed. Merge when all tests are passing label Sep 19, 2025
@nsajko nsajko deleted the CoreLogging-handle_message-prevent_AnnotatedString-related_type-instability_by_adding_concrete_typeasserts branch September 19, 2025 13:24
This was referenced Sep 24, 2025
KristofferC pushed a commit that referenced this pull request Oct 10, 2025
Add some concrete `typeassert`s to increase the resistance of the
sysimage to invalidation by helping inference within the method body.

(cherry picked from commit bb51d56)
KristofferC pushed a commit that referenced this pull request Oct 12, 2025
Add some concrete `typeassert`s to increase the resistance of the
sysimage to invalidation by helping inference within the method body.

(cherry picked from commit bb51d56)
KristofferC pushed a commit that referenced this pull request Oct 14, 2025
Add some concrete `typeassert`s to increase the resistance of the
sysimage to invalidation by helping inference within the method body.

(cherry picked from commit bb51d56)
@KristofferC KristofferC removed the backport 1.12 Change should be backported to release-1.12 label Oct 21, 2025
DilumAluthge added a commit that referenced this pull request Nov 3, 2025
Backported PRs:
- [x] #57523 <!-- Remove usages of weak symbols -->
- [x] #58127 <!-- [DOC] Update installation docs: /downloads/ =>
/install/ -->
- [x] #58202 <!-- [release-1.11] malloc: use jl_get_current_task to fix
null check -->
- [x] #58554 <!-- remove workaround for controlling terminal behavior in
repl_cmd -->
- [x] #58584 <!-- Make `Ptr` values static-show w/ type-information -->
- [x] #59062 <!-- remove a testset from MMAP that might cause CI to now
fail on Windows -->
- [x] #59300 <!-- Update the developer docs to reflect the use of
JuliaSyntax.jl -->
- [x] #57604 <!-- `@nospecialize` for `string_index_err` -->
- [x] #59329 <!-- aotcompile: destroy LLVM context after serializing
combined module -->
- [x] #59418 <!-- Fix startup when history file is bad -->
- [x] #56890 <!-- Enable getting non-boxed LLVM type from Julia Type -->
- [x] #59559 <!-- codegen: mark write barrier field load as volatile -->
- [x] #59572 <!-- Only apply Base.Sort.SubArrayOptimization when
iszero(v.offset1) -->

Need manual backport:
- [ ] #56329 <!-- loading: clean up more concurrency issues -->
- [ ] #56956 <!-- Add "mea culpa" to foreign module assignment error.
-->
- [ ] #57035 <!-- linux: workaround to avoid deadlock inside
dl_iterate_phdr in glibc -->
- [ ] #57089 <!-- Block thread from receiving profile signal with
stackwalk lock -->
- [ ] #57249 <!-- restore non-freebsd-unix fix for profiling -->
- [ ] #58011 <!-- Remove try-finally scope from `@time_imports`
`@trace_compile` `@trace_dispatch` -->
- [ ] #58062 <!-- remove unnecessary edge from `exp_impl` to `pow` -->
- [ ] #58157 <!-- add showing a string to REPL precompile workload -->
- [ ] #58209 <!-- Specialize `one` for the `SizedArray` test helper -->
- [ ] #58356 <!-- codegen: remove readonly from abstract type calling
convention -->
- [ ] #58415 <!-- [REPL] more reliable extension loading -->
- [ ] #58510 <!-- Don't filter `Core` methods from newly-inferred list
-->
- [ ] #58110 <!-- relax dispatch for the `IteratorSize` method for
`Generator` -->
- [ ] #58965 <!-- Fix `hygienic-scope`s in inner macro expansions -->
- [ ] #58971 <!-- Fix alignment of failed precompile jobs on CI -->
- [ ] #59066 <!-- build: Also pass -fno-strict-aliasing for C++ -->
- [ ] #59428 <!-- Correctly set the variant bits of uuid1 -->

Contains multiple commits, manual intervention needed:
- [ ] #55877 <!-- fix FileWatching designs and add workaround for a stat
bug on Apple -->
- [ ] #56755 <!-- docs: fix scope type of a `struct` to hard -->
- [ ] #57809 <!-- Fix fptrunc Float64 -> Float16 rounding through
Float32 -->
- [ ] #57398 <!-- Make remaining float intrinsics require float
arguments -->
- [ ] #56351 <!-- Fix `--project=@script` when outside script directory
-->
- [ ] #57129 <!-- clarify that time_ns is monotonic -->
- [ ] #58134 <!-- Note annotated string API is experimental in Julia
1.11 in HISTORY.md -->
- [ ] #58401 <!-- check that hashing of types does not foreigncall
(`jl_type_hash` is concrete evaluated) -->
- [ ] #58435 <!-- Fix layout flags for types that have oddly sized
primitive type fields -->
- [ ] #58483 <!-- Fix tbaa usage when storing into heap allocated
immutable structs -->
- [ ] #58512 <!-- Make more types jl_static_show readably -->
- [ ] #58012 <!-- Re-enable tab completion of kwargs for large method
tables -->
- [ ] #58683 <!-- Add 0 predecessor to entry basic block and handle it
in inlining -->
- [ ] #59112 <!-- Add builtin function name to add methods error -->
- [ ] #56823 <!-- Make version of opaque closure constructor in world
-->
- [ ] #59467 <!-- `CoreLogging`: prevent some `Annotated*`-related
instability -->

Non-merged PRs with backport label:
- [ ] #59450 <!-- Propagate Addrspaces: fix lift of memset -->
- [ ] #58848 <!-- Set array size only when safe to do so -->
- [ ] #55958 <!-- also redirect JL_STDERR etc. when redirecting to
devnull -->
- [ ] #55956 <!-- Make threadcall gc safe -->
- [ ] #55534 <!-- Set stdlib sources as read-only during installation
-->
- [ ] #55499 <!-- propagate the terminal's `displaysize` to the
`IOContext` used by the REPL -->
- [ ] #55458 <!-- Allow for generically extracting unannotated string
-->
- [ ] #55457 <!-- Make AnnotateChar equality consider annotations -->
- [ ] #55220 <!-- `isfile_casesensitive` fixes on Windows -->
- [ ] #53957 <!-- tweak how filtering is done for what packages should
be precompiled -->
- [ ] #51479 <!-- prevent code loading from lookin in the versioned
environment when building Julia -->
- [ ] #50813 <!-- More doctests for Sockets and capitalization fix -->
- [ ] #50157 <!-- improve docs for `@inbounds` and
`Base.@propagate_inbounds` -->

---------

Co-authored-by: Dilum Aluthge <dilum@aluthge.com>
Co-authored-by: Sam Schweigel <sam.schweigel@juliahub.com>
Co-authored-by: Cody Tapscott <84105208+topolarity@users.noreply.github.com>
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
Co-authored-by: Adam Wheeler <adamwhlr@gmail.com>
Co-authored-by: Neven Sajko <4944410+nsajko@users.noreply.github.com>
Co-authored-by: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com>
Co-authored-by: Ian Butterworth <i.r.butterworth@gmail.com>
Co-authored-by: William Moses <gh@wsmoses.com>
Co-authored-by: Valentin Churavy <v.churavy@gmail.com>
Co-authored-by: Lilith Orion Hafner <lilithhafner@gmail.com>
@DilumAluthge DilumAluthge mentioned this pull request Jan 14, 2026
57 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport 1.11 Change should be backported to release-1.11 invalidations logging The logging framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants