Skip to content
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

restrict dispatch of some custrom string macros to String #57781

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

nsajko
Copy link
Contributor

@nsajko nsajko commented Mar 15, 2025

Restricts the dispatch for these macros so that only String (literal) arguments are accepted:

  • int128_str
  • uint128_str
  • big_str
  • ip_str from the Sockets stdlib
  • dateformat_str from the Dates stdlib

Some of these changes make the code in the sysimage less vulnerable to invalidation. The big_str and ip_str changes, to be specific. The number of invalidations on running the following code is decreased from 167 to 153:

struct I <: Integer end
Base.Int(::I) = 7

As far as I understand this change can't break any existing code, because:

  • the macro definitions in question require AbstractString
  • the way Julia's macros work, the argument is either a literal or an Expr
  • String is the only AbstractString with literals

Restricts the dispatch for these macros so that only `String` (literal)
arguments are accepted:
* `int128_str`
* `uint128_str`
* `big_str`
* `ip_str` from the Sockets stdlib
* `dateformat_str` from the Dates stdlib

Some of these changes make the code in the sysimage less vulnerable to
invalidation. The `big_str` and `ip_str` changes, to be specific. The
number of invalidations on running the following code is decreased from
167 to 153:

```julia
struct I <: Integer end
Base.Int(::I) = 7
```

As far as I understand this change can't break any existing code,
because:
* the macro definitions in question require `AbstractString`
* the way Julia's macros work, the argument is either a literal or an
  `Expr`
* `String` is the only `AbstractString` with literals
@nsajko nsajko added backport 1.10 Change should be backported to the 1.10 release backport 1.11 Change should be backported to release-1.11 invalidations backport 1.12 Change should be backported to release-1.12 labels Mar 15, 2025
@nsajko
Copy link
Contributor Author

nsajko commented Mar 15, 2025

