Skip to content

Commit

Permalink
Backports for 1.11.0-rc1 (#54611)
Browse files Browse the repository at this point in the history
Backported PRs:
- [x] #54361 <!-- [LBT] Upgrade to v5.9.0 -->
- [x] #54474 <!-- Unalias source from dest in copytrito -->
- [x] #54548 <!-- Fixes for bitcast bugs with LLVM 17 / opaque pointers
-->
- [x] #54191 <!-- make `AbstractPipe` public -->
- [x] #53402 <!-- Add `jl_getaffinity` and `jl_setaffinity` -->
- [x] #53356 <!-- Rename at-scriptdir project argument to at-script and
search upwards for Project.toml -->
- [x] #54545 <!-- typeintersect: fix incorrect innervar handling under
circular env -->
- [x] #54586 <!-- Set storage class of julia globals to dllimport on
windows to avoid auto-import weirdness. Forward port of #54572 -->
- [x] #54587 <!-- Accomodate for rectangular matrices in `copytrito!`
-->
- [x] #54617 <!-- CLI: Use `GetModuleHandleExW` to locate libjulia.dll
-->
- [x] #54605 <!-- Allow libquadmath to also fail as it is not available
on all systems -->
- [x] #54634 <!-- Fix trampoline assembly for build on clang 18 on apple
silicon -->
- [x] #54635 <!-- Aggressive constprop in trevc! to stabilize triangular
eigvec -->
- [x] #54645 <!-- ensure we set the right value to gc_first_tid -->
- [x] #54554 <!-- make elsize public -->
- [x] #54648 <!-- Construct LazyString in error paths for tridiag -->
- [x] #54658 <!-- fix missing uuid check on extension when finding the
location of an extension -->
- [x] #54594 <!-- Switch to Pkg mode prompt immediately and load Pkg in
the background -->
- [x] #54669 <!-- Improve error message in inplace transpose -->
- [x] #54671 <!-- Add boundscheck in bindingkey_eq to avoid OOB access
due to data race -->
- [x] #54672 <!-- make: Fix `sed` command for LLVM libraries with no
symbol versioning -->
- [x] #54624 <!-- more precise aliasing checks for SubArray -->
- [x] #54679 <!-- 🤖 [master] Bump the Distributed stdlib from 6a07d98 to
6c7cdb5 -->
- [x] #54604 <!-- Fix tbaa annotation on union selector bytes inside of
structs -->
- [x] #54690 <!-- Fix assertion/crash when optimizing function with dead
basic block -->
- [x] #54704 <!-- LazyString in reinterpretarray error messages -->
- [x] #54718 <!-- fix prepend StackOverflow issue -->
- [x] #54674 <!-- Reimplement dummy pkg prompt as standard prompt -->
- [x] #54737 <!-- LazyString in interpolated error messages involving
types -->
- [x] #54642 <!-- Document GenericMemory and AtomicMemory -->
- [x] #54713 <!-- make: use `readelf` for LLVM symbol version detection
-->
- [x] #54760 <!-- REPL: improve prompt! async function handler -->
- [x] #54606 <!-- fix double-counting and non-deterministic results in
`summarysize` -->
- [x] #54759 <!-- REPL: Fully populate the dummy Pkg prompt -->
- [x] #54702 <!-- lowering: Recognize argument destructuring inside
macro hygiene -->
- [x] #54678 <!-- Don't let setglobal! implicitly create bindings -->
- [x] #54730 <!-- Fix uuidkey of exts in fast path of `require_stdlib`
-->
- [x] #54765 <!-- Handle no-postdominator case in finalizer pass -->
- [x] #54591 <!-- Don't expose guard pages to malloc_stack API consumers
-->
- [x] #54755 <!-- [TOML] remove Dates hack, replace with explicit usage
-->
- [x] #54721 <!-- add try/catch around scheduler to reset sleep state
-->
- [x] #54631 <!-- Avoid concatenating LazyString in setindex! for
triangular matrices -->
- [x] #54322 <!-- effects: add new `@consistent_overlay` macro -->
- [x] #54785
- [x] #54865
- [x] #54815
- [x] #54795
- [x] #54779
- [x] #54837 

Contains multiple commits, manual intervention needed:
- [ ] #52694 <!-- Reinstate similar for AbstractQ for backward
compatibility -->
- [ ] #54649 <!-- Less restrictive copyto! signature for triangular
matrices -->

Non-merged PRs with backport label:
- [ ] #54779 <!-- make recommendation clearer on manifest version
mismatch -->
- [ ] #54739 <!-- finish implementation of upgradable stdlibs -->
- [ ] #54738 <!-- serialization: fix relocatability bug -->
- [ ] #54574 <!-- Make ScopedValues public -->
- [ ] #54457 <!-- Make `String(::Memory)` copy -->
- [ ] #53957 <!-- tweak how filtering is done for what packages should
be precompiled -->
- [ ] #53452 <!-- RFC: allow Tuple{Union{}}, returning Union{} -->
- [ ] #53286 <!-- Raise an error when using `include_dependency` with
non-existent file or directory -->
- [ ] #51479 <!-- prevent code loading from lookin in the versioned
environment when building Julia -->
  • Loading branch information
KristofferC authored Jun 25, 2024
2 parents edb3c92 + c644312 commit ec84807
Show file tree
Hide file tree
Showing 132 changed files with 2,079 additions and 787 deletions.
2 changes: 1 addition & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ ifeq ($(OS), WINNT)
HAVE_SSP := 1
OSLIBS += -Wl,--export-all-symbols -Wl,--version-script=$(BUILDROOT)/src/julia.expmap \
$(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic -lole32
JLDFLAGS += -Wl,--stack,8388608
JLDFLAGS += -Wl,--stack,8388608 --disable-auto-import --disable-runtime-pseudo-reloc
ifeq ($(ARCH),i686)
JLDFLAGS += -Wl,--large-address-aware
endif
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ win-extras:
ifeq ($(USE_SYSTEM_LLVM), 1)
LLVM_SIZE := llvm-size$(EXE)
else
LLVM_SIZE := $(build_depsbindir)/llvm-size$(EXE)
LLVM_SIZE := PATH=$(build_bindir):$$PATH; $(build_depsbindir)/llvm-size$(EXE)
endif
build-stats:
ifeq ($(USE_BINARYBUILDER_LLVM),1)
Expand Down
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,13 @@ Command-line option changes
difference between defining a `main` function and executing the code directly at the end of the script ([#50974]).
* The `--compiled-modules` and `--pkgimages` flags can now be set to `existing`, which will
cause Julia to consider loading existing cache files, but not to create new ones ([#50586], [#52573]).
* The `--project` argument now accepts `@script` to give a path to a directory with a Project.toml relative to the passed script file. `--project=@script/foo` for the `foo` subdirectory. If no path is given after (i.e. `--project=@script`) then (like `--project=@.`) the directory and its parents are searched for a Project.toml ([#50864] and [#53352])

Multi-threading changes
-----------------------

* `Threads.@threads` now supports the `:greedy` scheduler, intended for non-uniform workloads ([#52096]).
* A new exported struct `Lockable{T, L<:AbstractLock}` makes it easy to bundle a resource and its lock together ([#52898]).
* A new public (but unexported) struct `Base.Lockable{T, L<:AbstractLock}` makes it easy to bundle a resource and its lock together ([#52898]).

New library functions
---------------------
Expand All @@ -87,6 +88,7 @@ New library functions
* `Sys.username()` can be used to return the current user's username ([#51897]).
* `Sys.isreadable(), Sys.iswritable()` can be used to check if the current user has access permissions
that permit reading and writing, respectively. ([#53320]).
* `wrap(Array, m::Union{MemoryRef{T}, Memory{T}}, dims)` is the safe counterpart to `unsafe_wrap` ([#52049]).
* `GC.logging_enabled()` can be used to test whether GC logging has been enabled via `GC.enable_logging` ([#51647]).
* `IdSet` is now exported from Base and considered public ([#53262]).
* `@time` now reports a count of any lock conflicts where a `ReentrantLock` had to wait, plus a new macro
Expand Down
21 changes: 11 additions & 10 deletions base/Enums.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ end
# give Enum types scalar behavior in broadcasting
Base.broadcastable(x::Enum) = Ref(x)

@noinline enum_argument_error(typename, x) = throw(ArgumentError(string("invalid value for Enum $(typename): $x")))
@noinline enum_argument_error(typename, x) = throw(ArgumentError(LazyString("invalid value for Enum ", typename, ": ", x)))

"""
@enum EnumName[::BaseType] value1[=x] value2[=y]
Expand Down Expand Up @@ -143,18 +143,19 @@ julia> Symbol(apple)
"""
macro enum(T::Union{Symbol,Expr}, syms...)
if isempty(syms)
throw(ArgumentError("no arguments given for Enum $T"))
throw(ArgumentError(LazyString("no arguments given for Enum ", T)))
end
basetype = Int32
typename = T
if isa(T, Expr) && T.head === :(::) && length(T.args) == 2 && isa(T.args[1], Symbol)
typename = T.args[1]
basetype = Core.eval(__module__, T.args[2])
if !isa(basetype, DataType) || !(basetype <: Integer) || !isbitstype(basetype)
throw(ArgumentError("invalid base type for Enum $typename, $T=::$basetype; base type must be an integer primitive type"))
throw(ArgumentError(
LazyString("invalid base type for Enum ", typename, ", ", T, "=::", basetype, "; base type must be an integer primitive type")))
end
elseif !isa(T, Symbol)
throw(ArgumentError("invalid type expression for enum $T"))
throw(ArgumentError(LazyString("invalid type expression for enum ", T)))
end
values = Vector{basetype}()
seen = Set{Symbol}()
Expand All @@ -169,32 +170,32 @@ macro enum(T::Union{Symbol,Expr}, syms...)
s isa LineNumberNode && continue
if isa(s, Symbol)
if i == typemin(basetype) && !isempty(values)
throw(ArgumentError("overflow in value \"$s\" of Enum $typename"))
throw(ArgumentError(LazyString("overflow in value \"", s, "\" of Enum ", typename)))
end
elseif isa(s, Expr) &&
(s.head === :(=) || s.head === :kw) &&
length(s.args) == 2 && isa(s.args[1], Symbol)
i = Core.eval(__module__, s.args[2]) # allow exprs, e.g. uint128"1"
if !isa(i, Integer)
throw(ArgumentError("invalid value for Enum $typename, $s; values must be integers"))
throw(ArgumentError(LazyString("invalid value for Enum ", typename, ", ", s, "; values must be integers")))
end
i = convert(basetype, i)
s = s.args[1]
hasexpr = true
else
throw(ArgumentError(string("invalid argument for Enum ", typename, ": ", s)))
throw(ArgumentError(LazyString("invalid argument for Enum ", typename, ": ", s)))
end
s = s::Symbol
if !Base.isidentifier(s)
throw(ArgumentError("invalid name for Enum $typename; \"$s\" is not a valid identifier"))
throw(ArgumentError(LazyString("invalid name for Enum ", typename, "; \"", s, "\" is not a valid identifier")))
end
if hasexpr && haskey(namemap, i)
throw(ArgumentError("both $s and $(namemap[i]) have value $i in Enum $typename; values must be unique"))
throw(ArgumentError(LazyString("both ", s, " and ", namemap[i], " have value ", i, " in Enum ", typename, "; values must be unique")))
end
namemap[i] = s
push!(values, i)
if s in seen
throw(ArgumentError("name \"$s\" in Enum $typename is not unique"))
throw(ArgumentError(LazyString("name \"", s, "\" in Enum ", typename, " is not unique")))
end
push!(seen, s)
if length(values) == 1
Expand Down
4 changes: 2 additions & 2 deletions base/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,12 @@ endif
ifneq (,$(LIBGFORTRAN_VERSION))
$(eval $(call symlink_system_library,CSL,libgfortran,$(LIBGFORTRAN_VERSION)))
endif
$(eval $(call symlink_system_library,CSL,libquadmath,0))
$(eval $(call symlink_system_library,CSL,libstdc++,6))
# We allow libssp, libatomic and libgomp to fail as they are not available on all systems
# We allow libssp, libatomic, libgomp and libquadmath to fail as they are not available on all systems
$(eval $(call symlink_system_library,CSL,libssp,0,ALLOW_FAILURE))
$(eval $(call symlink_system_library,CSL,libatomic,1,ALLOW_FAILURE))
$(eval $(call symlink_system_library,CSL,libgomp,1,ALLOW_FAILURE))
$(eval $(call symlink_system_library,CSL,libquadmath,0,ALLOW_FAILURE))
$(eval $(call symlink_system_library,PCRE,libpcre2-8))
$(eval $(call symlink_system_library,DSFMT,libdSFMT))
$(eval $(call symlink_system_library,LIBBLASTRAMPOLINE,libblastrampoline))
Expand Down
16 changes: 9 additions & 7 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ julia> checkindex(Bool, 1:20, 21)
false
```
"""
checkindex(::Type{Bool}, inds, i) = throw(ArgumentError("unable to check bounds for indices of type $(typeof(i))"))
checkindex(::Type{Bool}, inds, i) = throw(ArgumentError(LazyString("unable to check bounds for indices of type ", typeof(i))))
checkindex(::Type{Bool}, inds::AbstractUnitRange, i::Real) = (first(inds) <= i) & (i <= last(inds))
checkindex(::Type{Bool}, inds::IdentityUnitRange, i::Real) = checkindex(Bool, inds.indices, i)
checkindex(::Type{Bool}, inds::OneTo{T}, i::T) where {T<:BitInteger} = unsigned(i - one(i)) < unsigned(last(inds))
Expand Down Expand Up @@ -1519,12 +1519,14 @@ much more common case where aliasing does not occur. By default,
unaliascopy(A::Array) = copy(A)
unaliascopy(A::AbstractArray)::typeof(A) = (@noinline; _unaliascopy(A, copy(A)))
_unaliascopy(A::T, C::T) where {T} = C
_unaliascopy(A, C) = throw(ArgumentError("""
an array of type `$(typename(typeof(A)).wrapper)` shares memory with another argument
and must make a preventative copy of itself in order to maintain consistent semantics,
but `copy(::$(typeof(A)))` returns a new array of type `$(typeof(C))`.
To fix, implement:
`Base.unaliascopy(A::$(typename(typeof(A)).wrapper))::typeof(A)`"""))
function _unaliascopy(A, C)
Aw = typename(typeof(A)).wrapper
throw(ArgumentError(LazyString("an array of type `", Aw, "` shares memory with another argument ",
"and must make a preventative copy of itself in order to maintain consistent semantics, ",
"but `copy(::", typeof(A), ")` returns a new array of type `", typeof(C), "`.\n",
"""To fix, implement:
`Base.unaliascopy(A::""", Aw, ")::typeof(A)`")))
end
unaliascopy(A) = A

"""
Expand Down
61 changes: 55 additions & 6 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1312,8 +1312,7 @@ end

append!(a::AbstractVector, iter) = _append!(a, IteratorSize(iter), iter)
push!(a::AbstractVector, iter...) = append!(a, iter)

append!(a::AbstractVector, iter...) = foldl(append!, iter, init=a)
append!(a::AbstractVector, iter...) = (for v in iter; append!(a, v); end; return a)

function _append!(a::AbstractVector, ::Union{HasLength,HasShape}, iter)
n = Int(length(iter))::Int
Expand Down Expand Up @@ -1372,10 +1371,9 @@ function prepend!(a::Vector{T}, items::Union{AbstractVector{<:T},Tuple}) where T
return a
end

prepend!(a::Vector, iter) = _prepend!(a, IteratorSize(iter), iter)
pushfirst!(a::Vector, iter...) = prepend!(a, iter)

prepend!(a::AbstractVector, iter...) = foldr((v, a) -> prepend!(a, v), iter, init=a)
prepend!(a::AbstractVector, iter) = _prepend!(a, IteratorSize(iter), iter)
pushfirst!(a::AbstractVector, iter...) = prepend!(a, iter)
prepend!(a::AbstractVector, iter...) = (for v = reverse(iter); prepend!(a, v); end; return a)

function _prepend!(a::Vector, ::Union{HasLength,HasShape}, iter)
@_terminates_locally_meta
Expand Down Expand Up @@ -3062,3 +3060,54 @@ intersect(r::AbstractRange, v::AbstractVector) = intersect(v, r)
_getindex(v, i)
end
end

"""
wrap(Array, m::Union{Memory{T}, MemoryRef{T}}, dims)
Create an array of size `dims` using `m` as the underlying memory. This can be thought of as a safe version
of [`unsafe_wrap`](@ref) utilizing `Memory` or `MemoryRef` instead of raw pointers.
"""
function wrap end

# validity checking for _wrap calls, separate from allocation of Array so that it can be more likely to inline into the caller
function _wrap(ref::MemoryRef{T}, dims::NTuple{N, Int}) where {T, N}
mem = ref.mem
mem_len = length(mem) + 1 - memoryrefoffset(ref)
len = Core.checked_dims(dims...)
@boundscheck mem_len >= len || invalid_wrap_err(mem_len, dims, len)
if N != 1 && !(ref === GenericMemoryRef(mem) && len === mem_len)
mem = ccall(:jl_genericmemory_slice, Memory{T}, (Any, Ptr{Cvoid}, Int), mem, ref.ptr_or_offset, len)
ref = MemoryRef(mem)
end
return ref
end

@noinline invalid_wrap_err(len, dims, proddims) = throw(DimensionMismatch(
"Attempted to wrap a MemoryRef of length $len with an Array of size dims=$dims, which is invalid because prod(dims) = $proddims > $len, so that the array would have more elements than the underlying memory can store."))

@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, dims::NTuple{N, Integer}) where {T, N}
dims = convert(Dims, dims)
ref = _wrap(m, dims)
$(Expr(:new, :(Array{T, N}), :ref, :dims))
end

@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, dims::NTuple{N, Integer}) where {T, N}
dims = convert(Dims, dims)
ref = _wrap(MemoryRef(m), dims)
$(Expr(:new, :(Array{T, N}), :ref, :dims))
end
@eval @propagate_inbounds function wrap(::Type{Array}, m::MemoryRef{T}, l::Integer) where {T}
dims = (Int(l),)
ref = _wrap(m, dims)
$(Expr(:new, :(Array{T, 1}), :ref, :dims))
end
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}, l::Integer) where {T}
dims = (Int(l),)
ref = _wrap(MemoryRef(m), (l,))
$(Expr(:new, :(Array{T, 1}), :ref, :dims))
end
@eval @propagate_inbounds function wrap(::Type{Array}, m::Memory{T}) where {T}
ref = MemoryRef(m)
dims = (length(m),)
$(Expr(:new, :(Array{T, 1}), :ref, :dims))
end
3 changes: 2 additions & 1 deletion base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ macro _foldable_meta()
#=:notaskstate=#true,
#=:inaccessiblememonly=#true,
#=:noub=#true,
#=:noub_if_noinbounds=#false))
#=:noub_if_noinbounds=#false,
#=:consistent_overlay=#false))
end

macro inline() Expr(:meta, :inline) end
Expand Down
2 changes: 1 addition & 1 deletion base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ function ccall_macro_lower(convention, func, rettype, types, args, nreq)
check = quote
if !isa(func, Ptr{Cvoid})
name = $name
throw(ArgumentError("interpolated function `$name` was not a Ptr{Cvoid}, but $(typeof(func))"))
throw(ArgumentError(LazyString("interpolated function `", name, "` was not a Ptr{Cvoid}, but ", typeof(func))))
end
end
push!(statements, check)
Expand Down
14 changes: 11 additions & 3 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ function add_call_backedges!(interp::AbstractInterpreter, @nospecialize(rettype)
# ignore the `:nonoverlayed` property if `interp` doesn't use overlayed method table
# since it will never be tainted anyway
if !isoverlayed(method_table(interp))
all_effects = Effects(all_effects; nonoverlayed=false)
all_effects = Effects(all_effects; nonoverlayed=ALWAYS_FALSE)
end
all_effects === Effects() && return nothing
end
Expand Down Expand Up @@ -889,7 +889,15 @@ function concrete_eval_eligible(interp::AbstractInterpreter,
mi = result.edge
if mi !== nothing && is_foldable(effects)
if f !== nothing && is_all_const_arg(arginfo, #=start=#2)
if is_nonoverlayed(interp) || is_nonoverlayed(effects)
if (is_nonoverlayed(interp) || is_nonoverlayed(effects) ||
# Even if overlay methods are involved, when `:consistent_overlay` is
# explicitly applied, we can still perform concrete evaluation using the
# original methods for executing them.
# While there's a chance that the non-overlayed counterparts may raise
# non-egal exceptions, it will not impact the compilation validity, since:
# - the results of the concrete evaluation will not be inlined
# - the exception types from the concrete evaluation will not be propagated
is_consistent_overlay(effects))
return :concrete_eval
end
# disable concrete-evaluation if this function call is tainted by some overlayed
Expand Down Expand Up @@ -2770,7 +2778,7 @@ function override_effects(effects::Effects, override::EffectsOverride)
notaskstate = override.notaskstate ? true : effects.notaskstate,
inaccessiblememonly = override.inaccessiblememonly ? ALWAYS_TRUE : effects.inaccessiblememonly,
noub = override.noub ? ALWAYS_TRUE :
override.noub_if_noinbounds && effects.noub !== ALWAYS_TRUE ? NOUB_IF_NOINBOUNDS :
(override.noub_if_noinbounds && effects.noub !== ALWAYS_TRUE) ? NOUB_IF_NOINBOUNDS :
effects.noub)
end

Expand Down
11 changes: 7 additions & 4 deletions base/compiler/compiler.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ struct EffectsOverride
inaccessiblememonly::Bool
noub::Bool
noub_if_noinbounds::Bool
consistent_overlay::Bool
end
function EffectsOverride(
override::EffectsOverride =
EffectsOverride(false, false, false, false, false, false, false, false, false);
EffectsOverride(false, false, false, false, false, false, false, false, false, false);
consistent::Bool = override.consistent,
effect_free::Bool = override.effect_free,
nothrow::Bool = override.nothrow,
Expand All @@ -59,7 +60,8 @@ function EffectsOverride(
notaskstate::Bool = override.notaskstate,
inaccessiblememonly::Bool = override.inaccessiblememonly,
noub::Bool = override.noub,
noub_if_noinbounds::Bool = override.noub_if_noinbounds)
noub_if_noinbounds::Bool = override.noub_if_noinbounds,
consistent_overlay::Bool = override.consistent_overlay)
return EffectsOverride(
consistent,
effect_free,
Expand All @@ -69,9 +71,10 @@ function EffectsOverride(
notaskstate,
inaccessiblememonly,
noub,
noub_if_noinbounds)
noub_if_noinbounds,
consistent_overlay)
end
const NUM_EFFECTS_OVERRIDES = 9 # sync with julia.h
const NUM_EFFECTS_OVERRIDES = 10 # sync with julia.h

# essential files and libraries
include("essentials.jl")
Expand Down
Loading

0 comments on commit ec84807

Please sign in to comment.