From e84634e3b2c7354a4ac99024ed839d3e720a40cb Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Thu, 15 Dec 2022 03:39:58 -0600 Subject: [PATCH] Reduce invalidations when loading JuliaData packages (#47889) --- base/Base.jl | 1 + base/array.jl | 7 ++++--- base/loading.jl | 3 ++- base/logging.jl | 4 ++-- base/reinterpretarray.jl | 16 +++++++--------- base/show.jl | 13 +++++++++---- base/strings/util.jl | 2 +- 7 files changed, 26 insertions(+), 20 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 0c53a8bc9124b..07b0a2f0f0d49 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -168,6 +168,7 @@ include("idset.jl") include("iterators.jl") using .Iterators: zip, enumerate, only using .Iterators: Flatten, Filter, product # for generators +using .Iterators: Stateful # compat (was formerly used in reinterpretarray.jl) include("namedtuple.jl") diff --git a/base/array.jl b/base/array.jl index 64d0ac05fd507..5257caabf2d45 100644 --- a/base/array.jl +++ b/base/array.jl @@ -2730,7 +2730,8 @@ keepat!(a::Vector, m::AbstractVector{Bool}) = _keepat!(a, m) # set-like operators for vectors # These are moderately efficient, preserve order, and remove dupes. -_unique_filter!(pred, update!, state) = function (x) +_unique_filter!(pred::P, update!::U, state) where {P,U} = function (x) + # P, U force specialization if pred(x, state) update!(state, x) true @@ -2756,7 +2757,7 @@ union!(v::AbstractVector{T}, itrs...) where {T} = symdiff!(v::AbstractVector{T}, itrs...) where {T} = _grow!(_shrink_filter!(symdiff!(Set{T}(), v, itrs...)), v, itrs) -function _shrink!(shrinker!, v::AbstractVector, itrs) +function _shrink!(shrinker!::F, v::AbstractVector, itrs) where F seen = Set{eltype(v)}() filter!(_grow_filter!(seen), v) shrinker!(seen, itrs...) @@ -2768,7 +2769,7 @@ setdiff!( v::AbstractVector, itrs...) = _shrink!(setdiff!, v, itrs) vectorfilter(T::Type, f, v) = T[x for x in v if f(x)] -function _shrink(shrinker!, itr, itrs) +function _shrink(shrinker!::F, itr, itrs) where F T = promote_eltype(itr, itrs...) keep = shrinker!(Set{T}(itr), itrs...) vectorfilter(T, _shrink_filter!(keep), itr) diff --git a/base/loading.jl b/base/loading.jl index ea350ff72d960..7c71167a8c176 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -809,7 +809,8 @@ function explicit_manifest_uuid_path(project_file::String, pkg::PkgId)::Union{No end end # Extensions - for (name, entries::Vector{Any}) in d + for (name, entries) in d + entries = entries::Vector{Any} for entry in entries uuid = get(entry, "uuid", nothing)::Union{Nothing, String} extensions = get(entry, "extensions", nothing)::Union{Nothing, Dict{String, Any}} diff --git a/base/logging.jl b/base/logging.jl index d7dc45122e063..c670d658cdaeb 100644 --- a/base/logging.jl +++ b/base/logging.jl @@ -378,14 +378,14 @@ function logmsg_code(_module, file, line, level, message, exs...) id = $(log_data._id) # Second chance at an early bail-out (before computing the message), # based on arbitrary logger-specific logic. - if _invoked_shouldlog(logger, level, _module, group, id) + if invokelatest(shouldlog, logger, level, _module, group, id) file = $(log_data._file) if file isa String file = Base.fixup_stdlib_path(file) end line = $(log_data._line) local msg, kwargs - $(logrecord) && handle_message( + $(logrecord) && invokelatest(handle_message, logger, level, msg, _module, group, id, file, line; kwargs...) end diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index f198761a09500..1fe0788a1739a 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -722,25 +722,23 @@ function CyclePadding(T::DataType) CyclePadding(pad, as) end -using .Iterators: Stateful @assume_effects :total function array_subpadding(S, T) - checked_size = 0 lcm_size = lcm(sizeof(S), sizeof(T)) - s, t = Stateful{<:Any, Any}(CyclePadding(S)), - Stateful{<:Any, Any}(CyclePadding(T)) + s, t = CyclePadding(S), CyclePadding(T) isempty(t) && return true isempty(s) && return false + checked_size = 0 + ps, sstate = iterate(s) # use of Stateful harms inference and makes this vulnerable to invalidation + pad, tstate = iterate(t) while checked_size < lcm_size - # Take padding in T - pad = popfirst!(t) - # See if there's corresponding padding in S while true - ps = peek(s) + # See if there's corresponding padding in S ps.offset > pad.offset && return false intersect(ps, pad) == pad && break - popfirst!(s) + ps, sstate = iterate(s, sstate) end checked_size = pad.offset + pad.size + pad, tstate = iterate(t, tstate) end return true end diff --git a/base/show.jl b/base/show.jl index 9e6b959f24fad..c7dbb4a46e18e 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1881,8 +1881,12 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In # . print(io, '.') # item - parens = !(field isa Symbol) || (field::Symbol in quoted_syms) - quoted = parens || isoperator(field) + if isa(field, Symbol) + parens = field in quoted_syms + quoted = parens || isoperator(field) + else + parens = quoted = true + end quoted && print(io, ':') parens && print(io, '(') show_unquoted(io, field, indent, 0, quote_level) @@ -2006,10 +2010,11 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int, quote_level::In # binary operator (i.e. "x + y") elseif func_prec > 0 # is a binary operator + func = func::Symbol # operator_precedence returns func_prec == 0 for non-Symbol na = length(func_args) - if (na == 2 || (na > 2 && isa(func, Symbol) && func in (:+, :++, :*)) || (na == 3 && func === :(:))) && + if (na == 2 || (na > 2 && func in (:+, :++, :*)) || (na == 3 && func === :(:))) && all(a -> !isa(a, Expr) || a.head !== :..., func_args) - sep = func === :(:) ? "$func" : " " * convert(String, string(func))::String * " " # if func::Any, avoid string interpolation (invalidation) + sep = func === :(:) ? "$func" : " $func " if func_prec <= prec show_enclosed_list(io, '(', func_args, sep, ')', indent, func_prec, quote_level, true) diff --git a/base/strings/util.jl b/base/strings/util.jl index 7d48fee9b1c52..dabb84ae65639 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -830,7 +830,7 @@ julia> hex2bytes(a) """ function hex2bytes end -hex2bytes(s) = hex2bytes!(Vector{UInt8}(undef, length(s) >> 1), s) +hex2bytes(s) = hex2bytes!(Vector{UInt8}(undef, length(s)::Int >> 1), s) # special case - valid bytes are checked in the generic implementation function hex2bytes!(dest::AbstractArray{UInt8}, s::String)