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

Add invalidation barriers for displaysize and implicit_typeinfo #56159

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add invalidation barriers for displaysize and implicit_typeinfo
These are invalidated by our own stdlibs (Dates and REPL) unfortunately
so we need to put this barrier in.
  • Loading branch information
topolarity committed Oct 14, 2024
commit 05a03a50f7aac322390308686c7d1611f9776ab6
16 changes: 11 additions & 5 deletions base/arrayshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,12 @@ typeinfo_eltype(typeinfo::Type{<:AbstractArray{T}}) where {T} = eltype(typeinfo)
typeinfo_eltype(typeinfo::Type{<:AbstractDict{K,V}}) where {K,V} = eltype(typeinfo)
typeinfo_eltype(typeinfo::Type{<:AbstractSet{T}}) where {T} = eltype(typeinfo)

# This is a fancy way to make de-specialize a call to `typeinfo_implicit(T)`
# which is unfortunately invalidated by Dates
# (https://github.com/JuliaLang/julia/issues/56080)
#
# This makes the call less efficient, but avoids being invalidated by Dates.
_typeinfo_implicit(@nospecialize(T)) = Base.invoke_in_world(Base.tls_world_age(), typeinfo_implicit, T)::Bool

# types that can be parsed back accurately from their un-decorated representations
function typeinfo_implicit(@nospecialize(T))
Expand All @@ -553,9 +559,9 @@ function typeinfo_implicit(@nospecialize(T))
return true
end
return isconcretetype(T) &&
((T <: Array && typeinfo_implicit(eltype(T))) ||
((T <: Tuple || T <: NamedTuple || T <: Pair) && all(typeinfo_implicit, fieldtypes(T))) ||
(T <: AbstractDict && typeinfo_implicit(keytype(T)) && typeinfo_implicit(valtype(T))))
((T <: Array && _typeinfo_implicit(eltype(T))) ||
((T <: Tuple || T <: NamedTuple || T <: Pair) && all(_typeinfo_implicit, fieldtypes(T))) ||
(T <: AbstractDict && _typeinfo_implicit(keytype(T)) && _typeinfo_implicit(valtype(T))))
end

# X not constrained, can be any iterable (cf. show_vector)
Expand All @@ -573,7 +579,7 @@ function typeinfo_prefix(io::IO, X)
if X isa AbstractDict
if eltype_X == eltype_ctx
sprint(show_type_name, typeof(X).name; context=io), false
elseif !isempty(X) && typeinfo_implicit(keytype(X)) && typeinfo_implicit(valtype(X))
elseif !isempty(X) && _typeinfo_implicit(keytype(X)) && _typeinfo_implicit(valtype(X))
sprint(show_type_name, typeof(X).name; context=io), true
else
sprint(print, typeof(X); context=io), false
Expand All @@ -582,7 +588,7 @@ function typeinfo_prefix(io::IO, X)
# Types hard-coded here are those which are created by default for a given syntax
if eltype_X == eltype_ctx
"", false
elseif !isempty(X) && typeinfo_implicit(eltype_X)
elseif !isempty(X) && _typeinfo_implicit(eltype_X)
"", true
elseif print_without_params(eltype_X)
sprint(show_type_name, unwrap_unionall(eltype_X).name; context=io), false # Print "Array" rather than "Array{T,N}"
Expand Down
2 changes: 1 addition & 1 deletion base/logging/ConsoleLogger.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module
if !(isopen(stream)::Bool)
stream = stderr
end
dsize = displaysize(stream)::Tuple{Int,Int}
dsize = Base.displaysize_(stream)::Tuple{Int,Int}
nkwargs = length(kwargs)::Int
if nkwargs > hasmaxlog
valbuf = IOBuffer()
Expand Down
4 changes: 2 additions & 2 deletions base/precompilation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ function precompilepkgs(pkgs::Vector{String}=String[];
n_print_rows = 0
while !printloop_should_exit
lock(print_lock) do
term_size = Base.displaysize(io)::Tuple{Int,Int}
term_size = Base.displaysize_(io)
num_deps_show = max(term_size[1] - 3, 2) # show at least 2 deps
pkg_queue_show = if !interrupted_or_done.set && length(pkg_queue) > num_deps_show
last(pkg_queue, num_deps_show)
Expand All @@ -687,7 +687,7 @@ function precompilepkgs(pkgs::Vector{String}=String[];
bar.max = n_total - n_already_precomp
# when sizing to the terminal width subtract a little to give some tolerance to resizing the
# window between print cycles
termwidth = displaysize(io)[2] - 4
termwidth = Base.displaysize_(io)[2] - 4
if !final_loop
str = sprint(io -> show_progress(io, bar; termwidth, carriagereturn=false); context=io)
print(iostr, Base._truncate_at_width_or_chars(true, str, termwidth), "\n")
Expand Down
4 changes: 2 additions & 2 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ get(io::IO, key, default) = default
keys(io::IOContext) = keys(io.dict)
keys(io::IO) = keys(ImmutableDict{Symbol,Any}())

displaysize(io::IOContext) = haskey(io, :displaysize) ? io[:displaysize]::Tuple{Int,Int} : displaysize(io.io)
displaysize(io::IOContext) = haskey(io, :displaysize) ? io[:displaysize]::Tuple{Int,Int} : Base.displaysize_(io.io)

show_circular(io::IO, @nospecialize(x)) = false
function show_circular(io::IOContext, @nospecialize(x))
Expand Down Expand Up @@ -2622,7 +2622,7 @@ end
function type_limited_string_from_context(out::IO, str::String)
typelimitflag = get(out, :stacktrace_types_limited, nothing)
if typelimitflag isa RefValue{Bool}
sz = get(out, :displaysize, displaysize(out))::Tuple{Int, Int}
sz = get(out, :displaysize, Base.displaysize_(out))::Tuple{Int, Int}
str_lim = type_depth_limit(str, max(sz[2], 120))
if sizeof(str_lim) < sizeof(str)
typelimitflag[] = true
Expand Down
7 changes: 7 additions & 0 deletions base/stream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,13 @@ displaysize(io::IO) = displaysize()
displaysize() = (parse(Int, get(ENV, "LINES", "24")),
parse(Int, get(ENV, "COLUMNS", "80")))::Tuple{Int, Int}

# This is a fancy way to make de-specialize a call to `displaysize(io::IO)`
# which is unfortunately invalidated by REPL
# (https://github.com/JuliaLang/julia/issues/56080)
#
# This makes the call less efficient, but avoids being invalidated by REPL.
displaysize_(io::IO) = Base.invoke_in_world(Base.tls_world_age(), displaysize, io)::Tuple{Int,Int}

function displaysize(io::TTY)
check_open(io)

Expand Down