fixed invalidations
{
    "type": "Tuple{Type{Int64}, Integer}",
    "tree": {
        "method_instance": {
            "method": "SubString(s::AbstractString, i::Integer, j::Integer) @ Base strings/substring.jl:51",
            "method_instance": "MethodInstance for SubString(::AbstractString, ::Int64, ::Integer)"
        },
        "children": [   
        ]
    }
}
{
    "type": "Tuple{Type{Int64}, Integer}",
    "tree": {
        "method_instance": {
            "method": "SubString(s::AbstractString, i::Integer, j::Integer) @ Base strings/substring.jl:51",
            "method_instance": "MethodInstance for SubString(::AbstractString, ::Int64, ::Integer)"
        },
        "children": [   
            {
                "method_instance": {
                    "method": "var\"@big_str\"(__source__::LineNumberNode, __module__::Module, s) @ Base int.jl:698",
                    "method_instance": "MethodInstance for Core.var\"@big_str\"(::LineNumberNode, ::Module, ::Any)"
                },              
                "children": [
                ]  
            }
        ]
    }
}
{
    "type": "Tuple{Type{Int64}, Integer}",
    "tree": {
        "method_instance": {
            "method": "SubString(s::AbstractString, i::Integer, j::Integer) @ Base strings/substring.jl:51",
            "method_instance": "MethodInstance for SubString(::AbstractString, ::Integer, ::Int64)"
        },
        "children": [
            {
                "method_instance": {
                    "method": "SubString(s::AbstractString, i::Integer) @ Base strings/substring.jl:51",
                    "method_instance": "MethodInstance for SubString(::AbstractString, ::Integer)"
                },
                "children": [
                    {
                        "method_instance": {
                            "method": "iterate(iter::Base.SplitIterator, ::Any) @ Base strings/util.jl:730",
                            "method_instance": "MethodInstance for iterate(::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:AbstractString, ::Tuple{Any, Int64, Int64})"
                        },
                        "children": [
                            {
                                "method_instance": {
                                    "method": "_collect(cont, itr, ::Base.HasEltype, isz::Base.SizeUnknown) @ Base array.jl:737",
                                    "method_instance": "MethodInstance for Base._collect(::UnitRange{Int64}, ::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:AbstractString, ::Base.HasEltype, ::Base.SizeUnknown)"
                                },
                                "children": [
                                    {
                                        "method_instance": {
                                            "method": "collect(itr) @ Base array.jl:728",
                                            "method_instance": "MethodInstance for collect(::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:AbstractString)"
                                        },
                                        "children": [
                                            {
                                                "method_instance": {
                                                    "method": "var\"#split#434\"(limit::Integer, keepempty::Bool, ::typeof(split), str::T, splitter) where T<:AbstractString @ Base strings/util.jl:897",
                                                    "method_instance": "MethodInstance for Base.var\"#split#434\"(::Int64, ::Bool, ::typeof(split), ::AbstractString, ::Char)"
                                                },
                                                "children": [
                                                    {
                                                        "method_instance": {
                                                            "method": "split(str::T, splitter; limit, keepempty) where T<:AbstractString @ Base strings/util.jl:897",
                                                            "method_instance": "MethodInstance for split(::AbstractString, ::Char)"
                                                        },
                                                        "children": [
                                                            {
                                                                "method_instance": {
                                                                    "method": "parse(::Type{Sockets.IPv4}, str::AbstractString) @ Sockets ~/tmp/jl/julia-git/invalidations_build/usr/share/julia/stdlib/v1.13/Sockets/src/IPAddr.jl:196",
                                                                    "method_instance": "MethodInstance for parse(::Type{Sockets.IPv4}, ::AbstractString)"
                                                                },
                                                                "children": [
                                                                    {
                                                                        "method_instance": {
                                                                            "method": "parse(::Type{Sockets.IPAddr}, str::AbstractString) @ Sockets ~/tmp/jl/julia-git/invalidations_build/usr/share/julia/stdlib/v1.13/Sockets/src/IPAddr.jl:267",
                                                                            "method_instance": "MethodInstance for parse(::Type{Sockets.IPAddr}, ::AbstractString)"
                                                                        },
                                                                        "children": [
                                                                        ]
                                                                    }
                                                                ]
                                                            },
                                                            {
                                                                "method_instance": {
                                                                    "method": "parse(::Type{Sockets.IPv6}, str::AbstractString) @ Sockets ~/tmp/jl/julia-git/invalidations_build/usr/share/julia/stdlib/v1.13/Sockets/src/IPAddr.jl:247",
                                                                    "method_instance": "MethodInstance for parse(::Type{Sockets.IPv6}, ::AbstractString)"
                                                                },
                                                                "children": [
                                                                    {
                                                                        "method_instance": {
                                                                            "method": "parse(::Type{Sockets.IPAddr}, str::AbstractString) @ Sockets ~/tmp/jl/julia-git/invalidations_build/usr/share/julia/stdlib/v1.13/Sockets/src/IPAddr.jl:267",
                                                                            "method_instance": "MethodInstance for parse(::Type{Sockets.IPAddr}, ::AbstractString)"
                                                                        },
                                                                        "children": [
                                                                            {
                                                                                "method_instance": {
                                                                                    "method": "var\"@ip_str\"(__source__::LineNumberNode, __module__::Module, str) @ Sockets ~/tmp/jl/julia-git/invalidations_build/usr/share/julia/stdlib/v1.13/Sockets/src/IPAddr.jl:289",
                                                                                    "method_instance": "MethodInstance for var\"@ip_str\"(::LineNumberNode, ::Module, ::Any)"
                                                                                },
                                                                                "children": [
                                                                                ]
                                                                            }
                                                                        ]
                                                                    }
                                                                ]
                                                            }
                                                        ]
                                                    }
                                                ]
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            },
            {
                "method_instance": {
                    "method": "iterate(iter::Base.SplitIterator, ::Any) @ Base strings/util.jl:730",
                    "method_instance": "MethodInstance for iterate(::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:AbstractString, ::Tuple{Any, Int64, Int64})"
                },
                "children": [
                ]
            }
        ]
    }
}
{
    "type": "Tuple{Type{Int64}, Integer}",
    "tree": {
        "method_instance": {
            "method": "SubString(s::AbstractString, i::Integer, j::Integer) @ Base strings/substring.jl:51",
            "method_instance": "MethodInstance for SubString(::AbstractString, ::Integer, ::Integer)"
        },
        "children": [
            {
                "method_instance": {
                    "method": "SubString(s::AbstractString, r::AbstractUnitRange{<:Integer}) @ Base strings/substring.jl:52",
                    "method_instance": "MethodInstance for SubString(::AbstractString, ::AbstractUnitRange{<:Integer})"
                },
                "children": [
                    {
                        "method_instance": {
                            "method": "iterate(iter::Base.SplitIterator, ::Any) @ Base strings/util.jl:730",
                            "method_instance": "MethodInstance for iterate(::Base.SplitIterator{S, Base.Fix2{typeof(isequal), Char}} where S<:AbstractString, ::Tuple{Any, Int64, Int64})"
                        },
                        "children": [
                        ]
                    }
                ]
            }
        ]
    }
}
{
    "type": "Tuple{Type{Int64}, Integer}",
    "tree": {
        "method_instance": {
            "method": "var\"#IOBuffer#387\"(read::Union{Nothing, Bool}, write::Union{Nothing, Bool}, append::Union{Nothing, Bool}, truncate::Union{Nothing, Bool}, maxsize::Integer, sizehint::Union{Nothing, Integer}, ::Type{IOBuffer}, data::AbstractVector{UInt8}) @ Base iobuffer.jl:106",
            "method_instance": "MethodInstance for Base.var\"#IOBuffer#387\"(::Bool, ::Bool, ::Bool, ::Bool, ::Integer, ::Nothing, ::Type{IOBuffer}, ::Memory{UInt8})"
        },
        "children": [   
            {
                "method_instance": {
                    "method": "kwcall(::NamedTuple, ::Type{IOBuffer}, data::AbstractVector{UInt8}) @ Base iobuffer.jl:106",
                    "method_instance": "MethodInstance for Core.kwcall(::NamedTuple{(:read, :write, :append, :truncate, :maxsize), <:Tuple{Bool, Bool, Bool, Bool, Integer}}, ::Type{IOBuffer}, ::Memory{UInt8})"
                },
                "children": [   
                    {
                        "method_instance": {
                            "method": "var\"#IOBuffer#388\"(read::Union{Nothing, Bool}, write::Union{Nothing, Bool}, append::Union{Nothing, Bool}, truncate::Union{Nothing, Bool}, maxsize::Integer, sizehint::Union{Nothing, Integer}, ::Type{IOBuffer}) @ Base iobuffer.jl:128",
                            "method_instance": "MethodInstance for Base.var\"#IOBuffer#388\"(::Bool, ::Bool, ::Nothing, ::Bool, ::Integer, ::Nothing, ::Type{IOBuffer})"
                        },
                        "children": [
                            {           
                                "method_instance": {
                                    "method": "kwcall(::NamedTuple, ::Type{IOBuffer}) @ Base iobuffer.jl:128",
                                    "method_instance": "MethodInstance for Core.kwcall(::NamedTuple{(:maxsize,), <:Tuple{Any}}, ::Type{IOBuffer})"
                                },
                                "children": [
                                    {           
                                        "method_instance": {
                                            "method": "var\"@big_str\"(__source__::LineNumberNode, __module__::Module, s) @ Base int.jl:698",
                                            "method_instance": "MethodInstance for Core.var\"@big_str\"(::LineNumberNode, ::Module, ::Any)" 
                                        },
                                        "children": [
                                        ]   
                                    }
                                ]         
                            }                   
                        ]
                    }
                ]                   
            }
        ]
    }
}
{
    "type": "Tuple{Type{Int64}, Integer}",
    "tree": {
        "method_instance": {
            "method": "var\"#IOBuffer#388\"(read::Union{Nothing, Bool}, write::Union{Nothing, Bool}, append::Union{Nothing, Bool}, truncate::Union{Nothing, Bool}, maxsize::Integer, sizehint::Union{Nothing, Integer}, ::Type{IOBuffer}) @ Base iobuffer.jl:128",
            "method_instance": "MethodInstance for Base.var\"#IOBuffer#388\"(::Bool, ::Bool, ::Nothing, ::Bool, ::Integer, ::Nothing, ::Type{IOBuffer})"
        },
        "children": [   
        ]
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport 1.10 Change should be backported to the 1.10 release backport 1.11 Change should be backported to release-1.11 backport 1.12 Change should be backported to release-1.12 invalidations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant