Skip to content

Commit 6cb5b1f

Browse files
authored
Backports for 1.11.0-rc4/1.11.0 (#55586)
Backported PRs: - [x] #55480 <!-- Fix push! for OffsetVectors, add tests for push! and append! on AbstractVector --> - [x] #55443 <!-- Add test for upper/lower/titlecase and fix call --> - [x] #55524 <!-- Set `.jl` sources as read-only during installation --> - [x] #55500 <!-- make jl_thread_suspend_and_get_state safe --> - [x] #55506 <!-- Fix indexing in _mapreducedim for OffsetArrays --> - [x] #55564 <!-- Empty out loaded_precompiles dict instead of asserting it's empty. --> - [x] #55567 <!-- Initialize threadpools correctly during sysimg build --> - [x] #55596 <!-- Fast bounds-check for CartesianIndex ranges --> - [x] #55605 <!-- Reroute Symmetric/Hermitian + Diagonal through triangular --> - [x] #55640 <!-- win: move stack_overflow_warning to the backtrace fiber --> - [x] #55715 <!-- Add precompile signatures to Markdown to reduce latency. --> - [x] #55593 <!-- Fix invalidations for FileIO --> - [x] #55555 <!-- Revert "Don't expose guard pages to malloc_stack API consumers" --> - [x] #55720 <!-- Fix `pkgdir` for extensions --> - [x] #55729 <!-- Avoid confounding compilation side effects of `@time_imports` --> - [x] #55718 <!-- Fix `@time_imports` extension recognition --> - [x] #55522 <!-- Fix tr for Symmetric/Hermitian block matrices --> Contains multiple commits, manual intervention needed: - [ ] #55509 <!-- Fix cong implementation to be properly random and not just cycling. --> Non-merged PRs with backport label: - [ ] #55641 <!-- fall back to slower stat filesize if optimized filesize fails --> - [ ] #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 --> - [ ] #55453 <!-- Privatise the annotations API, for StyledStrings --> - [ ] #55355 <!-- relocation: account for trailing path separator in depot paths --> - [ ] #55220 <!-- `isfile_casesensitive` fixes on Windows --> - [ ] #55169 <!-- `propertynames` for SVD respects private argument --> - [ ] #54457 <!-- Make `String(::Memory)` copy --> - [ ] #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` --> - [ ] #41244 <!-- Fix shell `cd` error when working dir has been deleted -->
2 parents 616e455 + 1c516dc commit 6cb5b1f

File tree

38 files changed

+387
-170
lines changed

38 files changed

+387
-170
lines changed

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,11 @@ endif
377377
cp -R -L $(JULIAHOME)/base/* $(DESTDIR)$(datarootdir)/julia/base
378378
cp -R -L $(JULIAHOME)/test/* $(DESTDIR)$(datarootdir)/julia/test
379379
cp -R -L $(build_datarootdir)/julia/* $(DESTDIR)$(datarootdir)/julia
380+
381+
# Set .jl sources as read-only to match package directories
382+
find $(DESTDIR)$(datarootdir)/julia/base -type f -name \*.jl -exec chmod 0444 '{}' \;
383+
find $(DESTDIR)$(datarootdir)/julia/test -type f -name \*.jl -exec chmod 0444 '{}' \;
384+
380385
# Copy documentation
381386
cp -R -L $(BUILDROOT)/doc/_build/html $(DESTDIR)$(docdir)/
382387
# Remove various files which should not be installed

base/Base.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ function __init__()
603603
init_active_project()
604604
append!(empty!(_sysimage_modules), keys(loaded_modules))
605605
empty!(explicit_loaded_modules)
606-
@assert isempty(loaded_precompiles)
606+
empty!(loaded_precompiles) # If we load a packageimage when building the image this might not be empty
607607
for (mod, key) in module_keys
608608
loaded_precompiles[key => module_build_id(mod)] = mod
609609
end

base/abstractarray.jl

+4-3
Original file line numberDiff line numberDiff line change
@@ -3504,24 +3504,25 @@ function push!(a::AbstractVector{T}, item) where T
35043504
itemT = item isa T ? item : convert(T, item)::T
35053505
new_length = length(a) + 1
35063506
resize!(a, new_length)
3507-
a[new_length] = itemT
3507+
a[end] = itemT
35083508
return a
35093509
end
35103510

35113511
# specialize and optimize the single argument case
35123512
function push!(a::AbstractVector{Any}, @nospecialize x)
35133513
new_length = length(a) + 1
35143514
resize!(a, new_length)
3515-
a[new_length] = x
3515+
a[end] = x
35163516
return a
35173517
end
35183518
function push!(a::AbstractVector{Any}, @nospecialize x...)
35193519
@_terminates_locally_meta
35203520
na = length(a)
35213521
nx = length(x)
35223522
resize!(a, na + nx)
3523+
e = lastindex(a) - nx
35233524
for i = 1:nx
3524-
a[na+i] = x[i]
3525+
a[e+i] = x[i]
35253526
end
35263527
return a
35273528
end

base/compiler/typelimits.jl

+1
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ end
815815
typenames[i] = Any.name
816816
simplify[i] = false
817817
types[j] = widen
818+
typenames[j] = ijname
818819
break
819820
end
820821
end

base/loading.jl

+99-46
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,8 @@ package root.
507507
To get the root directory of the package that implements the current module
508508
the form `pkgdir(@__MODULE__)` can be used.
509509
510+
If an extension module is given, the root of the parent package is returned.
511+
510512
```julia-repl
511513
julia> pkgdir(Foo)
512514
"/path/to/Foo.jl"
@@ -524,7 +526,19 @@ function pkgdir(m::Module, paths::String...)
524526
rootmodule = moduleroot(m)
525527
path = pathof(rootmodule)
526528
path === nothing && return nothing
527-
return joinpath(dirname(dirname(path)), paths...)
529+
original = path
530+
path, base = splitdir(dirname(path))
531+
if base == "src"
532+
# package source in `../src/Foo.jl`
533+
elseif base == "ext"
534+
# extension source in `../ext/FooExt.jl`
535+
elseif basename(path) == "ext"
536+
# extension source in `../ext/FooExt/FooExt.jl`
537+
path = dirname(path)
538+
else
539+
error("Unexpected path structure for module source: $original")
540+
end
541+
return joinpath(path, paths...)
528542
end
529543

530544
function get_pkgversion_from_path(path)
@@ -1152,7 +1166,7 @@ const TIMING_IMPORTS = Threads.Atomic{Int}(0)
11521166
# these return either the array of modules loaded from the path / content given
11531167
# or an Exception that describes why it couldn't be loaded
11541168
# and it reconnects the Base.Docs.META
1155-
function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{Nothing, String}, depmods::Vector{Any}, ignore_native::Union{Nothing,Bool}=nothing)
1169+
function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{Nothing, String}, depmods::Vector{Any}, ignore_native::Union{Nothing,Bool}=nothing; register::Bool=true)
11561170
if isnothing(ignore_native)
11571171
if JLOptions().code_coverage == 0 && JLOptions().malloc_log == 0
11581172
ignore_native = false
@@ -1201,23 +1215,11 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No
12011215
for M in restored
12021216
M = M::Module
12031217
if parentmodule(M) === M && PkgId(M) == pkg
1218+
register && register_root_module(M)
12041219
if timing_imports
1205-
elapsed = round((time_ns() - t_before) / 1e6, digits = 1)
1220+
elapsed_time = time_ns() - t_before
12061221
comp_time, recomp_time = cumulative_compile_time_ns() .- t_comp_before
1207-
print(lpad(elapsed, 9), " ms ")
1208-
parentid = get(EXT_PRIMED, pkg, nothing)
1209-
if parentid !== nothing
1210-
print(parentid.name, "")
1211-
end
1212-
print(pkg.name)
1213-
if comp_time > 0
1214-
printstyled(" ", Ryu.writefixed(Float64(100 * comp_time / (elapsed * 1e6)), 2), "% compilation time", color = Base.info_color())
1215-
end
1216-
if recomp_time > 0
1217-
perc = Float64(100 * recomp_time / comp_time)
1218-
printstyled(" (", perc < 1 ? "<1" : Ryu.writefixed(perc, 0), "% recompilation)", color = Base.warn_color())
1219-
end
1220-
println()
1222+
print_time_imports_report(M, elapsed_time, comp_time, recomp_time)
12211223
end
12221224
return M
12231225
end
@@ -1229,6 +1231,73 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No
12291231
end
12301232
end
12311233

1234+
# printing functions for @time_imports
1235+
# note that the time inputs are UInt64 on all platforms. Give default values here so that we don't have
1236+
# confusing UInt64 types in generate_precompile.jl
1237+
function print_time_imports_report(
1238+
mod::Module,
1239+
elapsed_time::UInt64=UInt64(1),
1240+
comp_time::UInt64=UInt64(1),
1241+
recomp_time::UInt64=UInt64(1)
1242+
)
1243+
print(lpad(round(elapsed_time / 1e6, digits=1), 9), " ms ")
1244+
ext_parent = extension_parent_name(mod)
1245+
if ext_parent !== nothing
1246+
print(ext_parent::String, "")
1247+
end
1248+
print(string(mod))
1249+
if comp_time > 0
1250+
perc = Ryu.writefixed(Float64(100 * comp_time / (elapsed_time)), 2)
1251+
printstyled(" $perc% compilation time", color = Base.info_color())
1252+
end
1253+
if recomp_time > 0
1254+
perc = Float64(100 * recomp_time / comp_time)
1255+
perc_show = perc < 1 ? "<1" : Ryu.writefixed(perc, 0)
1256+
printstyled(" ($perc_show% recompilation)", color = Base.warn_color())
1257+
end
1258+
println()
1259+
end
1260+
function print_time_imports_report_init(
1261+
mod::Module, i::Int=1,
1262+
elapsed_time::UInt64=UInt64(1),
1263+
comp_time::UInt64=UInt64(1),
1264+
recomp_time::UInt64=UInt64(1)
1265+
)
1266+
connector = i > 1 ? "" : ""
1267+
printstyled(" $connector ", color = :light_black)
1268+
print("$(round(elapsed_time / 1e6, digits=1)) ms $mod.__init__() ")
1269+
if comp_time > 0
1270+
perc = Ryu.writefixed(Float64(100 * (comp_time) / elapsed_time), 2)
1271+
printstyled("$perc% compilation time", color = Base.info_color())
1272+
end
1273+
if recomp_time > 0
1274+
perc = Float64(100 * recomp_time / comp_time)
1275+
printstyled(" ($(perc < 1 ? "<1" : Ryu.writefixed(perc, 0))% recompilation)", color = Base.warn_color())
1276+
end
1277+
println()
1278+
end
1279+
1280+
# if M is an extension, return the string name of the parent. Otherwise return nothing
1281+
function extension_parent_name(M::Module)
1282+
rootmodule = moduleroot(M)
1283+
src_path = pathof(rootmodule)
1284+
src_path === nothing && return nothing
1285+
pkgdir_parts = splitpath(src_path)
1286+
ext_pos = findlast(==("ext"), pkgdir_parts)
1287+
if ext_pos !== nothing && ext_pos >= length(pkgdir_parts) - 2
1288+
parent_package_root = joinpath(pkgdir_parts[1:ext_pos-1]...)
1289+
parent_package_project_file = locate_project_file(parent_package_root)
1290+
if parent_package_project_file isa String
1291+
d = parsed_toml(parent_package_project_file)
1292+
name = get(d, "name", nothing)
1293+
if name !== nothing
1294+
return name
1295+
end
1296+
end
1297+
end
1298+
return nothing
1299+
end
1300+
12321301
function register_restored_modules(sv::SimpleVector, pkg::PkgId, path::String)
12331302
# This function is also used by PkgCacheInspector.jl
12341303
restored = sv[1]::Vector{Any}
@@ -1265,31 +1334,18 @@ function run_module_init(mod::Module, i::Int=1)
12651334
# `i` informs ordering for the `@time_imports` report formatting
12661335
if TIMING_IMPORTS[] == 0
12671336
ccall(:jl_init_restored_module, Cvoid, (Any,), mod)
1268-
else
1269-
if isdefined(mod, :__init__)
1270-
connector = i > 1 ? "" : ""
1271-
printstyled(" $connector ", color = :light_black)
1272-
1273-
elapsedtime = time_ns()
1274-
cumulative_compile_timing(true)
1275-
compile_elapsedtimes = cumulative_compile_time_ns()
1337+
elseif isdefined(mod, :__init__)
1338+
elapsed_time = time_ns()
1339+
cumulative_compile_timing(true)
1340+
compile_elapsedtimes = cumulative_compile_time_ns()
12761341

1277-
ccall(:jl_init_restored_module, Cvoid, (Any,), mod)
1342+
ccall(:jl_init_restored_module, Cvoid, (Any,), mod)
12781343

1279-
elapsedtime = (time_ns() - elapsedtime) / 1e6
1280-
cumulative_compile_timing(false);
1281-
comp_time, recomp_time = (cumulative_compile_time_ns() .- compile_elapsedtimes) ./ 1e6
1344+
elapsed_time = time_ns() - elapsed_time
1345+
cumulative_compile_timing(false);
1346+
comp_time, recomp_time = cumulative_compile_time_ns() .- compile_elapsedtimes
12821347

1283-
print("$(round(elapsedtime, digits=1)) ms $mod.__init__() ")
1284-
if comp_time > 0
1285-
printstyled(Ryu.writefixed(Float64(100 * comp_time / elapsedtime), 2), "% compilation time", color = Base.info_color())
1286-
end
1287-
if recomp_time > 0
1288-
perc = Float64(100 * recomp_time / comp_time)
1289-
printstyled(" ($(perc < 1 ? "<1" : Ryu.writefixed(perc, 0))% recompilation)", color = Base.warn_color())
1290-
end
1291-
println()
1292-
end
1348+
print_time_imports_report_init(mod, i, elapsed_time, comp_time, recomp_time)
12931349
end
12941350
end
12951351

@@ -1403,7 +1459,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, Any}
14031459
triggers = triggers::Union{String, Vector{String}}
14041460
triggers isa String && (triggers = [triggers])
14051461
id = PkgId(uuid5(parent.uuid::UUID, ext), ext)
1406-
if id in keys(EXT_PRIMED) || haskey(Base.loaded_modules, id)
1462+
if haskey(EXT_PRIMED, id) || haskey(Base.loaded_modules, id)
14071463
continue # extension is already primed or loaded, don't add it again
14081464
end
14091465
EXT_PRIMED[id] = parent
@@ -1833,8 +1889,7 @@ function _tryrequire_from_serialized(pkg::PkgId, path::String, ocachepath::Union
18331889
depmods[i] = dep
18341890
end
18351891
# then load the file
1836-
loaded = _include_from_serialized(pkg, path, ocachepath, depmods, ignore_native)
1837-
loaded isa Module && register_root_module(loaded)
1892+
loaded = _include_from_serialized(pkg, path, ocachepath, depmods, ignore_native; register = true)
18381893
return loaded
18391894
end
18401895

@@ -1901,8 +1956,7 @@ end
19011956
if dep === nothing
19021957
try
19031958
set_pkgorigin_version_path(modkey, modpath)
1904-
dep = _include_from_serialized(modkey, modcachepath, modocachepath, modstaledeps)
1905-
dep isa Module && stalecheck && register_root_module(dep)
1959+
dep = _include_from_serialized(modkey, modcachepath, modocachepath, modstaledeps; register = stalecheck)
19061960
finally
19071961
end_loading(modkey, dep)
19081962
end
@@ -1918,9 +1972,8 @@ end
19181972
end
19191973
restored = get(loaded_precompiles, pkg => newbuild_id, nothing)
19201974
if !isa(restored, Module)
1921-
restored = _include_from_serialized(pkg, path_to_try, ocachefile, staledeps)
1975+
restored = _include_from_serialized(pkg, path_to_try, ocachefile, staledeps; register = stalecheck)
19221976
end
1923-
isa(restored, Module) && stalecheck && register_root_module(restored)
19241977
isa(restored, Module) && return restored
19251978
@debug "Deserialization checks failed while attempting to load cache from $path_to_try" exception=restored
19261979
@label check_next_path

base/multidimensional.jl

+2
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,8 @@ using .IteratorsMD
693693
end
694694
@inline checkindex(::Type{Bool}, inds::Tuple, I::CartesianIndex) =
695695
checkbounds_indices(Bool, inds, I.I)
696+
@inline checkindex(::Type{Bool}, inds::Tuple, i::AbstractRange{<:CartesianIndex}) =
697+
isempty(i) | (checkindex(Bool, inds, first(i)) & checkindex(Bool, inds, last(i)))
696698

697699
# Indexing into Array with mixtures of Integers and CartesianIndices is
698700
# extremely performance-sensitive. While the abstract fallbacks support this,

base/reducedim.jl

+3-2
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,9 @@ function _mapreducedim!(f, op, R::AbstractArray, A::AbstractArrayOrBroadcasted)
261261
# use mapreduce_impl, which is probably better tuned to achieve higher performance
262262
nslices = div(length(A), lsiz)
263263
ibase = first(LinearIndices(A))-1
264-
for i = 1:nslices
265-
@inbounds R[i] = op(R[i], mapreduce_impl(f, op, A, ibase+1, ibase+lsiz))
264+
for i in eachindex(R)
265+
r = op(@inbounds(R[i]), mapreduce_impl(f, op, A, ibase+1, ibase+lsiz))
266+
@inbounds R[i] = r
266267
ibase += lsiz
267268
end
268269
return R

base/strings/annotated.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ a vector of region–annotation tuples.
384384
In accordance with the semantics documented in [`AnnotatedString`](@ref), the
385385
order of annotations returned matches the order in which they were applied.
386386
387-
See also: `annotate!`.
387+
See also: [`annotate!`](@ref).
388388
"""
389389
annotations(s::AnnotatedString) = s.annotations
390390

base/strings/io.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,8 @@ function _join_preserve_annotations(iterator, args...)
365365
# in nature, we extract an `AnnotatedString`, otherwise we just extract
366366
# a plain `String` from `io`.
367367
if isconcretetype(et) || !isempty(io.annotations)
368-
read(seekstart(io), AnnotatedString{String})
368+
seekstart(io)
369+
read(io, AnnotatedString{String})
369370
else
370371
String(take!(io.io))
371372
end

base/strings/unicode.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module Unicode
55

66
import Base: show, ==, hash, string, Symbol, isless, length, eltype,
77
convert, isvalid, ismalformed, isoverlong, iterate,
8-
AnnotatedString, AnnotatedChar, annotated_chartransform
8+
AnnotatedString, AnnotatedChar, annotated_chartransform,
9+
annotations
910

1011
# whether codepoints are valid Unicode scalar values, i.e. 0-0xd7ff, 0xe000-0x10ffff
1112

contrib/generate_precompile.jl

+9
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ precompile(Base.__require_prelocked, (Base.PkgId, Nothing))
4141
precompile(Base._require, (Base.PkgId, Nothing))
4242
precompile(Base.indexed_iterate, (Pair{Symbol, Union{Nothing, String}}, Int))
4343
precompile(Base.indexed_iterate, (Pair{Symbol, Union{Nothing, String}}, Int, Int))
44+
precompile(Tuple{typeof(Base.Threads.atomic_add!), Base.Threads.Atomic{Int}, Int})
45+
precompile(Tuple{typeof(Base.Threads.atomic_sub!), Base.Threads.Atomic{Int}, Int})
4446
4547
# Pkg loading
4648
precompile(Tuple{typeof(Base.Filesystem.normpath), String, String, Vararg{String}})
@@ -163,6 +165,8 @@ for match = Base._methods(+, (Int, Int), -1, Base.get_world_counter())
163165
push!(Expr[], Expr(:return, false))
164166
vcat(String[], String[])
165167
k, v = (:hello => nothing)
168+
Base.print_time_imports_report(Base)
169+
Base.print_time_imports_report_init(Base)
166170
167171
# Preferences uses these
168172
get(Dict{String,Any}(), "missing", nothing)
@@ -174,6 +178,11 @@ for match = Base._methods(+, (Int, Int), -1, Base.get_world_counter())
174178
# interactive statup uses this
175179
write(IOBuffer(), "")
176180
181+
# not critical, but helps hide unrelated compilation from @time when using --trace-compile
182+
foo() = rand(2,2) * rand(2,2)
183+
@time foo()
184+
@time foo()
185+
177186
break # only actually need to do this once
178187
end
179188
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
70878dd96911d6960537dfee2a820d98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
87d2bdc6c85cbbce5302aab8ffe92fc542c9c71a396844fcc04c0416be059b00298b4816ab5e5491dbf865660a3a6152f1c245875a1ec75fb49b4c7ba0d303d8

deps/checksums/Downloads-a9d274ff6588cc5dbfa90e908ee34c2408bab84a.tar.gz/md5

-1
This file was deleted.

deps/checksums/Downloads-a9d274ff6588cc5dbfa90e908ee34c2408bab84a.tar.gz/sha512

-1
This file was deleted.

deps/checksums/Pkg-2ff691035e9b2780cbd2fcb8dd30b640d85edde2.tar.gz/md5

-1
This file was deleted.

deps/checksums/Pkg-2ff691035e9b2780cbd2fcb8dd30b640d85edde2.tar.gz/sha512

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
248ce4c4b85394431e71b6f555f82216
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
84f193d72062199f2791ba7f7c2b6eb547e1a97569ae20cbb3557bc291715dd0cf55b2e121c4829b4572929e97255fd53b9210a168a7fde36f09ae6cf76c7f40

0 commit comments

Comments
 (0)