From b80dd58346a9644d18c52d1cf0e949c62d9e281b Mon Sep 17 00:00:00 2001 From: Michael Persico Date: Thu, 9 Jan 2025 21:24:04 -0500 Subject: [PATCH 01/65] Fix devcontainer definition (#57006) --- .devcontainer/Dockerfile | 3 --- .devcontainer/devcontainer.json | 16 ++++++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) delete mode 100644 .devcontainer/Dockerfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index a688be130711c..0000000000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM julia:latest - -RUN apt-get update && apt-get install -y build-essential libatomic1 python gfortran perl wget m4 cmake pkg-config git diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a3747ca019694..455f8bea3e952 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,8 +1,12 @@ { - "extensions": [ - "julialang.language-julia", - "ms-vscode.cpptools" - ], - - "dockerFile": "Dockerfile" + "image": "docker.io/library/julia:latest", + "customizations": { + "vscode": { + "extensions": [ + "julialang.language-julia", + "ms-vscode.cpptools" + ] + } + }, + "onCreateCommand": "apt-get update && apt-get install -y build-essential libatomic1 python3 gfortran perl wget m4 cmake pkg-config git" } From 6ac351a9890272db959396a77254c8b4b807d69f Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Thu, 9 Jan 2025 23:24:49 -0300 Subject: [PATCH 02/65] Make write(IO, Char) actually return the amount of printed bytes instead of the attempted written bytes. (#56980) --- base/io.jl | 5 ++--- test/iobuffer.jl | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/base/io.jl b/base/io.jl index 83a215d6359fc..46aec6ca393b7 100644 --- a/base/io.jl +++ b/base/io.jl @@ -864,11 +864,10 @@ end function write(io::IO, c::Char) u = bswap(reinterpret(UInt32, c)) - n = 1 + n = 0 while true - write(io, u % UInt8) + n += write(io, u % UInt8) (u >>= 8) == 0 && return n - n += 1 end end # write(io, ::AbstractChar) is not defined: implementations diff --git a/test/iobuffer.jl b/test/iobuffer.jl index 933662f7e41d1..a9d58f4b7871e 100644 --- a/test/iobuffer.jl +++ b/test/iobuffer.jl @@ -399,3 +399,9 @@ end io = IOBuffer(data) @test read(io) == data end + +@testset "Writing Char to full buffer" begin + io = IOBuffer(;maxsize=1) + write(io, 'a') + @test write(io, 'a') == 0 +end From d3964b600a5e596bd47cf04b3da4a1e78d4aecaf Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:00:22 +0100 Subject: [PATCH 03/65] broadcast: align `ndims` implementation with intent behind code (#56999) The `N<:Integer` constraint was nonsensical, given that `(N === Any) || (N isa Int)`. N5N3 noticed this back in 2022: https://github.com/JuliaLang/julia/pull/44061#discussion_r883261337 Follow up on #44061. Also xref #45477. --- base/broadcast.jl | 9 +++++++-- test/broadcast.jl | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/base/broadcast.jl b/base/broadcast.jl index 7f278fc1ca66f..512b397352040 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -280,9 +280,14 @@ Base.@propagate_inbounds function Base.iterate(bc::Broadcasted, s) end Base.IteratorSize(::Type{T}) where {T<:Broadcasted} = Base.HasShape{ndims(T)}() -Base.ndims(BC::Type{<:Broadcasted{<:Any,Nothing}}) = _maxndims(fieldtype(BC, :args)) -Base.ndims(::Type{<:Broadcasted{<:AbstractArrayStyle{N},Nothing}}) where {N<:Integer} = N +Base.ndims(BC::Type{<:Broadcasted{<:Any,Nothing}}) = _maxndims_broadcasted(BC) +# the `AbstractArrayStyle` type parameter is required to be either equal to `Any` or be an `Int` value +Base.ndims(BC::Type{<:Broadcasted{<:AbstractArrayStyle{Any},Nothing}}) = _maxndims_broadcasted(BC) +Base.ndims(::Type{<:Broadcasted{<:AbstractArrayStyle{N},Nothing}}) where {N} = N::Int +function _maxndims_broadcasted(BC::Type{<:Broadcasted}) + _maxndims(fieldtype(BC, :args)) +end _maxndims(::Type{T}) where {T<:Tuple} = reduce(max, ntuple(n -> (F = fieldtype(T, n); F <: Tuple ? 1 : ndims(F)), Base._counttuple(T))) _maxndims(::Type{<:Tuple{T}}) where {T} = T <: Tuple ? 1 : ndims(T) function _maxndims(::Type{<:Tuple{T, S}}) where {T, S} diff --git a/test/broadcast.jl b/test/broadcast.jl index 57441de67c0ce..0f5bdf7a40bb1 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -930,6 +930,8 @@ let @test @inferred(Base.IteratorSize(Broadcast.broadcasted(+, (1,2,3), a1, zeros(3,3,3)))) === Base.HasShape{3}() + @test @inferred(Base.IteratorSize(Base.broadcasted(randn))) === Base.HasShape{0}() + # inference on nested bc = Base.broadcasted(+, AD1(randn(3)), AD1(randn(3))) bc_nest = Base.broadcasted(+, bc , bc) From 9211a932bb5e73adfa9c494d068bf0ad10e5f552 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 10 Jan 2025 18:44:21 +0100 Subject: [PATCH 04/65] Add edge kind for access to non-explicit partitioned bindings (#57009) Our binding partion invalidation code scans the original source for any GlobalRefs that need to be invalidated. However, this is not the only source of access to binding partitions. Various intrinsics (in particular the `*global` ones) also operate on bindings. Since these are not manifest in the source, we instead use the existing `edges` mechanism to give them forward edges. This PR only includes the basic info type, and validation in the replacement case. There's a bit more work to do there, but I'm waiting on #56499 for that part, precompilation in particular. --- Compiler/src/abstractinterpretation.jl | 86 ++++++++++++-------------- Compiler/src/stmtinfo.jl | 14 +++++ Compiler/src/typeinfer.jl | 3 + base/invalidation.jl | 41 ++++++++---- src/module.c | 8 +-- src/staticdata_utils.c | 8 +++ stdlib/REPL/src/REPLCompletions.jl | 6 +- sysimage.mk | 1 + test/rebinding.jl | 9 ++- 9 files changed, 110 insertions(+), 66 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 0c340a89d9878..3766907905aef 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -2395,7 +2395,8 @@ function abstract_eval_getglobal(interp::AbstractInterpreter, sv::AbsIntState, s if M isa Const && s isa Const M, s = M.val, s.val if M isa Module && s isa Symbol - return CallMeta(abstract_eval_globalref(interp, GlobalRef(M, s), saw_latestworld, sv), NoCallInfo()) + (ret, bpart) = abstract_eval_globalref(interp, GlobalRef(M, s), saw_latestworld, sv) + return CallMeta(ret, bpart === nothing ? NoCallInfo() : GlobalAccessInfo(bpart)) end return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) elseif !hasintersect(widenconst(M), Module) || !hasintersect(widenconst(s), Symbol) @@ -2473,8 +2474,8 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState, if isa(M, Const) && isa(s, Const) M, s = M.val, s.val if M isa Module && s isa Symbol - rt, exct = global_assignment_rt_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v) - return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo()) + (rt, exct), partition = global_assignment_rt_exct(interp, sv, saw_latestworld, GlobalRef(M, s), v) + return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), GlobalAccessInfo(partition)) end return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) end @@ -2512,7 +2513,7 @@ function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, scm = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v) scm.rt === Bottom && return scm gcm = abstract_eval_getglobal(interp, sv, saw_latestworld, M, s) - return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), NoCallInfo()) + return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), scm.info) end function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, @@ -2520,7 +2521,7 @@ function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, scm = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v, order) scm.rt === Bottom && return scm gcm = abstract_eval_getglobal(interp, sv, saw_latestworld, M, s, order) - return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), NoCallInfo()) + return CallMeta(gcm.rt, Union{scm.exct,gcm.exct}, merge_effects(scm.effects, gcm.effects), scm.info) end function abstract_eval_swapglobal!(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, argtypes::Vector{Any}) @@ -2569,7 +2570,7 @@ function abstract_eval_replaceglobal!(interp::AbstractInterpreter, sv::AbsIntSta end exct = Union{rte.exct, global_assignment_binding_rt_exct(interp, partition, v)[2]} effects = merge_effects(rte.effects, Effects(setglobal!_effects, nothrow=exct===Bottom)) - sg = CallMeta(Any, exct, effects, NoCallInfo()) + sg = CallMeta(Any, exct, effects, GlobalAccessInfo(partition)) else sg = abstract_eval_setglobal!(interp, sv, saw_latestworld, M, s, v) end @@ -2937,7 +2938,8 @@ function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize( return RTEffects(sv.ir.argtypes[e.n], Union{}, EFFECTS_TOTAL) # TODO frame_argtypes(sv)[e.n] and remove the assertion end elseif isa(e, GlobalRef) - return abstract_eval_globalref(interp, e, sstate.saw_latestworld, sv) + # No need for an edge since an explicit GlobalRef will be picked up by the source scan + return abstract_eval_globalref(interp, e, sstate.saw_latestworld, sv)[1] end if isa(e, QuoteNode) e = e.value @@ -3193,14 +3195,31 @@ function abstract_eval_isdefined_expr(interp::AbstractInterpreter, e::Expr, ssta end return RTEffects(rt, Union{}, EFFECTS_TOTAL) end - return abstract_eval_isdefined(interp, sym, sstate.saw_latestworld, sv) + rt = Bool + effects = EFFECTS_TOTAL + exct = Union{} + if isexpr(sym, :static_parameter) + n = sym.args[1]::Int + if 1 <= n <= length(sv.sptypes) + sp = sv.sptypes[n] + if !sp.undef + rt = Const(true) + elseif sp.typ === Bottom + rt = Const(false) + end + end + else + effects = EFFECTS_UNKNOWN + exct = Any + end + return RTEffects(rt, exct, effects) end const generic_isdefinedglobal_effects = Effects(EFFECTS_TOTAL, consistent=ALWAYS_FALSE, nothrow=false) function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, mod::Module, sym::Symbol, allow_import::Union{Bool, Nothing}, saw_latestworld::Bool, sv::AbsIntState) rt = Bool if saw_latestworld - return RTEffects(rt, Union{}, Effects(generic_isdefinedglobal_effects, nothrow=true)) + return CallMeta(RTEffects(rt, Union{}, Effects(generic_isdefinedglobal_effects, nothrow=true)), NoCallInfo()) end effects = EFFECTS_TOTAL @@ -3222,7 +3241,7 @@ function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, mod::Module, effects = Effects(generic_isdefinedglobal_effects, nothrow=true) end end - return RTEffects(rt, Union{}, effects) + return CallMeta(RTEffects(rt, Union{}, effects), GlobalAccessInfo(partition)) end function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecialize(M), @nospecialize(s), @nospecialize(allow_import_arg), @nospecialize(order_arg), saw_latestworld::Bool, sv::AbsIntState) @@ -3247,7 +3266,7 @@ function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecializ if M isa Const && s isa Const M, s = M.val, s.val if M isa Module && s isa Symbol - return merge_exct(CallMeta(abstract_eval_isdefinedglobal(interp, M, s, allow_import, saw_latestworld, sv), NoCallInfo()), exct) + return merge_exct(abstract_eval_isdefinedglobal(interp, M, s, allow_import, saw_latestworld, sv), exct) end return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) elseif !hasintersect(widenconst(M), Module) || !hasintersect(widenconst(s), Symbol) @@ -3258,26 +3277,6 @@ function abstract_eval_isdefinedglobal(interp::AbstractInterpreter, @nospecializ return CallMeta(Bool, Union{exct, TypeError, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo()) end -function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym), saw_latestworld::Bool, sv::AbsIntState) - rt = Bool - effects = EFFECTS_TOTAL - exct = Union{} - if isexpr(sym, :static_parameter) - n = sym.args[1]::Int - if 1 <= n <= length(sv.sptypes) - sp = sv.sptypes[n] - if !sp.undef - rt = Const(true) - elseif sp.typ === Bottom - rt = Const(false) - end - end - else - effects = EFFECTS_UNKNOWN - end - return RTEffects(rt, exct, effects) -end - function abstract_eval_throw_undef_if_not(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState) condt = abstract_eval_value(interp, e.args[2], sstate, sv) condval = maybe_extract_const_bool(condt) @@ -3533,26 +3532,29 @@ end function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, saw_latestworld::Bool, sv::AbsIntState) if saw_latestworld - return RTEffects(Any, Any, generic_getglobal_effects) + return Pair{RTEffects, Union{Nothing, Core.BindingPartition}}(RTEffects(Any, Any, generic_getglobal_effects), nothing) end partition = abstract_eval_binding_partition!(interp, g, sv) ret = abstract_eval_partition_load(interp, partition) if ret.rt !== Union{} && ret.exct === UndefVarError && InferenceParams(interp).assume_bindings_static if isdefined(g, :binding) && isdefined(g.binding, :value) - return RTEffects(ret.rt, Union{}, Effects(generic_getglobal_effects, nothrow=true)) + ret = RTEffects(ret.rt, Union{}, Effects(generic_getglobal_effects, nothrow=true)) end # We do not assume in general that assigned global bindings remain assigned. # The existence of pkgimages allows them to revert in practice. end - return ret + return Pair{RTEffects, Union{Nothing, Core.BindingPartition}}(ret, partition) end function global_assignment_rt_exct(interp::AbstractInterpreter, sv::AbsIntState, saw_latestworld::Bool, g::GlobalRef, @nospecialize(newty)) if saw_latestworld - return Pair{Any,Any}(newty, Union{ErrorException, TypeError}) + return Pair{Pair{Any,Any}, Union{Core.BindingPartition, Nothing}}( + Pair{Any,Any}(newty, Union{ErrorException, TypeError}), nothing) end partition = abstract_eval_binding_partition!(interp, g, sv) - return global_assignment_binding_rt_exct(interp, partition, newty) + return Pair{Pair{Any,Any}, Union{Core.BindingPartition, Nothing}}( + global_assignment_binding_rt_exct(interp, partition, newty), + partition) end function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partition::Core.BindingPartition, @nospecialize(newty)) @@ -3573,18 +3575,6 @@ function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partitio return Pair{Any,Any}(newty, Bottom) end -function handle_global_assignment!(interp::AbstractInterpreter, frame::InferenceState, saw_latestworld::Bool, lhs::GlobalRef, @nospecialize(newty)) - effect_free = ALWAYS_FALSE - nothrow = global_assignment_rt_exct(interp, frame, saw_latestworld, lhs, ignorelimited(newty))[2] === Union{} - inaccessiblememonly = ALWAYS_FALSE - if !nothrow - sub_curr_ssaflag!(frame, IR_FLAG_NOTHROW) - end - sub_curr_ssaflag!(frame, IR_FLAG_EFFECT_FREE) - merge_effects!(interp, frame, Effects(EFFECTS_TOTAL; effect_free, nothrow, inaccessiblememonly)) - return nothing -end - abstract_eval_ssavalue(s::SSAValue, sv::InferenceState) = abstract_eval_ssavalue(s, sv.ssavaluetypes) function abstract_eval_ssavalue(s::SSAValue, ssavaluetypes::Vector{Any}) diff --git a/Compiler/src/stmtinfo.jl b/Compiler/src/stmtinfo.jl index a42a9e47b328e..e3f8e2f56c86b 100644 --- a/Compiler/src/stmtinfo.jl +++ b/Compiler/src/stmtinfo.jl @@ -481,4 +481,18 @@ end add_edges_impl(edges::Vector{Any}, info::VirtualMethodMatchInfo) = _add_edges_impl(edges, info.info, #=mi_edge=#true) +""" + info::GlobalAccessInfo <: CallInfo + +Represents access to a global through runtime reflection, rather than as a manifest +`GlobalRef` in the source code. Used for builtins (getglobal/setglobal/etc.) that +perform such accesses. +""" +struct GlobalAccessInfo <: CallInfo + bpart::Core.BindingPartition +end +GlobalAccessInfo(::Nothing) = NoCallInfo() +add_edges_impl(edges::Vector{Any}, info::GlobalAccessInfo) = + push!(edges, info.bpart) + @specialize diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 49cc711dc72df..ec1e62817106d 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -544,6 +544,9 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector) # ignore `Method`-edges (from e.g. failed `abstract_call_method`) i += 1 continue + elseif isa(item, Core.BindingPartition) + i += 1 + continue end if isa(item, CodeInstance) item = item.def diff --git a/base/invalidation.jl b/base/invalidation.jl index 40a010ab7361c..5abb0b74ad884 100644 --- a/base/invalidation.jl +++ b/base/invalidation.jl @@ -9,7 +9,7 @@ globalrefs(mod::Module) = GlobalRefIterator(mod) function iterate(gri::GlobalRefIterator, i = 1) m = gri.mod table = ccall(:jl_module_get_bindings, Ref{SimpleVector}, (Any,), m) - i == length(table) && return nothing + i > length(table) && return nothing b = table[i] b === nothing && return iterate(gri, i+1) return ((b::Core.Binding).globalref, i+1) @@ -85,18 +85,33 @@ function should_invalidate_code_for_globalref(gr::GlobalRef, src::CodeInfo) return found_any end -function invalidate_code_for_globalref!(gr::GlobalRef, new_max_world::UInt) - valid_in_valuepos = false - foreach_reachable_mtable(new_max_world) do mt::Core.MethodTable - for method in MethodList(mt) - if isdefined(method, :source) - src = _uncompressed_ir(method) - old_stmts = src.code - if should_invalidate_code_for_globalref(gr, src) +function scan_edge_list(ci::Core.CodeInstance, bpart::Core.BindingPartition) + isdefined(ci, :edges) || return false + edges = ci.edges + i = 1 + while i <= length(edges) + if isassigned(edges, i) && edges[i] === bpart + return true + end + i += 1 + end + return false +end + +function invalidate_code_for_globalref!(gr::GlobalRef, invalidated_bpart::Core.BindingPartition, new_max_world::UInt) + try + valid_in_valuepos = false + foreach_reachable_mtable(new_max_world) do mt::Core.MethodTable + for method in MethodList(mt) + if isdefined(method, :source) + src = _uncompressed_ir(method) + old_stmts = src.code + invalidate_all = should_invalidate_code_for_globalref(gr, src) for mi in specializations(method) + isdefined(mi, :cache) || continue ci = mi.cache while true - if ci.max_world > new_max_world + if ci.max_world > new_max_world && (invalidate_all || scan_edge_list(ci, invalidated_bpart)) ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), ci, new_max_world) end isdefined(ci, :next) || break @@ -105,7 +120,11 @@ function invalidate_code_for_globalref!(gr::GlobalRef, new_max_world::UInt) end end end + return true end - return true + catch err + bt = catch_backtrace() + invokelatest(Base.println, "Internal Error during invalidation:") + invokelatest(Base.display_error, err, bt) end end diff --git a/src/module.c b/src/module.c index 004371b9144b2..66049031f8790 100644 --- a/src/module.c +++ b/src/module.c @@ -1032,7 +1032,7 @@ JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var jl_gc_wb(bpart, val); } -void jl_invalidate_binding_refs(jl_globalref_t *ref, size_t new_world) +void jl_invalidate_binding_refs(jl_globalref_t *ref, jl_binding_partition_t *invalidated_bpart, size_t new_world) { static jl_value_t *invalidate_code_for_globalref = NULL; if (invalidate_code_for_globalref == NULL && jl_base_module != NULL) @@ -1043,7 +1043,7 @@ void jl_invalidate_binding_refs(jl_globalref_t *ref, size_t new_world) jl_error("Binding invalidation is not permitted during image generation."); jl_value_t *boxed_world = jl_box_ulong(new_world); JL_GC_PUSH1(&boxed_world); - jl_call2((jl_function_t*)invalidate_code_for_globalref, (jl_value_t*)ref, boxed_world); + jl_call3((jl_function_t*)invalidate_code_for_globalref, (jl_value_t*)ref, (jl_value_t*)invalidated_bpart, boxed_world); JL_GC_POP(); } @@ -1063,10 +1063,10 @@ JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr) jl_task_t *ct = jl_current_task; size_t last_world = ct->world_age; size_t new_max_world = jl_atomic_load_acquire(&jl_world_counter); + jl_atomic_store_release(&bpart->max_world, new_max_world); ct->world_age = jl_typeinf_world; - jl_invalidate_binding_refs(gr, new_max_world); + jl_invalidate_binding_refs(gr, bpart, new_max_world); ct->world_age = last_world; - jl_atomic_store_release(&bpart->max_world, new_max_world); jl_atomic_store_release(&jl_world_counter, new_max_world + 1); JL_UNLOCK(&world_counter_lock); } diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index 5de85a8d6ec77..79d2909970d99 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -878,6 +878,10 @@ static int jl_verify_method(jl_code_instance_t *codeinst, size_t *minworld, size size_t min_valid2; size_t max_valid2; assert(!jl_is_method(edge)); // `Method`-edge isn't allowed for the optimized one-edge format + if (jl_is_binding_partition(edge)) { + j += 1; + continue; + } if (jl_is_code_instance(edge)) edge = (jl_value_t*)jl_get_ci_mi((jl_code_instance_t*)edge); if (jl_is_method_instance(edge)) { @@ -1051,6 +1055,10 @@ static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_ci_list) j += 1; continue; } + else if (jl_is_binding_partition(edge)) { + j += 1; + continue; + } if (jl_is_code_instance(edge)) edge = (jl_value_t*)((jl_code_instance_t*)edge)->def; if (jl_is_method_instance(edge)) { diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 2c03c6d563c1e..723a008b10f28 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -646,9 +646,11 @@ function CC.abstract_eval_globalref(interp::REPLInterpreter, g::GlobalRef, baile sv::CC.InferenceState) if (interp.limit_aggressive_inference ? is_repl_frame(sv) : is_call_graph_uncached(sv)) if isdefined_globalref(g) - return CC.RTEffects(Const(ccall(:jl_get_globalref_value, Any, (Any,), g)), Union{}, CC.EFFECTS_TOTAL) + return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( + CC.RTEffects(Const(ccall(:jl_get_globalref_value, Any, (Any,), g)), Union{}, CC.EFFECTS_TOTAL), nothing) end - return CC.RTEffects(Union{}, UndefVarError, CC.EFFECTS_THROWS) + return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( + CC.RTEffects(Union{}, UndefVarError, CC.EFFECTS_THROWS), nothing) end return @invoke CC.abstract_eval_globalref(interp::CC.AbstractInterpreter, g::GlobalRef, bailed::Bool, sv::CC.InferenceState) diff --git a/sysimage.mk b/sysimage.mk index a74aace4dd11c..571e2da003346 100644 --- a/sysimage.mk +++ b/sysimage.mk @@ -43,6 +43,7 @@ COMPILER_SRCS := $(addprefix $(JULIAHOME)/, \ base/int.jl \ base/indices.jl \ base/iterators.jl \ + base/invalidation.jl \ base/namedtuple.jl \ base/number.jl \ base/operators.jl \ diff --git a/test/rebinding.jl b/test/rebinding.jl index ad0ad1fc1643d..10da27ce3ad8f 100644 --- a/test/rebinding.jl +++ b/test/rebinding.jl @@ -31,7 +31,7 @@ module Rebinding # Tests for @world syntax @test Base.@world(Foo, defined_world_age) == typeof(x) - @test Base.@world(Rebinding.Foo, defined_world_age) == typeof(x) + nameof(@__MODULE__) === :Rebinding && @test Base.@world(Rebinding.Foo, defined_world_age) == typeof(x) @test Base.@world((@__MODULE__).Foo, defined_world_age) == typeof(x) # Test invalidation (const -> undefined) @@ -40,4 +40,11 @@ module Rebinding @test f_return_delete_me() == 1 Base.delete_binding(@__MODULE__, :delete_me) @test_throws UndefVarError f_return_delete_me() + + ## + via indirect access + const delete_me = 2 + f_return_delete_me_indirect() = getglobal(@__MODULE__, :delete_me) + @test f_return_delete_me_indirect() == 2 + Base.delete_binding(@__MODULE__, :delete_me) + @test_throws UndefVarError f_return_delete_me_indirect() end From 64706d789f4816230d595b03f527fc0e9d934a3e Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 10 Jan 2025 14:14:07 -0500 Subject: [PATCH 05/65] remove fence that GC change made unnecessary (#56986) @gbaraldi and I think that this fence can probably be removed now that https://github.com/JuliaLang/julia/pull/55223 is merged. This should slightly expand the set of cases where the Memory is removable. --- src/cgutils.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 295dd93e869ba..98c5627578b80 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -4463,8 +4463,6 @@ static void emit_memory_zeroinit_and_stores(jl_codectx_t &ctx, jl_datatype_t *ty auto len_store = ctx.builder.CreateAlignedStore(nel, len_field, Align(sizeof(void*))); auto aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memorylen); aliasinfo.decorateInst(len_store); - //This avoids the length store from being deleted which is illegal - ctx.builder.CreateFence(AtomicOrdering::Release, SyncScope::SingleThread); // zeroinit pointers and unions if (zi) { Value *memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); From db8cc484fd8e9b6120483acc6387d843de8f7fd4 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:34:21 -0500 Subject: [PATCH 06/65] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20Pk?= =?UTF-8?q?g=20stdlib=20from=208d3cf02e5=20to=20bc9fb21b1=20(#57013)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: IanButterworth <1694067+IanButterworth@users.noreply.github.com> --- .../Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 | 1 - .../Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 | 1 - .../Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 | 1 + .../Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 | 1 + stdlib/Pkg.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 delete mode 100644 deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 create mode 100644 deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 create mode 100644 deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 diff --git a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 deleted file mode 100644 index 0ec07e44a059d..0000000000000 --- a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -30eed5409ab2f5e7791cac9f6583ccad diff --git a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 b/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 deleted file mode 100644 index 37415fcac993c..0000000000000 --- a/deps/checksums/Pkg-8d3cf02e5e35913c89440c3b5c6678c1a806e975.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -bb995ff7bc047121e79162da8775cbf21a2874427af53ea46ccf9db2a01d5d3e864262d232e2988f41248e6b45a266a64467ada7e6a88f2306135ac4f1bb794f diff --git a/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 new file mode 100644 index 0000000000000..5180b5f916d1b --- /dev/null +++ b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/md5 @@ -0,0 +1 @@ +2332986e216728bc85e364994f2ed910 diff --git a/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 new file mode 100644 index 0000000000000..04bc79171c734 --- /dev/null +++ b/deps/checksums/Pkg-bc9fb21b1f2d72038491eff938673fc5fbc99445.tar.gz/sha512 @@ -0,0 +1 @@ +99bf03f921ae79767009dbd68a94a7119513b2454d5c9832b157bc1e092a35a6b90cb7a5d81346a7d927f9b0275328582098ca6b8b376b4a406ddf0b3167a280 diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 568a15dae1cc0..4240c77105583 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = 8d3cf02e5e35913c89440c3b5c6678c1a806e975 +PKG_SHA1 = bc9fb21b1f2d72038491eff938673fc5fbc99445 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 From c1db3a419699a92c29ce2aff7547019eec3045a4 Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:29:48 -0500 Subject: [PATCH 07/65] Miscellaneous `Meta.partially_inline!` fixes (#56813) This fixes up a couple of conspicuous problems I noticed when reviewing #56787 I'm unsure we should have accepted this pass in Base to begin with... It should at least be re-written to error on unexpected IR elements (instead of performing an invalid transform silently), but the real problem is that this pass is out-of-pipeline and so it doesn't run on most user code and we have much worse coverage compared to passes in the main Compiler. --- base/meta.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/base/meta.jl b/base/meta.jl index 85b54e8225d4e..36875b8e2c625 100644 --- a/base/meta.jl +++ b/base/meta.jl @@ -364,6 +364,19 @@ function _partially_inline!(@nospecialize(x), slot_replacements::Vector{Any}, x.edges .+= slot_offset return x end + if isa(x, Core.UpsilonNode) + if !isdefined(x, :val) + return x + end + return Core.UpsilonNode( + _partially_inline!(x.val, slot_replacements, type_signature, static_param_values, + slot_offset, statement_offset, boundscheck), + ) + end + if isa(x, Core.PhiCNode) + _partially_inline!(x.values, slot_replacements, type_signature, static_param_values, + slot_offset, statement_offset, boundscheck) + end if isa(x, Core.ReturnNode) # Unreachable doesn't have val defined if !isdefined(x, :val) @@ -383,6 +396,9 @@ function _partially_inline!(@nospecialize(x), slot_replacements::Vector{Any}, ) end if isa(x, Core.EnterNode) + if x.catch_dest == 0 + return x + end return Core.EnterNode(x, x.catch_dest + statement_offset) end if isa(x, Expr) From 49428e8fa2f787d8df894a4a8f538350ec0e54fe Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Fri, 10 Jan 2025 18:19:03 -0500 Subject: [PATCH 08/65] README.md: Update current stable version (#57016) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfa2111600f22..021322336d286 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ and then use the command prompt to change into the resulting julia directory. By Julia. However, most users should use the [most recent stable version](https://github.com/JuliaLang/julia/releases) of Julia. You can get this version by running: - git checkout v1.11.1 + git checkout v1.11.2 To build the `julia` executable, run `make` from within the julia directory. From 71bfbb3b0134c05e1af49c385738b8f5d8f06e7c Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 10 Jan 2025 19:41:51 -0800 Subject: [PATCH 09/65] Update HelloWorldC in Artifacts tests and bump LazyArtifacts for the same change (#57000) This updates the version of HelloWorldC in `stdlib/Artifacts/test/Artifacts.toml` from 1.1.2 to 1.4.0, for which there are binaries for FreeBSD AArch64 and Linux RISC-V. The same change was made to LazyArtifacts, as it contains that same `Artifacts.toml` file in its tests, and the version of LazyArtifacts used here has been updated accordingly. No other changes have been made to LazyArtifacts since the previous version used here. --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/Artifacts/test/Artifacts.toml | 113 ++++++++++-------- stdlib/Artifacts/test/runtests.jl | 12 +- stdlib/LazyArtifacts.version | 2 +- 7 files changed, 74 insertions(+), 57 deletions(-) delete mode 100644 deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 delete mode 100644 deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 create mode 100644 deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 create mode 100644 deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 diff --git a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 deleted file mode 100644 index 363c289573765..0000000000000 --- a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -ce3754f1d195e1533fc1f3c51e2a2d4c diff --git a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 b/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 deleted file mode 100644 index 62227971fe7f7..0000000000000 --- a/deps/checksums/LazyArtifacts-a719c0e3d68a95c6f3dc9571459428ca8761fa2c.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -1e1beb6202f089b82f06c1f1fcb129a31d2b438df8a3a49c7367d3df4587d8b9b8fbcf74d3f5ff3c25c241314c71e5dfd72014338b822f01252890e2a14831d1 diff --git a/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 new file mode 100644 index 0000000000000..48bd7a8a7fa25 --- /dev/null +++ b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/md5 @@ -0,0 +1 @@ +405faa2237105ff823e80e759b2df17a diff --git a/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 new file mode 100644 index 0000000000000..9fa6aec4d1939 --- /dev/null +++ b/deps/checksums/LazyArtifacts-e4cfc39598c238f75bdfdbdb3f82c9329a5af59c.tar.gz/sha512 @@ -0,0 +1 @@ +9bd2bdd5a83df28a26ebfb0d4e59b50584962e07b1364e6fd76bc7a6a7b109f1facaa04366beaa9f340192ea9efa540decde1393ddd50dc3efa13937deeb5d7f diff --git a/stdlib/Artifacts/test/Artifacts.toml b/stdlib/Artifacts/test/Artifacts.toml index 4b715b74c128b..5faf1012dec54 100644 --- a/stdlib/Artifacts/test/Artifacts.toml +++ b/stdlib/Artifacts/test/Artifacts.toml @@ -1,146 +1,163 @@ [[HelloWorldC]] arch = "aarch64" -git-tree-sha1 = "95fce80ec703eeb5f4270fef6821b38d51387499" +git-tree-sha1 = "0835a23111b12d2aa5e1f7a852ed71e0b92e3425" os = "macos" [[HelloWorldC.download]] - sha256 = "23f45918421881de8e9d2d471c70f6b99c26edd1dacd7803d2583ba93c8bbb28" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.aarch64-apple-darwin.tar.gz" + sha256 = "4406a35689feaf532ff0347a11896449571e8a1c919e5550b01dfe10f2e64822" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-apple-darwin.tar.gz" [[HelloWorldC]] arch = "aarch64" -git-tree-sha1 = "1ccbaad776766366943fd5a66a8cbc9877ee8df9" +git-tree-sha1 = "c82465bd6d0aa1369ff2fd961b73884d1f5de49a" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "82bca07ff25a75875936116ca977285160a2afcc4f58dd160c7b1600f55da655" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.aarch64-linux-gnu.tar.gz" + sha256 = "5bfa84332c7ee485ca8e2eee216ad9fa77b2c43d5f261baa823e301b7c789ec4" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-linux-gnu.tar.gz" [[HelloWorldC]] arch = "aarch64" -git-tree-sha1 = "dc43ab874611cfc26641741c31b8230276d7d664" +git-tree-sha1 = "cb4b8c88778c6cd93b6df38ec5b95a2678434f5d" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "36b7c554f1cb04d5282b991c66a10b2100085ac8deb2156bf52b4f7c4e406c04" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.aarch64-linux-musl.tar.gz" + sha256 = "924df1c2a386f79a2727a2f989393102649a24863214f2e88cb4a677d3d22e14" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-linux-musl.tar.gz" +[[HelloWorldC]] +arch = "aarch64" +git-tree-sha1 = "7db155cf8485fbeb23d30a305f76ece191db9dc4" +os = "freebsd" + + [[HelloWorldC.download]] + sha256 = "d86d992f428df1264d55d7ac886ccd0a0539fda82363bf5dda872d12ea742528" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.aarch64-unknown-freebsd.tar.gz" [[HelloWorldC]] arch = "armv6l" call_abi = "eabihf" -git-tree-sha1 = "b7128521583d02d2dbe9c8de6fe156b79df781d9" +git-tree-sha1 = "20a32b71145b67e708f63fb5880a7243727aec0f" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "5e094b9c6e4c6a77ecc8dfc2b841ac1f2157f6a81f4c47f1e0d3e9a04eec7945" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv6l-linux-gnueabihf.tar.gz" + sha256 = "6f0997b0aad387ba6e2402530642bb4ded85b0243460d2e4b13d94f2c8340a44" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv6l-linux-gnueabihf.tar.gz" [[HelloWorldC]] arch = "armv6l" call_abi = "eabihf" -git-tree-sha1 = "edb3893a154519d6786234f5c83994c34e11feed" +git-tree-sha1 = "c1179604ea37fa66ee6d5d592c7bbfd1f20292c3" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "0a2203f061ba2ef7ce4c452ec7874be3acc6db1efac8091f85d113c3404e6bb6" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv6l-linux-musleabihf.tar.gz" + sha256 = "0aca47bce6f09c38a7939277a593deb988123fe59f7992225a1ede8e174f1b06" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv6l-linux-musleabihf.tar.gz" [[HelloWorldC]] arch = "armv7l" call_abi = "eabihf" -git-tree-sha1 = "5a8288c8a30578c0d0f24a9cded29579517ce7a8" +git-tree-sha1 = "0a8e7b523ef6be31311aefe9983a488616e58201" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "a4392a4c8f834c97f9d8822ddfb1813d8674fa602eeaf04d6359c0a9e98478ec" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv7l-linux-gnueabihf.tar.gz" + sha256 = "f29f4da556d2b4ee9eaff7740aa0f9436406b75b0f1ec428e881a47ab7b7477b" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv7l-linux-gnueabihf.tar.gz" [[HelloWorldC]] arch = "armv7l" call_abi = "eabihf" -git-tree-sha1 = "169c261b321c4dc95894cdd2db9d0d0caa84677f" +git-tree-sha1 = "ca94b4d87f1a276066a2994733142e35046c41dd" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "ed1aacbf197a6c78988725a39defad130ed31a2258f8e7846f73b459821f21d3" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.armv7l-linux-musleabihf.tar.gz" + sha256 = "5fb4019d6d797e5e3860cfec90cab12f6865fa624e87b51c20220a44bb94846a" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.armv7l-linux-musleabihf.tar.gz" [[HelloWorldC]] arch = "i686" -git-tree-sha1 = "fd35f9155dc424602d01fbf983eb76be3217a28f" +git-tree-sha1 = "91376c8b0bc90c47076cab4e55bf77e86bb59076" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "048fcff5ff47a3cc1e84a2688935fcd658ad1c7e7c52c0e81fe88ce6c3697aba" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.i686-linux-gnu.tar.gz" + sha256 = "b775c985231cd0626afd0111902a764c75c9a8a123b12e1f386a1c2af3cef799" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.i686-linux-gnu.tar.gz" [[HelloWorldC]] arch = "i686" -git-tree-sha1 = "8db14df0f1d2a3ed9c6a7b053a590ca6527eb95e" +git-tree-sha1 = "b50220be02e9c839749f91a70694ae68c2712c8e" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "d521b4420392b8365de5ed0ef38a3b6c822665d7c257d3eef6f725c205bb3d78" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.i686-linux-musl.tar.gz" + sha256 = "6aecc06cf803ad16703744610deb243a21b39e19ae1951a38977610881698f9e" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.i686-linux-musl.tar.gz" [[HelloWorldC]] arch = "i686" -git-tree-sha1 = "56f82168947b8dc7bb98038f063209b9f864eaff" +git-tree-sha1 = "cc9cfa3272d4d3844d6fcf8b6b971bd68dbc792f" os = "windows" [[HelloWorldC.download]] - sha256 = "de578cf5ee2f457e9ff32089cbe17d03704a929980beddf4c41f4c0eb32f19c6" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.i686-w64-mingw32.tar.gz" + sha256 = "bbf3276bcfc8223061c3b1cf8725425bfc33ac2929214ba57eecfd170d30f096" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.i686-w64-mingw32.tar.gz" [[HelloWorldC]] arch = "powerpc64le" -git-tree-sha1 = "9c8902b62f5b1aaa7c2839c804bed7c3a0912c7b" +git-tree-sha1 = "5e9c87fc4e3372c27a77061a49d97fa5002df0e4" +libc = "glibc" +os = "linux" + + [[HelloWorldC.download]] + sha256 = "e2a728b29124fc7408d6e47cc6fc943d0336d1386e56a3775a0665b34528881b" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.powerpc64le-linux-gnu.tar.gz" +[[HelloWorldC]] +arch = "riscv64" +git-tree-sha1 = "3c9b23e46b82ab59141bbbc042158af4037d846d" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "63ddbfbb6ea0cafef544cc25415e7ebee6ee0a69db0878d0d4e1ed27c0ae0ab5" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.powerpc64le-linux-gnu.tar.gz" + sha256 = "59e2250eab04924eb7167d3232e4b0176c53097e4b21f2f3e3621f1e39f43107" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.riscv64-linux-gnu.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "f8ab5a03697f9afc82210d8a2be1d94509aea8bc" +git-tree-sha1 = "2e1742c9c0addd693b0b025f7a1e7aa4c50a0e6c" os = "macos" [[HelloWorldC.download]] - sha256 = "f5043338613672b12546c59359c7997c5381a9a60b86aeb951dee74de428d5e3" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-apple-darwin.tar.gz" + sha256 = "c4f0c83ae4f72a039c33beb26ebb1d4c0fb739f34360102be79909a0dc17f47f" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-apple-darwin.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "1ed3d81088f16e3a1fa4e3d4c4c509b8c117fecf" +git-tree-sha1 = "8c8251b0c21615bce0701995eded26ac7697b5cc" libc = "glibc" os = "linux" [[HelloWorldC.download]] - sha256 = "a18212e7984b08b23bec06e8bf9286a89b9fa2e8ee0dd46af3b852fe22013a4f" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-linux-gnu.tar.gz" + sha256 = "974f7e1d1cdbebad149e51fed4f1b7c6a0b5ccfa350f7d252dfcf66c2dbf9f63" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-linux-gnu.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "c04ef757b8bb773d17a0fd0ea396e52db1c7c385" +git-tree-sha1 = "cfaaf0517421585561e3b30dd6f53f6c14b2835f" libc = "musl" os = "linux" [[HelloWorldC.download]] - sha256 = "7a3d1b09410989508774f00e073ea6268edefcaba7617fc5085255ec8e82555b" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-linux-musl.tar.gz" + sha256 = "25d3d6ecc753f4dbbcaab0db7b6c20b29b0a79b0c31f7a26a0cf18c365d27809" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-linux-musl.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "5f7e7abf7d545a1aaa368f22e3e01ea0268870b1" +git-tree-sha1 = "8e8a17876a9c1147bae6a53a175344b805ee72d4" os = "freebsd" [[HelloWorldC.download]] - sha256 = "56aedffe38fe20294e93cfc2eb0a193c8e2ddda5a697b302e77ff48ac1195198" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-unknown-freebsd.tar.gz" + sha256 = "61a3f945941adbf75c87c1c28f05e95b187959fedf29ecaa36519c5d1941bf23" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-unknown-freebsd.tar.gz" [[HelloWorldC]] arch = "x86_64" -git-tree-sha1 = "2f1a6d4f82cd1eea785a5141b992423c09491f1b" +git-tree-sha1 = "6e1eb164b0651aa44621eac4dfa340d6e60295ef" os = "windows" [[HelloWorldC.download]] - sha256 = "aad77a16cbc9752f6ec62549a28c7e9f3f7f57919f6fa9fb924e0c669b11f8c4" - url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.1.2+0/HelloWorldC.v1.1.2.x86_64-w64-mingw32.tar.gz" + sha256 = "1f10e46f7b073136f7f668de89096d631ae8bb8903547d588f6817f0b780b2fc" + url = "https://github.com/JuliaBinaryWrappers/HelloWorldC_jll.jl/releases/download/HelloWorldC-v1.4.0+0/HelloWorldC.v1.4.0.x86_64-w64-mingw32.tar.gz" [socrates] git-tree-sha1 = "43563e7631a7eafae1f9f8d9d332e3de44ad7239" diff --git a/stdlib/Artifacts/test/runtests.jl b/stdlib/Artifacts/test/runtests.jl index a09b3c7531996..cb81c16347abf 100644 --- a/stdlib/Artifacts/test/runtests.jl +++ b/stdlib/Artifacts/test/runtests.jl @@ -195,8 +195,8 @@ end with_artifacts_directory(artifacts_dir) do win64 = Platform("x86_64", "windows") mac64 = Platform("x86_64", "macos") - @test basename(@artifact_str("HelloWorldC", win64)) == "2f1a6d4f82cd1eea785a5141b992423c09491f1b" - @test basename(@artifact_str("HelloWorldC", mac64)) == "f8ab5a03697f9afc82210d8a2be1d94509aea8bc" + @test basename(@artifact_str("HelloWorldC", win64)) == "6e1eb164b0651aa44621eac4dfa340d6e60295ef" + @test basename(@artifact_str("HelloWorldC", mac64)) == "2e1742c9c0addd693b0b025f7a1e7aa4c50a0e6c" end end @@ -206,7 +206,7 @@ end # Check the first key in Artifacts.toml is hashed correctly @test artifact_hash("HelloWorldC", joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) == - SHA1("5a8288c8a30578c0d0f24a9cded29579517ce7a8") + SHA1("0a8e7b523ef6be31311aefe9983a488616e58201") # Check the second key in Artifacts.toml is hashed correctly @test artifact_hash("socrates", joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) == @@ -214,18 +214,18 @@ end # Check artifact_hash() works for any AbstractString @test artifact_hash(SubString("HelloWorldC0", 1, 11), joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) == - SHA1("5a8288c8a30578c0d0f24a9cded29579517ce7a8") + SHA1("0a8e7b523ef6be31311aefe9983a488616e58201") end @testset "select_downloadable_artifacts()" begin armv7l_linux = Platform("armv7l", "linux") artifacts = select_downloadable_artifacts(joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux) @test length(keys(artifacts)) == 1 - @test artifacts["HelloWorldC"]["git-tree-sha1"] == "5a8288c8a30578c0d0f24a9cded29579517ce7a8" + @test artifacts["HelloWorldC"]["git-tree-sha1"] == "0a8e7b523ef6be31311aefe9983a488616e58201" artifacts = select_downloadable_artifacts(joinpath(@__DIR__, "Artifacts.toml"); platform=armv7l_linux, include_lazy=true) @test length(keys(artifacts)) == 2 - @test artifacts["HelloWorldC"]["git-tree-sha1"] == "5a8288c8a30578c0d0f24a9cded29579517ce7a8" + @test artifacts["HelloWorldC"]["git-tree-sha1"] == "0a8e7b523ef6be31311aefe9983a488616e58201" @test artifacts["socrates"]["git-tree-sha1"] == "43563e7631a7eafae1f9f8d9d332e3de44ad7239" end diff --git a/stdlib/LazyArtifacts.version b/stdlib/LazyArtifacts.version index f740516eb9953..8988e27bcb4ac 100644 --- a/stdlib/LazyArtifacts.version +++ b/stdlib/LazyArtifacts.version @@ -1,4 +1,4 @@ LAZYARTIFACTS_BRANCH = main -LAZYARTIFACTS_SHA1 = a719c0e3d68a95c6f3dc9571459428ca8761fa2c +LAZYARTIFACTS_SHA1 = e4cfc39598c238f75bdfdbdb3f82c9329a5af59c LAZYARTIFACTS_GIT_URL := https://github.com/JuliaPackaging/LazyArtifacts.jl.git LAZYARTIFACTS_TAR_URL = https://api.github.com/repos/JuliaPackaging/LazyArtifacts.jl/tarball/$1 From 056a69d1eb2a1f9525c44d89d7439714c78001ca Mon Sep 17 00:00:00 2001 From: Daniel Karrasch Date: Sun, 12 Jan 2025 18:03:34 +0100 Subject: [PATCH 10/65] Avoid promotion in `muladd` involving unitful `Furlong` (#56886) --- base/complex.jl | 2 +- test/testhelpers/Furlongs.jl | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/base/complex.jl b/base/complex.jl index 095c842795d38..5d9f9df6f2b78 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -342,7 +342,7 @@ end *(x::Real, z::Complex) = Complex(x * real(z), x * imag(z)) *(z::Complex, x::Real) = Complex(x * real(z), x * imag(z)) -muladd(x::Real, z::Complex, y::Number) = muladd(z, x, y) +muladd(x::Real, z::Complex, y::Union{Real,Complex}) = muladd(z, x, y) muladd(z::Complex, x::Real, y::Real) = Complex(muladd(real(z),x,y), imag(z)*x) muladd(z::Complex, x::Real, w::Complex) = Complex(muladd(real(z),x,real(w)), muladd(imag(z),x,imag(w))) diff --git a/test/testhelpers/Furlongs.jl b/test/testhelpers/Furlongs.jl index 6d52260bb20fd..3ddf42bf1a82c 100644 --- a/test/testhelpers/Furlongs.jl +++ b/test/testhelpers/Furlongs.jl @@ -100,5 +100,11 @@ for op in (:rem, :mod) end Base.sqrt(x::Furlong) = _div(sqrt(x.val), x, Val(2)) Base.muladd(x::Furlong, y::Furlong, z::Furlong) = x*y + z +Base.muladd(x::Furlong, y::Number, z::Number) = x*y + z +Base.muladd(x::Furlong, y::Furlong, z::Number) = x*y + z +Base.muladd(x::Number, y::Furlong, z::Number) = x*y + z +Base.muladd(x::Number, y::Number, z::Furlong) = x*y + z +Base.muladd(x::Number, y::Furlong, z::Furlong) = x*y + z +Base.muladd(x::Furlong, y::Number, z::Furlong) = x*y + z end From 37b8b61ee0bd4b8db1b210a5389cf794a1358ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:12:35 +0000 Subject: [PATCH 11/65] [docs] Add RISC-V page to table of content (#57022) This was missed in #56105. --- doc/make.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/make.jl b/doc/make.jl index 5ef5fcf55b215..43d51e9936b58 100644 --- a/doc/make.jl +++ b/doc/make.jl @@ -248,6 +248,7 @@ DevDocs = [ "devdocs/build/windows.md", "devdocs/build/freebsd.md", "devdocs/build/arm.md", + "devdocs/build/riscv.md", "devdocs/build/distributing.md", ] ] From cac16d2e862a0b5719121b268c892f8abf38acef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 12 Jan 2025 23:52:21 +0000 Subject: [PATCH 12/65] [CompilerSupportLibraries_jll] Update to new build with GCC 14 (#57024) --- Make.inc | 2 +- deps/checksums/compilersupportlibraries | 194 +++++++++--------- deps/csl.mk | 11 +- .../CompilerSupportLibraries_jll/Project.toml | 2 +- 4 files changed, 106 insertions(+), 103 deletions(-) diff --git a/Make.inc b/Make.inc index 216fc6fd7adde..26b5ae7752555 100644 --- a/Make.inc +++ b/Make.inc @@ -1395,7 +1395,7 @@ LIBGFORTRAN_VERSION := $(subst libgfortran,,$(filter libgfortran%,$(subst -,$(SP # shipped with CSL. Although we do not depend on any of the symbols, it is entirely # possible that a user might choose to install a library which depends on symbols provided # by a newer libstdc++. Without runtime detection, those libraries would break. -CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.33|GLIBCXX_3\.5\.|GLIBCXX_4\. +CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.34|GLIBCXX_3\.5\.|GLIBCXX_4\. # This is the set of projects that BinaryBuilder dependencies are hooked up for. diff --git a/deps/checksums/compilersupportlibraries b/deps/checksums/compilersupportlibraries index a03ae8ee83f9a..08802ca1f4de3 100644 --- a/deps/checksums/compilersupportlibraries +++ b/deps/checksums/compilersupportlibraries @@ -1,96 +1,98 @@ -CompilerSupportLibraries.v1.2.0+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/20ebaad57850393b6ac9fa924e511fe4 -CompilerSupportLibraries.v1.2.0+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/020de4d8b0ff6bedbadaa305ff8445e6849f12053762ea4aa68412d1ec763dbd86f479587a2fbb862487f1feb04d976c38099ddf3887817a3d32b3f029cf85b1 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/d641904255ee412c45b089d92c53262b -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/ace0383fe9bd64faeed1fb05a11bbec932bd56b8460d06d2b7c3e1b5f4f6e9a9b3345937088684e5cd1ca9a85ef1a5ff56a97a1f60449cd6e35247de1e123d81 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/2a71f320d8b9242ad26aabed74cbf404 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/03e2a4482baaca2d6ce5cc207224d03bd7851486ebe8072c7317f5fcdd641395d945552d9462ab44a9f2e4b0ffaa3874a76f314d67bc0f75393a1151ab518611 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/1beec15ad689a5f572040ca2a7b6a880 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/27bbe212a8d43e841cf8f3e9964b72bc220fea03cf5e65721b02d2f3aa5193acdce41e512578ed6be935b413cd0d2224a6bcd2e9624931f39092ba3cfc5cbcc0 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/9e949c2efe48a7b2a62bff7e1ffdede0 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/2947acb250f8ff4936da5ed02ddbfa492fc38bc87baa588a36bb892ba68b6636a912cda976f8fff00cc7a710c3bfb185826b4cd4a726750ef5f161d5f1aa21a2 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/7202764b1a89a748b07460d9c40a9279 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/63236225a9becdd166c4395ea5081c64f57bc51af89c2edb5abeb419d6eb8224a380a633afd861bb84a12435fd19c8554cbe5ffadf8324ff2c7f17021ed53e69 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/f66c30d3cec8057ae47f05df022ead51 -CompilerSupportLibraries.v1.2.0+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/5329d9469bb0f47560e52b15eb21ab70e0e2da0275bdb2f8e6ed4feb132bc9989a6b44984329455104546c95d05a05f8fb4f1cf232856219ba005100f4b16dc3 -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/1d8ae93fe000440d00c404ba5044f169 -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/6733bd456c389c7c2cd83c5e44aa575552aa7ab5549a5b3efefbc745a6129aa76d78bacb1441208fc77c58b36f1b0775aa3a44bb97e6769ff730744ecf5e8abc -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/bf1a5a3320a0a38133f04861afab33b8 -CompilerSupportLibraries.v1.2.0+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/221502795c075f64196dae687a35b83aa83a9a1ecf1ec3e9f51613bd7431c526015e412132a081e00ca13a5730d733330df79baad6fccc8758c17db9877e59dd -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/05ff63780f5b7c8c6c590c3626f32ac0 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/8d3c4149531f3782f5efbb6a6fbbb7080ba005298ba962b5bc5f66250ea9fde91b34836ed909c16f306d21d2e358f985360962e9362a8e807ccd4254da3bb19b -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/3ca2b6e8101d831e546c1b6ed2ca9a42 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/21a0b9c5acde96c0a91303f4f395e55f272d5585ad18f0365105188d129a3ca94ad66d4dd99b471abdf41a7a7262a3b258fd04b887110ad15255b284cd1612b0 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/d4d560b8ecce0ff2cb4dbc88cb25942a -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/d405f61525af1b2fe85107a70ed67b8a1eb767923487fa71539e0f49d6e70358c8a24f4ef1c224256cf677af99b54a2f8243f1e207350fcb14d426a7a6bb3915 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/8c6eddaa156fd0afee28ac5a154bc3f7 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/b9fc86bb706ad98d61b63eb4cc8bfce6b2c67b58ba2cebecea7574f44790cce044bb1b4db1d20050b59538fa43b51cb352d752c77333a0f0621fde47c63a3596 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/0a54c16fea86c6dadb39eff65c465528 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/c635c636384d3af5b4b078be7398fbc665a185eae69dd223279affb4836fb5c575d6ab296ae940ccbe73777bdb5e355f4f28a2fa27606ac143ff424641c60c65 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/892dfd91703f0f77d170a5371a1c25d4 -CompilerSupportLibraries.v1.2.0+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/8ac59d00192c0e847168e61b3e93957f3909aab59ba8d05e47686a9f8b7226496f89b932151c42198ec966ccd47721cdf547a247ea4e5c61b22bfccce2ec591c -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/05ff63780f5b7c8c6c590c3626f32ac0 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/8d3c4149531f3782f5efbb6a6fbbb7080ba005298ba962b5bc5f66250ea9fde91b34836ed909c16f306d21d2e358f985360962e9362a8e807ccd4254da3bb19b -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/3ca2b6e8101d831e546c1b6ed2ca9a42 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/21a0b9c5acde96c0a91303f4f395e55f272d5585ad18f0365105188d129a3ca94ad66d4dd99b471abdf41a7a7262a3b258fd04b887110ad15255b284cd1612b0 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/d4d560b8ecce0ff2cb4dbc88cb25942a -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/d405f61525af1b2fe85107a70ed67b8a1eb767923487fa71539e0f49d6e70358c8a24f4ef1c224256cf677af99b54a2f8243f1e207350fcb14d426a7a6bb3915 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/8c6eddaa156fd0afee28ac5a154bc3f7 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/b9fc86bb706ad98d61b63eb4cc8bfce6b2c67b58ba2cebecea7574f44790cce044bb1b4db1d20050b59538fa43b51cb352d752c77333a0f0621fde47c63a3596 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/0a54c16fea86c6dadb39eff65c465528 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/c635c636384d3af5b4b078be7398fbc665a185eae69dd223279affb4836fb5c575d6ab296ae940ccbe73777bdb5e355f4f28a2fa27606ac143ff424641c60c65 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/892dfd91703f0f77d170a5371a1c25d4 -CompilerSupportLibraries.v1.2.0+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/8ac59d00192c0e847168e61b3e93957f3909aab59ba8d05e47686a9f8b7226496f89b932151c42198ec966ccd47721cdf547a247ea4e5c61b22bfccce2ec591c -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran3.tar.gz/md5/3094705222b6b61fd6a10422a73e1149 -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/27f874cde357ffa45aaa10f2e620ec0f8ab4e5a8bf4607fc023a2ec42040bcc9a724f959237c340d67451f8621402fa05133c1420086b87135f40326c30b97af -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran4.tar.gz/md5/ba0acaff60648efa3915348a8a353df8 -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/0b6aaf75363cbe6133ca3aed351ab58ef1e441f61375f5baf702d8043813c459d48e8af17630f1a07dc22772ec9b02076af33726ed94e6314ae37d5a139d6dcc -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran5.tar.gz/md5/95f1d57cfc43677e40bfc121bce79274 -CompilerSupportLibraries.v1.2.0+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/edacd9960e9de1236c91752e103cddfc018d697e87fabb3cceadf36153b4e97842ef284bd1532290a5620007234882b4c4cd4f36525b61763d97b2f608358262 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran3.tar.gz/md5/f37fe1818e1634476c44afae478611c8 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran3.tar.gz/sha512/6e4e3eb5ac9570bfdf5280f59167eb6c4a74f3aa152afb4c5d180b9a6cdbdca557e7dd13f0b5b76943b45a65e848fe77c5b3bbc6ddb0fd846d03fbc9fbedf7ce -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran4.tar.gz/md5/b4ffd52179aa0006c56f279b87cb7556 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran4.tar.gz/sha512/a047ac7db204c31802f646351af51c55fe06498e851b2df58d7f93f75d9c0067f8736f247f108991ec01ac7f86f3026ecf58b5f2f3a76d7eab00130754e7f704 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran5.tar.gz/md5/2d38fc835f236f89f457fdf859ccb903 -CompilerSupportLibraries.v1.2.0+0.i686-linux-musl-libgfortran5.tar.gz/sha512/51fbe41efbce33b1cf3728df6fa59fd0e85a13308b3e868fe9f70f4d67857615f83542ba69be824a73e89959503dd7a11335d1c495704bd7d6cad6656d0c5d57 -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/9650002f6729c0964d33afcab334d77d -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/0b7907811a13d09b7b33203c7e46888308c7d6fcf5d69790babafc39f640541551f784264247f159a552f15df1ddd061c421a93b983d838d3bd7f85ba6427f70 -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/47e9fb99906b9647e26e4126a913074e -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/d7285691fbe1318e48e061d678e54890762cc16996652a34b190924cc1462d24ab0b08729945eb25f4bef60e60d50f3e78db57d4cda0302b8ba579db8a1311e1 -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/b588b2710f2b83d2c70c6104e585a3bd -CompilerSupportLibraries.v1.2.0+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/b62a63b0c8750f85fc265db88456307b794e912352a68997c7cce06444391307c03edbe5b901833f53c5bd55f5a1e61a586538b08487cc139a2d71fccdce1d31 -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/7cce4f3dc057ebebaa677bf6f0d51e9e -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/a0dd93905f0ede4da5e2fbacf2579154db8ac8e9963c77fb62284489686f2aa372925b3341742d86430a839267421af55f6e1e413473d17f13a1a199e6a904a0 -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/06ee6aaeca78b3e9005f53f1fa32731f -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/ff0e33ce9f93b3a867cf409b95e763efbc8f4dde65ed19107eb14d29460d084f253e03ebd6375f1da996182b3d96e1fda4abff06507258da9a89ece36663db84 -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/483251d28076ee959dff131d13d7e53b -CompilerSupportLibraries.v1.2.0+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/a7c9053a8c1b784cb6459762f26e0c2106a9758cbe2aefe8975a14aaaf61b8a08e51c465e733e44d01537beb59d467c57e536ebd8b27b7b68f46945174c469c7 -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/a147bf3a6d6550c177b8a784b9b02e21 -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/c6f7a13f0195eae8f7ad980a4b24de9b155be69c4437522723411f9866a4aee3c5b350ee2f0c95f41f19aba43acaca78309881157e8498df0664c902d0c05a5d -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/3f19c9d0e723a8d5591357ac3a9452a0 -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/5752bac310d80ed2dc1fc3d6580300d185787b9b933e31c8e0f572099abd0727d9483da8f9af858f706e96a183d2b10702c44381a080438cbb17d6459321ccfb -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/ad0f0e2fe3e7d147a0a27271a2aba0fc -CompilerSupportLibraries.v1.2.0+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/f42231adea3d0b6133c3b5bc5fbf765bc6a7ba8ef0f407fa1b8def36dd8a71d20ef39fb6e57b43208489c2795a96562cdbf15f3d20b3f3a09edb29b99d19a33a -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/4c78d56dbbbff682c0a78d11fb9d1e70 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/0e9d6dcc4b8fddaaa94a26a46e915d33fb474f8a8ee14edd4d1c7e774846c44c5c5d852649a4f70409c99ac0e1d458077b7f0eb7dc0b0326ee8b625644d7074d -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/039d37f813b183c75feebadd21011eb6 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/05e7291de1fd2520247402f0db9d348fdd7a02d8dd9133ac65701f88d237110a3cc6c6e2c5717364ab786b6e6063038ec10c9605e77bc4dbe1064a0e77617f5d -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/a985f13a85eb14d1b6339ba4983dc372 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/27468ccd5642e6e11bd5972684518a0fb883bf4835ac18f5279c3fce97b1779131c7d9e39d8de26a15c293c832946334e964919f51d7679cd0569ce82b938579 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/9d86ce2fe481ea97a1fd098bd47d524c -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/a865a4127bacaedd81b6c81279f6a44bc3497ab29a0401f66da1abfc0738ea459be9f158d06969c161a65925739665084bec5f8650a8cd1e8f0d08f1f44d729f -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/86d9db869a7af6c96dea39f5d9d90505 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/01e0c69b04138989200ded92eddae6ff1873d3a440d17273d08bee40d53b2929e35bfd14be051074fe78671cac34ac2dd7360c1571790ee52f94a5921de42a65 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/e72d28df4bcb60ab2f3389046e7c83a8 -CompilerSupportLibraries.v1.2.0+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/cac193a26328ddeff5f7bcc3d7207101c574f9bdb1bff5c2b925315c5c2404a2fdb6591d1968f30931373fbfcae9bda784c72e65580ad3acc398448cd193f65d -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/35642304a9a2f435cf5214b2715198fe -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/a67f41ba31c99a064f504f508711537f9e90089ca5352bfc2698c3fcd3e499ca716f07ffeac4fb1b88c2c934f7f380f262af8c863d3b16ac7e805d5c805ab358 -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/01df0fbb265e5ff1a480a7a5e23b0835 -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/57a79f2b8e846c1514dcb18420f26ae2889962040f410b746836cab4395749155fa9cd9d00d4c25954c0ffa72f9f3823b1b50688a20ddf675301f64e0d4b5c7e -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/1f1f6380ce8815cc9cedcea0b40860e7 -CompilerSupportLibraries.v1.2.0+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/a88ea8af8c8df792861812bfdf7f1bcaae31582ab78ce78b47a0dc6fd57b93441c0471f529ce23877131ac9701c6eed72ce89241746e18271f3686fbd718138c -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/38fc8c445a1a610db40a7609155e22d6 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/085652c7ca583c3623611ca9262b70765c9936c9feb5f9034b2c6b6d6677a7a1d7d201b83d82d0d268f3190bd1a62eab0124e8fae3625407dee7f1df89d4106c -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/f3f89eb3c2e441fde6e6b9c1c1a61183 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/c53f79e20ad043ab099873f38ece98c6bed22950610ba88b9c178a4bd943039cc426473828d509deb8c65c93309da1de87bdf36fb3954b8f8047277c418fe2e0 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/024f7133425db23e215dc55589bb9171 -CompilerSupportLibraries.v1.2.0+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/819945496ea48dd44d8c0f12a11a358b7d1ebf198d60fbad576d74ddee68cdea98070cdd11ca96567d0c772ec007c03cbc83ff5c7d2ad737cbd486fe0c9afcd5 +CompilerSupportLibraries.v1.3.0+1.aarch64-apple-darwin-libgfortran5.tar.gz/md5/20ebaad57850393b6ac9fa924e511fe4 +CompilerSupportLibraries.v1.3.0+1.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/020de4d8b0ff6bedbadaa305ff8445e6849f12053762ea4aa68412d1ec763dbd86f479587a2fbb862487f1feb04d976c38099ddf3887817a3d32b3f029cf85b1 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran3.tar.gz/md5/c679907ddce62f21bc30667cc40d8d52 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/284b17b6634087f0b969d3e99b2e4152667ab5eb9e6b5813f9739bd14ae1c25dba01f15488e901ca5fcfd780b02bc02b6bff670fefed7d965dcb585e81b03782 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran4.tar.gz/md5/1b4f6efeb83f5f3e27c42eddeafe993a +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/b1d5aa122b2bd25bcd1ce47e000f71785d617d77f44acda56f9f5ad77101a0c54f6c6a4c5560a7c12ffb8c89ae325d4f056bd92f893d219385c3d5c85aa457e9 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran5.tar.gz/md5/834adb105f78ac1bb223ef309dbf7cdc +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/dd0440805145f1a8e8521633a955317567606bf2e3725a5a7eb90515128b077f2163832ab608022fab152526f2a55991f50256ab92104d5d62bbb8a740e25009 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran3.tar.gz/md5/d613881e48181bb8ac0bf34a456c9736 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran3.tar.gz/sha512/34214bca9f7c66e3c508b2f9d88cb296695721cfba0c001660e2edb0387a2efbb2fecb0360f8eb2b1d0ec502480fe63e802f350367498a342c455c0f58aadd82 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran4.tar.gz/md5/97e4ea4394df1d784ce4de3f75aed580 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran4.tar.gz/sha512/a072ceece6600b704dae5a7491f1ead9b4e11da3d4438b7056f2c71e59b0a37d3023fb812cbae205a4f1fcaf18a4b223a5ba2cea32131c5eda0d55b1f0649c23 +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran5.tar.gz/md5/df09c5b33b2e307e0d9c2b39b450c0eb +CompilerSupportLibraries.v1.3.0+1.aarch64-linux-musl-libgfortran5.tar.gz/sha512/d0a8dc03ea1667d90bd58c2376b575a1090a54a4412bc53b311a3ea910c76dc698be5ca1078e6ca8341244f1fd6b84201ba10c10baba194c1d6c3ffb7e69563c +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/4f9b257eabaf0a817755495cfbf75088 +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/876036a8b599008512ab7010f4bc5f11fbf963bb9b9f77499adcca21fcad89f94180f653dce3121e5c1206f4fd4ace717ef8f3b40d8009a71039a84ae7272588 +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/0d296a080921b54d959a2a60884b7938 +CompilerSupportLibraries.v1.3.0+1.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/d8232dd9131c2890ea2f5c90f62c646ea1dc93a0a6de4af0a98c7e69928c5ca5698e79ff9d23bdcf47de1f5670467c9e8fed5f01e82e009696641896f0658030 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/3e0727a3813c699b6daa041e336d6e13 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/00cc2c34af7c4a5df06deaff27dff5b94b231ede4afe7a47b7b783a8d2e62158c0ba1b2062d40df949fdc0a21ac703f8c9011f998ab032bac265aef153cea012 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/b7cb328b5e5fae5b5e456d058f5c18b7 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ff191595bdf4dfb2cdd77d42e591adc0b27ca0e1055efa7fb25fc06784f26add83e6c5c7594405bdfd715f9c8e6ae3f2171a50ae218b4b691099da754fe9bedd +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/46a3fc18a65e223ba59d984f99d42979 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/cb470147f6695b101d497bf2d84caeb1f97d967bf23d1844ad70be47505588d981df096378136a98c35cda5aec090255d60cf7c1c8def9801233c72ca002b563 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/28e1bc0fb0ac1512a8598f26ee3f376a +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/7ec17859790cd08942929281906918e4c69d7f306a8302dcd591a4a67b3d95f7f72f7afbeea3a86a0d94ca5b608b3bda00ce43b594e9f173edb0228c0f79ba49 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/f9bff1a49d95fc0f3ad3d4a90b259c87 +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/8ad503a213b949f569c5b9eac28e33ed51cc55298bb66b147375dc12cb9ed90e60165aa2dca8e3d28f1a2c153894a9e4672bdb2ae3cfb3a67b1e06b345cb454f +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/d550a4dac1b20606681a56acc00c01ad +CompilerSupportLibraries.v1.3.0+1.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/14ca10ad8809dfd2434e300ad5280915f21cc1ba159a9f4aed7aa2164ae624687a2a7a9e6dd99abcfe95f40cb037c72292c992f4483fa1affcf8a9b5cf29c9bf +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/3e0727a3813c699b6daa041e336d6e13 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/00cc2c34af7c4a5df06deaff27dff5b94b231ede4afe7a47b7b783a8d2e62158c0ba1b2062d40df949fdc0a21ac703f8c9011f998ab032bac265aef153cea012 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/b7cb328b5e5fae5b5e456d058f5c18b7 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ff191595bdf4dfb2cdd77d42e591adc0b27ca0e1055efa7fb25fc06784f26add83e6c5c7594405bdfd715f9c8e6ae3f2171a50ae218b4b691099da754fe9bedd +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/46a3fc18a65e223ba59d984f99d42979 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/cb470147f6695b101d497bf2d84caeb1f97d967bf23d1844ad70be47505588d981df096378136a98c35cda5aec090255d60cf7c1c8def9801233c72ca002b563 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/28e1bc0fb0ac1512a8598f26ee3f376a +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/7ec17859790cd08942929281906918e4c69d7f306a8302dcd591a4a67b3d95f7f72f7afbeea3a86a0d94ca5b608b3bda00ce43b594e9f173edb0228c0f79ba49 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/f9bff1a49d95fc0f3ad3d4a90b259c87 +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/8ad503a213b949f569c5b9eac28e33ed51cc55298bb66b147375dc12cb9ed90e60165aa2dca8e3d28f1a2c153894a9e4672bdb2ae3cfb3a67b1e06b345cb454f +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/d550a4dac1b20606681a56acc00c01ad +CompilerSupportLibraries.v1.3.0+1.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/14ca10ad8809dfd2434e300ad5280915f21cc1ba159a9f4aed7aa2164ae624687a2a7a9e6dd99abcfe95f40cb037c72292c992f4483fa1affcf8a9b5cf29c9bf +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran3.tar.gz/md5/73e14b94dc74d17aca38a51ad402f836 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran3.tar.gz/sha512/d37263a216fb3e9b94dd032642ed6bf5be154a5c66de3e4bd74e5e2059d9740958a673796eb652ca9ebea8ec09a7eec837d8906a50775913325899aa190808db +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran4.tar.gz/md5/23996e5c6690b35e7c36bff245f6f4d1 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran4.tar.gz/sha512/660dc4866a13f9a1ae98424b605723b250218a034e02151d4160d58ca07bba4fa1390e99e7fe2f31eccdd518d1ac4c5f5454968ce52525e3a2d21918b6b5bba8 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran5.tar.gz/md5/af836562cfaf76f0728be0d875d29ae1 +CompilerSupportLibraries.v1.3.0+1.i686-linux-gnu-libgfortran5.tar.gz/sha512/a2b10c2f72d1e84c7b496b7ad6d38629342c93cd6a7f691e5bbe96ce28ef40fd38509d382d22208e40cc4953e7b93d1c211bf59529db0ad1a77b684ba75bc68a +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran3.tar.gz/md5/502f089e5ee03b3a290ee6e18577a22f +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran3.tar.gz/sha512/13a97c2386f37aba2416ec35fe67b99a1eccb880b0254ff0a70f2ba01a01a15c80251606ec7eb0503d59a7723542b6b9778d6c9d9e4ba66ae5cce51e46a9cb40 +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran4.tar.gz/md5/221aa40c278faee74ab6af46686d68d6 +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran4.tar.gz/sha512/9e4e598c8acdecebc812555de9631f022f6158d679c329537e37f83c76c818f31476a5827924b5ac12978515d64a7e913f220ca75314f41d3227573e9a2ac9af +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran5.tar.gz/md5/c364ec196e66dd5eadc3932b208a0385 +CompilerSupportLibraries.v1.3.0+1.i686-linux-musl-libgfortran5.tar.gz/sha512/3f7b80fb35a967d9354c2f4c40bb6d62751a0d791aeec09817cdc278393cacef089214f61d8338c0981f7a4ed3144d37bc9267cf0e7ce6c4cf651bc67c431b70 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran3.tar.gz/md5/4177f1ede00d81472bb69888f5b3e26f +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran3.tar.gz/sha512/09ab710599d237ee35fca6a39b4d67b36bbadb7d127797724743026eae72319faa161755b03f4cb67c83f801aa4132968b561245487b2c2c0836d0ff867c0e83 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran4.tar.gz/md5/9402d280886784bc245096bdc838fbc6 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran4.tar.gz/sha512/60e72336efdd307b88b1e6db5234388ac1892504ac858b412d18f072a33ca1aeaf1b8621ccf43027508b7a4653150f0849a89c57164beb1e7f24ef32f7fb7f11 +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran5.tar.gz/md5/310b163628e7defdfa6a293360b203db +CompilerSupportLibraries.v1.3.0+1.i686-w64-mingw32-libgfortran5.tar.gz/sha512/02e9a797246feb9c4b09b0c67c773dac5c3bb61568bdd48be147adeb2dc08fd2bd7151f2293e2756685d011e463e39dc5ca0f79593dda7501cacbc15adfc74e0 +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/c139a9d54f39701e805d2af185a6f17c +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/0d1f29cb04b42b276edd7998a02f6166295f6b7a2a8ffdf6b2986145476385b19c2f93b012974835363ef57f2018bdb80814adef3b72b9378f0d2c6a8805c43e +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/3ab360133835e1d0a6a24bb2de1dde02 +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/9c2f765b58a73b3705f787f68c995d8f2cbd211978c0ec8ac2adbfec6685f4b3a02aa63bf75b9dbf0a2a5c048e35536929d04b89c120671174d76132cbd2c7ed +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/6ce9e27ab33b35900d8f81c2ad05eec2 +CompilerSupportLibraries.v1.3.0+1.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/1d8af2664e68d18ef4f68b9fed28979af0acf3dd09c8064c4b25b3268808bc6901ce727b5b3ec3c27e37914a7c1f8c92e5ce35de093d66cb6a2e98ad59c2252b +CompilerSupportLibraries.v1.3.0+1.riscv64-linux-gnu-libgfortran5.tar.gz/md5/6c292cf98c6b4cbf10aeb4f0af383222 +CompilerSupportLibraries.v1.3.0+1.riscv64-linux-gnu-libgfortran5.tar.gz/sha512/1497789d918d633f319f89a04241678602d3b0f441ca6f8f6d756f6d1fba59d5eca54fd24183e39e9b956cd3c053afd747dc03a9a1e2d4819d26de3539c5eb07 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran3.tar.gz/md5/0aae7ac19dade024e0228bb1a3565edf +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/b779badad7e6021875b5df04793445b4056d84cc217f389f9496d8ca61af71d98a667ec29b912131c83319be4d6e82c59e7c3f409f302cc3691899f0e77edd46 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran4.tar.gz/md5/6fcb9749463a96504f1e23cd97695f60 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/66d4cb8237859234f8fd49461b5976a7f155e02fb93c765208701c43c041dc8693f3f8b868ba74bd28614586c0f5109a5b5aa0d0d69ac38732ad6d84d2635e04 +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran5.tar.gz/md5/af01aefc789a0388df504abae68fc01f +CompilerSupportLibraries.v1.3.0+1.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/444d1d54fb6ef95f2093894c685a4065e9708504b820bd9325bdf32619eac8b2972b1601e788ff8f1ee2759117b726c04c8bb395820359bdc737bdfdc3c4026b +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran3.tar.gz/md5/df1c55a47f9faebf09ea093d5d1ee344 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/03477fdf14d8dfce204999e6825d9ad94c2c78686d59b251f39d1bb357b3c9d9a74339c4d5f5e97420870d44f7bc2fceca637fbf7b862d0d1cf04a19a2a0b036 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran4.tar.gz/md5/8812418d84c2ac289d64a597d4968704 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/4da50ea541c13a98ae05c6ff67b8021496b871a205f994605f0230a67eb6c58ede55aa3a471df8bbdd5618177d34914186cfae106664b80a7fef795e5fe97e8f +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran5.tar.gz/md5/55bd8dacbc4afff6196494542ea13eec +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/2bb63e68f56818c0a3bb988f395ebcbe99af2740f806e324c385c1dcd7a5dbb058afd286fb6d85a1621ca668aba962a8701bef96a4547b0d22f92d9e4f4b51cc +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran3.tar.gz/md5/1e06592e53de4448b0712a79e61b9a51 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran3.tar.gz/sha512/cf92bbc217a51b9a18e07c5b5248ac5f59f92a7924c5fc566a1bd5b87a1acd36ec9c1d64871b273f80670596c05c1795cec91294f32f8dc1490633ea6d543037 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran4.tar.gz/md5/fa81135fc7e697eb8409baf3fcafdcb6 +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran4.tar.gz/sha512/32ab98be0521f2451ce9b71c5ce7dfc70094583df80ed8db3990a2041594839f065abcf6c847fe6b8293eac3b3395da16ab3d24cf5e15c962aa320b28a6cd4be +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran5.tar.gz/md5/d6f0a90da74eaf2f9bf4f7b884231a2a +CompilerSupportLibraries.v1.3.0+1.x86_64-linux-musl-libgfortran5.tar.gz/sha512/cbbbd0284799f78cf20a41f1b2d110651ee0460f0191d519d522a5034a31edaaf62ef130e7ef42c28882e224a4f997f0bead5b569254cdda7100b1f41e286b78 +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/c525e70e726f0fc1c49deedd08ab6026 +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/eb50d1443e1d13b892c141ac579b2e807f346d98a75e2ce9a0a23494c754b7149d1900046f5c39e324b48bfeedc6bee590a7e2c182e6f0e3c07b9f816fcb9d6d +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/9777c3216792efd8e8625f5f72442be6 +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/215398a9c893a5298101d98a3cf3df1e59e6dd4b0d66b3cdcd9decd8725541ae33c30d1e391fb51d7aaaa33dc5911511257f7ee7e3ea6350a8942ae70fcb3ada +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/c7571567040d646935234b51c121745b +CompilerSupportLibraries.v1.3.0+1.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/159900879d46eb2a2e45f0bfbf6eb7b03c1e28705d576ad712f67a3ae242e7e4642c08f3be181b9fbac659e1c76de6ca278ad3662fd15e8371adc7bf19e9e9b3 +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/63187354746bbcfd43c11b8047595d21 +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/7c004e5ee255a9cc410b2f8f8836d0dffae8f4e35552c57a74a9c2eb8dadd6f0966ffceb296fd61c5c0ad7a0ea25c80ee2d7bd80ed3ccf1305f236b64e2dad5a +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/64f5d316b2d694dbdb2c96e557482de8 +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/e1b3be2e6e9d4ccae55ec131f6cd51a7c4391639365057f7c8ecde539c9f5fa4d73942cbc2d06c62f43c2e1bca0469862a9ac6dc064536400ec09f37a20e2b1d +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/d10bb5d9facb9428c22f920798876f9b +CompilerSupportLibraries.v1.3.0+1.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/7671d0a7e1d965d0dfd56e3f037dbb47a2748cbff2656be26741e1b15687b3ba48bb44e7d43e005cd610257c94ffa8e71eb3e3ade772ee5c6f6aeee4535f04ce diff --git a/deps/csl.mk b/deps/csl.mk index a50a08fab8506..fef950aa41621 100644 --- a/deps/csl.mk +++ b/deps/csl.mk @@ -117,13 +117,14 @@ distclean-csl: clean-csl else $(eval $(call bb-install,csl,CSL,true)) ifeq ($(OS),WINNT) +GCC_VERSION = 14 install-csl: mkdir -p $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc_s.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libgcc.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libmsvcrt.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_private_libdir)/ - cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/13/libssp.dll.a $(build_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libgcc_s.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libgcc.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libmsvcrt.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libssp.dll.a $(build_private_libdir)/ + cp -a $(build_libdir)/gcc/$(BB_TRIPLET)/$(GCC_VERSION)/libssp.dll.a $(build_libdir)/ endif endif ifeq ($(OS),WINNT) diff --git a/stdlib/CompilerSupportLibraries_jll/Project.toml b/stdlib/CompilerSupportLibraries_jll/Project.toml index 12806e4bc427a..2f8143a77d740 100644 --- a/stdlib/CompilerSupportLibraries_jll/Project.toml +++ b/stdlib/CompilerSupportLibraries_jll/Project.toml @@ -4,7 +4,7 @@ uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" # NOTE: When updating this, also make sure to update the value # `CSL_NEXT_GLIBCXX_VERSION` in `Make.inc`, to properly disable # automatic usage of BB-built CSLs on extremely up-to-date systems! -version = "1.2.0+0" +version = "1.3.0+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From b671c9dcdd715ea8c2ff7123b2905a0259873739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:30:14 +0000 Subject: [PATCH 13/65] [OpenBLAS_jll] Upgrade to v0.3.29 (#57025) [OpenBLAS v0.3.29](https://github.com/OpenMathLib/OpenBLAS/releases) was released just 6 hours ago. Note that OpenBLAS 0.3.29 [doesn't support building for PowerPC with GCC before v11](https://github.com/OpenMathLib/OpenBLAS/issues/5068#issuecomment-2585836284), which means we can't support libgfortran3 and 4 anymore. --- deps/checksums/openblas | 194 +++++++++--------- deps/openblas.mk | 7 +- deps/openblas.version | 6 +- ...enblas-memory-buffer-multi-threading.patch | 49 ----- stdlib/OpenBLAS_jll/Project.toml | 2 +- 5 files changed, 101 insertions(+), 157 deletions(-) delete mode 100644 deps/patches/openblas-memory-buffer-multi-threading.patch diff --git a/deps/checksums/openblas b/deps/checksums/openblas index 74cdaa26c30b2..f1bcf3f322d8c 100644 --- a/deps/checksums/openblas +++ b/deps/checksums/openblas @@ -1,98 +1,96 @@ -OpenBLAS.v0.3.28+3.aarch64-apple-darwin-libgfortran5.tar.gz/md5/312aa603d089d680205dad7d5da58195 -OpenBLAS.v0.3.28+3.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/ffb0069561f52f8ac2f8affe937a00592e0c5d75c6d64bb0d5c93d1c925c93a46b763638031c88818b9dcef4a7b149ee3f15792a812e87f57a8ad086604164c4 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran3.tar.gz/md5/7c43d9e9ac07820130a3d5faefdef882 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/3ade0f098796148c37b118f9c052bad4e40431b4792f001043f040f8b1e4b7c3bae512f56ea21e6c0111246b2200e7720fe720a56a19dd11d1fba789344f29e3 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran4.tar.gz/md5/cd2fe87dac703c8bfa25406aa732b88a -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/2aea68bd8f1db2ac920951c8d9a47ce8c071f3736ee8aad8d185a09be25234a0ffd11b9f9640015b82770ba3b3fad9aa511cc43501c1bb5a3a44f1fb7ccd5692 -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran5.tar.gz/md5/e3db2bf2f1f38aeee8530c78f3ec049a -OpenBLAS.v0.3.28+3.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/a0ccb92e818650ac3cbc292d5af1a000ee9b123953cc3eb16e2479e926af3f2be0ed9858e3c0c1075b1b9dd70ec1e51b9dce2c9d45b999d296aa050d257a3cb1 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran3.tar.gz/md5/5bb605738930037259e773ebdb4a7041 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran3.tar.gz/sha512/967e0f33be7b743d9617627a947a802286962a46c7c3b2418aaa1504cffc5f311b01e1702b35ded18ae3686b1914c6085213b03fa8a51e0a7ca16dc4cfee8504 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran4.tar.gz/md5/ce175e82b9c6597c546552e79a43f934 -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran4.tar.gz/sha512/8ff5dff293d9786fc4f541b209b35afcbe325c13ddd0f9c8f9bfca8ba5c318c7890152260a5441b9e9088751ce03b1ff8f0f5d6fd4f142fae34bdb7390d1952c -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran5.tar.gz/md5/cae6aabbdccf31fb78b234785b52d48a -OpenBLAS.v0.3.28+3.aarch64-linux-musl-libgfortran5.tar.gz/sha512/ac842023e5db243fcfada22adca051bd2ffa04fca496454539931eede159e5d0490d444c338684c2d178c3367b23b8f3d76c544e30f1897bbed181f56237619f -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/875223f1a3867d1d77ca911da1f12e7d -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/a53eced30cd5d85bf13f17959f0d43127a1d967dfa3fc18fd931b8a0670d8f4fa7fa4e5360937ec301a195e8c4757d2454c8d1d189e6429b97fe3b322559c970 -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/efc5b9b88bbb515b88b4cd84d280d6f2 -OpenBLAS.v0.3.28+3.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/16581e2b61500c939f3be0d1e1aab3c103c2cdf56b9e5880368ff87bd2ecec89e6ee6ed00f2db90208ca26132c0b92f318084b0b2644ed93e72ca3c9706f951c -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/5d1f45f53dd1730051095fb8e027b14f -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/0b1f91e86b5078b7cd6b64bc429a0e63bb5adf28df1baa336e67819fbd2c09f59b643c39e580f63e3bbccdc631c5d5e14c7d8afa6af94250453ce5286958f90f -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/8b3e3ea928975c575798d47466aafb82 -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ebac0f7047dd8b97d85e4251953a23824701af02754afd6808f13eb276326b30eb292c85fa717fbd2f21b929e6a9816a012b8ea378a0fa27e671f81435f5d3b9 -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/5aacfce96d5673b4d8341cb097d22c4a -OpenBLAS.v0.3.28+3.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/b84dc2b8cbe5453555182c3fcd8624d7a2b28fe3826d54fde3b77ad2c33e60309317d150f07554dd85e168b0ac1f91537a5c2c17fff9c02dd9216f01161e4965 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/dfeac22ee204868cf254dab5ae79382b -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/710117eb7400a0aacf69d6053730eb3b3ff4767f8d38defb2aaad94aebf1646a794489e78a8f46b469901159cdca73dd2b9460fff11e95daa4a2642cab721a25 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/13ff2a40bc55839bdef76b796db1eb76 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/eb61fe6c0221e8f9d7a626b8d088ae1497155341dafb69835e7d53af76689ae212e1e4621e0729df5d896888c0b2d7354a24f7b57fe1d68f0b35c26bcf096699 -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/aa7349724ba1d47256705777e755289a -OpenBLAS.v0.3.28+3.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/25ab56c44b7d0d5de17344f39071e6894e878e89b5e35412a3c9fe345abd2eef76d7816cabb6407c7c521c3bf67a4741b37ad7e580962ead9275273e431f1fb3 -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/5d1f45f53dd1730051095fb8e027b14f -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/0b1f91e86b5078b7cd6b64bc429a0e63bb5adf28df1baa336e67819fbd2c09f59b643c39e580f63e3bbccdc631c5d5e14c7d8afa6af94250453ce5286958f90f -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/8b3e3ea928975c575798d47466aafb82 -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ebac0f7047dd8b97d85e4251953a23824701af02754afd6808f13eb276326b30eb292c85fa717fbd2f21b929e6a9816a012b8ea378a0fa27e671f81435f5d3b9 -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/5aacfce96d5673b4d8341cb097d22c4a -OpenBLAS.v0.3.28+3.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/b84dc2b8cbe5453555182c3fcd8624d7a2b28fe3826d54fde3b77ad2c33e60309317d150f07554dd85e168b0ac1f91537a5c2c17fff9c02dd9216f01161e4965 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/dfeac22ee204868cf254dab5ae79382b -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/710117eb7400a0aacf69d6053730eb3b3ff4767f8d38defb2aaad94aebf1646a794489e78a8f46b469901159cdca73dd2b9460fff11e95daa4a2642cab721a25 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/13ff2a40bc55839bdef76b796db1eb76 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/eb61fe6c0221e8f9d7a626b8d088ae1497155341dafb69835e7d53af76689ae212e1e4621e0729df5d896888c0b2d7354a24f7b57fe1d68f0b35c26bcf096699 -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/aa7349724ba1d47256705777e755289a -OpenBLAS.v0.3.28+3.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/25ab56c44b7d0d5de17344f39071e6894e878e89b5e35412a3c9fe345abd2eef76d7816cabb6407c7c521c3bf67a4741b37ad7e580962ead9275273e431f1fb3 -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran3.tar.gz/md5/53087cc770708c57d2654fd0095b64df -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran3.tar.gz/sha512/90961448ae40b0445bf881d0815aec54d2096ad235dc8e3db8d698a72961ef9a97e7fcd08f79c83cd1f7c5a341464f52a90351d927d5f1c3e9c8ee32b17970db -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran4.tar.gz/md5/ee910e19faa961bde11fdf90c211df9d -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran4.tar.gz/sha512/f5cfecfe965991cfd7843eff71efa71d6842058565bb63657e909b2942e58a8c7506aa66335308961e59f392da16e1177d79542ae509795566a14122f67a1782 -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran5.tar.gz/md5/fe52ba7ca8e16f37aa04b79248e0471d -OpenBLAS.v0.3.28+3.i686-linux-gnu-libgfortran5.tar.gz/sha512/79b5108886d60f12424709a841e359dc1cf23cef21bb0ee6d1a48043ac48a35dac1637e43c8ebf3f2e10dd34721993a7a12c5776f2975dd5bd7b6e29e1a9adc3 -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran3.tar.gz/md5/88d8ff421d29456f1d7670ceaf8867ca -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran3.tar.gz/sha512/91c1bd8142845d11fecba87a719315a14218e3863955ddd2ed82cecd4a2c177a48c660b6aac374ee9a11008245c0ced1bae70eaf5a1a6e3114db02e09a96396f -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran4.tar.gz/md5/3035066a53032b551e49f56b323e941d -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran4.tar.gz/sha512/f218e152a1c92bd374599814612add8010aedc78113cbe06465e8a1ee7f66892bb654cad687aa55555e74f3a65d74608692d41c9f0ce6c0bc63475ef62ab55b7 -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran5.tar.gz/md5/f7cf36ac9a0cbb535952ec73f2e6c9ea -OpenBLAS.v0.3.28+3.i686-linux-musl-libgfortran5.tar.gz/sha512/00ab052d9fa4a72a640545782019f24ed6017b36aa89c5e659ce73b1e821817f560c09f71b26c027c0a05bd13567c71a6d7f5995d1c39ab233bec56cd3a7fd9e -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran3.tar.gz/md5/b19d09297372e071805ba033afb55def -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran3.tar.gz/sha512/eb1138578033167ececfe428db17fe28fad70631da3c25532edb4204fe733821156d6c619b6541fd47d53d335d6ab11b3d1ac1effb56031a2f782a5e8d863a89 -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran4.tar.gz/md5/98ed2a8f2d3249438b913d5f35715a53 -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran4.tar.gz/sha512/fbc32d81a4189ac170b18a029419bc98bb0655ee4d485f4bd165a394d223b80ba77f848d94a9ad96d926291de3db4a7602abd81c44fec55e4591dfe0aa91e29e -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran5.tar.gz/md5/cb99d7d4944c5283a1a0142683e1d377 -OpenBLAS.v0.3.28+3.i686-w64-mingw32-libgfortran5.tar.gz/sha512/b77d3225e60f49506917bfff78c187df7157dbc834eccda2fa03d03eef8214b225682888a411a8b6e4b29a8d7e2b0ca625ea8c56b84ecc39e1f4f1012523c096 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/c6e5d4867a068e08b3f56f474e498b81 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/de6249439758a501bfd27d3ef04ec04cc06edf64de73f0709a6a40a2eaf40bd3d5d77dfd54b7b19e2f6bf6c104b4416d3e225faa0cff4cb631785c08d90b8614 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/32e70466cfa3cfec65ab4cad3abc5f03 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/2642385a5e9fc8e9c3839a5a44f9753b21b5078725f7d0c3e1ebe96b76129a3b8e2627d92629dee4f6fd7e8e51e86a7fbedc80cbe4d1a6812cea363559950da0 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/e2332831bd88d57132241697952819e7 -OpenBLAS.v0.3.28+3.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/ad03edf9ac56bf6311f0ca70a1bc359242accfe82cba9e42f39f6cb1c3006226179ff9be8218847889cae10fac13bc33f60837e1e3249e309172da7fbc25400f -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran3.tar.gz/md5/27c24775af446a44a72a28ffd197696d -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/2af8caa33bee88efff84653f3932b04e8fd4aabb1bf16d49fa73657b0ec13c9457fde7ab3f953fc9b01da5c2841c3c9b588e3b0f559b89df0e6268468d1f7cc8 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran4.tar.gz/md5/414e701d918d5fba08a12de6979db4b5 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/949886d388b80e19b944d102852f2bb58ffa03c42e624986dd9dc076797c996634d4a8fc0f04544451d6848c2079969816979e1f68a999b2747e9dd5472be7a6 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran5.tar.gz/md5/29fcf62c0280cc10f91d22189a2e8de8 -OpenBLAS.v0.3.28+3.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/02e75d4ecf9cd922157a72c0ca2e713cf336b125df3982cd5f7cc4f2a04367ad4c2b1190ca2a0a9df8b639c7ebcfc9783066e99dd0b13acde7b02038391e8567 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran3.tar.gz/md5/147d5e8eb2ec78fc8a31bdb091fab001 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/2319eda568800c0b1f2d96a8a36c59b1bbd792c06de1d740aea3f1e49798242426ea8d10c100c42c3c281702e2b4f5b673b6ab5252b276d48542e875bcaa3094 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran4.tar.gz/md5/448857d9c4b2e95afc12a14c75b24055 -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/3e7c8cd55e0b15a30992b1e0b48a6e2ae36fd9babf689fa5595c7de94aec401de1d7821d45a22bf14cd5c45c708bc8fa3511d34d732dadd4daaca3f49e200bdb -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran5.tar.gz/md5/3aaf417685b44e0e505208f7b31b981a -OpenBLAS.v0.3.28+3.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/f7b1d123e48ede93fe624a79d9535a8915bfa3441d7a6f9c6643467027414c9f2538e299858ea98bbb49d4e6d385a6a491063cb1878ac3b0b3d6a8f7ff0a48df -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran3.tar.gz/md5/5723136deaaf4b2e5960fb0774943288 -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran3.tar.gz/sha512/127ea8b2b0d8d4586a23a2b8ecbf148d512efe68626e89b0688c3c9e29ed9420b45ae86755c1467313c565f9f3835762051d7086a815b813dbe6e9eb05fb4be1 -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran4.tar.gz/md5/80b1b9cf5346916edda653174a987aa2 -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran4.tar.gz/sha512/77e1387ec969bbed4945d2a598a1cd04d258265c4b2d5c43af92118eb32e0c69e40619a20ea1835f277febcfea068b241343d44932afef832bdcfd2e9f618f0a -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran5.tar.gz/md5/44dcedf01c938d1a1c67dd3bc90ab61d -OpenBLAS.v0.3.28+3.x86_64-linux-musl-libgfortran5.tar.gz/sha512/e490d49b8d41d73ab3e71aca8c691ca58704f0fc6930cbfcc203f97b8db8d83144bad597a2c53ff0c0c4f7c40316d975a1b589a3603873d508f6beeb75970c5b -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/0e8a7e88b54cb836292c289d1c456fa9 -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/0e9b3af6839b9c41c950bb4d8b739f0243a890af7092ef9f3a00e4931f2acc3820afb78e40c7bfef716dcd3230c1d0acc7b0b37f30eb47441b476bd7540745e6 -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/5fc47ad55780c99ef9cab7ef1b26d9c0 -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/c531201e4abddd652efeb5801658f5c1e4891578f181e99d6e41fc0d3bc6347b82e5e928ff8a717ee1e75bb0a6a765260bf7c99fce44aa24c21f1c5a5e3c1e3b -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/dc127f3ab984b5d47b325d5701ab73cd -OpenBLAS.v0.3.28+3.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/50850911703320894a2e1e996c5de4613b5f9e3012f5cbf591f3677799599c45d9cc4c42cf310bdc6ba91ef550e52f6424bbbabdf47f96748d4669d94e6b46a4 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/937847e2ad00539f3422d1ecb9d26d55 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/751d889661ddd46cd5718b49e34f826a4fb34b1b992251a5a975bc0af15b74a75d8a56f403e8fae570223477b2b8927d9cb36764e4b9e466045d5f317b8e7196 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/180c54c50362d05696589b270693ee8f -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/2e3b76be5b7c4a7dc45f07e17493abd7ef9185e92429d8fa4d38766e0da96dd0777b619a9e420d2e1142bdab2ae1f755f9bc9ad97ee9a7927741778f89b9135f -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/2f0fac7c96af66ea63fce26e409f4db6 -OpenBLAS.v0.3.28+3.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/141522971447c38b4908342f3ad09ffb18142d2e79b44f66fd80047b44c09216c9b94c39f776e3093f9ceb6bc4d6270cbbfb4209b2fc0debfe93e7145cb4dbff -openblas-5ef8b1964658f9cb6a6324a06f6a1a022609b0c5.tar.gz/md5/f7a1fe86cefbf7d4f2608843c7833ca7 -openblas-5ef8b1964658f9cb6a6324a06f6a1a022609b0c5.tar.gz/sha512/5f6020e958967a12a3c5b18bde13331f9c0602bd073563f35cd7cec848c92b45f30ca362819b12cd16989c0e4641ee3e63db8322d1092f61b31ba2e4068dd7a7 +OpenBLAS.v0.3.29+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/227fc95ef10e30698aade797ebd8b685 +OpenBLAS.v0.3.29+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/49a932f0c1c2d1087d20a3de2940733ed6a944284e1cf2a384a7401c5ca6bd90a35e9679b4f19bac176923aa170427e7514a47fc16261413ee03a59bbb301bd0 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/77acdfde5dc6f05629f3fb68a95b78f8 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/f28187213eac2d481bc12263fe13fcb35f4771084bacaa42b0b149ac15cf89d033910519ecc5cada77915a48c95a2de3ea4a476c0c6bc3f154e7f2ceb4bf3ffd +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/4fb2bd80d3e4ad8ce04fa33c9a2aaa19 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/8cc2aee3b351cc5c78e494efededdf98f65ce8942453bb3a55c90e0822ddcc07bc7716d0746bbc16701eca458b7a7aa933e9363f71bd56788c9fab36bd9bcf6d +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/3a3ef97dc80dec3d0debade503ca2232 +OpenBLAS.v0.3.29+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/53d707f9bf57c1a19279f0146e767d779280f922ef621b5f372cedc018efb2798adabbd762324819f342d0fd98ec17c68badc50da7b6e9aa3e57c3a3c045dab2 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/463cb6b46091f4b4b4f2535b9f38f11d +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/5a5a7d5a7ca5e619d5af9bcbab7cfffcb4b7954005cb4a2d03f4cd0ef29c95707e830ad0b0303d694cace557cb1e9973c0244ae1f635249a313fb9f9cdfaacd9 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/699ca0247ec7cccec0d9d2801b5a35a7 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/3bb2926d2d2a43c280bb947063dd74b65194118edbd99df820bef56a546648ed903245e0947ebc31765ff43784b11349bf86cd592c78d143c0627d692162b344 +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/2ab069e5abd5014495b849bfbaabbd3a +OpenBLAS.v0.3.29+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/fd10e4ce326c524d97e69e50342ab63b8298c796faab8f4512772fbb9c4ae1ddc85d54643c868f3b2dc8084af974430e1f8751576bedfdc88af2ba0d2affba1a +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/md5/ce5d04e041e9447529ad8e043e45895c +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran4.tar.gz/sha512/eaf521d3957713e9d22b2c0b991f5eb846096891dc15bc42ad0817c32e6a1343617d28afe739dce0e39c185d022d3cdd44db2610635691990003b1b0a29f4657 +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/md5/00b3a4433f93a56fa8b0f17acc254865 +OpenBLAS.v0.3.29+0.aarch64-unknown-freebsd-libgfortran5.tar.gz/sha512/a9845380778ec15642d74a46dfa65f8a325929f8ec8d61915941f6e228bb1ed29310f86f20ec559fdc2d5dac98a780f71a1b3116676a34e18ee7c0cb86cb7124 +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/1be6fa7ef684733faab744fdec6c8dbd +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/7c7803a0484b8c8e343ff5049e52fe81b76e43f0aaca7a5ad0134079147d2311cb5b159738486dcdd7ec69eb42cb0eea738741401179499a53fead2fbd8dba3b +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/451dad687dd26a299e4a44db37a8db2a +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ea73ee91896203566dd7510303c73d77189afec913ac1de3b7c7935dc2c460f87c83a8ddd272d9542b619e419b9392479f02540ef1c8d3daa528bf05aaf5c3f1 +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/07ca32f715981570f2e1a5ac6721e569 +OpenBLAS.v0.3.29+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/c6ece0dac375fd66a303ca6f503e46f78472a59dc13381e8462e3e9c29e133cbe87ee77f6144a80924ae286162620c4395f5217e4f9ba379a471409085950427 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/49ac07fcdf0d7ce221051d089b408e05 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/6c9c379473f1bb5f202ca183c6ef4d43b442c867e67712e6ec2936790c282143c1edae0a1385e366f729c952e02fca13604f6b51d778dabb28ca7be0f359281e +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/87e3dea9e115fbc9a0c7f64020c41f74 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/63a37a9cc882562978460e1e0f603177921a64ece7d4050b0b7a584e05d80f58314e7f8e988ea5446945d7009620c4f746ce547fe7dcb77a0707d54fd830983e +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/8c85e7ce9bd702438c548bdae54f5c32 +OpenBLAS.v0.3.29+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/3dbaa326944d79688fa167c968a7e2660bf3b94c2e052755cc8b1ede853c02364edb7fa974880c37c60ee6e6f84c75848eb4d999c5c1e8881441191dbab056e2 +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/1be6fa7ef684733faab744fdec6c8dbd +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/7c7803a0484b8c8e343ff5049e52fe81b76e43f0aaca7a5ad0134079147d2311cb5b159738486dcdd7ec69eb42cb0eea738741401179499a53fead2fbd8dba3b +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/451dad687dd26a299e4a44db37a8db2a +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/ea73ee91896203566dd7510303c73d77189afec913ac1de3b7c7935dc2c460f87c83a8ddd272d9542b619e419b9392479f02540ef1c8d3daa528bf05aaf5c3f1 +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/07ca32f715981570f2e1a5ac6721e569 +OpenBLAS.v0.3.29+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/c6ece0dac375fd66a303ca6f503e46f78472a59dc13381e8462e3e9c29e133cbe87ee77f6144a80924ae286162620c4395f5217e4f9ba379a471409085950427 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/49ac07fcdf0d7ce221051d089b408e05 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/6c9c379473f1bb5f202ca183c6ef4d43b442c867e67712e6ec2936790c282143c1edae0a1385e366f729c952e02fca13604f6b51d778dabb28ca7be0f359281e +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/87e3dea9e115fbc9a0c7f64020c41f74 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/63a37a9cc882562978460e1e0f603177921a64ece7d4050b0b7a584e05d80f58314e7f8e988ea5446945d7009620c4f746ce547fe7dcb77a0707d54fd830983e +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/8c85e7ce9bd702438c548bdae54f5c32 +OpenBLAS.v0.3.29+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/3dbaa326944d79688fa167c968a7e2660bf3b94c2e052755cc8b1ede853c02364edb7fa974880c37c60ee6e6f84c75848eb4d999c5c1e8881441191dbab056e2 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran3.tar.gz/md5/86834236dee3db3affb38b8cdcf59681 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/6731b4ea22a0f3d25f9d041e2baa6d66f1027dce49931a334a33711fc4c6de5da368274c9328618ed78158855c5d38524b917447d1aafb5c551934cf982505d2 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran4.tar.gz/md5/c63c2fb1bda01456d99590e9aec3b45f +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/437c260499f4a28db9efb4bbdff31c0f675f3ccef1bd48fd2dfbb8c8897fc75608bd7247293bd3eae129b133cb05c3c8150dd19c243faa09b6506688f57c633a +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran5.tar.gz/md5/376567d56bf4314f8a4adcfc4d1baa66 +OpenBLAS.v0.3.29+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/c4952874b19af4fd0d5541999d07094f7e7e983124964405a4756b9adf619172b7128e11557e64a80bc4eadaf76c783609a75f25ccfc44fc4f181886a0c8ca18 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran3.tar.gz/md5/8f7abbc6d5cefdbefb2b9499ec8874c9 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran3.tar.gz/sha512/b8c39674df9400efecbe4ac740f0c3ef11a04dd852f31774d63db3ca6583a21c8e0a0b80aa4e7b82be7a8fa3de38892d4fbca34244acef7fb49e8ffc0e1eed09 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran4.tar.gz/md5/6b0f0544fe45de9d2dea946c7f55cc40 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran4.tar.gz/sha512/8c21df39a8ee99614ef0880706c1497d032f68dfc332cc5ee111f69bfc818db4896115a964f16115ac49b01b31713037c905792d9586dd05471efdb21dd0be88 +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran5.tar.gz/md5/aa343048c35c5227a4bcc37f25ddfacb +OpenBLAS.v0.3.29+0.i686-linux-musl-libgfortran5.tar.gz/sha512/af6c9d15d9d5a4901d228522d2e20da5276f1bf35d7f34648697ba7a39153a9152dc17f5f0d360593e733ef3e3317df29581cb86fdd9fe8d6e6093592a6240bb +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/8595dda5ee1f15b2070d8ac20077f389 +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/df7d7ad68b47f8865d01f6edd6ba44587c6563ebc4a1900f92210b5117fc7c581e6145f95e10fe7a3db48eda9805330073c8cbeec7eb8a19978ec33f2528cef8 +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/4e67905ab599f24327e9726f70d261cf +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/13ba78e98d7c2cda62a6ca9226365e90fa8a5404e4006ae5e49030b314b762a37d78977f14c72448c844e68a6b83ecd679c60362fde023c9052b9b8597d7775c +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/e78c5005d9ee57ab464fca86c6d6fff1 +OpenBLAS.v0.3.29+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/8ceb9527461136cd4f4d02f10c241f5e7070991f73c974389acedb1d9d7be4bade592bc021ba1001c5ac148ea580cf8355fb89c88438820bfa665bf3e72392fa +OpenBLAS.v0.3.29+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/421d93da4cfab0df79569e09dff1015b +OpenBLAS.v0.3.29+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/351174d948626ad36daf40c45672cd1ac40bbe4af25c28332fbea62a7ba89188a7d33836d327d31ce99b9a9334c6053366d33b58f588355c2818e332e46b34d0 +OpenBLAS.v0.3.29+0.riscv64-linux-gnu-libgfortran5.tar.gz/md5/34cc0b3260d9471bc8fb32005e3c5043 +OpenBLAS.v0.3.29+0.riscv64-linux-gnu-libgfortran5.tar.gz/sha512/5eec279c5eead55d099d8db4a75dd4a3f2bcbc8bb22b33884a89d678e4eebf87c6dece1aa4c24374d0162b35f376648a473c2d6d7866583e61016e37f4262820 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/f921a0ad6ebf91f444cb8d927886e573 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/5cc98edf9fa8ba8981ce78b2595fd27645c783561ff19d0fd25ecc927f63492437a4b9b80d5caf51ad619b7ca5d24cb43e153156921f9f03c64741014b686196 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/0126b52c134954e63ab8f9197afebd7a +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/6d1e37009e6831a26f25bfd3e95dbcc841ee50a3f84dc4355d7fd528cd74a400138955558306345e986a732d0d1ef9294c4f5be457d05119a8e1e5851cc8ca20 +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/e8c7bd786672a9caf989dbe4fcef896a +OpenBLAS.v0.3.29+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/2e708fddfa8e5821d2e44bbc00a86df83b09cdfc0054d7c2bbb2a8de52ed80c95973e6602048335a60b54be1baeb617121b605644daf50579b2044d0c5766063 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/b1efd957a2a63f814168bd318381812e +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/097a750b7f381089588498e52a2b07a67202bfd4bc2e38f5abbbeb372129e392fcd53beade2fa7cb60ef0038f2baf61d57fab40b5585806d3ddb1fcdad73bbe3 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/c3560828f503962c6ae94135c4f00ac5 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/1ad514172e51a5d3eb6fea03182e3eb9c6db99d9d11c430e3d8542a9ce0f5d6967e623b9c0951535b683210ce0b02460358c67520b06363594f6063f8f012396 +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/07a9c3050824bbc6a96efdb333fff0ea +OpenBLAS.v0.3.29+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/b737ab1fc8c5ffd1494804c59f8fd3e5d3d8a063a89fbbc29cbd75d43af233ddf77f63d0e514059164517f408ea340ffe95c020a7c696af8c52be3a7259922ab +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/9a4a828a1b58737c79eb170c94021c52 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/785443a38cda87a63ee4268cdaa51bbc2c4662de27e0695cd7e21ffe55c3bddb1fa1a399edec39c3466f2ea0bd5ce727daca2eb381213059419c2e8371b5a733 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/cd4afdd6f6ba06c7541e7124316802b3 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/55796fdb52e1ac92750dfc2233d3feb37b53920b12024be605bf6c7322153c4dbeb650f16d6def4f0fac685733a04a1c4cacb1fc4e562a27a00b4f44484a4715 +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/8cd55ac7a7f0a7bda80b44171793718e +OpenBLAS.v0.3.29+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/728991a4c39d691abebac3ebbb2dbe093f3a4acd2d3aefb5c7c08bccf0dc1fd5aaa24de6367961d278d448b76a4ddacab36b7be15128f7ccec5049eab83828da +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/c2dda93a61e02812831b6a6e33f7d2ca +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/bd62e44f266b834c6dfab068841506a83eaf510eefbcf8896dfca36671321430293dc251885af108d94affc5b193919e0e29c965fef3ce6d994df37324aef013 +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/8cbd64d2ce4e3944e702696839a4ad3a +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/3621dfa5cf8bca62bb8f2a049acdc0ed4e02cb2b5585758e6e1173e61b3a5f0e1655a10f2feb2f0e70a098b00181d0b24dcd61e1205324d436b712f58e58df5d +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/476f1ebfb93baad6fac778fa00c4f99e +OpenBLAS.v0.3.29+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/06aa18da572b0904e5d8ec0823626d0af02a29224aba98efd43d8fbf4636d2625ece9f88f9a86d2e493f016c106f2ae71422191afc16dda2b26bbc81eb09d901 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/8c55d04d9def74f6bc2cc0d03b764975 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/d6196a339a263d80c05b94596ec5acfeff6e3ce93fafee348a864f760aa1239aa59ee294cab29fd730dcf7974ac6dcb230433184be093612bad3bc3edc067649 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/8427f098a44457ba65b21a16439ee6c0 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/4855321b2a16d55e1c6e830e33d0a199286002798c0f33c7f594a55626b5a502df94c172de4fd0a38ab6ba92f384abbbc3ef06123c3115a3f290f50a9d43ae9d +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/9d1636bb7500d9ba15ed703231f8def2 +OpenBLAS.v0.3.29+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/0b3530fd95e01d58b85157d7bb75e44ee7b2f0c5a912920ff0763f404e1ab28d16a624463f3f20241c7baea57e00fca3f896d6e0befb6a1c9e5ece4264b87e35 +openblas-8795fc7985635de1ecf674b87e2008a15097ffab.tar.gz/md5/095d293409140dd8eee500eb92372eb7 +openblas-8795fc7985635de1ecf674b87e2008a15097ffab.tar.gz/sha512/7b10d4c2bef68159e0a88fb6d4fd0ecca17b4c6394479e8f838f5078d9d5acef24c6bd44777d43c03859c952d4612d76b57aa0bff367b197920ea16eb3839144 diff --git a/deps/openblas.mk b/deps/openblas.mk index 8cea044ca348f..e5a988ba84df2 100644 --- a/deps/openblas.mk +++ b/deps/openblas.mk @@ -90,12 +90,7 @@ $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-winexit.patch-applied: $(BUILDDIR)/$(OP patch -p1 -f < $(SRCDIR)/patches/openblas-winexit.patch echo 1 > $@ -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-memory-buffer-multi-threading.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-winexit.patch-applied - cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ - patch -p1 -f < $(SRCDIR)/patches/openblas-memory-buffer-multi-threading.patch - echo 1 > $@ - -$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-memory-buffer-multi-threading.patch-applied +$(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-ofast-power.patch-applied: $(BUILDDIR)/$(OPENBLAS_SRC_DIR)/openblas-winexit.patch-applied cd $(BUILDDIR)/$(OPENBLAS_SRC_DIR) && \ patch -p1 -f < $(SRCDIR)/patches/openblas-ofast-power.patch echo 1 > $@ diff --git a/deps/openblas.version b/deps/openblas.version index 09dcdc45af1ef..f9729639c67ab 100644 --- a/deps/openblas.version +++ b/deps/openblas.version @@ -3,9 +3,9 @@ OPENBLAS_JLL_NAME := OpenBLAS ## source build -OPENBLAS_VER := 0.3.28 -OPENBLAS_BRANCH=v0.3.28 -OPENBLAS_SHA1=5ef8b1964658f9cb6a6324a06f6a1a022609b0c5 +OPENBLAS_VER := 0.3.29 +OPENBLAS_BRANCH=v0.3.29 +OPENBLAS_SHA1=8795fc7985635de1ecf674b87e2008a15097ffab # LAPACK, source-only LAPACK_VER := 3.9.0 diff --git a/deps/patches/openblas-memory-buffer-multi-threading.patch b/deps/patches/openblas-memory-buffer-multi-threading.patch deleted file mode 100644 index 9693b5cf61597..0000000000000 --- a/deps/patches/openblas-memory-buffer-multi-threading.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 23b5d66a86417a071bba9a96a0573192237981b6 Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Wed, 14 Aug 2024 10:35:44 +0200 -Subject: [PATCH 1/2] Ensure a memory buffer has been allocated for each thread - before invoking it - ---- - driver/others/blas_server.c | 2 ++ - 1 file changed, 2 insertions(+) - -From d24b3cf39392a99e81ed47a5f093fbd074d4b39b Mon Sep 17 00:00:00 2001 -From: Martin Kroeker -Date: Thu, 15 Aug 2024 15:32:58 +0200 -Subject: [PATCH 2/2] properly fix buffer allocation and assignment - ---- - driver/others/blas_server.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) -diff --git a/driver/others/blas_server.c b/driver/others/blas_server.c -index 765511d8c7..b9a7674c17 100644 ---- a/driver/others/blas_server.c -+++ b/driver/others/blas_server.c -@@ -1076,6 +1076,8 @@ fprintf(STDERR, "Server[%2ld] Calculation started. Mode = 0x%03x M = %3ld N=%3l - main_status[cpu] = MAIN_RUNNING1; - #endif - -+if (buffer == NULL) blas_thread_buffer[cpu] = blas_memory_alloc(2); -+ - //For target LOONGSON3R5, applying an offset to the buffer is essential - //for minimizing cache conflicts and optimizing performance. - #if defined(ARCH_LOONGARCH64) && !defined(NO_AFFINITY) - -diff --git a/driver/others/blas_server.c b/driver/others/blas_server.c -index b9a7674c17..29f8a5e646 100644 ---- a/driver/others/blas_server.c -+++ b/driver/others/blas_server.c -@@ -1076,7 +1076,11 @@ fprintf(STDERR, "Server[%2ld] Calculation started. Mode = 0x%03x M = %3ld N=%3l - main_status[cpu] = MAIN_RUNNING1; - #endif - --if (buffer == NULL) blas_thread_buffer[cpu] = blas_memory_alloc(2); -+if (buffer == NULL) { -+ blas_thread_buffer[cpu] = blas_memory_alloc(2); -+ buffer = blas_thread_buffer[cpu]; -+} -+ - - //For target LOONGSON3R5, applying an offset to the buffer is essential - //for minimizing cache conflicts and optimizing performance. diff --git a/stdlib/OpenBLAS_jll/Project.toml b/stdlib/OpenBLAS_jll/Project.toml index 01e3af1d9467c..07a81d3c1d547 100644 --- a/stdlib/OpenBLAS_jll/Project.toml +++ b/stdlib/OpenBLAS_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenBLAS_jll" uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.28+3" +version = "0.3.29+0" [deps] # See note in `src/OpenBLAS_jll.jl` about this dependency. From de1dba2c96649d0dd30403cee1ae456ae19a2ac8 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Mon, 13 Jan 2025 04:56:14 +0100 Subject: [PATCH 14/65] Check channel state on iterate (#52981) --- base/channels.jl | 9 +++++++++ test/channels.jl | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/base/channels.jl b/base/channels.jl index 8882171095e7a..527c22b3d45fd 100644 --- a/base/channels.jl +++ b/base/channels.jl @@ -716,6 +716,15 @@ function iterate(c::Channel, state=nothing) end end else + # If the channel was closed with an exception, it needs to be thrown + if (@atomic :acquire c.state) === :closed + e = c.excp + if isa(e, InvalidStateException) && e.state === :closed + nothing + else + throw(e) + end + end return nothing end end diff --git a/test/channels.jl b/test/channels.jl index f3e5381a62e94..4acf6c94da1b6 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -499,12 +499,35 @@ end end end +struct CustomError <: Exception end + @testset "check_channel_state" begin c = Channel(1) close(c) @test !isopen(c) c.excp === nothing # to trigger the branch @test_throws InvalidStateException Base.check_channel_state(c) + + # Issue 52974 - closed channels with exceptions + # must be thrown on iteration, if channel is empty + c = Channel(2) + put!(c, 5) + close(c, CustomError()) + @test take!(c) == 5 + @test_throws CustomError iterate(c) + + c = Channel(Inf) + put!(c, 1) + close(c) + @test take!(c) == 1 + @test_throws InvalidStateException take!(c) + @test_throws InvalidStateException put!(c, 5) + + c = Channel(3) + put!(c, 1) + close(c) + @test first(iterate(c)) == 1 + @test isnothing(iterate(c)) end # PR #36641 From cea96c9046c6f8efaa01ae10880d9a67f4527073 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:53:43 -0500 Subject: [PATCH 15/65] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20Sp?= =?UTF-8?q?arseArrays=20stdlib=20from=204fd3aad=20to=205f52721=20(#57027)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: 4fd3aad New commit: 5f52721 Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @ViralBShah Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaSparse/SparseArrays.jl/compare/4fd3aad5735e3b80eefe7b068f3407d7dd0c0924...5f527215c188ee99247cdce31ba8ce9e11f35055 ``` $ git log --oneline 4fd3aad..5f52721 5f52721 Update wrappers for SuiteSparse 7.8.3 (#593) c575811 Mention vectors in more docstrings (#591) ``` Co-authored-by: ViralBShah <744411+ViralBShah@users.noreply.github.com> --- .../md5 | 1 - .../sha512 | 1 - .../md5 | 1 + .../sha512 | 1 + stdlib/SparseArrays.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 delete mode 100644 deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 create mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 create mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 diff --git a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 deleted file mode 100644 index 4c75f5c1f619a..0000000000000 --- a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -308e26cc6171656caaa7f6ba07e83d1c diff --git a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 b/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 deleted file mode 100644 index ad389d6e42048..0000000000000 --- a/deps/checksums/SparseArrays-4fd3aad5735e3b80eefe7b068f3407d7dd0c0924.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -62b94ad0dca0d62e5753f50aef806ebdb5c8b56b241a285957190845be21fc6b8c8f93089b6f627795f6d7f2b1b01118bcff87c21102a3f3bae6d4c408362681 diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 new file mode 100644 index 0000000000000..946bec189c1bd --- /dev/null +++ b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 @@ -0,0 +1 @@ +4b07db52a5a6d3cc6eeab380bd783a1e diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 new file mode 100644 index 0000000000000..846867193d932 --- /dev/null +++ b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 @@ -0,0 +1 @@ +4c631f1046ad0a6b972a4dce285c2092372ecbed269c83524c10b4be5124035670d703af53e1f8058d23230be20c06aa554097cc9bc7a12b3de3c039d3c545e8 diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index 0ff7a761bffa3..3f6ab5b878069 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 4fd3aad5735e3b80eefe7b068f3407d7dd0c0924 +SPARSEARRAYS_SHA1 = 5f527215c188ee99247cdce31ba8ce9e11f35055 SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1 From 3b629f1b95db6280cb67783ef6427cd6e71c6618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Mon, 13 Jan 2025 06:37:04 +0000 Subject: [PATCH 16/65] Update builds of MPFR_jll and OpenSSL_jll (#57026) --- deps/checksums/mpfr | 70 +++++++++++++++++---------------- deps/checksums/openssl | 70 +++++++++++++++++---------------- stdlib/MPFR_jll/Project.toml | 2 +- stdlib/OpenSSL_jll/Project.toml | 2 +- 4 files changed, 74 insertions(+), 70 deletions(-) diff --git a/deps/checksums/mpfr b/deps/checksums/mpfr index 4d029986663c9..7b3b57978bd01 100644 --- a/deps/checksums/mpfr +++ b/deps/checksums/mpfr @@ -1,36 +1,38 @@ -MPFR.v4.2.1+1.aarch64-apple-darwin.tar.gz/md5/816f9ff59070f21f1df2f310e2606c06 -MPFR.v4.2.1+1.aarch64-apple-darwin.tar.gz/sha512/dad9adba7a8867d1ce26d77efb5c33b602b920a2cdbec84ea58a054cfab3ab7df54d2bda101de72b71604e7844993f1e216b002ba092e69277d0764040216c81 -MPFR.v4.2.1+1.aarch64-linux-gnu.tar.gz/md5/c1e3c9619af6454d8adae9bcbd911dba -MPFR.v4.2.1+1.aarch64-linux-gnu.tar.gz/sha512/5d916492aa73d11e022a7ca3f31940ceb8f8667bdf878ba29d6256736a380a2f6a11ac90cd8de3f1d3454a79165db240a1b971b9794fd21692ed64502ec34b9a -MPFR.v4.2.1+1.aarch64-linux-musl.tar.gz/md5/8ada267e2d23eb0c65ab2d2df02362d5 -MPFR.v4.2.1+1.aarch64-linux-musl.tar.gz/sha512/0c7f18e6d0f3e2052541e3279dfa9a74eb34067ac4fea0b17ab805cd73010cc83f8d7cb4eda8f4a904da398268d1c0d638c35521a9f339f8c7c3b5f159f27277 -MPFR.v4.2.1+1.aarch64-unknown-freebsd.tar.gz/md5/8aa99bf9c6157b8bb2833d8987ce0806 -MPFR.v4.2.1+1.aarch64-unknown-freebsd.tar.gz/sha512/6e4f547596eb8dd8ee2e1d3aefd7c73eed744add401c1f93d9951a9187c96fa9fc39be14683723dcb43cdf6891ea0021dc3416e43a0e2ec2038b0d1cd7c8434e -MPFR.v4.2.1+1.armv6l-linux-gnueabihf.tar.gz/md5/42bdb78eee83f496d7da699ad9603913 -MPFR.v4.2.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/edaa9ece1404a606d6b635406ad5e721c8d094ffa1c73ce19222afc2b4ea7b3b9e23e7c5589ae10fd9f4c4aefa265773bcfce6c510efbca57782115d43daeb13 -MPFR.v4.2.1+1.armv6l-linux-musleabihf.tar.gz/md5/2213207772b8a50de4768816fdc20e2f -MPFR.v4.2.1+1.armv6l-linux-musleabihf.tar.gz/sha512/d24debc38b8135ac5c10c4ea19de0c69126b6881940b4e182118e12cc2c7cf0aca2db065620f0cca636742da32eddec5bda3b4f449a035274f05120c977ed449 -MPFR.v4.2.1+1.armv7l-linux-gnueabihf.tar.gz/md5/a0d9fe20c9ff0027b6816ee0102b1f9a -MPFR.v4.2.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/97ce02898dc0d29a616048fd7ecee3100a710f7a30a21f2276c01675749034a5241be88bd46dff3dbf9ea0adca98a4357bd16e43fa9520e7a02477494c2d072e -MPFR.v4.2.1+1.armv7l-linux-musleabihf.tar.gz/md5/7898b9047c914b290b5928af5df63030 -MPFR.v4.2.1+1.armv7l-linux-musleabihf.tar.gz/sha512/cbefa9588752c65751630832417c1c42e4819d49ff9a505f61c2567ef4271097e585542fa898efd61409a43e439d827bb79f693a0937d0a3a427b39535979588 -MPFR.v4.2.1+1.i686-linux-gnu.tar.gz/md5/ac5a9db4bef94e7062dac463b5f87346 -MPFR.v4.2.1+1.i686-linux-gnu.tar.gz/sha512/2b5f3656e25065bfd83c81ee75999e6162c6e5436fcb0e3e3a767e2d941a556b4ebd3bebab78c63e8165105f81576959d8ad6e6d9cef1052751e39849e85df73 -MPFR.v4.2.1+1.i686-linux-musl.tar.gz/md5/6dc6a00d3ea22e2c60374d49926598d6 -MPFR.v4.2.1+1.i686-linux-musl.tar.gz/sha512/4a90356091b53d7238dda59f6e9c5c420614f16460dc67310e581611ad46a2dd3324d6164cfecf1bcd660b8f2e473f0afe137aac954c608b11be3acbda648e14 -MPFR.v4.2.1+1.i686-w64-mingw32.tar.gz/md5/7f7158a28ce8f262b897b38218f57958 -MPFR.v4.2.1+1.i686-w64-mingw32.tar.gz/sha512/8fbae0f1dd36534d4b9c63192c6e5cb1e531732d8eb1ab36783a6c71182f24ef80245b31a03460fd2f412fd0acaf1c4b9c8b574725271391217a3977b9ae4c79 -MPFR.v4.2.1+1.powerpc64le-linux-gnu.tar.gz/md5/ac70f716bddd5323b4add663b473b52d -MPFR.v4.2.1+1.powerpc64le-linux-gnu.tar.gz/sha512/ebb0f5ea76c892b7a4e4636706e71f476aaea58bb88e1734a7966c44495fda8c81318e0e8629e208185f0fc8d0c73b6f3463034cd831dfb5fbbd493a0689bc06 -MPFR.v4.2.1+1.x86_64-apple-darwin.tar.gz/md5/ff13e865e3be717b0fffc16296cb2f56 -MPFR.v4.2.1+1.x86_64-apple-darwin.tar.gz/sha512/98479210910945714da0285a40803674242581894a731ba4709c70dc1341849e736a88aa4914df0ff536c15f8848c417e712ff6abeb25047d300f8b215fd131f -MPFR.v4.2.1+1.x86_64-linux-gnu.tar.gz/md5/ca582be47601b8e6edb9d39f2881f44a -MPFR.v4.2.1+1.x86_64-linux-gnu.tar.gz/sha512/44a2e6158fde9fa8eaa6fac513dd5a8cae25a4b8879e5bb752a3f6af53d750c3a8e79be669ad87925b10c559cf9518fae431a607a342c48c00a390555e7e7b1f -MPFR.v4.2.1+1.x86_64-linux-musl.tar.gz/md5/0babbb823964ccebf63b42fd07f08936 -MPFR.v4.2.1+1.x86_64-linux-musl.tar.gz/sha512/880b685d9b456fa2bf78e707273783423f9ff00791b529eba00c5e1b94ff96f4ba01e680152a4d6b45b695e3c1169d07f793db42c5a4120861813d5458dfc828 -MPFR.v4.2.1+1.x86_64-unknown-freebsd.tar.gz/md5/f11d634e5a19177fe36b2b2f6f5727ca -MPFR.v4.2.1+1.x86_64-unknown-freebsd.tar.gz/sha512/291245c06edf31b2e39b6774359ebd4f95b924f19d2a7e8581822a5bf908426d00f0452c061a027da0d7d4bb2fa1bb7ef8ab6d8e49bc848d6d7450a8d5c8a9c4 -MPFR.v4.2.1+1.x86_64-w64-mingw32.tar.gz/md5/dcfad84470f15484443734feccbf8bf6 -MPFR.v4.2.1+1.x86_64-w64-mingw32.tar.gz/sha512/ceba1814fa671c2ba3e1ffeb6c736776981052e14111112fe963b5c11fd070136f8f022c5c21895f1f4f5084a5612fa673dddbb6b9622d7cade9b62eefcc8a14 +MPFR.v4.2.1+2.aarch64-apple-darwin.tar.gz/md5/1f5bba3e8e540720e239da75e5ae79eb +MPFR.v4.2.1+2.aarch64-apple-darwin.tar.gz/sha512/7de26c625e540a5b88e280ec2cb8712d4514732d80a0c6342d2b2cabc6bc17c05f6c614b8e38800c93a4af5438c554733d3fa2002ef70072dfb44c08d3f03d26 +MPFR.v4.2.1+2.aarch64-linux-gnu.tar.gz/md5/112ddd4e5cddf36b005394f9cd81b8e5 +MPFR.v4.2.1+2.aarch64-linux-gnu.tar.gz/sha512/dc125f625e8c74ce18c052ef759ccbcfc2f3a932f2810a306bdddf70d5f37f3546200690fd08fb76742022322a7c1b9aa907b4aec6edb318060f0648ff426cbc +MPFR.v4.2.1+2.aarch64-linux-musl.tar.gz/md5/a0919ef7cc35bb663d05e27da2bcb9a7 +MPFR.v4.2.1+2.aarch64-linux-musl.tar.gz/sha512/8acbaaca766c2ce225ac8df88c103a57fc52119d1fd54e9fc7d1f9d725c4ca9f74a0090e86eea0c140482a1abaf5b6086c453824a7516e9aef3ede5058f1767c +MPFR.v4.2.1+2.aarch64-unknown-freebsd.tar.gz/md5/61e1dcc7e323b976854a4e8164316d37 +MPFR.v4.2.1+2.aarch64-unknown-freebsd.tar.gz/sha512/f3a5493f88b290d15aff9bf79b15158d19bea05af7210b2967368e0b2f98cd291f77e62f39ee0c7ad4e9d2ef6ebdba4bf2fea24c723791f71f7b9b1ef989a67d +MPFR.v4.2.1+2.armv6l-linux-gnueabihf.tar.gz/md5/629aad4ac45ba23becd8a26df188638c +MPFR.v4.2.1+2.armv6l-linux-gnueabihf.tar.gz/sha512/bb05a8bf127eb16608a82037546f48462cb6168e1adcdb2c60dc3bd08f62cff30cf603abcab87bb336305d37dbb7b0480ea8f6664191879bdcd487738a33dd99 +MPFR.v4.2.1+2.armv6l-linux-musleabihf.tar.gz/md5/0c3c026051b096d98c8d476dd44db334 +MPFR.v4.2.1+2.armv6l-linux-musleabihf.tar.gz/sha512/9e791fe9748c87068c167517883cc905fe51ea38d2db89562a7a0959cfd83b268eed2897e5eaaf90c0b0b08a4efd8039bdeece64e83b17bf1d676570d13c2b98 +MPFR.v4.2.1+2.armv7l-linux-gnueabihf.tar.gz/md5/a2433a717e49ad95c3e430a538d01134 +MPFR.v4.2.1+2.armv7l-linux-gnueabihf.tar.gz/sha512/abde21a943d4af312e0d44b1ff1d4aefa10b2f38c74ff0e04c0c2b8561750ef5d164679564ffe1b551821d83ebcafbe99467230b37fe4591c593a24dfb070c6a +MPFR.v4.2.1+2.armv7l-linux-musleabihf.tar.gz/md5/4c892b4cbf1926d5d2b6a88330015c8f +MPFR.v4.2.1+2.armv7l-linux-musleabihf.tar.gz/sha512/24825bb1268ef2ea42894ec9ff6589308abae430dd8e43a2ca0d368f1e718fd3cdf6d9bc4bc383346970ba845d2ef1721c4848ee0c783d09addc5505131db3e6 +MPFR.v4.2.1+2.i686-linux-gnu.tar.gz/md5/0b1e0268dcaeb3aa0f7f0a6451c6b841 +MPFR.v4.2.1+2.i686-linux-gnu.tar.gz/sha512/f0ef142c7b86e8f92b78a7ff0607da70bf8f3970b118fa77438cbb0acbea604dc0c7566b52ff1f85b179aac7661b31e4aee049f2c5ff799c95b385ba9cde2a25 +MPFR.v4.2.1+2.i686-linux-musl.tar.gz/md5/2fc9a938e76e7bdc0b73d7e8bfc8b8ee +MPFR.v4.2.1+2.i686-linux-musl.tar.gz/sha512/4aed3884ad569b7695b9383db9d9dbb279ffe5349f7757b867ff860fa600b47faa4c169f4a60409666ce45fc6e6f269c18cef2df6fa0585f056d7e07e55005b8 +MPFR.v4.2.1+2.i686-w64-mingw32.tar.gz/md5/d13c44bb28d721107639c8555db5e157 +MPFR.v4.2.1+2.i686-w64-mingw32.tar.gz/sha512/1b5562d2df322c28bd06bb4ba8c9039cf90ed62affcf7f2b0d7ae8925d503c76a0d3d2f9b65c8c55575f245a4df8fbc4c7c63e93e7b973188f203a7fbda4eac5 +MPFR.v4.2.1+2.powerpc64le-linux-gnu.tar.gz/md5/52b3912b2c5f59ab3dcd7c3e06ca41b5 +MPFR.v4.2.1+2.powerpc64le-linux-gnu.tar.gz/sha512/533cf1f93c4464b4bed1d56ea79946fc2d20f3a7825d6b0383ed98cec99f85713e7bca549fd8948adb69aedc14e5d14a54238b3e67ef103e1b049b0cfb6cc1c9 +MPFR.v4.2.1+2.riscv64-linux-gnu.tar.gz/md5/aef7709c8457ee2db2622c39f1da16b7 +MPFR.v4.2.1+2.riscv64-linux-gnu.tar.gz/sha512/7a9c88563e3e7ab22a3aaa45690ed89c3e7eb22333a3d45c5e04ad2660c91ad2c97f10cd6c1aa1ccfdbf97186f9fd7f92330a41ec0be026e2ff84c5ba91f2652 +MPFR.v4.2.1+2.x86_64-apple-darwin.tar.gz/md5/12afc9778e39a5b6d9ea0161e2c80a95 +MPFR.v4.2.1+2.x86_64-apple-darwin.tar.gz/sha512/a9070423a898fa865740753ae7513d3cc0b500bd9b6b5c6aa672833dcac429efd806eff48501b51afcba5db0d31e79dac243b11b2f8847a1551576c6131506f5 +MPFR.v4.2.1+2.x86_64-linux-gnu.tar.gz/md5/46c6a5f40243795bdff51bd68a89c82e +MPFR.v4.2.1+2.x86_64-linux-gnu.tar.gz/sha512/df8209d69ae55dd54491055078f113f4ac8be7bc68e1c0eb62944e6c9c04ed3e9a55c4a5f28ec68eb69f558d9f4d1b975f36de572fbd0ef7720568efc8042327 +MPFR.v4.2.1+2.x86_64-linux-musl.tar.gz/md5/045236ee0d558d2eda42df76c3397f69 +MPFR.v4.2.1+2.x86_64-linux-musl.tar.gz/sha512/52b68a673160af7cd09b191f3c28e17d5af7516b5baa86c0df9cb63a116772a15b5358f3db5f0b254b5752c652f8959454667cc1726ea4ff30946e3bbdb90ab4 +MPFR.v4.2.1+2.x86_64-unknown-freebsd.tar.gz/md5/da3da71bc7572eca5bc3d3895abf73c2 +MPFR.v4.2.1+2.x86_64-unknown-freebsd.tar.gz/sha512/4270b83ebe72d431f8fd9127b2b8d3bd75c2e52c563d390a4ca8d40c0514f5996fce57746d07b7d3bcbf93bfe78d420f815fde5eda4d84a5bcb7b7cf0e092504 +MPFR.v4.2.1+2.x86_64-w64-mingw32.tar.gz/md5/2a6f5ccb8d45591a845ad43916beb85a +MPFR.v4.2.1+2.x86_64-w64-mingw32.tar.gz/sha512/db9ecc9d8247fe4421c4cc9c6ab540e17a7445056b7a1062d4e334b353783a1c067062fd8e6f0517d8bd8782c9bb75abcce8ab8247be707ba066dc90b7fc12ff mpfr-4.2.1.tar.bz2/md5/7765afa036e4ce7fb0e02bce0fef894b mpfr-4.2.1.tar.bz2/sha512/c81842532ecc663348deb7400d911ad71933d3b525a2f9e5adcd04265c9c0fdd1f22eca229f482703ac7f222ef209fc9e339dd1fa47d72ae57f7f70b2336a76f diff --git a/deps/checksums/openssl b/deps/checksums/openssl index 4d56641b34c80..c973f592861f3 100644 --- a/deps/checksums/openssl +++ b/deps/checksums/openssl @@ -1,36 +1,38 @@ -OpenSSL.v3.0.15+1.aarch64-apple-darwin.tar.gz/md5/8495727a34f178bc474c970855b88e8d -OpenSSL.v3.0.15+1.aarch64-apple-darwin.tar.gz/sha512/2beb6003e0431d56fd4161a7739d0ea2e2238181b2a064f552d5083b59e7724904e8a991e5d0ecaeb05e21d17b56ca44f321c71ac477db4ddaa05d792cb61c9b -OpenSSL.v3.0.15+1.aarch64-linux-gnu.tar.gz/md5/652845c276f3403e8374111fd6654aa0 -OpenSSL.v3.0.15+1.aarch64-linux-gnu.tar.gz/sha512/5d7a20836fffd253eaf574eb461eb10dcbb3fcf0d4f3d763539ef02a922af944e4ff29e8f20cec210ed798a48c742684ea713d511c58c784f33793e167a98469 -OpenSSL.v3.0.15+1.aarch64-linux-musl.tar.gz/md5/52397b6264c156815cdf9de5709533ef -OpenSSL.v3.0.15+1.aarch64-linux-musl.tar.gz/sha512/f1e8c0a3a7bac3c8b78d68fce551c29e5d537f7289f51c297e75c5c7bc3678747dc19ed579387021def041f02bf08d0e7938c5498b4493438efeb4685e01a191 -OpenSSL.v3.0.15+1.aarch64-unknown-freebsd.tar.gz/md5/bbdbea23761b13821d99f9eb4ba5d198 -OpenSSL.v3.0.15+1.aarch64-unknown-freebsd.tar.gz/sha512/a1c3985658eaf38a901bc7de1e782101ab41638d4641fea3115c5020b229d3f6fba3e3709c5568b3395986f396d82feb32b804d343dfd05c2fa1e6eefe120e96 -OpenSSL.v3.0.15+1.armv6l-linux-gnueabihf.tar.gz/md5/ceeb288e5c8da5831047dc4b1c2a983e -OpenSSL.v3.0.15+1.armv6l-linux-gnueabihf.tar.gz/sha512/961c4ec351b69aaf42082b462623afd7315b6606c2a5fb98142ca1bc6ce0494c388f5020474eff5081e850fd34aed8b3ef2f881304872255236fcae0b0b641e4 -OpenSSL.v3.0.15+1.armv6l-linux-musleabihf.tar.gz/md5/e75d83ecf3876a595cfe36cf81853489 -OpenSSL.v3.0.15+1.armv6l-linux-musleabihf.tar.gz/sha512/3e113a275233f434df685b114342f2a59634282a9b68606d4c16da51e5173cbed26498512b22f84017100a18415cc1bb2d269f1ba0d44941d51b8d05c73950cc -OpenSSL.v3.0.15+1.armv7l-linux-gnueabihf.tar.gz/md5/fbe3bf8921cf9b679b60ea12e2d19458 -OpenSSL.v3.0.15+1.armv7l-linux-gnueabihf.tar.gz/sha512/294c91308eede14b8db255ff1b47fe5dba3b6441318e38e284446f276355b93d97b88e6c78d9ed6bb6623623c47be5c65ce6b2fa5ce5ea087a8bfaeb94830627 -OpenSSL.v3.0.15+1.armv7l-linux-musleabihf.tar.gz/md5/ab35b5d4f79e349d558742c69c775d34 -OpenSSL.v3.0.15+1.armv7l-linux-musleabihf.tar.gz/sha512/6a5c85e36ed609ad33d0d2466fa1732a47072af37226052456172d7b049b9d943ad48d94b444600ed1f859a4c016226fc1952fda7381f3aaa6229bcd15c72f78 -OpenSSL.v3.0.15+1.i686-linux-gnu.tar.gz/md5/99e76e6c5d50fd0a4e6218bb807f1062 -OpenSSL.v3.0.15+1.i686-linux-gnu.tar.gz/sha512/30235842672e3b854d38ffd3ba1812a9e81b1f9fcf285ed12d07622d386a5355b79f2264be3d0e84d0bec0e57a9f3e1ac6de898463c43f6d2e3290854205cb30 -OpenSSL.v3.0.15+1.i686-linux-musl.tar.gz/md5/adb2ed9a8ef34294643f7762de1c7842 -OpenSSL.v3.0.15+1.i686-linux-musl.tar.gz/sha512/56d56eb89ea0dcadafbfc92a3bd2032b6c934d217882f56ba47086783b7a5134816f43d391a569963fa978ab708bf695af5abf03cac11c709930752882c761b7 -OpenSSL.v3.0.15+1.i686-w64-mingw32.tar.gz/md5/4596a947bb22aab728ba585d2727053a -OpenSSL.v3.0.15+1.i686-w64-mingw32.tar.gz/sha512/6a1479036c7ccb170daf42ed7d6054d2c7f3a4115dbb01fe34e518efdf0a60929eb89771d5f7fdcb3d055ebf05351cbc82397606d49ea4bde44c465cdb60274e -OpenSSL.v3.0.15+1.powerpc64le-linux-gnu.tar.gz/md5/f36402387dde259a64b0bed2a0d2a3c9 -OpenSSL.v3.0.15+1.powerpc64le-linux-gnu.tar.gz/sha512/3011eec16c1abcbf3c452a2d8e4e7c5a3c280981ea57374a938e3f8843f25022e9b0beaa6a87a1e5f7547ae4abd614221cc2a0a51495869fe99a03f6b3f46d8e -OpenSSL.v3.0.15+1.x86_64-apple-darwin.tar.gz/md5/f4c82b74f80a3cda4ae409e4623b6615 -OpenSSL.v3.0.15+1.x86_64-apple-darwin.tar.gz/sha512/d4a08a914533e603f06e584b8d7e69f4fca9671635fe24e1a896a362bfd388eea2397b9b66b82aecc0ba751e72dfcfbd8b46c5a148349f5aaeb9c37bc257ed37 -OpenSSL.v3.0.15+1.x86_64-linux-gnu.tar.gz/md5/9868c286c6275581a5891167540def7d -OpenSSL.v3.0.15+1.x86_64-linux-gnu.tar.gz/sha512/5631aa288e0e174bd05d520d90a29423c743576eb2385e97a58ed45361e94e59daa3b3193e81ce649bfed21d07fd508c135a38b486b34120afc3af1b4f92451d -OpenSSL.v3.0.15+1.x86_64-linux-musl.tar.gz/md5/e118f2b842a3a1be539208aff17281ec -OpenSSL.v3.0.15+1.x86_64-linux-musl.tar.gz/sha512/1c6fa866bebf5c0c6cc5ea8a423d2a522b186e7f2590146e464813be22d66de0a9bc797449508fa5508d296309348b8dd3a881c0099e6fb77b8d28ff270fab35 -OpenSSL.v3.0.15+1.x86_64-unknown-freebsd.tar.gz/md5/03830b4a8735a7e704df444e9a4353ab -OpenSSL.v3.0.15+1.x86_64-unknown-freebsd.tar.gz/sha512/bfc9e4ca160a9e3d4232117d819ea37f3997d4c433cfc85a4055ced60e8c65e7df6009d58f6b94f6f2aa1b436a8ee9f08dcf5a21faf7106bfdb50ca9a05322c6 -OpenSSL.v3.0.15+1.x86_64-w64-mingw32.tar.gz/md5/5b2c640cb72115f417cdd7ec82a8336f -OpenSSL.v3.0.15+1.x86_64-w64-mingw32.tar.gz/sha512/d2224dd37205c7781be93f1581a08c4008f4c35cb3f457f3b4455a00805c1a20be7f7e29188a55164364c42a926ffa12527af379d1bc8d11f4351b07d8a5928b +OpenSSL.v3.0.15+2.aarch64-apple-darwin.tar.gz/md5/d11d92e6530705e3d93925bbb4dfccff +OpenSSL.v3.0.15+2.aarch64-apple-darwin.tar.gz/sha512/e30d763d956f930c3dab961ef1b382385b78cbb2324ae7f5e943420b9178bc2b086d9877c2d2b41b30a92ca109d7832a2ae50f70547fcc9788e25889d8252ffc +OpenSSL.v3.0.15+2.aarch64-linux-gnu.tar.gz/md5/d29f0d3a35d592488ba3a8bbb0dc8d0e +OpenSSL.v3.0.15+2.aarch64-linux-gnu.tar.gz/sha512/67c527c1930b903d2fbb55df1bd3fc1b8394bc4fadd15dd8fb84e776bae8c448487c117492e22b9b014f823cc7fe709695f4064639066b10427b06355540e997 +OpenSSL.v3.0.15+2.aarch64-linux-musl.tar.gz/md5/4f5313f1f18e29585951e95372a7a0fe +OpenSSL.v3.0.15+2.aarch64-linux-musl.tar.gz/sha512/48007a1f6667d6aeb87cc7287723ed00e39fe2bc9c353ff33348442516f1a28961985cc4a29a2a8f76b3a7049bd955973562d7c6c4af43af884596def636f7f8 +OpenSSL.v3.0.15+2.aarch64-unknown-freebsd.tar.gz/md5/5b6041353197bb8f75b39ed8f58cf4e9 +OpenSSL.v3.0.15+2.aarch64-unknown-freebsd.tar.gz/sha512/9be617d51fdc167085887380e720e6baf8e1e180f455b297f44d0bc0862fd490f015b5292d952d4ad095750cde796cc7dac4f901389b73135cb399b3a9d378c1 +OpenSSL.v3.0.15+2.armv6l-linux-gnueabihf.tar.gz/md5/858f548a28e289153842226473138a3e +OpenSSL.v3.0.15+2.armv6l-linux-gnueabihf.tar.gz/sha512/f9385678fca65d1fb8d96756442518b16607a57a9b6d76991414b37dfc4e30a7e1eebe5f3977b088b491216af4a34f958b64fe95062ee9ae23a9212f46c4e923 +OpenSSL.v3.0.15+2.armv6l-linux-musleabihf.tar.gz/md5/c4e52ecb4f9e24d948724424f1070071 +OpenSSL.v3.0.15+2.armv6l-linux-musleabihf.tar.gz/sha512/12f9276c68049026f2741c7d97e62d24525e5e832911546e1ea3868362034e6384304d749730122edf828b8c5573084055d59cc0bd75bda32f000ce630837c2b +OpenSSL.v3.0.15+2.armv7l-linux-gnueabihf.tar.gz/md5/767d3f3047366ccd6e2aa275f80d9f6c +OpenSSL.v3.0.15+2.armv7l-linux-gnueabihf.tar.gz/sha512/17700fd33c221070a7dd2db79d045e102591b85e16b3d4099356fb6a8635aea297b5fcef91740f75c55344a12ed356772b3b85c0cc68627856093ceb53ea8eb3 +OpenSSL.v3.0.15+2.armv7l-linux-musleabihf.tar.gz/md5/3ef2385cb1fec9e2d3af2ba9385ac733 +OpenSSL.v3.0.15+2.armv7l-linux-musleabihf.tar.gz/sha512/6156e9431fa8269b8d037149271be6cca0b119be67be01cfd958dabf59cdd468ef2a5ebf885e5835585006efdedd29afc308076283d070d4ae743146b57cd2b1 +OpenSSL.v3.0.15+2.i686-linux-gnu.tar.gz/md5/e62992d214cec6b1970f9fbd04cb8ecd +OpenSSL.v3.0.15+2.i686-linux-gnu.tar.gz/sha512/dfdb3d2d1d5fed7bf1c322899d6138c81f0653350f4b918858dd51bf7bcc86d2d04de824533925fa5f8d366a5c18ee33ade883f50a538b657717f8a428be8c60 +OpenSSL.v3.0.15+2.i686-linux-musl.tar.gz/md5/186a6bb8055ce089ac0c9897bd2cd697 +OpenSSL.v3.0.15+2.i686-linux-musl.tar.gz/sha512/f3c8d608113e9b0e91dd6af697172a46892d4a66572e35e13ad394397291dded3042667c1ec4fafe051778e71ff56a876dc3e848a2b85cef9f925ef3969ab950 +OpenSSL.v3.0.15+2.i686-w64-mingw32.tar.gz/md5/b72b8e4883337e4bc90094dce86c8b8b +OpenSSL.v3.0.15+2.i686-w64-mingw32.tar.gz/sha512/3b5ddef15ca1463ab92ef5b88df36f8418c8c44ffb123a0922e55718ab317b5fe379994aba9a5e8ca112475043d5cf99b1574702cdb30de438f458ee06ac80ea +OpenSSL.v3.0.15+2.powerpc64le-linux-gnu.tar.gz/md5/da194ce6f37f34cc19cc78d25c9af5e2 +OpenSSL.v3.0.15+2.powerpc64le-linux-gnu.tar.gz/sha512/e256a9d9a0af8764de730419281aa4d3ee9f6146692ec9105a318d8301d8fda5cca82c6ef4d0d7b70d721992361771724b237ce26ef81f92c295f6056d5a7cdd +OpenSSL.v3.0.15+2.riscv64-linux-gnu.tar.gz/md5/86825ee5f83ec0c827d5c051fe1a3d41 +OpenSSL.v3.0.15+2.riscv64-linux-gnu.tar.gz/sha512/7db4ae2f0a9491ae484da5b8b0c3698d970ada91c83f9783c9e5bd92006f52dffa1a4c7fb282b63e34760199a97c52793040dc306ad0986970cfa233e29cb195 +OpenSSL.v3.0.15+2.x86_64-apple-darwin.tar.gz/md5/271cc359f5bc4718659044ad5ac7631d +OpenSSL.v3.0.15+2.x86_64-apple-darwin.tar.gz/sha512/10e7575dc4cce6c617c96e6f94dbfe3058aad696292d3fac4bde7c92623f2a849b7d10e35b156b7582294b3cf103d61b3ea73605f958ee4c9f8ff05b647939a7 +OpenSSL.v3.0.15+2.x86_64-linux-gnu.tar.gz/md5/5d045d93d632af9914bff551f67eed9b +OpenSSL.v3.0.15+2.x86_64-linux-gnu.tar.gz/sha512/240791382d9549be029e2d404bc0e962f9876ab0597bf20cf34c87fcfafc3d75ba9f223641287895f9aee8519a5a33293910ed6d67bc1424ff3513eedaa8b699 +OpenSSL.v3.0.15+2.x86_64-linux-musl.tar.gz/md5/bb2637babf3730ed1117f89cb8aab34a +OpenSSL.v3.0.15+2.x86_64-linux-musl.tar.gz/sha512/b847539acc00870f77b242eeccfcf16f590493b7deb0089fa3654026f4016d40f9595d3bbb21ab981e9decfde4321da71f162beb1837a158fd3a884375a86fee +OpenSSL.v3.0.15+2.x86_64-unknown-freebsd.tar.gz/md5/23b69e0256e6c86e026be3ade20aed5c +OpenSSL.v3.0.15+2.x86_64-unknown-freebsd.tar.gz/sha512/1b7da1e13d325c7776b8e1a63aaa334bd633bb10604f8bed5f5f6a81955268b3d11ad221a5dd181dbdc7ad27c35d5754e6875d36226003c2fd7da6cd91854de1 +OpenSSL.v3.0.15+2.x86_64-w64-mingw32.tar.gz/md5/73cf4138ab403b7c9f91368a030590f9 +OpenSSL.v3.0.15+2.x86_64-w64-mingw32.tar.gz/sha512/052bb52837c29b4b18a97df71a80ad77486bd6ccef6e2e57dfa68a02754180976dc0302a158886393ef13fe91904f963119b17429a4ecc6f8b6c80ff878df05d openssl-3.0.15.tar.gz/md5/08f458c00fff496a52ef931c481045cd openssl-3.0.15.tar.gz/sha512/acd80f2f7924d90c1416946a5c61eff461926ad60f4821bb6b08845ea18f8452fd5e88a2c2c5bd0d7590a792cb8341a3f3be042fd0a5b6c9c1b84a497c347bbf diff --git a/stdlib/MPFR_jll/Project.toml b/stdlib/MPFR_jll/Project.toml index a9987ccfa38f6..50de38f169ff0 100644 --- a/stdlib/MPFR_jll/Project.toml +++ b/stdlib/MPFR_jll/Project.toml @@ -1,6 +1,6 @@ name = "MPFR_jll" uuid = "3a97d323-0669-5f0c-9066-3539efd106a3" -version = "4.2.1+1" +version = "4.2.1+2" [deps] GMP_jll = "781609d7-10c4-51f6-84f2-b8444358ff6d" diff --git a/stdlib/OpenSSL_jll/Project.toml b/stdlib/OpenSSL_jll/Project.toml index df00f99b205c9..0773311e11043 100644 --- a/stdlib/OpenSSL_jll/Project.toml +++ b/stdlib/OpenSSL_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenSSL_jll" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.15+1" +version = "3.0.15+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" From f135f3a2dc89d8aa6b885795f27ae989dadc6c3f Mon Sep 17 00:00:00 2001 From: Nicholas Bauer Date: Mon, 13 Jan 2025 14:51:46 -0500 Subject: [PATCH 17/65] More efficient hvcat of scalars and arrays of numbers (#39729) First attempt to address #39713 Original: ``` const a, b, c, d = zeros(Int, 2, 2), [3 4], [2 ; 4], 5 using BenchmarkTools @btime [a c ; b d] # 31 allocations and 1.25 kb ``` New: ``` @btime [a c ; b d] # 15 allocations and 656 bytes ``` Others unchanged, as expected. ~~Though if different types of numbers are mixed, it still takes the longer path. I tried expanding the definition but there's some weird stuff going on that increases allocations in the other situations I posted in that issue.~~ Works for any Number element type. Fixes #39713 --- base/abstractarray.jl | 59 ++++--------------------------------------- 1 file changed, 5 insertions(+), 54 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index a370b79976ab0..1ab78a55c93b5 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2189,48 +2189,8 @@ true hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractArray...) = typed_hvcat(promote_eltype(xs...), rows, xs...) hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractArray{T}...) where {T} = typed_hvcat(T, rows, xs...) -function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMat...) where T - nbr = length(rows) # number of block rows - - nc = 0 - for i=1:rows[1] - nc += size(as[i],2) - end - - nr = 0 - a = 1 - for i = 1:nbr - nr += size(as[a],1) - a += rows[i] - end - - out = similar(as[1], T, nr, nc) - - a = 1 - r = 1 - for i = 1:nbr - c = 1 - szi = size(as[a],1) - for j = 1:rows[i] - Aj = as[a+j-1] - szj = size(Aj,2) - if size(Aj,1) != szi - throw(DimensionMismatch("mismatched height in block row $(i) (expected $szi, got $(size(Aj,1)))")) - end - if c-1+szj > nc - throw(DimensionMismatch("block row $(i) has mismatched number of columns (expected $nc, got $(c-1+szj))")) - end - out[r:r-1+szi, c:c-1+szj] = Aj - c += szj - end - if c != nc+1 - throw(DimensionMismatch("block row $(i) has mismatched number of columns (expected $nc, got $(c-1))")) - end - r += szi - a += rows[i] - end - out -end +rows_to_dimshape(rows::Tuple{Vararg{Int}}) = all(==(rows[1]), rows) ? (length(rows), rows[1]) : (rows, (sum(rows),)) +typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMat...) where T = typed_hvncat(T, rows_to_dimshape(rows), true, as...) hvcat(rows::Tuple{Vararg{Int}}) = [] typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}) where {T} = Vector{T}() @@ -2288,16 +2248,7 @@ function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, xs::Number...) where T hvcat_fill!(Matrix{T}(undef, nr, nc), xs) end -function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as...) where T - nbr = length(rows) # number of block rows - rs = Vector{Any}(undef, nbr) - a = 1 - for i = 1:nbr - rs[i] = typed_hcat(T, as[a:a-1+rows[i]]...) - a += rows[i] - end - T[rs...;] -end +typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as...) where T = typed_hvncat(T, rows_to_dimshape(rows), true, as...) ## N-dimensional concatenation ## @@ -2645,7 +2596,7 @@ function _typed_hvncat_dims(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as throw(DimensionMismatch("mismatched number of elements; expected $(outlen), got $(elementcount)")) # copy into final array - A = cat_similar(as[1], T, outdims) + A = cat_similar(as[1], T, ntuple(i -> outdims[i], N)) # @assert all(==(0), currentdims) outdims .= 0 hvncat_fill!(A, currentdims, outdims, d1, d2, as) @@ -2739,7 +2690,7 @@ function _typed_hvncat_shape(::Type{T}, shape::NTuple{N, Tuple}, row_first, as:: # @assert all(==(0), blockcounts) # copy into final array - A = cat_similar(as[1], T, outdims) + A = cat_similar(as[1], T, ntuple(i -> outdims[i], nd)) hvncat_fill!(A, currentdims, blockcounts, d1, d2, as) return A end From 664528adac261df806f291493593f63b66ff169c Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 14 Jan 2025 05:26:23 +0900 Subject: [PATCH 18/65] make `datatype_min_ninitialized` robust against non `DataType` input (#57033) By unwrapping the input type in `datatype_min_ninitialized`, and guard against non `DataType` input by returning the most conservative value `0` in such cases. Fixes #56997 --- Compiler/src/abstractinterpretation.jl | 2 +- Compiler/src/typelimits.jl | 2 +- Compiler/src/typeutils.jl | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 3766907905aef..59510dbfbb65a 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -3708,7 +3708,7 @@ end if isa(rt, PartialStruct) fields = copy(rt.fields) anyrefine = !isvarargtype(rt.fields[end]) && - length(rt.fields) > datatype_min_ninitialized(unwrap_unionall(rt.typ)) + length(rt.fields) > datatype_min_ninitialized(rt.typ) 𝕃 = typeinf_lattice(info.interp) ⊏ = strictpartialorder(𝕃) for i in 1:length(fields) diff --git a/Compiler/src/typelimits.jl b/Compiler/src/typelimits.jl index 11245fbaee9b0..536b5fb34d1b1 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -601,7 +601,7 @@ end end nflds == 0 && return nothing fields = Vector{Any}(undef, nflds) - anyrefine = nflds > datatype_min_ninitialized(unwrap_unionall(aty)) + anyrefine = nflds > datatype_min_ninitialized(aty) for i = 1:nflds ai = getfield_tfunc(𝕃, typea, Const(i)) bi = getfield_tfunc(𝕃, typeb, Const(i)) diff --git a/Compiler/src/typeutils.jl b/Compiler/src/typeutils.jl index 4af8fed0e40c3..5175e00612270 100644 --- a/Compiler/src/typeutils.jl +++ b/Compiler/src/typeutils.jl @@ -64,7 +64,9 @@ end # Compute the minimum number of initialized fields for a particular datatype # (therefore also a lower bound on the number of fields) -function datatype_min_ninitialized(t::DataType) +function datatype_min_ninitialized(@nospecialize t0) + t = unwrap_unionall(t0) + t isa DataType || return 0 isabstracttype(t) && return 0 if t.name === _NAMEDTUPLE_NAME names, types = t.parameters[1], t.parameters[2] From a861a551b764062d47ab3c2a3748bcf540221bae Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Tue, 14 Jan 2025 01:14:56 -0300 Subject: [PATCH 19/65] Move all platforms to use llvm.minimum/llvm.maximum for fmin/fmax (#56371) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This used to not work but LLVM now has support for this on all platforms we care about. Maybe this should be a builtin. This allows for more vectorization opportunities since llvm understands the code better Fix #48487. --------- Co-authored-by: Mosè Giordano <765740+giordano@users.noreply.github.com> Co-authored-by: oscarddssmith --- Compiler/src/tfuncs.jl | 4 ++++ base/fastmath.jl | 10 ++++----- base/math.jl | 45 +++++----------------------------------- src/intrinsics.cpp | 32 ++++++++++++++++++++++++++++ src/intrinsics.h | 4 ++++ src/julia_internal.h | 2 ++ src/runtime_intrinsics.c | 39 +++++++++++++++++++++++++++++++++- 7 files changed, 89 insertions(+), 47 deletions(-) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index f0c793a4ae3b7..cfb865b06e9e5 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -189,6 +189,8 @@ add_tfunc(add_float, 2, 2, math_tfunc, 2) add_tfunc(sub_float, 2, 2, math_tfunc, 2) add_tfunc(mul_float, 2, 2, math_tfunc, 8) add_tfunc(div_float, 2, 2, math_tfunc, 10) +add_tfunc(min_float, 2, 2, math_tfunc, 1) +add_tfunc(max_float, 2, 2, math_tfunc, 1) add_tfunc(fma_float, 3, 3, math_tfunc, 8) add_tfunc(muladd_float, 3, 3, math_tfunc, 8) @@ -198,6 +200,8 @@ add_tfunc(add_float_fast, 2, 2, math_tfunc, 2) add_tfunc(sub_float_fast, 2, 2, math_tfunc, 2) add_tfunc(mul_float_fast, 2, 2, math_tfunc, 8) add_tfunc(div_float_fast, 2, 2, math_tfunc, 10) +add_tfunc(min_float_fast, 2, 2, math_tfunc, 1) +add_tfunc(max_float_fast, 2, 2, math_tfunc, 1) # bitwise operators # ----------------- diff --git a/base/fastmath.jl b/base/fastmath.jl index b82d613f1fc76..f2f60519b99ac 100644 --- a/base/fastmath.jl +++ b/base/fastmath.jl @@ -28,7 +28,7 @@ module FastMath export @fastmath import Core.Intrinsics: sqrt_llvm_fast, neg_float_fast, - add_float_fast, sub_float_fast, mul_float_fast, div_float_fast, + add_float_fast, sub_float_fast, mul_float_fast, div_float_fast, min_float_fast, max_float_fast, eq_float_fast, ne_float_fast, lt_float_fast, le_float_fast import Base: afoldl @@ -168,6 +168,9 @@ add_fast(x::T, y::T) where {T<:FloatTypes} = add_float_fast(x, y) sub_fast(x::T, y::T) where {T<:FloatTypes} = sub_float_fast(x, y) mul_fast(x::T, y::T) where {T<:FloatTypes} = mul_float_fast(x, y) div_fast(x::T, y::T) where {T<:FloatTypes} = div_float_fast(x, y) +max_fast(x::T, y::T) where {T<:FloatTypes} = max_float_fast(x, y) +min_fast(x::T, y::T) where {T<:FloatTypes} = min_float_fast(x, y) +minmax_fast(x::T, y::T) where {T<:FloatTypes} = (min_fast(x, y), max_fast(x, y)) @fastmath begin cmp_fast(x::T, y::T) where {T<:FloatTypes} = ifelse(x==y, 0, ifelse(x x, y, x) - min_fast(x::T, y::T) where {T<:FloatTypes} = ifelse(y > x, x, y) - minmax_fast(x::T, y::T) where {T<:FloatTypes} = ifelse(y > x, (x,y), (y,x)) end # fall-back implementations and type promotion diff --git a/base/math.jl b/base/math.jl index 16a8a547e8de1..650fc6bc0cef0 100644 --- a/base/math.jl +++ b/base/math.jl @@ -25,7 +25,7 @@ using .Base: sign_mask, exponent_mask, exponent_one, significand_bits, exponent_bits, exponent_bias, exponent_max, exponent_raw_max, clamp, clamp! -using Core.Intrinsics: sqrt_llvm +using Core.Intrinsics: sqrt_llvm, min_float, max_float using .Base: IEEEFloat @@ -831,47 +831,12 @@ min(x::T, y::T) where {T<:AbstractFloat} = isnan(x) || ~isnan(y) && _isless(x, y max(x::T, y::T) where {T<:AbstractFloat} = isnan(x) || ~isnan(y) && _isless(y, x) ? x : y minmax(x::T, y::T) where {T<:AbstractFloat} = min(x, y), max(x, y) -_isless(x::Float16, y::Float16) = signbit(widen(x) - widen(y)) - -const has_native_fminmax = Sys.ARCH === :aarch64 -@static if has_native_fminmax - @eval begin - Base.@assume_effects :total @inline llvm_min(x::Float64, y::Float64) = ccall("llvm.minimum.f64", llvmcall, Float64, (Float64, Float64), x, y) - Base.@assume_effects :total @inline llvm_min(x::Float32, y::Float32) = ccall("llvm.minimum.f32", llvmcall, Float32, (Float32, Float32), x, y) - Base.@assume_effects :total @inline llvm_max(x::Float64, y::Float64) = ccall("llvm.maximum.f64", llvmcall, Float64, (Float64, Float64), x, y) - Base.@assume_effects :total @inline llvm_max(x::Float32, y::Float32) = ccall("llvm.maximum.f32", llvmcall, Float32, (Float32, Float32), x, y) - end -end - -function min(x::T, y::T) where {T<:Union{Float32,Float64}} - @static if has_native_fminmax - return llvm_min(x,y) - end - diff = x - y - argmin = ifelse(signbit(diff), x, y) - anynan = isnan(x)|isnan(y) - return ifelse(anynan, diff, argmin) +function min(x::T, y::T) where {T<:IEEEFloat} + return min_float(x, y) end -function max(x::T, y::T) where {T<:Union{Float32,Float64}} - @static if has_native_fminmax - return llvm_max(x,y) - end - diff = x - y - argmax = ifelse(signbit(diff), y, x) - anynan = isnan(x)|isnan(y) - return ifelse(anynan, diff, argmax) -end - -function minmax(x::T, y::T) where {T<:Union{Float32,Float64}} - @static if has_native_fminmax - return llvm_min(x, y), llvm_max(x, y) - end - diff = x - y - sdiff = signbit(diff) - min, max = ifelse(sdiff, x, y), ifelse(sdiff, y, x) - anynan = isnan(x)|isnan(y) - return ifelse(anynan, diff, min), ifelse(anynan, diff, max) +function max(x::T, y::T) where {T<:IEEEFloat} + return max_float(x, y) end """ diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 09916297e16ff..7b5aa7c397129 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -83,10 +83,14 @@ const auto &float_func() { float_func[sub_float] = true; float_func[mul_float] = true; float_func[div_float] = true; + float_func[min_float] = true; + float_func[max_float] = true; float_func[add_float_fast] = true; float_func[sub_float_fast] = true; float_func[mul_float_fast] = true; float_func[div_float_fast] = true; + float_func[min_float_fast] = true; + float_func[max_float_fast] = true; float_func[fma_float] = true; float_func[muladd_float] = true; float_func[eq_float] = true; @@ -1490,6 +1494,34 @@ static Value *emit_untyped_intrinsic(jl_codectx_t &ctx, intrinsic f, ArrayRefgetType() == y->getType()); + FunctionCallee minintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::minimum, ArrayRef(t)); + return ctx.builder.CreateCall(minintr, {x, y}); + } + case max_float: { + assert(x->getType() == y->getType()); + FunctionCallee maxintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::maximum, ArrayRef(t)); + return ctx.builder.CreateCall(maxintr, {x, y}); + } + case min_float_fast: { + assert(x->getType() == y->getType()); + FunctionCallee minintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::minimum, ArrayRef(t)); + auto call = ctx.builder.CreateCall(minintr, {x, y}); + auto fmf = call->getFastMathFlags(); + fmf.setFast(); + call->copyFastMathFlags(fmf); + return call; + } + case max_float_fast: { + assert(x->getType() == y->getType()); + FunctionCallee maxintr = Intrinsic::getDeclaration(jl_Module, Intrinsic::maximum, ArrayRef(t)); + auto call = ctx.builder.CreateCall(maxintr, {x, y}); + auto fmf = call->getFastMathFlags(); + fmf.setFast(); + call->copyFastMathFlags(fmf); + return call; + } case add_float_fast: return math_builder(ctx, true)().CreateFAdd(x, y); case sub_float_fast: return math_builder(ctx, true)().CreateFSub(x, y); case mul_float_fast: return math_builder(ctx, true)().CreateFMul(x, y); diff --git a/src/intrinsics.h b/src/intrinsics.h index 5b463e3bafe28..5765e3e671bc6 100644 --- a/src/intrinsics.h +++ b/src/intrinsics.h @@ -17,6 +17,8 @@ ADD_I(sub_float, 2) \ ADD_I(mul_float, 2) \ ADD_I(div_float, 2) \ + ADD_I(min_float, 2) \ + ADD_I(max_float, 2) \ ADD_I(fma_float, 3) \ ADD_I(muladd_float, 3) \ /* fast arithmetic */ \ @@ -25,6 +27,8 @@ ALIAS(sub_float_fast, sub_float) \ ALIAS(mul_float_fast, mul_float) \ ALIAS(div_float_fast, div_float) \ + ALIAS(min_float_fast, min_float) \ + ALIAS(max_float_fast, max_float) \ /* same-type comparisons */ \ ADD_I(eq_int, 2) \ ADD_I(ne_int, 2) \ diff --git a/src/julia_internal.h b/src/julia_internal.h index f8dd49eab65a3..81e9ebb537667 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1595,6 +1595,8 @@ JL_DLLEXPORT jl_value_t *jl_add_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_sub_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_mul_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_div_float(jl_value_t *a, jl_value_t *b); +JL_DLLEXPORT jl_value_t *jl_min_float(jl_value_t *a, jl_value_t *b); +JL_DLLEXPORT jl_value_t *jl_max_float(jl_value_t *a, jl_value_t *b); JL_DLLEXPORT jl_value_t *jl_fma_float(jl_value_t *a, jl_value_t *b, jl_value_t *c); JL_DLLEXPORT jl_value_t *jl_muladd_float(jl_value_t *a, jl_value_t *b, jl_value_t *c); diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 80281b733bf44..1790b9bd8d106 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -1398,13 +1398,50 @@ bi_iintrinsic_fast(LLVMURem, rem, urem_int, u) bi_iintrinsic_fast(jl_LLVMSMod, smod, smod_int, ) #define frem(a, b) \ fp_select2(a, b, fmod) - un_fintrinsic(neg_float,neg_float) bi_fintrinsic(add,add_float) bi_fintrinsic(sub,sub_float) bi_fintrinsic(mul,mul_float) bi_fintrinsic(div,div_float) +float min_float(float x, float y) JL_NOTSAFEPOINT +{ + float diff = x - y; + float argmin = signbit(diff) ? x : y; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +double min_double(double x, double y) JL_NOTSAFEPOINT +{ + double diff = x - y; + double argmin = signbit(diff) ? x : y; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +#define _min(a, b) sizeof(a) == sizeof(float) ? min_float(a, b) : min_double(a, b) +bi_fintrinsic(_min, min_float) + +float max_float(float x, float y) JL_NOTSAFEPOINT +{ + float diff = x - y; + float argmin = signbit(diff) ? y : x; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +double max_double(double x, double y) JL_NOTSAFEPOINT +{ + double diff = x - y; + double argmin = signbit(diff) ? x : y; + int is_nan = isnan(x) || isnan(y); + return is_nan ? diff : argmin; +} + +#define _max(a, b) sizeof(a) == sizeof(float) ? max_float(a, b) : max_double(a, b) +bi_fintrinsic(_max, max_float) + // ternary operators // // runtime fma is broken on windows, define julia_fma(f) ourself with fma_emulated as reference. #if defined(_OS_WINDOWS_) From 9b1ea1a880e1c47ebdc549a12fca288b5cc60013 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:37:18 +0900 Subject: [PATCH 20/65] publish Compiler.jl v0.0.3 (#57032) Cthulhu.jl requires this (as the signature of `jl_update_codeinst` has been updated). --- Compiler/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Compiler/Project.toml b/Compiler/Project.toml index 046d672c4877c..994634f5a8b78 100644 --- a/Compiler/Project.toml +++ b/Compiler/Project.toml @@ -1,6 +1,6 @@ name = "Compiler" uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" -version = "0.0.2" +version = "0.0.3" [compat] julia = "1.10" From 3ba504a5484c48720aa3f19e7ef51a5a32c3a7db Mon Sep 17 00:00:00 2001 From: Yi Lin Date: Wed, 15 Jan 2025 00:39:11 +1300 Subject: [PATCH 21/65] Fix getall failure with MMTk dependency (#57038) This PR fixes https://github.com/JuliaLang/julia/issues/57002. The current makefile checks if `MMTK_JULIA_DIR` points to `$(BUILDROOT)/usr/lib/mmtk_julia` and defines the rule `get-mmtk_julia` if the condition is met. For non-mmtk builds (e.g. `make -C deps getall`), `MMTK_JULIA_DIR` is not defined, thus `get-mmtk_julia` is not defined. This PR moves the rule `get-mmtk_julia` outside the condition so it always exists. --- deps/mmtk_julia.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/deps/mmtk_julia.mk b/deps/mmtk_julia.mk index ccf638e9211bb..7ec55426821c3 100644 --- a/deps/mmtk_julia.mk +++ b/deps/mmtk_julia.mk @@ -6,9 +6,11 @@ MMTK_MOVING := 0 MMTK_VARS := MMTK_PLAN=$(MMTK_PLAN) MMTK_MOVING=$(MMTK_MOVING) +$(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR))) +get-mmtk_julia: $(MMTK_JULIA_SRC_FILE) + # Download the binding, build it from source ifeq (${MMTK_JULIA_DIR},$(BUILDROOT)/usr/lib/mmtk_julia) -$(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR))) MMTK_JULIA_DIR=$(BUILDROOT)/deps/$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR) MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD) @@ -24,7 +26,6 @@ $(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted @$(PROJECT_DIRS) $(MMTK_VARS) $(MAKE) -C $(MMTK_JULIA_DIR) $(MMTK_BUILD) -get-mmtk_julia: $(MMTK_JULIA_SRC_FILE) extract-mmtk_julia: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted configure-mmtk_julia: extract-mmtk_julia compile-mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so From b23f557e80cabac1624fc98abacfba152156ef8f Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 14 Jan 2025 16:28:34 +0100 Subject: [PATCH 22/65] Revert "Avoid allocations in views of views (#53231)" (#57044) This reverts commit 2bd4cf8090f2c651543f562a4c469d73e4b15bd6. (#53231) The reason for this revert is that it caused exponential blowup of types in iterated views causing some packages to simply freeze when doing something that worked ok in 1.10. In my opinion, the perf gain from the PR is not outweighed by the "risk" of hitting this compilation blowup case. Fixes https://github.com/JuliaLang/julia/issues/56760. Co-authored-by: KristofferC --- base/subarray.jl | 6 +++--- test/subarray.jl | 25 ------------------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/base/subarray.jl b/base/subarray.jl index d6ddf7786f7ec..eacaddc068f1f 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -291,18 +291,18 @@ reindex(idxs::Tuple{Slice, Vararg{Any}}, subidxs::Tuple{Any, Vararg{Any}}) = # Re-index into parent vectors with one subindex reindex(idxs::Tuple{AbstractVector, Vararg{Any}}, subidxs::Tuple{Any, Vararg{Any}}) = - (@_propagate_inbounds_meta; (maybeview(idxs[1], subidxs[1]), reindex(tail(idxs), tail(subidxs))...)) + (@_propagate_inbounds_meta; (idxs[1][subidxs[1]], reindex(tail(idxs), tail(subidxs))...)) # Parent matrices are re-indexed with two sub-indices reindex(idxs::Tuple{AbstractMatrix, Vararg{Any}}, subidxs::Tuple{Any, Any, Vararg{Any}}) = - (@_propagate_inbounds_meta; (maybeview(idxs[1], subidxs[1], subidxs[2]), reindex(tail(idxs), tail(tail(subidxs)))...)) + (@_propagate_inbounds_meta; (idxs[1][subidxs[1], subidxs[2]], reindex(tail(idxs), tail(tail(subidxs)))...)) # In general, we index N-dimensional parent arrays with N indices @generated function reindex(idxs::Tuple{AbstractArray{T,N}, Vararg{Any}}, subidxs::Tuple{Vararg{Any}}) where {T,N} if length(subidxs.parameters) >= N subs = [:(subidxs[$d]) for d in 1:N] tail = [:(subidxs[$d]) for d in N+1:length(subidxs.parameters)] - :(@_propagate_inbounds_meta; (maybeview(idxs[1], $(subs...)), reindex(tail(idxs), ($(tail...),))...)) + :(@_propagate_inbounds_meta; (idxs[1][$(subs...)], reindex(tail(idxs), ($(tail...),))...)) else :(throw(ArgumentError("cannot re-index SubArray with fewer indices than dimensions\nThis should not occur; please submit a bug report."))) end diff --git a/test/subarray.jl b/test/subarray.jl index 818365730f079..a462224e7643a 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -1027,31 +1027,6 @@ catch err err isa ErrorException && startswith(err.msg, "syntax:") end - -@testset "avoid allocating in reindex" begin - a = reshape(1:16, 4, 4) - inds = ([2,3], [3,4]) - av = view(a, inds...) - av2 = view(av, 1, 1) - @test parentindices(av2) === (2,3) - av2 = view(av, 2:2, 2:2) - @test parentindices(av2) === (view(inds[1], 2:2), view(inds[2], 2:2)) - - inds = (reshape([eachindex(a);], size(a)),) - av = view(a, inds...) - av2 = view(av, 1, 1) - @test parentindices(av2) === (1,) - av2 = view(av, 2:2, 2:2) - @test parentindices(av2) === (view(inds[1], 2:2, 2:2),) - - inds = (reshape([eachindex(a);], size(a)..., 1),) - av = view(a, inds...) - av2 = view(av, 1, 1, 1) - @test parentindices(av2) === (1,) - av2 = view(av, 2:2, 2:2, 1:1) - @test parentindices(av2) === (view(inds[1], 2:2, 2:2, 1:1),) -end - @testset "isassigned" begin a = Vector{BigFloat}(undef, 5) a[2] = 0 From 1b0fba7ffd455d919f1c4f6bb8f31d7c4fae0cc0 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 14 Jan 2025 10:31:17 -0500 Subject: [PATCH 23/65] debuginfo: fix GC error in OC debuginfo (#57036) Also add some extra annotations that seemed to be required locally, though unrelated to the primary change. Observed on CI: https://buildkite.com/julialang/julia-master/builds/43693#01946057-7150-4741-a756-79e7d59a7717 Fixes #57042 --- src/aotcompile.cpp | 112 +++++++++++++++++++++++---------------------- src/debuginfo.cpp | 8 +++- src/jitlayers.cpp | 2 +- src/jitlayers.h | 11 +++-- 4 files changed, 72 insertions(+), 61 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index b839ced8336da..0235758979cd1 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -2209,65 +2209,67 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_ if (src && jl_is_code_info(src)) { auto ctx = jl_ExecutionEngine->makeContext(); orc::ThreadSafeModule m = jl_create_ts_module(name_from_method_instance(mi), ctx); - uint64_t compiler_start_time = 0; - uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); - if (measure_compile_time_enabled) - compiler_start_time = jl_hrtime(); - auto target_info = m.withModuleDo([&](Module &M) { - return std::make_pair(M.getDataLayout(), Triple(M.getTargetTriple())); - }); - jl_codegen_params_t output(ctx, std::move(target_info.first), std::move(target_info.second)); - output.params = ¶ms; - output.imaging_mode = jl_options.image_codegen; - output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); - JL_GC_PUSH1(&output.temporary_roots); - auto decls = jl_emit_code(m, mi, src, NULL, output); - output.temporary_roots = nullptr; - JL_GC_POP(); // GC the global_targets array contents now since reflection doesn't need it - - Function *F = NULL; - if (m) { - // if compilation succeeded, prepare to return the result - // Similar to jl_link_global from jitlayers.cpp, - // so that code_llvm shows similar codegen to the jit - for (auto &global : output.global_targets) { - if (jl_options.image_codegen) { - global.second->setLinkage(GlobalValue::ExternalLinkage); + Function *F = nullptr; + { + uint64_t compiler_start_time = 0; + uint8_t measure_compile_time_enabled = jl_atomic_load_relaxed(&jl_measure_compile_time_enabled); + if (measure_compile_time_enabled) + compiler_start_time = jl_hrtime(); + auto target_info = m.withModuleDo([&](Module &M) { + return std::make_pair(M.getDataLayout(), Triple(M.getTargetTriple())); + }); + jl_codegen_params_t output(ctx, std::move(target_info.first), std::move(target_info.second)); + output.params = ¶ms; + output.imaging_mode = jl_options.image_codegen; + output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); + JL_GC_PUSH1(&output.temporary_roots); + auto decls = jl_emit_code(m, mi, src, NULL, output); + output.temporary_roots = nullptr; + JL_GC_POP(); // GC the global_targets array contents now since reflection doesn't need it + + if (m) { + // if compilation succeeded, prepare to return the result + // Similar to jl_link_global from jitlayers.cpp, + // so that code_llvm shows similar codegen to the jit + for (auto &global : output.global_targets) { + if (jl_options.image_codegen) { + global.second->setLinkage(GlobalValue::ExternalLinkage); + } + else { + auto p = literal_static_pointer_val(global.first, global.second->getValueType()); + Type *elty = PointerType::get(output.getContext(), 0); + // For pretty printing, when LLVM inlines the global initializer into its loads + auto alias = GlobalAlias::create(elty, 0, GlobalValue::PrivateLinkage, global.second->getName() + ".jit", p, global.second->getParent()); + global.second->setInitializer(ConstantExpr::getBitCast(alias, global.second->getValueType())); + global.second->setConstant(true); + global.second->setLinkage(GlobalValue::PrivateLinkage); + global.second->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); + global.second->setVisibility(GlobalValue::DefaultVisibility); + } } - else { - auto p = literal_static_pointer_val(global.first, global.second->getValueType()); - Type *elty = PointerType::get(output.getContext(), 0); - // For pretty printing, when LLVM inlines the global initializer into its loads - auto alias = GlobalAlias::create(elty, 0, GlobalValue::PrivateLinkage, global.second->getName() + ".jit", p, global.second->getParent()); - global.second->setInitializer(ConstantExpr::getBitCast(alias, global.second->getValueType())); - global.second->setConstant(true); - global.second->setLinkage(GlobalValue::PrivateLinkage); - global.second->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); - global.second->setVisibility(GlobalValue::DefaultVisibility); + if (!jl_options.image_codegen) { + optimizeDLSyms(*m.getModuleUnlocked()); } - } - if (!jl_options.image_codegen) { - optimizeDLSyms(*m.getModuleUnlocked()); - } - assert(!verifyLLVMIR(*m.getModuleUnlocked())); - if (optimize) { - NewPM PM{jl_ExecutionEngine->cloneTargetMachine(), getOptLevel(jl_options.opt_level)}; - //Safe b/c context lock is held by output - PM.run(*m.getModuleUnlocked()); assert(!verifyLLVMIR(*m.getModuleUnlocked())); + if (optimize) { + NewPM PM{jl_ExecutionEngine->cloneTargetMachine(), getOptLevel(jl_options.opt_level)}; + //Safe b/c context lock is held by output + PM.run(*m.getModuleUnlocked()); + assert(!verifyLLVMIR(*m.getModuleUnlocked())); + } + const std::string *fname; + if (decls.functionObject == "jl_fptr_args" || decls.functionObject == "jl_fptr_sparam") + getwrapper = false; + if (!getwrapper) + fname = &decls.specFunctionObject; + else + fname = &decls.functionObject; + F = cast(m.getModuleUnlocked()->getNamedValue(*fname)); + } + if (measure_compile_time_enabled) { + auto end = jl_hrtime(); + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); } - const std::string *fname; - if (decls.functionObject == "jl_fptr_args" || decls.functionObject == "jl_fptr_sparam") - getwrapper = false; - if (!getwrapper) - fname = &decls.specFunctionObject; - else - fname = &decls.functionObject; - F = cast(m.getModuleUnlocked()->getNamedValue(*fname)); - } - if (measure_compile_time_enabled) { - auto end = jl_hrtime(); - jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); } if (F) { dump->TSM = wrap(new orc::ThreadSafeModule(std::move(m))); diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index c16fb559a6516..17e093cecb89a 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -162,14 +162,18 @@ static void jl_profile_atomic(T f) JL_NOTSAFEPOINT // --- storing and accessing source location metadata --- -void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL) +void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER { // Non-opaque-closure MethodInstances are considered globally rooted // through their methods, but for OC, we need to create a global root // here. jl_method_instance_t *mi = jl_get_ci_mi(codeinst); - if (jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure) + if (jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure) { + jl_task_t *ct = jl_current_task; + int8_t gc_state = jl_gc_unsafe_enter(ct->ptls); jl_as_global_root((jl_value_t*)mi, 1); + jl_gc_unsafe_leave(ct->ptls, gc_state); + } getJITDebugRegistry().add_code_in_flight(name, codeinst, DL); } diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 396a42505188a..0acb7beaca9ab 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -699,7 +699,7 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst) } } -void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL); +void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER; extern "C" JL_DLLEXPORT_CODEGEN void jl_emit_codeinst_to_jit_impl( diff --git a/src/jitlayers.h b/src/jitlayers.h index b41f2e38bc470..7198c9b2f0210 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -178,10 +178,15 @@ struct jl_locked_stream { } }; -typedef struct _jl_llvm_functions_t { +struct jl_llvm_functions_t { std::string functionObject; // jlcall llvm Function name std::string specFunctionObject; // specialized llvm Function name -} jl_llvm_functions_t; + jl_llvm_functions_t() JL_NOTSAFEPOINT = default; + jl_llvm_functions_t &operator=(const jl_llvm_functions_t&) JL_NOTSAFEPOINT = default; + jl_llvm_functions_t(const jl_llvm_functions_t &) JL_NOTSAFEPOINT = default; + jl_llvm_functions_t(jl_llvm_functions_t &&) JL_NOTSAFEPOINT = default; + ~jl_llvm_functions_t() JL_NOTSAFEPOINT = default; +}; struct jl_returninfo_t { llvm::FunctionCallee decl; @@ -642,7 +647,7 @@ Module &jl_codegen_params_t::shared_module() JL_NOTSAFEPOINT { } void fixupTM(TargetMachine &TM) JL_NOTSAFEPOINT; -void optimizeDLSyms(Module &M); +void optimizeDLSyms(Module &M) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER; // NewPM #include "passes.h" From 1f05953fab1e14e1e881a224d8719d2c7d637da3 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 14 Jan 2025 10:33:09 -0500 Subject: [PATCH 24/65] linux: workaround to avoid deadlock inside dl_iterate_phdr in glibc (#57035) Extend the fix for #43578 on Darwin to also cover the same bug in Glibc (and just assume other libc have the same bug). We cannot use the same atfork trick, since the atfork implementation of this in Glibc makes this unsafe to use this after fork, just like Darwin (though for different basic concurrency mistakes in each of their respective codes). Fix #57017 --- src/julia_internal.h | 3 +- src/signals-mach.c | 9 +-- src/signals-unix.c | 186 +++++++++++++++++++++++-------------------- src/signals-win.c | 19 +++-- src/stackwalk.c | 18 ++++- 5 files changed, 130 insertions(+), 105 deletions(-) diff --git a/src/julia_internal.h b/src/julia_internal.h index 81e9ebb537667..a464025edf856 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -208,8 +208,7 @@ JL_DLLEXPORT void jl_lock_profile(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER; JL_DLLEXPORT void jl_unlock_profile(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE; JL_DLLEXPORT void jl_lock_profile_wr(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER; JL_DLLEXPORT void jl_unlock_profile_wr(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE; -int jl_lock_stackwalk(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER; -void jl_unlock_stackwalk(int lockret) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE; +void jl_with_stackwalk_lock(void (*f)(void*) JL_NOTSAFEPOINT, void *ctx) JL_NOTSAFEPOINT; arraylist_t *jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT; typedef struct { diff --git a/src/signals-mach.c b/src/signals-mach.c index 24508a8902d5e..1c4af2cf9d033 100644 --- a/src/signals-mach.c +++ b/src/signals-mach.c @@ -714,13 +714,10 @@ static void jl_unlock_profile_mach(int dlsymlock, int keymgr_locked) jl_unlock_profile(); } -int jl_lock_stackwalk(void) -{ - return jl_lock_profile_mach(1); -} - -void jl_unlock_stackwalk(int lockret) +void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { + int lockret = jl_lock_profile_mach(1); + f(ctx); jl_unlock_profile_mach(1, lockret); } diff --git a/src/signals-unix.c b/src/signals-unix.c index 394c4a108b647..91d3378068f84 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -308,20 +308,27 @@ int exc_reg_is_write_fault(uintptr_t esr) { #else #include #include +#include -int jl_lock_stackwalk(void) +typedef struct { + void (*f)(void*) JL_NOTSAFEPOINT; + void *ctx; +} callback_t; +static int with_dl_iterate_phdr_lock(struct dl_phdr_info *info, size_t size, void *data) { jl_lock_profile(); - return 0; + callback_t *callback = (callback_t*)data; + callback->f(callback->ctx); + jl_unlock_profile(); + return 1; // only call this once } -void jl_unlock_stackwalk(int lockret) +void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { - (void)lockret; - jl_unlock_profile(); + callback_t callback = {f, ctx}; + dl_iterate_phdr(with_dl_iterate_phdr_lock, &callback); } - #if defined(_OS_LINUX_) && (defined(_CPU_X86_64_) || defined(_CPU_X86_)) int is_write_fault(void *context) { ucontext_t *ctx = (ucontext_t*)context; @@ -435,7 +442,7 @@ JL_NO_ASAN static void segv_handler(int sig, siginfo_t *info, void *context) } pthread_mutex_t in_signal_lock; // shared with jl_delete_thread -static bt_context_t *signal_context; // protected by in_signal_lock +static bt_context_t *usr2_signal_context; // protected by in_signal_lock static int exit_signal_cond = -1; static int signal_caught_cond = -1; static int signals_inflight = 0; @@ -507,7 +514,7 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx) request = jl_atomic_load_acquire(&ptls2->signal_request); assert(request == 0 || request == -1); (void) request; jl_atomic_store_release(&ptls2->signal_request, 4); // prepare to resume normally, but later code may change this - *ctx = *signal_context; + *ctx = *usr2_signal_context; return 1; } @@ -587,8 +594,8 @@ void usr2_handler(int sig, siginfo_t *info, void *ctx) if (!jl_atomic_cmpswap(&ptls->signal_request, &request, -1)) return; if (request == 1) { - signal_context = jl_to_bt_context(ctx); - // acknowledge that we saw the signal_request and set signal_context + usr2_signal_context = jl_to_bt_context(ctx); + // acknowledge that we saw the signal_request and set usr2_signal_context int err; eventfd_t got = 1; err = write(signal_caught_cond, &got, sizeof(eventfd_t)); @@ -602,7 +609,7 @@ void usr2_handler(int sig, siginfo_t *info, void *ctx) if (err != sizeof(eventfd_t)) abort(); assert(got == 1); request = jl_atomic_exchange(&ptls->signal_request, -1); - signal_context = NULL; + usr2_signal_context = NULL; assert(request == 2 || request == 3 || request == 4); } int err; @@ -806,7 +813,7 @@ void trigger_profile_peek(void) jl_safe_printf("\n======================================================================================\n"); jl_safe_printf("Information request received. A stacktrace will print followed by a %.1f second profile\n", profile_peek_duration); jl_safe_printf("======================================================================================\n"); - if (profile_bt_size_max == 0){ + if (profile_bt_size_max == 0) { // If the buffer hasn't been initialized, initialize with default size // Keep these values synchronized with Profile.default_init() if (jl_profile_init(10000000, 1000000) == -1) { @@ -821,59 +828,93 @@ void trigger_profile_peek(void) profile_autostop_time = jl_hrtime() + (profile_peek_duration * 1e9); } -// assumes holding `jl_lock_stackwalk` -void jl_profile_thread_unix(int tid, bt_context_t *signal_context) +#if !defined(JL_DISABLE_LIBUNWIND) + +static jl_bt_element_t signal_bt_data[JL_MAX_BT_SIZE + 1]; +static size_t signal_bt_size = 0; +static void do_critical_profile(void *ctx) { - if (jl_profile_is_buffer_full()) { - // Buffer full: Delete the timer - jl_profile_stop_timer(); - return; - } - // notify thread to stop - if (!jl_thread_suspend_and_get_state(tid, 1, signal_context)) - return; - // unwinding can fail, so keep track of the current state - // and restore from the SEGV handler if anything happens. - jl_jmp_buf *old_buf = jl_get_safe_restore(); - jl_jmp_buf buf; - - jl_set_safe_restore(&buf); - if (jl_setjmp(buf, 0)) { - jl_safe_printf("WARNING: profiler attempt to access an invalid memory location\n"); - } else { - // Get backtrace data - profile_bt_size_cur += rec_backtrace_ctx((jl_bt_element_t*)profile_bt_data_prof + profile_bt_size_cur, - profile_bt_size_max - profile_bt_size_cur - 1, signal_context, NULL); + bt_context_t signal_context; + // sample each thread, round-robin style in reverse order + // (so that thread zero gets notified last) + int nthreads = jl_atomic_load_acquire(&jl_n_threads); + for (int i = nthreads; i-- > 0; ) { + // notify thread to stop + if (!jl_thread_suspend_and_get_state(i, 1, &signal_context)) + continue; + + // do backtrace on thread contexts for critical signals + // this part must be signal-handler safe + signal_bt_size += rec_backtrace_ctx(signal_bt_data + signal_bt_size, + JL_MAX_BT_SIZE / nthreads - 1, + &signal_context, NULL); + signal_bt_data[signal_bt_size++].uintptr = 0; + jl_thread_resume(i); } - jl_set_safe_restore(old_buf); +} - jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[tid]; +static void do_profile(void *ctx) +{ + bt_context_t signal_context; + int nthreads = jl_atomic_load_acquire(&jl_n_threads); + int *randperm = profile_get_randperm(nthreads); + for (int idx = nthreads; idx-- > 0; ) { + // Stop the threads in the random order. + int tid = randperm[idx]; + // do backtrace for profiler + if (!profile_running) + return; + if (jl_profile_is_buffer_full()) { + // Buffer full: Delete the timer + jl_profile_stop_timer(); + return; + } + // notify thread to stop + if (!jl_thread_suspend_and_get_state(tid, 1, &signal_context)) + return; + // unwinding can fail, so keep track of the current state + // and restore from the SEGV handler if anything happens. + jl_jmp_buf *old_buf = jl_get_safe_restore(); + jl_jmp_buf buf; + + jl_set_safe_restore(&buf); + if (jl_setjmp(buf, 0)) { + jl_safe_printf("WARNING: profiler attempt to access an invalid memory location\n"); + } + else { + // Get backtrace data + profile_bt_size_cur += rec_backtrace_ctx((jl_bt_element_t*)profile_bt_data_prof + profile_bt_size_cur, + profile_bt_size_max - profile_bt_size_cur - 1, &signal_context, NULL); + } + jl_set_safe_restore(old_buf); - // store threadid but add 1 as 0 is preserved to indicate end of block - profile_bt_data_prof[profile_bt_size_cur++].uintptr = ptls2->tid + 1; + jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[tid]; - // store task id (never null) - profile_bt_data_prof[profile_bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls2->current_task); + // store threadid but add 1 as 0 is preserved to indicate end of block + profile_bt_data_prof[profile_bt_size_cur++].uintptr = ptls2->tid + 1; - // store cpu cycle clock - profile_bt_data_prof[profile_bt_size_cur++].uintptr = cycleclock(); + // store task id (never null) + profile_bt_data_prof[profile_bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls2->current_task); - // store whether thread is sleeping (don't ever encode a state as `0` since is preserved to indicate end of block) - int state = jl_atomic_load_relaxed(&ptls2->sleep_check_state) == 0 ? PROFILE_STATE_THREAD_NOT_SLEEPING : PROFILE_STATE_THREAD_SLEEPING; - profile_bt_data_prof[profile_bt_size_cur++].uintptr = state; + // store cpu cycle clock + profile_bt_data_prof[profile_bt_size_cur++].uintptr = cycleclock(); - // Mark the end of this block with two 0's - profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; - profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; + // store whether thread is sleeping (don't ever encode a state as `0` since is preserved to indicate end of block) + int state = jl_atomic_load_relaxed(&ptls2->sleep_check_state) == 0 ? PROFILE_STATE_THREAD_NOT_SLEEPING : PROFILE_STATE_THREAD_SLEEPING; + profile_bt_data_prof[profile_bt_size_cur++].uintptr = state; - // notify thread to resume - jl_thread_resume(tid); + // Mark the end of this block with two 0's + profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; + profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; + + // notify thread to resume + jl_thread_resume(tid); + } } +#endif static void *signal_listener(void *arg) { - static jl_bt_element_t bt_data[JL_MAX_BT_SIZE + 1]; - static size_t bt_size = 0; sigset_t sset; int sig, critical, profile; jl_sigsetset(&sset); @@ -1005,28 +1046,10 @@ static void *signal_listener(void *arg) } } - int nthreads = jl_atomic_load_acquire(&jl_n_threads); - bt_size = 0; + signal_bt_size = 0; #if !defined(JL_DISABLE_LIBUNWIND) - bt_context_t signal_context; if (critical) { - int lockret = jl_lock_stackwalk(); - // sample each thread, round-robin style in reverse order - // (so that thread zero gets notified last) - for (int i = nthreads; i-- > 0; ) { - // notify thread to stop - if (!jl_thread_suspend_and_get_state(i, 1, &signal_context)) - continue; - - // do backtrace on thread contexts for critical signals - // this part must be signal-handler safe - bt_size += rec_backtrace_ctx(bt_data + bt_size, - JL_MAX_BT_SIZE / nthreads - 1, - &signal_context, NULL); - bt_data[bt_size++].uintptr = 0; - jl_thread_resume(i); - } - jl_unlock_stackwalk(lockret); + jl_with_stackwalk_lock(do_critical_profile, NULL); } else if (profile) { if (profile_all_tasks) { @@ -1034,17 +1057,7 @@ static void *signal_listener(void *arg) jl_profile_task(); } else { - int lockret = jl_lock_stackwalk(); - int *randperm = profile_get_randperm(nthreads); - for (int idx = nthreads; idx-- > 0; ) { - // Stop the threads in the random order. - int i = randperm[idx]; - // do backtrace for profiler - if (profile_running) { - jl_profile_thread_unix(i, &signal_context); - } - } - jl_unlock_stackwalk(lockret); + jl_with_stackwalk_lock(do_profile, NULL); } } #ifndef HAVE_MACH @@ -1065,11 +1078,12 @@ static void *signal_listener(void *arg) //#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L && !HAVE_KEVENT // si_code = info.si_code; //#endif - jl_exit_thread0(sig, bt_data, bt_size); + jl_exit_thread0(sig, signal_bt_data, signal_bt_size); } else if (critical) { // critical in this case actually means SIGINFO request #ifndef SIGINFO // SIGINFO already prints something similar automatically + int nthreads = jl_atomic_load_acquire(&jl_n_threads); int n_threads_running = 0; for (int idx = nthreads; idx-- > 0; ) { jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[idx]; @@ -1080,8 +1094,8 @@ static void *signal_listener(void *arg) jl_safe_printf("\nsignal (%d): %s\n", sig, strsignal(sig)); size_t i; - for (i = 0; i < bt_size; i += jl_bt_entry_size(bt_data + i)) { - jl_print_bt_entry_codeloc(bt_data + i); + for (i = 0; i < signal_bt_size; i += jl_bt_entry_size(signal_bt_data + i)) { + jl_print_bt_entry_codeloc(signal_bt_data + i); } } } diff --git a/src/signals-win.c b/src/signals-win.c index dbf95fdb19791..c8ae74f52dba4 100644 --- a/src/signals-win.c +++ b/src/signals-win.c @@ -383,20 +383,25 @@ void jl_thread_resume(int tid) } } -int jl_lock_stackwalk(void) +void jl_lock_stackwalk(void) { uv_mutex_lock(&jl_in_stackwalk); jl_lock_profile(); - return 0; } -void jl_unlock_stackwalk(int lockret) +void jl_unlock_stackwalk(void) { - (void)lockret; jl_unlock_profile(); uv_mutex_unlock(&jl_in_stackwalk); } +void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) +{ + jl_lock_stackwalk(); + f(ctx); + jl_unlock_stackwalk(); +} + static DWORD WINAPI profile_bt( LPVOID lparam ) { @@ -416,10 +421,10 @@ static DWORD WINAPI profile_bt( LPVOID lparam ) } else { // TODO: bring this up to parity with other OS by adding loop over tid here - int lockret = jl_lock_stackwalk(); + jl_lock_stackwalk(); CONTEXT ctxThread; if (!jl_thread_suspend_and_get_state(0, 0, &ctxThread)) { - jl_unlock_stackwalk(lockret); + jl_unlock_stackwalk(); fputs("failed to suspend main thread. aborting profiling.", stderr); jl_profile_stop_timer(); break; @@ -446,7 +451,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam ) // Mark the end of this block with two 0's profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; profile_bt_data_prof[profile_bt_size_cur++].uintptr = 0; - jl_unlock_stackwalk(lockret); + jl_unlock_stackwalk(); jl_thread_resume(0); jl_check_profile_autostop(); } diff --git a/src/stackwalk.c b/src/stackwalk.c index 28adef030395e..f1d807908cf42 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -1249,6 +1249,17 @@ return 0; #endif } +typedef struct { + int16_t old; + bt_context_t *c; + int success; +} suspend_t; +static void suspend(void *ctx) +{ + suspend_t *suspenddata = (suspend_t*)ctx; + suspenddata->success = jl_thread_suspend_and_get_state(suspenddata->old, 1, suspenddata->c); +} + JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, jl_bt_element_t *bt_data, size_t max_bt_size, int all_tasks_profiler) JL_NOTSAFEPOINT { int16_t tid = INT16_MAX; @@ -1270,15 +1281,14 @@ JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, jl_b bt_context_t c; int16_t old; for (old = -1; !jl_atomic_cmpswap(&t->tid, &old, tid) && old != tid; old = -1) { - int lockret = jl_lock_stackwalk(); // if this task is already running somewhere, we need to stop the thread it is running on and query its state - if (!jl_thread_suspend_and_get_state(old, 1, &c)) { - jl_unlock_stackwalk(lockret); + suspend_t suspenddata = {old, &c}; + jl_with_stackwalk_lock(suspend, &suspenddata); + if (!suspenddata.success) { if (jl_atomic_load_relaxed(&t->tid) != old) continue; return result; } - jl_unlock_stackwalk(lockret); if (jl_atomic_load_relaxed(&t->tid) == old) { jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[old]; if (ptls2->previous_task == t || // we might print the wrong stack here, since we can't know whether we executed the swapcontext yet or not, but it at least avoids trying to access the state inside uc_mcontext which might not be set yet From 723c3e603c8b19e471b2f773047c9432471f0e68 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 15 Jan 2025 03:52:45 +0900 Subject: [PATCH 25/65] improve pcre.jl code a bit (#57031) - `PCRE._mth()` now uses `Base._maxthreadid` instead of manual inlining of `Threads.maxthreadid()` - `PCRE_COMPILE_LOCK` is now typed global --- base/Base.jl | 12 ++++++------ base/pcre.jl | 8 ++++---- base/regex.jl | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/base/Base.jl b/base/Base.jl index 1f737452fa17a..9119b3a482242 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -91,6 +91,12 @@ include("osutils.jl") include("io.jl") include("iobuffer.jl") +# Concurrency (part 1) +include("linked_list.jl") +include("condition.jl") +include("threads.jl") +include("lock.jl") + # strings & printing include("intfuncs.jl") include("strings/strings.jl") @@ -117,12 +123,6 @@ include("missing.jl") # version include("version.jl") -# Concurrency (part 1) -include("linked_list.jl") -include("condition.jl") -include("threads.jl") -include("lock.jl") - # system & environment include("sysinfo.jl") include("libc.jl") diff --git a/base/pcre.jl b/base/pcre.jl index b357bbc8f3bf9..e4567fe03e8f8 100644 --- a/base/pcre.jl +++ b/base/pcre.jl @@ -24,19 +24,19 @@ function create_match_context() return ctx end -THREAD_MATCH_CONTEXTS::Vector{Ptr{Cvoid}} = [C_NULL] +global THREAD_MATCH_CONTEXTS::Vector{Ptr{Cvoid}} = [C_NULL] -PCRE_COMPILE_LOCK = nothing +global PCRE_COMPILE_LOCK::Threads.SpinLock _tid() = Int(ccall(:jl_threadid, Int16, ())) + 1 -_mth() = Int(Core.Intrinsics.atomic_pointerref(cglobal(:jl_n_threads, Cint), :acquire)) +_mth() = Threads.maxthreadid() function get_local_match_context() tid = _tid() ctxs = THREAD_MATCH_CONTEXTS if length(ctxs) < tid # slow path to allocate it - l = PCRE_COMPILE_LOCK::Threads.SpinLock + l = PCRE_COMPILE_LOCK lock(l) try ctxs = THREAD_MATCH_CONTEXTS diff --git a/base/regex.jl b/base/regex.jl index 9444c9a9fb63e..09922b8a25111 100644 --- a/base/regex.jl +++ b/base/regex.jl @@ -69,11 +69,11 @@ Regex(pattern::AbstractString) = Regex(pattern, DEFAULT_COMPILER_OPTS, DEFAULT_M function compile(regex::Regex) if regex.regex == C_NULL - if PCRE.PCRE_COMPILE_LOCK === nothing + if !isdefinedglobal(PCRE, :PCRE_COMPILE_LOCK) regex.regex = PCRE.compile(regex.pattern, regex.compile_options) PCRE.jit_compile(regex.regex) else - l = PCRE.PCRE_COMPILE_LOCK::Threads.SpinLock + l = PCRE.PCRE_COMPILE_LOCK lock(l) try if regex.regex == C_NULL From 2cc296c8fd3cba6b7caa872d5fb13c947b190780 Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Tue, 14 Jan 2025 17:13:24 -0500 Subject: [PATCH 26/65] MozillaCACerts_jll: Update to 2024.12.31 (#57039) --- deps/checksums/cacert-2024-11-26.pem/md5 | 1 - deps/checksums/cacert-2024-11-26.pem/sha512 | 1 - deps/checksums/cacert-2024-12-31.pem/md5 | 1 + deps/checksums/cacert-2024-12-31.pem/sha512 | 1 + deps/libgit2.version | 2 +- stdlib/MozillaCACerts_jll/Project.toml | 2 +- 6 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 deps/checksums/cacert-2024-11-26.pem/md5 delete mode 100644 deps/checksums/cacert-2024-11-26.pem/sha512 create mode 100644 deps/checksums/cacert-2024-12-31.pem/md5 create mode 100644 deps/checksums/cacert-2024-12-31.pem/sha512 diff --git a/deps/checksums/cacert-2024-11-26.pem/md5 b/deps/checksums/cacert-2024-11-26.pem/md5 deleted file mode 100644 index 865c6abf3e77a..0000000000000 --- a/deps/checksums/cacert-2024-11-26.pem/md5 +++ /dev/null @@ -1 +0,0 @@ -92c13373d7dbe43bdc167479274a43e2 diff --git a/deps/checksums/cacert-2024-11-26.pem/sha512 b/deps/checksums/cacert-2024-11-26.pem/sha512 deleted file mode 100644 index d51605348faf4..0000000000000 --- a/deps/checksums/cacert-2024-11-26.pem/sha512 +++ /dev/null @@ -1 +0,0 @@ -26c6fa1ac7bcfd523f9ab9e6c2d971103ccfc610ad0df504d4e9b064dad74576d77240c052b808f4c37c9240302a7e973a20f79ee39ac7bf3201a6fa9f0dfa96 diff --git a/deps/checksums/cacert-2024-12-31.pem/md5 b/deps/checksums/cacert-2024-12-31.pem/md5 new file mode 100644 index 0000000000000..b01bf68ddc247 --- /dev/null +++ b/deps/checksums/cacert-2024-12-31.pem/md5 @@ -0,0 +1 @@ +d9178b626f8b87f51b47987418d012bf diff --git a/deps/checksums/cacert-2024-12-31.pem/sha512 b/deps/checksums/cacert-2024-12-31.pem/sha512 new file mode 100644 index 0000000000000..c12b8215a7855 --- /dev/null +++ b/deps/checksums/cacert-2024-12-31.pem/sha512 @@ -0,0 +1 @@ +bf578937d7826106bae1ebe74a70bfbc439387445a1f41ef57430de9d9aea6fcfa1884381bf0ef14632f6b89e9543642c9b774fcca93837efffdc557c4958dbd diff --git a/deps/libgit2.version b/deps/libgit2.version index 57744b6c96d8e..6bfb6106e67d2 100644 --- a/deps/libgit2.version +++ b/deps/libgit2.version @@ -11,4 +11,4 @@ LIBGIT2_SHA1=338e6fb681369ff0537719095e22ce9dc602dbf0 # The versions of cacert.pem are identified by the date (YYYY-MM-DD) of their changes. # See https://curl.haxx.se/docs/caextract.html for more details. # Keep in sync with `stdlib/MozillaCACerts_jll/Project.toml`. -MOZILLA_CACERT_VERSION := 2024-11-26 +MOZILLA_CACERT_VERSION := 2024-12-31 diff --git a/stdlib/MozillaCACerts_jll/Project.toml b/stdlib/MozillaCACerts_jll/Project.toml index 5df9bd5949972..2f9bf67e22a74 100644 --- a/stdlib/MozillaCACerts_jll/Project.toml +++ b/stdlib/MozillaCACerts_jll/Project.toml @@ -1,7 +1,7 @@ name = "MozillaCACerts_jll" uuid = "14a3606d-f60d-562e-9121-12d972cd8159" # Keep in sync with `deps/libgit2.version`. -version = "2024.11.26" +version = "2024.12.31" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" From ef0405584dd3280f8e23906d9eef8f8799a236f9 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Wed, 15 Jan 2025 18:13:44 +0900 Subject: [PATCH 27/65] aot: move `jl_insert_backedges` to Julia side (#56499) With JuliaLang/julia#56447, the dependency between `jl_insert_backedges` and method insertion has been eliminated, allowing `jl_insert_backedges` to be performed after loading. As a result, it is now possible to move `jl_insert_backedges` to the Julia side. Currently this commit simply moves the implementation without adding any new features. --------- Co-authored-by: Jameson Nash --- Compiler/src/typeinfer.jl | 5 +- base/Base.jl | 1 + base/loading.jl | 17 +- base/staticdata.jl | 296 +++++++++++++++++++++++++++++++ src/staticdata.c | 14 +- src/staticdata_utils.c | 362 -------------------------------------- test/precompile.jl | 12 +- 7 files changed, 323 insertions(+), 384 deletions(-) create mode 100644 base/staticdata.jl diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index ec1e62817106d..e3896870d82b8 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -560,12 +560,11 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector) ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any, Any), callee, item, caller) i += 2 continue - end - # `invoke` edge - if isa(callee, Method) + elseif isa(callee, Method) # ignore `Method`-edges (from e.g. failed `abstract_call_method`) i += 2 continue + # `invoke` edge elseif isa(callee, CodeInstance) callee = get_ci_mi(callee) end diff --git a/base/Base.jl b/base/Base.jl index 9119b3a482242..20b1636c29a8d 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -262,6 +262,7 @@ include("uuid.jl") include("pkgid.jl") include("toml_parser.jl") include("linking.jl") +include("staticdata.jl") include("loading.jl") # misc useful functions & macros diff --git a/base/loading.jl b/base/loading.jl index 024c4ceb356fd..4193aae13b96a 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1280,17 +1280,20 @@ function _include_from_serialized(pkg::PkgId, path::String, ocachepath::Union{No sv = try if ocachepath !== nothing @debug "Loading object cache file $ocachepath for $(repr("text/plain", pkg))" - ccall(:jl_restore_package_image_from_file, Any, (Cstring, Any, Cint, Cstring, Cint), ocachepath, depmods, false, pkg.name, ignore_native) + ccall(:jl_restore_package_image_from_file, Ref{SimpleVector}, (Cstring, Any, Cint, Cstring, Cint), + ocachepath, depmods, #=completeinfo=#false, pkg.name, ignore_native) else @debug "Loading cache file $path for $(repr("text/plain", pkg))" - ccall(:jl_restore_incremental, Any, (Cstring, Any, Cint, Cstring), path, depmods, false, pkg.name) + ccall(:jl_restore_incremental, Ref{SimpleVector}, (Cstring, Any, Cint, Cstring), + path, depmods, #=completeinfo=#false, pkg.name) end finally lock(require_lock) end - if isa(sv, Exception) - return sv - end + + edges = sv[3]::Vector{Any} + ext_edges = sv[4]::Union{Nothing,Vector{Any}} + StaticData.insert_backedges(edges, ext_edges) restored = register_restored_modules(sv, pkg, path) @@ -4198,7 +4201,7 @@ function precompile(@nospecialize(argt::Type)) end # Variants that work for `invoke`d calls for which the signature may not be sufficient -precompile(mi::Core.MethodInstance, world::UInt=get_world_counter()) = +precompile(mi::MethodInstance, world::UInt=get_world_counter()) = (ccall(:jl_compile_method_instance, Cvoid, (Any, Ptr{Cvoid}, UInt), mi, C_NULL, world); return true) """ @@ -4214,7 +4217,7 @@ end function precompile(@nospecialize(argt::Type), m::Method) atype, sparams = ccall(:jl_type_intersection_with_env, Any, (Any, Any), argt, m.sig)::SimpleVector - mi = Core.Compiler.specialize_method(m, atype, sparams) + mi = Base.Compiler.specialize_method(m, atype, sparams) return precompile(mi) end diff --git a/base/staticdata.jl b/base/staticdata.jl new file mode 100644 index 0000000000000..79d81788cc16a --- /dev/null +++ b/base/staticdata.jl @@ -0,0 +1,296 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +module StaticData + +using Core: CodeInstance, MethodInstance +using Base: get_world_counter + +const WORLD_AGE_REVALIDATION_SENTINEL::UInt = 1 +const _jl_debug_method_invalidation = Ref{Union{Nothing,Vector{Any}}}(nothing) +debug_method_invalidation(onoff::Bool) = + _jl_debug_method_invalidation[] = onoff ? Any[] : nothing + +function get_ci_mi(codeinst::CodeInstance) + def = codeinst.def + if def isa Core.ABIOverride + return def.def + else + return def::MethodInstance + end +end + +# Restore backedges to external targets +# `edges` = [caller1, ...], the list of worklist-owned code instances internally +# `ext_ci_list` = [caller1, ...], the list of worklist-owned code instances externally +function insert_backedges(edges::Vector{Any}, ext_ci_list::Union{Nothing,Vector{Any}}) + # determine which CodeInstance objects are still valid in our image + # to enable any applicable new codes + stack = CodeInstance[] + visiting = IdDict{CodeInstance,Int}() + _insert_backedges(edges, stack, visiting) + if ext_ci_list !== nothing + _insert_backedges(ext_ci_list, stack, visiting, #=external=#true) + end +end + +function _insert_backedges(edges::Vector{Any}, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}, external::Bool=false) + for i = 1:length(edges) + codeinst = edges[i]::CodeInstance + verify_method_graph(codeinst, stack, visiting) + minvalid = codeinst.min_world + maxvalid = codeinst.max_world + if maxvalid ≥ minvalid + if get_world_counter() == maxvalid + # if this callee is still valid, add all the backedges + Base.Compiler.store_backedges(codeinst, codeinst.edges) + end + if get_world_counter() == maxvalid + maxvalid = typemax(UInt) + @atomic :monotonic codeinst.max_world = maxvalid + end + if external + caller = get_ci_mi(codeinst) + @assert isdefined(codeinst, :inferred) # See #53586, #53109 + inferred = @ccall jl_rettype_inferred( + codeinst.owner::Any, caller::Any, minvalid::UInt, maxvalid::UInt)::Any + if inferred !== nothing + # We already got a code instance for this world age range from + # somewhere else - we don't need this one. + else + @ccall jl_mi_cache_insert(caller::Any, codeinst::Any)::Cvoid + end + end + end + end +end + +function verify_method_graph(codeinst::CodeInstance, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}) + @assert isempty(stack); @assert isempty(visiting); + child_cycle, minworld, maxworld = verify_method(codeinst, stack, visiting) + @assert child_cycle == 0 + @assert isempty(stack); @assert isempty(visiting); + nothing +end + +# Test all edges relevant to a method: +# - Visit the entire call graph, starting from edges[idx] to determine if that method is valid +# - Implements Tarjan's SCC (strongly connected components) algorithm, simplified to remove the count variable +# and slightly modified with an early termination option once the computation reaches its minimum +function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}) + world = codeinst.min_world + let max_valid2 = codeinst.max_world + if max_valid2 ≠ WORLD_AGE_REVALIDATION_SENTINEL + return 0, world, max_valid2 + end + end + current_world = get_world_counter() + local minworld::UInt, maxworld::UInt = 1, current_world + @assert get_ci_mi(codeinst).def isa Method + if haskey(visiting, codeinst) + return visiting[codeinst], minworld, maxworld + end + push!(stack, codeinst) + depth = length(stack) + visiting[codeinst] = depth + # TODO JL_TIMING(VERIFY_IMAGE, VERIFY_Methods) + callees = codeinst.edges + # verify current edges + if isempty(callees) + # quick return: no edges to verify (though we probably shouldn't have gotten here from WORLD_AGE_REVALIDATION_SENTINEL) + elseif maxworld == unsafe_load(cglobal(:jl_require_world, UInt)) + # if no new worlds were allocated since serializing the base module, then no new validation is worth doing right now either + minworld = maxworld + else + j = 1 + while j ≤ length(callees) + local min_valid2::UInt, max_valid2::UInt + edge = callees[j] + @assert !(edge isa Method) # `Method`-edge isn't allowed for the optimized one-edge format + if edge isa Core.BindingPartition + j += 1 + continue + end + if edge isa CodeInstance + edge = get_ci_mi(edge) + end + if edge isa MethodInstance + sig = typeintersect((edge.def::Method).sig, edge.specTypes) # TODO?? + min_valid2, max_valid2, matches = verify_call(sig, callees, j, 1, world) + j += 1 + elseif edge isa Int + sig = callees[j+1] + min_valid2, max_valid2, matches = verify_call(sig, callees, j+2, edge, world) + j += 2 + edge + edge = sig + else + callee = callees[j+1] + if callee isa Core.MethodTable # skip the legacy edge (missing backedge) + j += 2 + continue + end + if callee isa CodeInstance + callee = get_ci_mi(callee) + end + if callee isa MethodInstance + meth = callee.def::Method + else + meth = callee::Method + end + min_valid2, max_valid2 = verify_invokesig(edge, meth, world) + matches = nothing + j += 2 + end + if minworld < min_valid2 + minworld = min_valid2 + end + if maxworld > max_valid2 + maxworld = max_valid2 + end + invalidations = _jl_debug_method_invalidation[] + if max_valid2 ≠ typemax(UInt) && invalidations !== nothing + push!(invalidations, edge, "insert_backedges_callee", codeinst, matches) + end + if max_valid2 == 0 && invalidations === nothing + break + end + end + end + # verify recursive edges (if valid, or debugging) + cycle = depth + cause = codeinst + if maxworld ≠ 0 || _jl_debug_method_invalidation[] !== nothing + for j = 1:length(callees) + edge = callees[j] + if !(edge isa CodeInstance) + continue + end + callee = edge + local min_valid2::UInt, max_valid2::UInt + child_cycle, min_valid2, max_valid2 = verify_method(callee, stack, visiting) + if minworld < min_valid2 + minworld = min_valid2 + end + if minworld > max_valid2 + max_valid2 = 0 + end + if maxworld > max_valid2 + cause = callee + maxworld = max_valid2 + end + if max_valid2 == 0 + # found what we were looking for, so terminate early + break + elseif child_cycle ≠ 0 && child_cycle < cycle + # record the cycle will resolve at depth "cycle" + cycle = child_cycle + end + end + end + if maxworld ≠ 0 && cycle ≠ depth + return cycle, minworld, maxworld + end + # If we are the top of the current cycle, now mark all other parts of + # our cycle with what we found. + # Or if we found a failed edge, also mark all of the other parts of the + # cycle as also having a failed edge. + while length(stack) ≥ depth + child = pop!(stack) + if maxworld ≠ 0 + @atomic :monotonic child.min_world = minworld + end + @atomic :monotonic child.max_world = maxworld + @assert visiting[child] == length(stack) + 1 + delete!(visiting, child) + invalidations = _jl_debug_method_invalidation[] + if invalidations !== nothing && maxworld < current_world + push!(invalidations, child, "verify_methods", cause) + end + end + return 0, minworld, maxworld +end + +function verify_call(@nospecialize(sig), expecteds::Core.SimpleVector, i::Int, n::Int, world::UInt) + # verify that these edges intersect with the same methods as before + lim = _jl_debug_method_invalidation[] !== nothing ? Int(typemax(Int32)) : n + minworld = Ref{UInt}(1) + maxworld = Ref{UInt}(typemax(UInt)) + has_ambig = Ref{Int32}(0) + result = Base._methods_by_ftype(sig, nothing, lim, world, #=ambig=#false, minworld, maxworld, has_ambig) + if result === nothing + maxworld[] = 0 + else + # setdiff!(result, expected) + if length(result) ≠ n + maxworld[] = 0 + end + ins = 0 + for k = 1:length(result) + match = result[k]::Core.MethodMatch + local found = false + for j = 1:n + t = expecteds[i+j-1] + if t isa Method + meth = t + else + if t isa CodeInstance + t = get_ci_mi(t) + else + t = t::MethodInstance + end + meth = t.def::Method + end + if match.method == meth + found = true + break + end + end + if !found + # intersection has a new method or a method was + # deleted--this is now probably no good, just invalidate + # everything about it now + maxworld[] = 0 + if _jl_debug_method_invalidation[] === nothing + break + end + ins += 1 + result[ins] = match.method + end + end + if maxworld[] ≠ typemax(UInt) && _jl_debug_method_invalidation[] !== nothing + resize!(result, ins) + end + end + return minworld[], maxworld[], result +end + +function verify_invokesig(@nospecialize(invokesig), expected::Method, world::UInt) + @assert invokesig isa Type + local minworld::UInt, maxworld::UInt + if invokesig === expected.sig + # the invoke match is `expected` for `expected->sig`, unless `expected` is invalid + minworld = expected.primary_world + maxworld = expected.deleted_world + @assert minworld ≤ world + if maxworld < world + maxworld = 0 + end + else + minworld = 1 + maxworld = typemax(UInt) + mt = Base.get_methodtable(expected) + if mt === nothing + maxworld = 0 + else + matched, valid_worlds = Base.Compiler._findsup(invokesig, mt, world) + minworld, maxworld = valid_worlds.min_world, valid_worlds.max_world + if matched === nothing + maxworld = 0 + elseif matched.method != expected + maxworld = 0 + end + end + end + return minworld, maxworld +end + +end # module StaticData diff --git a/src/staticdata.c b/src/staticdata.c index 4124d3b481bb3..7fad87652b26a 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -89,7 +89,7 @@ External links: #include "julia_assert.h" static const size_t WORLD_AGE_REVALIDATION_SENTINEL = 0x1; -size_t jl_require_world = ~(size_t)0; +JL_DLLEXPORT size_t jl_require_world = ~(size_t)0; #include "staticdata_utils.c" #include "precompile_utils.c" @@ -4110,12 +4110,13 @@ static jl_value_t *jl_restore_package_image_from_stream(void* pkgimage_handle, i jl_atomic_store_release(&jl_world_counter, world); // now permit more methods to be added again JL_UNLOCK(&world_counter_lock); - // but one of those immediate users is going to be our cache insertions - jl_insert_backedges((jl_array_t*)edges, (jl_array_t*)new_ext_cis); // restore existing caches (needs to be last) + // reinit ccallables jl_reinit_ccallable(&ccallable_list, base, pkgimage_handle); arraylist_free(&ccallable_list); + jl_value_t *ext_edges = new_ext_cis ? (jl_value_t*)new_ext_cis : jl_nothing; + if (completeinfo) { cachesizes_sv = jl_alloc_svec(7); jl_svecset(cachesizes_sv, 0, jl_box_long(cachesizes.sysdata)); @@ -4125,12 +4126,11 @@ static jl_value_t *jl_restore_package_image_from_stream(void* pkgimage_handle, i jl_svecset(cachesizes_sv, 4, jl_box_long(cachesizes.reloclist)); jl_svecset(cachesizes_sv, 5, jl_box_long(cachesizes.gvarlist)); jl_svecset(cachesizes_sv, 6, jl_box_long(cachesizes.fptrlist)); - restored = (jl_value_t*)jl_svec(7, restored, init_order, extext_methods, - new_ext_cis ? (jl_value_t*)new_ext_cis : jl_nothing, - method_roots_list, edges, cachesizes_sv); + restored = (jl_value_t*)jl_svec(7, restored, init_order, edges, ext_edges, + extext_methods, method_roots_list, cachesizes_sv); } else { - restored = (jl_value_t*)jl_svec(2, restored, init_order); + restored = (jl_value_t*)jl_svec(4, restored, init_order, edges, ext_edges); } } } diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index 79d2909970d99..1985357321a3a 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -750,368 +750,6 @@ static void jl_copy_roots(jl_array_t *method_roots_list, uint64_t key) } } -static void verify_invokesig(jl_value_t *invokesig, jl_method_t *expected, size_t world, size_t *minworld, size_t *maxworld) -{ - assert(jl_is_type(invokesig)); - assert(jl_is_method(expected)); - if (jl_egal(invokesig, expected->sig)) { - // the invoke match is `expected` for `expected->sig`, unless `expected` is invalid - *minworld = jl_atomic_load_relaxed(&expected->primary_world); - *maxworld = jl_atomic_load_relaxed(&expected->deleted_world); - assert(*minworld <= world); - if (*maxworld < world) - *maxworld = 0; - } - else { - *minworld = 1; - *maxworld = ~(size_t)0; - jl_methtable_t *mt = jl_method_get_table(expected); - if ((jl_value_t*)mt == jl_nothing) { - *maxworld = 0; - } - else { - jl_value_t *matches = jl_gf_invoke_lookup_worlds(invokesig, (jl_value_t*)mt, world, minworld, maxworld); - if (matches == jl_nothing) { - *maxworld = 0; - } - else { - if (((jl_method_match_t*)matches)->method != expected) { - *maxworld = 0; - } - } - } - } -} - -static void verify_call(jl_value_t *sig, jl_svec_t *expecteds, size_t i, size_t n, size_t world, size_t *minworld, size_t *maxworld, jl_value_t **matches JL_REQUIRE_ROOTED_SLOT) -{ - // verify that these edges intersect with the same methods as before - *minworld = 1; - *maxworld = ~(size_t)0; - int ambig = 0; - // TODO: possibly need to included ambiguities too (for the optimizer correctness)? - jl_value_t *result = jl_matching_methods((jl_tupletype_t*)sig, jl_nothing, - _jl_debug_method_invalidation ? INT32_MAX : n, - 0, world, minworld, maxworld, &ambig); - *matches = result; - if (result == jl_nothing) { - *maxworld = 0; - } - else { - // setdiff!(result, expected) - size_t j, k, ins = 0; - if (jl_array_nrows(result) != n) { - *maxworld = 0; - } - for (k = 0; k < jl_array_nrows(result); k++) { - jl_method_t *match = ((jl_method_match_t*)jl_array_ptr_ref(result, k))->method; - for (j = 0; j < n; j++) { - jl_value_t *t = jl_svecref(expecteds, j + i); - if (jl_is_code_instance(t)) - t = (jl_value_t*)((jl_code_instance_t*)t)->def; - jl_method_t *meth; - if (jl_is_method(t)) - meth = (jl_method_t*)t; - else { - assert(jl_is_method_instance(t)); - meth = ((jl_method_instance_t*)t)->def.method; - } - if (match == meth) - break; - } - if (j == n) { - // intersection has a new method or a method was - // deleted--this is now probably no good, just invalidate - // everything about it now - *maxworld = 0; - if (!_jl_debug_method_invalidation) - break; - jl_array_ptr_set(result, ins++, match); - } - } - if (*maxworld != ~(size_t)0 && _jl_debug_method_invalidation) - jl_array_del_end((jl_array_t*)result, jl_array_nrows(result) - ins); - } -} - -// Test all edges relevant to a method: -//// Visit the entire call graph, starting from edges[idx] to determine if that method is valid -//// Implements Tarjan's SCC (strongly connected components) algorithm, simplified to remove the count variable -//// and slightly modified with an early termination option once the computation reaches its minimum -static int jl_verify_method(jl_code_instance_t *codeinst, size_t *minworld, size_t *maxworld, arraylist_t *stack, htable_t *visiting) -{ - size_t world = jl_atomic_load_relaxed(&codeinst->min_world); - size_t max_valid2 = jl_atomic_load_relaxed(&codeinst->max_world); - if (max_valid2 != WORLD_AGE_REVALIDATION_SENTINEL) { - *minworld = world; - *maxworld = max_valid2; - return 0; - } - *minworld = 1; - size_t current_world = jl_atomic_load_relaxed(&jl_world_counter); - *maxworld = current_world; - assert(jl_is_method_instance(jl_get_ci_mi(codeinst)) && jl_is_method(jl_get_ci_mi(codeinst)->def.method)); - void **bp = ptrhash_bp(visiting, codeinst); - if (*bp != HT_NOTFOUND) - return (char*)*bp - (char*)HT_NOTFOUND; // cycle idx - arraylist_push(stack, (void*)codeinst); - size_t depth = stack->len; - *bp = (char*)HT_NOTFOUND + depth; - JL_TIMING(VERIFY_IMAGE, VERIFY_Methods); - jl_svec_t *callees = jl_atomic_load_relaxed(&codeinst->edges); - assert(jl_is_svec((jl_value_t*)callees)); - // verify current edges - if (callees == jl_emptysvec) { - // quick return: no edges to verify (though we probably shouldn't have gotten here from WORLD_AGE_REVALIDATION_SENTINEL) - } - else if (*maxworld == jl_require_world) { - // if no new worlds were allocated since serializing the base module, then no new validation is worth doing right now either - *minworld = *maxworld; - } - else { - jl_value_t *loctag = NULL; - jl_value_t *sig = NULL; - jl_value_t *matches = NULL; - JL_GC_PUSH3(&loctag, &matches, &sig); - for (size_t j = 0; j < jl_svec_len(callees); ) { - jl_value_t *edge = jl_svecref(callees, j); - size_t min_valid2; - size_t max_valid2; - assert(!jl_is_method(edge)); // `Method`-edge isn't allowed for the optimized one-edge format - if (jl_is_binding_partition(edge)) { - j += 1; - continue; - } - if (jl_is_code_instance(edge)) - edge = (jl_value_t*)jl_get_ci_mi((jl_code_instance_t*)edge); - if (jl_is_method_instance(edge)) { - jl_method_instance_t *mi = (jl_method_instance_t*)edge; - sig = jl_type_intersection(mi->def.method->sig, (jl_value_t*)mi->specTypes); // TODO: ?? - verify_call(sig, callees, j, 1, world, &min_valid2, &max_valid2, &matches); - sig = NULL; - j += 1; - } - else if (jl_is_long(edge)) { - jl_value_t *sig = jl_svecref(callees, j + 1); - size_t nedges = jl_unbox_long(edge); - verify_call(sig, callees, j + 2, nedges, world, &min_valid2, &max_valid2, &matches); - j += 2 + nedges; - edge = sig; - } - else { - jl_method_instance_t *callee = (jl_method_instance_t*)jl_svecref(callees, j + 1); - jl_method_t *meth; - if (jl_is_mtable(callee)) { - // skip the legacy edge (missing backedge) - j += 2; - continue; - } - if (jl_is_code_instance(callee)) - callee = jl_get_ci_mi((jl_code_instance_t*)callee); - if (jl_is_method_instance(callee)) { - meth = callee->def.method; - } - else { - assert(jl_is_method(callee)); - meth = (jl_method_t*)callee; - } - verify_invokesig(edge, meth, world, &min_valid2, &max_valid2); - j += 2; - } - if (*minworld < min_valid2) - *minworld = min_valid2; - if (*maxworld > max_valid2) - *maxworld = max_valid2; - if (max_valid2 != ~(size_t)0 && _jl_debug_method_invalidation) { - jl_array_ptr_1d_push(_jl_debug_method_invalidation, edge); - loctag = jl_cstr_to_string("insert_backedges_callee"); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)codeinst); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, matches); - } - //jl_static_show((JL_STREAM*)ios_stderr, (jl_value_t*)edge); - //ios_puts(max_valid2 == ~(size_t)0 ? "valid\n" : "INVALID\n", ios_stderr); - if (max_valid2 == 0 && !_jl_debug_method_invalidation) - break; - } - JL_GC_POP(); - } - // verify recursive edges (if valid, or debugging) - size_t cycle = depth; - jl_code_instance_t *cause = codeinst; - if (*maxworld != 0 || _jl_debug_method_invalidation) { - for (size_t j = 0; j < jl_svec_len(callees); j++) { - jl_value_t *edge = jl_svecref(callees, j); - if (!jl_is_code_instance(edge)) - continue; - jl_code_instance_t *callee = (jl_code_instance_t*)edge; - size_t min_valid2; - size_t max_valid2; - size_t child_cycle = jl_verify_method(callee, &min_valid2, &max_valid2, stack, visiting); - if (*minworld < min_valid2) - *minworld = min_valid2; - if (*minworld > max_valid2) - max_valid2 = 0; - if (*maxworld > max_valid2) { - cause = callee; - *maxworld = max_valid2; - } - if (max_valid2 == 0) { - // found what we were looking for, so terminate early - break; - } - else if (child_cycle && child_cycle < cycle) { - // record the cycle will resolve at depth "cycle" - cycle = child_cycle; - } - } - } - if (*maxworld != 0 && cycle != depth) - return cycle; - // If we are the top of the current cycle, now mark all other parts of - // our cycle with what we found. - // Or if we found a failed edge, also mark all of the other parts of the - // cycle as also having a failed edge. - while (stack->len >= depth) { - jl_code_instance_t *child = (jl_code_instance_t*)arraylist_pop(stack); - if (jl_atomic_load_relaxed(&jl_n_threads) == 1) { - // a different thread might simultaneously come to a different, but equally valid, alternative result - assert(jl_atomic_load_relaxed(&child->max_world) == WORLD_AGE_REVALIDATION_SENTINEL); - assert(*minworld <= jl_atomic_load_relaxed(&child->min_world)); - } - if (*maxworld != 0) - jl_atomic_store_relaxed(&child->min_world, *minworld); - jl_atomic_store_relaxed(&child->max_world, *maxworld); - void **bp = ptrhash_bp(visiting, child); - assert(*bp == (char*)HT_NOTFOUND + stack->len + 1); - *bp = HT_NOTFOUND; - if (_jl_debug_method_invalidation && *maxworld < current_world) { - jl_value_t *loctag; - jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)child); - loctag = jl_cstr_to_string("verify_methods"); - JL_GC_PUSH1(&loctag); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); - jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)cause); - JL_GC_POP(); - } - } - //jl_static_show((JL_STREAM*)ios_stderr, (jl_value_t*)codeinst->def); - //ios_puts(max_valid == ~(size_t)0 ? "valid\n\n" : "INVALID\n\n", ios_stderr); - return 0; -} - -static void jl_verify_method_graph(jl_code_instance_t *codeinst, arraylist_t *stack, htable_t *visiting) -{ - size_t minworld; - size_t maxworld; - assert(stack->len == 0); - for (size_t i = 0, hsz = visiting->size; i < hsz; i++) - assert(visiting->table[i] == HT_NOTFOUND); - int child_cycle = jl_verify_method(codeinst, &minworld, &maxworld, stack, visiting); - assert(child_cycle == 0); (void)child_cycle; - assert(stack->len == 0); - for (size_t i = 0, hsz = visiting->size / 2; i < hsz; i++) { - assert(visiting->table[2 * i + 1] == HT_NOTFOUND); - visiting->table[2 * i] = HT_NOTFOUND; - } - if (jl_atomic_load_relaxed(&jl_n_threads) == 1) { // a different thread might simultaneously come to a different, but equally valid, alternative result - assert(maxworld == 0 || jl_atomic_load_relaxed(&codeinst->min_world) == minworld); - assert(jl_atomic_load_relaxed(&codeinst->max_world) == maxworld); - } -} - -// Restore backedges to external targets -// `edges` = [caller1, ...], the list of worklist-owned code instances internally -// `ext_ci_list` = [caller1, ...], the list of worklist-owned code instances externally -static void jl_insert_backedges(jl_array_t *edges, jl_array_t *ext_ci_list) -{ - // determine which CodeInstance objects are still valid in our image - // to enable any applicable new codes - arraylist_t stack; - arraylist_new(&stack, 0); - htable_t visiting; - htable_new(&visiting, 0); - for (size_t external = 0; external < (ext_ci_list ? 2 : 1); external++) { - if (external) - edges = ext_ci_list; - size_t nedges = jl_array_nrows(edges); - for (size_t i = 0; i < nedges; i++) { - jl_code_instance_t *codeinst = (jl_code_instance_t*)jl_array_ptr_ref(edges, i); - jl_svec_t *callees = jl_atomic_load_relaxed(&codeinst->edges); - jl_method_instance_t *caller = jl_get_ci_mi(codeinst); - jl_verify_method_graph(codeinst, &stack, &visiting); - size_t minvalid = jl_atomic_load_relaxed(&codeinst->min_world); - size_t maxvalid = jl_atomic_load_relaxed(&codeinst->max_world); - if (maxvalid >= minvalid) { - if (jl_atomic_load_relaxed(&jl_world_counter) == maxvalid) { - // if this callee is still valid, add all the backedges - for (size_t j = 0; j < jl_svec_len(callees); ) { - jl_value_t *edge = jl_svecref(callees, j); - if (jl_is_long(edge)) { - j += 2; // skip over signature and count but not methods - continue; - } - else if (jl_is_method(edge)) { - j += 1; - continue; - } - else if (jl_is_binding_partition(edge)) { - j += 1; - continue; - } - if (jl_is_code_instance(edge)) - edge = (jl_value_t*)((jl_code_instance_t*)edge)->def; - if (jl_is_method_instance(edge)) { - jl_method_instance_add_backedge((jl_method_instance_t*)edge, NULL, codeinst); - j += 1; - } - else { - jl_value_t *callee = jl_svecref(callees, j + 1); - if (jl_is_mtable(callee)) { - jl_methtable_t *mt = (jl_methtable_t*)callee; - jl_method_table_add_backedge(mt, edge, codeinst); - j += 2; - continue; - } - else if (jl_is_code_instance(callee)) { - callee = (jl_value_t*)((jl_code_instance_t*)callee)->def; - } - else if (jl_is_method(callee)) { - j += 2; - continue; - } - jl_method_instance_add_backedge((jl_method_instance_t*)callee, edge, codeinst); - j += 2; - } - } - } - if (jl_atomic_load_relaxed(&jl_world_counter) == maxvalid) { - maxvalid = ~(size_t)0; - jl_atomic_store_relaxed(&codeinst->max_world, maxvalid); - } - if (external) { - jl_value_t *owner = codeinst->owner; - JL_GC_PROMISE_ROOTED(owner); - - // See #53586, #53109 - assert(jl_atomic_load_relaxed(&codeinst->inferred)); - - if (jl_rettype_inferred(owner, caller, minvalid, maxvalid) != jl_nothing) { - // We already got a code instance for this world age range from somewhere else - we don't need - // this one. - } - else { - jl_mi_cache_insert(caller, codeinst); - } - } - } - } - } - - htable_free(&visiting); - arraylist_free(&stack); -} - static jl_value_t *read_verify_mod_list(ios_t *s, jl_array_t *depmods) { if (!jl_main_module->build_id.lo) { diff --git a/test/precompile.jl b/test/precompile.jl index 3b193e1facd7c..78a96250600a4 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -1004,9 +1004,9 @@ precompile_test_harness("code caching") do dir MA = getfield(@__MODULE__, StaleA) Base.eval(MA, :(nbits(::UInt8) = 8)) @eval using $StaleC - invalidations = ccall(:jl_debug_method_invalidation, Any, (Cint,), 1) + invalidations = Base.StaticData.debug_method_invalidation(true) @eval using $StaleB - ccall(:jl_debug_method_invalidation, Any, (Cint,), 0) + Base.StaticData.debug_method_invalidation(false) MB = getfield(@__MODULE__, StaleB) MC = getfield(@__MODULE__, StaleC) world = Base.get_world_counter() @@ -1820,12 +1820,14 @@ precompile_test_harness("PkgCacheInspector") do load_path end if ocachefile !== nothing - sv = ccall(:jl_restore_package_image_from_file, Any, (Cstring, Any, Cint, Cstring, Cint), ocachefile, depmods, true, "PCI", false) + sv = ccall(:jl_restore_package_image_from_file, Any, (Cstring, Any, Cint, Cstring, Cint), + ocachefile, depmods, #=completeinfo=#true, "PCI", false) else - sv = ccall(:jl_restore_incremental, Any, (Cstring, Any, Cint, Cstring), cachefile, depmods, true, "PCI") + sv = ccall(:jl_restore_incremental, Any, (Cstring, Any, Cint, Cstring), + cachefile, depmods, #=completeinfo=#true, "PCI") end - modules, init_order, external_methods, new_ext_cis, new_method_roots, external_targets, edges = sv + modules, init_order, edges, new_ext_cis, external_methods, new_method_roots, cache_sizes = sv m = only(external_methods).func::Method @test m.name == :repl_cmd && m.nargs < 2 @test new_ext_cis === nothing || any(new_ext_cis) do ci From 6cf2b146c68e85ea62f233b2f6e4bbb9e7e32e93 Mon Sep 17 00:00:00 2001 From: NegaScout <42321060+NegaScout@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:13:39 +0100 Subject: [PATCH 28/65] remove unused Base.GMP.MPZ.import! and test Base.GMP.MPZ.export! (#56903) --- base/gmp.jl | 2 -- test/gmp.jl | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/base/gmp.jl b/base/gmp.jl index d5db71b0630d6..4d2b4b66ac41b 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -264,8 +264,6 @@ end limbs_write!(x::BigInt, a) = ccall((:__gmpz_limbs_write, libgmp), Ptr{Limb}, (mpz_t, Clong), x, a) limbs_finish!(x::BigInt, a) = ccall((:__gmpz_limbs_finish, libgmp), Cvoid, (mpz_t, Clong), x, a) -import!(x::BigInt, a, b, c, d, e, f) = ccall((:__gmpz_import, libgmp), Cvoid, - (mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), x, a, b, c, d, e, f) setbit!(x, a) = (ccall((:__gmpz_setbit, libgmp), Cvoid, (mpz_t, bitcnt_t), x, a); x) tstbit(a::BigInt, b) = ccall((:__gmpz_tstbit, libgmp), Cint, (mpz_t, bitcnt_t), a, b) % Bool diff --git a/test/gmp.jl b/test/gmp.jl index 9ca327e63493b..0812775672969 100644 --- a/test/gmp.jl +++ b/test/gmp.jl @@ -445,6 +445,44 @@ end @test string(big(0), base = rand(2:62), pad = 0) == "" end +@testset "Base.GMP.MPZ.export!" begin + + function Base_GMP_MPZ_import!(x::BigInt, n::AbstractVector{T}; order::Integer=-1, nails::Integer=0, endian::Integer=0) where {T<:Base.BitInteger} + ccall((:__gmpz_import, Base.GMP.MPZ.libgmp), + Cvoid, + (Base.GMP.MPZ.mpz_t, Csize_t, Cint, Csize_t, Cint, Csize_t, Ptr{Cvoid}), + x, length(n), order, sizeof(T), endian, nails, n) + return x + end + # test import + bytes_to_import_from = Vector{UInt8}([1, 0]) + int_to_import_to = BigInt() + Base_GMP_MPZ_import!(int_to_import_to, bytes_to_import_from, order=0) + @test int_to_import_to == BigInt(256) + + # test export + int_to_export_from = BigInt(256) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + @test all(bytes_to_export_to .== bytes_to_import_from) + + # test both composed import(export) is identity + int_to_export_from = BigInt(256) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + int_to_import_to = BigInt() + Base_GMP_MPZ_import!(int_to_import_to, bytes_to_export_to, order=0) + @test int_to_export_from == int_to_import_to + + # test both composed export(import) is identity + bytes_to_import_from = Vector{UInt8}([1, 0]) + int_to_import_to = BigInt() + Base_GMP_MPZ_import!(int_to_import_to, bytes_to_import_from, order=0) + bytes_to_export_to = Vector{UInt8}(undef, 2) + Base.GMP.MPZ.export!(bytes_to_export_to, int_to_export_from, order=0) + @test all(bytes_to_export_to .== bytes_to_import_from) +end + @test isqrt(big(4)) == 2 @test isqrt(big(5)) == 2 From 30177d0578d283cda3bace0c2984b5fdcd114c2f Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 15 Jan 2025 22:49:18 +0100 Subject: [PATCH 29/65] cleanup: Remove fallback post-lowering global resolution (#57051) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After recent changes, essentially all global symbol scopes are resolved by lowering, so the code in method.c that replaces symbols by globalrefs is no longer necessary. The one small exception to this were symbols resulting from closure conversion, because these get inserted after the point at which lowering converts symbols to globalrefs. However, in the current design, I think that's basically a bug (and easily addressed by inserting `globalref`s where appropriate). Removing this extra resolution step is not particularly necessary, but for the upcoming binding partition backedges, it removes an ambiguity as to which version of the lowered code to scan. It also partially resolves a very old todo about not performing post-hoc mutation of lowered code (although we still do this for ccall). --- src/jl_exported_funcs.inc | 2 +- src/julia-syntax.scm | 14 +- src/julia_internal.h | 4 +- src/method.c | 355 ++++++++++++----------------- src/toplevel.c | 4 +- stdlib/REPL/src/REPLCompletions.jl | 2 +- 6 files changed, 156 insertions(+), 225 deletions(-) diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index cb48cf6f9962c..b92380df7a49c 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -388,7 +388,7 @@ XX(jl_read_verify_header) \ XX(jl_realloc) \ XX(jl_register_newmeth_tracer) \ - XX(jl_resolve_globals_in_ir) \ + XX(jl_resolve_definition_effects_in_ir) \ XX(jl_restore_excstack) \ XX(jl_restore_incremental) \ XX(jl_restore_package_image_from_file) \ diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 007c3ce820820..7fd2dc7409c0e 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -3683,11 +3683,17 @@ f(x) = yt(x) (else (error (string "invalid assignment location \"" (deparse var) "\""))))) +(define (sig-type-expr namemap name expr) + (let ((newname (get namemap name expr))) + (if (symbol? newname) + `(globalref (thismodule) ,newname) + newname))) + (define (rename-sig-types ex namemap) (pattern-replace (pattern-set (pattern-lambda (call (core (-/ Typeof)) name) - (get namemap name __))) + (sig-type-expr namemap name __))) ex)) ;; replace leading (function) argument type with `typ` @@ -4242,7 +4248,7 @@ f(x) = yt(x) (contains (lambda (x) (eq? x 'kwftype)) sig)) (renamemap (map cons closure-param-names closure-param-syms)) (arg-defs (replace-vars - (fix-function-arg-type sig type-name iskw namemap closure-param-syms) + (fix-function-arg-type sig `(globalref (thismodule) ,type-name) iskw namemap closure-param-syms) renamemap))) (append (map (lambda (gs tvar) (make-assignment gs `(call (core TypeVar) ',tvar (core Any)))) @@ -4270,8 +4276,8 @@ f(x) = yt(x) `(call (core _typeof_captured_variable) ,ve))) capt-vars var-exprs))))) `(new ,(if (null? P) - type-name - `(call (core apply_type) ,type-name ,@P)) + `(globalref (thismodule) ,type-name) + `(call (core apply_type) (globalref (thismodule) ,type-name) ,@P)) ,@var-exprs)))) (if (pair? moved-vars) (set-car! (lam:vinfo lam) diff --git a/src/julia_internal.h b/src/julia_internal.h index a464025edf856..00d603f26c7f2 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -717,8 +717,8 @@ jl_value_t *jl_code_or_ci_for_interpreter(jl_method_instance_t *lam JL_PROPAGATE int jl_code_requires_compiler(jl_code_info_t *src, int include_force_compile); jl_code_info_t *jl_new_code_info_from_ir(jl_expr_t *ast); JL_DLLEXPORT jl_code_info_t *jl_new_code_info_uninit(void); -JL_DLLEXPORT void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, - int binding_effects); +JL_DLLEXPORT void jl_resolve_definition_effects_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, + int binding_effects); int get_next_edge(jl_array_t *list, int i, jl_value_t** invokesig, jl_code_instance_t **caller) JL_NOTSAFEPOINT; int set_next_edge(jl_array_t *list, int i, jl_value_t *invokesig, jl_code_instance_t *caller); diff --git a/src/method.c b/src/method.c index 0d173d960c90f..0a58f0d5c482c 100644 --- a/src/method.c +++ b/src/method.c @@ -41,235 +41,160 @@ static void check_c_types(const char *where, jl_value_t *rt, jl_value_t *at) // Resolve references to non-locally-defined variables to become references to global // variables in `module` (unless the rvalue is one of the type parameters in `sparam_vals`). -static jl_value_t *resolve_globals(jl_value_t *expr, jl_module_t *module, jl_svec_t *sparam_vals, +static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *module, jl_svec_t *sparam_vals, int binding_effects, int eager_resolve) { if (jl_is_symbol(expr)) { - if (module == NULL) - return expr; - return jl_module_globalref(module, (jl_sym_t*)expr); + jl_error("Found raw symbol in code returned from lowering. Expected all symbols to have been resolved to GlobalRef or slots."); } - else if (jl_is_returnnode(expr)) { - jl_value_t *retval = jl_returnnode_value(expr); - if (retval) { - jl_value_t *val = resolve_globals(retval, module, sparam_vals, binding_effects, eager_resolve); - if (val != retval) { - JL_GC_PUSH1(&val); - expr = jl_new_struct(jl_returnnode_type, val); - JL_GC_POP(); - } - } + if (!jl_is_expr(expr)) { return expr; } - else if (jl_is_enternode(expr)) { - jl_value_t *scope = jl_enternode_scope(expr); - if (scope) { - jl_value_t *val = resolve_globals(scope, module, sparam_vals, binding_effects, eager_resolve); - if (val != scope) { - intptr_t catch_dest = jl_enternode_catch_dest(expr); - JL_GC_PUSH1(&val); - expr = jl_new_struct_uninit(jl_enternode_type); - jl_enternode_catch_dest(expr) = catch_dest; - jl_enternode_scope(expr) = val; - JL_GC_POP(); - } - } + + jl_expr_t *e = (jl_expr_t*)expr; + if (e->head == jl_global_sym && binding_effects) { + // execute the side-effects of "global x" decl immediately: + // creates uninitialized mutable binding in module for each global + jl_eval_global_expr(module, e, 1); + return jl_nothing; + } + // These exprs are not fully linearized + if (e->head == jl_assign_sym) { + jl_exprargset(e, 1, resolve_definition_effects(jl_exprarg(e, 1), module, sparam_vals, binding_effects, eager_resolve)); + return expr; + } else if (e->head == jl_new_opaque_closure_sym) { + jl_exprargset(e, 4, resolve_definition_effects(jl_exprarg(e, 4), module, sparam_vals, binding_effects, eager_resolve)); return expr; } - else if (jl_is_gotoifnot(expr)) { - jl_value_t *cond = resolve_globals(jl_gotoifnot_cond(expr), module, sparam_vals, binding_effects, eager_resolve); - if (cond != jl_gotoifnot_cond(expr)) { - intptr_t label = jl_gotoifnot_label(expr); - JL_GC_PUSH1(&cond); - expr = jl_new_struct_uninit(jl_gotoifnot_type); - set_nth_field(jl_gotoifnot_type, expr, 0, cond, 0); - jl_gotoifnot_label(expr) = label; - JL_GC_POP(); + size_t nargs = jl_array_nrows(e->args); + if (e->head == jl_opaque_closure_method_sym) { + if (nargs != 5) { + jl_error("opaque_closure_method: invalid syntax"); } - return expr; + jl_value_t *name = jl_exprarg(e, 0); + jl_value_t *oc_nargs = jl_exprarg(e, 1); + int isva = jl_exprarg(e, 2) == jl_true; + jl_value_t *functionloc = jl_exprarg(e, 3); + jl_value_t *ci = jl_exprarg(e, 4); + if (!jl_is_code_info(ci)) { + jl_error("opaque_closure_method: lambda should be a CodeInfo"); + } else if (!jl_is_long(oc_nargs)) { + jl_type_error("opaque_closure_method", (jl_value_t*)jl_long_type, oc_nargs); + } + jl_method_t *m = jl_make_opaque_closure_method(module, name, + jl_unbox_long(oc_nargs), functionloc, (jl_code_info_t*)ci, isva, /*isinferred*/0); + return (jl_value_t*)m; } - else if (jl_is_expr(expr)) { - jl_expr_t *e = (jl_expr_t*)expr; - if (e->head == jl_global_sym && binding_effects) { - // execute the side-effects of "global x" decl immediately: - // creates uninitialized mutable binding in module for each global - jl_eval_global_expr(module, e, 1); - expr = jl_nothing; + if (e->head == jl_cfunction_sym) { + JL_NARGS(cfunction method definition, 5, 5); // (type, func, rt, at, cc) + jl_task_t *ct = jl_current_task; + jl_value_t *typ = jl_exprarg(e, 0); + if (!jl_is_type(typ)) + jl_error("first parameter to :cfunction must be a type"); + if (typ == (jl_value_t*)jl_voidpointer_type) { + jl_value_t *a = jl_exprarg(e, 1); + JL_TYPECHK(cfunction method definition, quotenode, a); + *(jl_value_t**)a = jl_toplevel_eval(module, *(jl_value_t**)a); + jl_gc_wb(a, *(jl_value_t**)a); } - if (jl_is_toplevel_only_expr(expr) || e->head == jl_const_sym || - e->head == jl_coverageeffect_sym || e->head == jl_copyast_sym || - e->head == jl_quote_sym || e->head == jl_inert_sym || - e->head == jl_meta_sym || e->head == jl_inbounds_sym || - e->head == jl_boundscheck_sym || e->head == jl_loopinfo_sym || - e->head == jl_aliasscope_sym || e->head == jl_popaliasscope_sym || - e->head == jl_inline_sym || e->head == jl_noinline_sym) { - // ignore these + jl_value_t *rt = jl_exprarg(e, 2); + jl_value_t *at = jl_exprarg(e, 3); + if (!jl_is_type(rt)) { + JL_TRY { + rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); + } + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate cfunction return type (it might depend on a local variable)"); + else + jl_rethrow(); + } + jl_exprargset(e, 2, rt); } - else { - size_t i = 0, nargs = jl_array_nrows(e->args); - if (e->head == jl_opaque_closure_method_sym) { - if (nargs != 5) { - jl_error("opaque_closure_method: invalid syntax"); - } - jl_value_t *name = jl_exprarg(e, 0); - jl_value_t *oc_nargs = jl_exprarg(e, 1); - int isva = jl_exprarg(e, 2) == jl_true; - jl_value_t *functionloc = jl_exprarg(e, 3); - jl_value_t *ci = jl_exprarg(e, 4); - if (!jl_is_code_info(ci)) { - jl_error("opaque_closure_method: lambda should be a CodeInfo"); - } else if (!jl_is_long(oc_nargs)) { - jl_type_error("opaque_closure_method", (jl_value_t*)jl_long_type, oc_nargs); - } - jl_method_t *m = jl_make_opaque_closure_method(module, name, - jl_unbox_long(oc_nargs), functionloc, (jl_code_info_t*)ci, isva, /*isinferred*/0); - return (jl_value_t*)m; + if (!jl_is_svec(at)) { + JL_TRY { + at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); } - if (e->head == jl_cfunction_sym) { - JL_NARGS(cfunction method definition, 5, 5); // (type, func, rt, at, cc) - jl_task_t *ct = jl_current_task; - jl_value_t *typ = jl_exprarg(e, 0); - if (!jl_is_type(typ)) - jl_error("first parameter to :cfunction must be a type"); - if (typ == (jl_value_t*)jl_voidpointer_type) { - jl_value_t *a = jl_exprarg(e, 1); - JL_TYPECHK(cfunction method definition, quotenode, a); - *(jl_value_t**)a = jl_toplevel_eval(module, *(jl_value_t**)a); - jl_gc_wb(a, *(jl_value_t**)a); - } - jl_value_t *rt = jl_exprarg(e, 2); - jl_value_t *at = jl_exprarg(e, 3); - if (!jl_is_type(rt)) { - JL_TRY { - rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate cfunction return type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 2, rt); - } - if (!jl_is_svec(at)) { - JL_TRY { - at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate cfunction argument type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 3, at); - } - check_c_types("cfunction method definition", rt, at); - JL_TYPECHK(cfunction method definition, quotenode, jl_exprarg(e, 4)); - JL_TYPECHK(cfunction method definition, symbol, *(jl_value_t**)jl_exprarg(e, 4)); - return expr; + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate cfunction argument type (it might depend on a local variable)"); + else + jl_rethrow(); } - if (e->head == jl_foreigncall_sym) { - JL_NARGSV(ccall method definition, 5); // (fptr, rt, at, nreq, (cc, effects)) - jl_task_t *ct = jl_current_task; - jl_value_t *rt = jl_exprarg(e, 1); - jl_value_t *at = jl_exprarg(e, 2); - if (!jl_is_type(rt)) { - JL_TRY { - rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate ccall return type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 1, rt); - } - if (!jl_is_svec(at)) { - JL_TRY { - at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); - } - JL_CATCH { - if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) - jl_error("could not evaluate ccall argument type (it might depend on a local variable)"); - else - jl_rethrow(); - } - jl_exprargset(e, 2, at); - } - check_c_types("ccall method definition", rt, at); - JL_TYPECHK(ccall method definition, long, jl_exprarg(e, 3)); - JL_TYPECHK(ccall method definition, quotenode, jl_exprarg(e, 4)); - jl_value_t *cc = jl_quotenode_value(jl_exprarg(e, 4)); - if (!jl_is_symbol(cc)) { - JL_TYPECHK(ccall method definition, tuple, cc); - if (jl_nfields(cc) != 2) { - jl_error("In ccall calling convention, expected two argument tuple or symbol."); - } - JL_TYPECHK(ccall method definition, symbol, jl_get_nth_field(cc, 0)); - JL_TYPECHK(ccall method definition, uint16, jl_get_nth_field(cc, 1)); - } - jl_exprargset(e, 0, resolve_globals(jl_exprarg(e, 0), module, sparam_vals, binding_effects, 1)); - i++; + jl_exprargset(e, 3, at); + } + check_c_types("cfunction method definition", rt, at); + JL_TYPECHK(cfunction method definition, quotenode, jl_exprarg(e, 4)); + JL_TYPECHK(cfunction method definition, symbol, *(jl_value_t**)jl_exprarg(e, 4)); + return expr; + } + if (e->head == jl_foreigncall_sym) { + JL_NARGSV(ccall method definition, 5); // (fptr, rt, at, nreq, (cc, effects)) + jl_task_t *ct = jl_current_task; + jl_value_t *rt = jl_exprarg(e, 1); + jl_value_t *at = jl_exprarg(e, 2); + if (!jl_is_type(rt)) { + JL_TRY { + rt = jl_interpret_toplevel_expr_in(module, rt, NULL, sparam_vals); + } + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate ccall return type (it might depend on a local variable)"); + else + jl_rethrow(); } - if (e->head == jl_method_sym || e->head == jl_module_sym || e->head == jl_throw_undef_if_not_sym) { - i++; + jl_exprargset(e, 1, rt); + } + if (!jl_is_svec(at)) { + JL_TRY { + at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); } - for (; i < nargs; i++) { - // TODO: this should be making a copy, not mutating the source - jl_exprargset(e, i, resolve_globals(jl_exprarg(e, i), module, sparam_vals, binding_effects, eager_resolve)); + JL_CATCH { + if (jl_typetagis(jl_current_exception(ct), jl_errorexception_type)) + jl_error("could not evaluate ccall argument type (it might depend on a local variable)"); + else + jl_rethrow(); } - if (e->head == jl_call_sym && jl_expr_nargs(e) == 3 && - jl_is_globalref(jl_exprarg(e, 0)) && - jl_is_globalref(jl_exprarg(e, 1)) && - jl_is_quotenode(jl_exprarg(e, 2))) { - // replace module_expr.sym with GlobalRef(module, sym) - // for expressions pattern-matching to `getproperty(module_expr, :sym)` in a top-module - // (this is expected to help inference performance) - // TODO: this was broken by linear-IR - jl_value_t *s = jl_fieldref(jl_exprarg(e, 2), 0); - jl_value_t *me = jl_exprarg(e, 1); - jl_value_t *fe = jl_exprarg(e, 0); - jl_module_t *fe_mod = jl_globalref_mod(fe); - jl_sym_t *fe_sym = jl_globalref_name(fe); - jl_module_t *me_mod = jl_globalref_mod(me); - jl_sym_t *me_sym = jl_globalref_name(me); - if (fe_mod->istopmod && !strcmp(jl_symbol_name(fe_sym), "getproperty") && jl_is_symbol(s)) { - if (eager_resolve || jl_binding_resolved_p(me_mod, me_sym)) { - jl_binding_t *b = jl_get_binding(me_mod, me_sym); - jl_value_t *v = jl_get_binding_value_if_const(b); - if (v && jl_is_module(v)) - return jl_module_globalref((jl_module_t*)v, (jl_sym_t*)s); - } - } + jl_exprargset(e, 2, at); + } + check_c_types("ccall method definition", rt, at); + JL_TYPECHK(ccall method definition, long, jl_exprarg(e, 3)); + JL_TYPECHK(ccall method definition, quotenode, jl_exprarg(e, 4)); + jl_value_t *cc = jl_quotenode_value(jl_exprarg(e, 4)); + if (!jl_is_symbol(cc)) { + JL_TYPECHK(ccall method definition, tuple, cc); + if (jl_nfields(cc) != 2) { + jl_error("In ccall calling convention, expected two argument tuple or symbol."); } - if (e->head == jl_call_sym && nargs > 0 && - jl_is_globalref(jl_exprarg(e, 0))) { - // TODO: this hack should be deleted once llvmcall is fixed - jl_value_t *fe = jl_exprarg(e, 0); - jl_module_t *fe_mod = jl_globalref_mod(fe); - jl_sym_t *fe_sym = jl_globalref_name(fe); - if (jl_binding_resolved_p(fe_mod, fe_sym)) { - // look at some known called functions - jl_binding_t *b = jl_get_binding(fe_mod, fe_sym); - if (jl_get_binding_value_if_const(b) == jl_builtin_tuple) { - size_t j; - for (j = 1; j < nargs; j++) { - if (!jl_is_quotenode(jl_exprarg(e, j))) - break; - } - if (j == nargs) { - jl_value_t *val = NULL; - JL_TRY { - val = jl_interpret_toplevel_expr_in(module, (jl_value_t*)e, NULL, sparam_vals); - } - JL_CATCH { - val = NULL; // To make the analyzer happy see #define JL_TRY - } - if (val) - return val; - } + JL_TYPECHK(ccall method definition, symbol, jl_get_nth_field(cc, 0)); + JL_TYPECHK(ccall method definition, uint16, jl_get_nth_field(cc, 1)); + } + } + if (e->head == jl_call_sym && nargs > 0 && + jl_is_globalref(jl_exprarg(e, 0))) { + // TODO: this hack should be deleted once llvmcall is fixed + jl_value_t *fe = jl_exprarg(e, 0); + jl_module_t *fe_mod = jl_globalref_mod(fe); + jl_sym_t *fe_sym = jl_globalref_name(fe); + if (jl_binding_resolved_p(fe_mod, fe_sym)) { + // look at some known called functions + jl_binding_t *b = jl_get_binding(fe_mod, fe_sym); + if (jl_get_binding_value_if_const(b) == jl_builtin_tuple) { + size_t j; + for (j = 1; j < nargs; j++) { + if (!jl_is_quotenode(jl_exprarg(e, j))) + break; + } + if (j == nargs) { + jl_value_t *val = NULL; + JL_TRY { + val = jl_interpret_toplevel_expr_in(module, (jl_value_t*)e, NULL, sparam_vals); + } + JL_CATCH { + val = NULL; // To make the analyzer happy see #define JL_TRY } + if (val) + return val; } } } @@ -277,13 +202,13 @@ static jl_value_t *resolve_globals(jl_value_t *expr, jl_module_t *module, jl_sve return expr; } -JL_DLLEXPORT void jl_resolve_globals_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, +JL_DLLEXPORT void jl_resolve_definition_effects_in_ir(jl_array_t *stmts, jl_module_t *m, jl_svec_t *sparam_vals, int binding_effects) { size_t i, l = jl_array_nrows(stmts); for (i = 0; i < l; i++) { jl_value_t *stmt = jl_array_ptr_ref(stmts, i); - jl_array_ptr_set(stmts, i, resolve_globals(stmt, m, sparam_vals, binding_effects, 0)); + jl_array_ptr_set(stmts, i, resolve_definition_effects(stmt, m, sparam_vals, binding_effects, 0)); } } @@ -697,7 +622,7 @@ JL_DLLEXPORT jl_code_info_t *jl_expand_and_resolve(jl_value_t *ex, jl_module_t * JL_GC_PUSH1(&func); if (jl_is_code_info(func)) { jl_array_t *stmts = (jl_array_t*)func->code; - jl_resolve_globals_in_ir(stmts, module, sparam_vals, 1); + jl_resolve_definition_effects_in_ir(stmts, module, sparam_vals, 1); } JL_GC_POP(); return func; @@ -777,7 +702,7 @@ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *mi, size_t if (jl_is_code_info(ex)) { func = (jl_code_info_t*)ex; jl_array_t *stmts = (jl_array_t*)func->code; - jl_resolve_globals_in_ir(stmts, def->module, mi->sparam_vals, 1); + jl_resolve_definition_effects_in_ir(stmts, def->module, mi->sparam_vals, 1); } else { // Lower the user's expression and resolve references to the type parameters @@ -1000,7 +925,7 @@ JL_DLLEXPORT void jl_method_set_source(jl_method_t *m, jl_code_info_t *src) } } else { - st = resolve_globals(st, m->module, sparam_vars, 1, 0); + st = resolve_definition_effects(st, m->module, sparam_vars, 1, 0); } jl_array_ptr_set(copy, i, st); } diff --git a/src/toplevel.c b/src/toplevel.c index 95a053f6135f6..fb217ec7cb52e 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -1048,7 +1048,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val jl_get_module_compile(m) != JL_OPTIONS_COMPILE_MIN)) { // use codegen mfunc = jl_method_instance_for_thunk(thk, m); - jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0); + jl_resolve_definition_effects_in_ir((jl_array_t*)thk->code, m, NULL, 0); // Don't infer blocks containing e.g. method definitions, since it's probably not worthwhile. size_t world = jl_atomic_load_acquire(&jl_world_counter); ct->world_age = world; @@ -1062,7 +1062,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val // use interpreter assert(thk); if (has_opaque) { - jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0); + jl_resolve_definition_effects_in_ir((jl_array_t*)thk->code, m, NULL, 0); } size_t world = jl_atomic_load_acquire(&jl_world_counter); ct->world_age = world; diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 723a008b10f28..e8aa1188ec213 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -716,7 +716,7 @@ function CC.const_prop_argument_heuristic(interp::REPLInterpreter, arginfo::CC.A end function resolve_toplevel_symbols!(src::Core.CodeInfo, mod::Module) - @ccall jl_resolve_globals_in_ir( + @ccall jl_resolve_definition_effects_in_ir( #=jl_array_t *stmts=# src.code::Any, #=jl_module_t *m=# mod::Any, #=jl_svec_t *sparam_vals=# Core.svec()::Any, From 2dc3337626cd1fa09d358e3f4b769720c0a0d527 Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Wed, 15 Jan 2025 21:22:35 -0500 Subject: [PATCH 30/65] base/strings: Add documentation to unicode conversion table (#56929) Co-authored-by: Neven Sajko <4944410+nsajko@users.noreply.github.com> --- base/strings/unicode.jl | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/base/strings/unicode.jl b/base/strings/unicode.jl index fcb4a371e9898..f2938ba6021f2 100644 --- a/base/strings/unicode.jl +++ b/base/strings/unicode.jl @@ -174,14 +174,21 @@ function utf8proc_map(str::Union{String,SubString{String}}, options::Integer, ch return String(resize!(buffer, nbytes)) end -# from julia_charmap.h, used by julia_chartransform in the Unicode stdlib +""" +`Dict` of `original codepoint => replacement codepoint` normalizations +to perform on Julia identifiers, to canonicalize characters that +are both easily confused and easily inputted by accident. + +!!! warning + When this table is updated, also update the corresponding table in `src/flisp/julia_charmap.h`. +""" const _julia_charmap = Dict{UInt32,UInt32}( - 0x025B => 0x03B5, - 0x00B5 => 0x03BC, - 0x00B7 => 0x22C5, - 0x0387 => 0x22C5, - 0x2212 => 0x002D, - 0x210F => 0x0127, + 0x025B => 0x03B5, # latin small letter open e -> greek small letter epsilon + 0x00B5 => 0x03BC, # micro sign -> greek small letter mu + 0x00B7 => 0x22C5, # middot char -> dot operator (#25098) + 0x0387 => 0x22C5, # Greek interpunct -> dot operator (#25098) + 0x2212 => 0x002D, # minus -> hyphen-minus (#26193) + 0x210F => 0x0127, # hbar -> small letter h with stroke (#48870) ) utf8proc_map(s::AbstractString, flags::Integer, chartransform::F = identity) where F = utf8proc_map(String(s), flags, chartransform) From b0ae24ffada04c16c1ab278027824e210693df08 Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Thu, 16 Jan 2025 03:23:17 +0100 Subject: [PATCH 31/65] test: add a bunch of `@inferred` to the iterators test set (#56885) The `@inferred` macro is applied to the following functions: * `Base.IteratorSize` * `Base.IteratorEltype` * `eltype` * `axes` * `size` * `length` * `ndims` * `isempty` xref #56802 xref #56838 --- test/iterators.jl | 430 +++++++++++++++++++++++----------------------- 1 file changed, 215 insertions(+), 215 deletions(-) diff --git a/test/iterators.jl b/test/iterators.jl index 1feccf5fb1d3e..06f08cff4f6ad 100644 --- a/test/iterators.jl +++ b/test/iterators.jl @@ -5,7 +5,7 @@ using Random using Base: IdentityUnitRange using Dates: Date, Day -@test Base.IteratorSize(Any) isa Base.SizeUnknown +@test (@inferred Base.IteratorSize(Any)) isa Base.SizeUnknown # zip and filter iterators # issue #4718 @@ -16,27 +16,27 @@ using Dates: Date, Day @test_throws ArgumentError Iterators.reverse(zip("abc", Iterators.cycle("ab"))) let z = zip(1:2) - @test size(z) == (2,) + @test (@inferred size(z)) == (2,) @test collect(z) == [(1,), (2,)] # Issue #13979 - @test eltype(z) == Tuple{Int} + @test (@inferred eltype(z)) == Tuple{Int} end for z in (zip(1:2, 3:4), zip(1:2, 3:5)) @test collect(z) == [(1,3), (2,4)] - @test eltype(z) == Tuple{Int,Int} - @test size(z) == (2,) - @test axes(z) == (Base.OneTo(2),) - @test length(z) == 2 + @test (@inferred eltype(z)) == Tuple{Int,Int} + @test (@inferred size(z)) == (2,) + @test (@inferred axes(z)) == (Base.OneTo(2),) + @test (@inferred length(z)) == 2 end let z = zip(1:2, Iterators.countfrom(3)) @test collect(z) == [(1,3), (2,4)] - @test eltype(z) == Tuple{Int,Int} + @test (@inferred eltype(z)) == Tuple{Int,Int} @test_throws MethodError size(z) # by convention, the zip of a finite and # an infinite iterator has only `length` @test_throws MethodError axes(z) - @test length(z) == 2 + @test (@inferred length(z)) == 2 end let z = zip([i*j for i in 1:3, j in -1:2:1], 1:6) @@ -46,29 +46,29 @@ let z = zip([i*j for i in 1:3, j in -1:2:1], 1:6) (1, 4) (2, 5) (3, 6) ] - @test eltype(z) == Tuple{Int,Int} + @test (@inferred eltype(z)) == Tuple{Int,Int} @test_throws DimensionMismatch size(z) @test_throws DimensionMismatch axes(z) - @test length(z) == 6 + @test (@inferred length(z)) == 6 end let z = zip([i*j for i in 1:3, j in -1:2:1], [i*j for i in 1:3, j in -1:2:1]) @test collect(z) == [(-1, -1) (1, 1) (-2, -2) (2, 2) (-3, -3) (3, 3)] - @test eltype(z) == Tuple{Int,Int} - @test size(z) == (3, 2) - @test axes(z) == (Base.OneTo(3), Base.OneTo(2)) - @test length(z) == 6 + @test (@inferred eltype(z)) == Tuple{Int,Int} + @test (@inferred size(z)) == (3, 2) + @test (@inferred axes(z)) == (Base.OneTo(3), Base.OneTo(2)) + @test (@inferred length(z)) == 6 end let z = zip(1:2, 3:4, 5:6) - @test size(z) == (2,) + @test (@inferred size(z)) == (2,) @test collect(z) == [(1,3,5), (2,4,6)] - @test eltype(z) == Tuple{Int,Int,Int} + @test (@inferred eltype(z)) == Tuple{Int,Int,Int} end -@test eltype(Iterators.filter(isodd, 1:5)) == Int +@test (@inferred eltype(Iterators.filter(isodd, 1:5))) == Int # typed `collect` @test collect(Float64, Iterators.filter(isodd, [1,2,3,4]))[1] === 1.0 @@ -102,10 +102,10 @@ let zeb = IOBuffer("1\n2\n3\n4\n5\n"), @test res == [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')] end -@test length(zip(cycle(1:3), 1:7)) == 7 -@test length(zip(cycle(1:3), 1:7, cycle(1:3))) == 7 -@test length(zip(1:3,product(1:7,cycle(1:3)))) == 3 -@test length(zip(1:3,product(1:7,cycle(1:3)),8)) == 1 +@test (@inferred length(zip(cycle(1:3), 1:7))) == 7 +@test (@inferred length(zip(cycle(1:3), 1:7, cycle(1:3)))) == 7 +@test (@inferred length(zip(1:3,product(1:7,cycle(1:3))))) == 3 +@test (@inferred length(zip(1:3,product(1:7,cycle(1:3)),8))) == 1 @test_throws ArgumentError length(zip()) # length of zip of empty tuple # map @@ -154,7 +154,7 @@ end # take # ---- let t = take(0:2:8, 10), i = 0 - @test length(collect(t)) == 5 == length(t) + @test length(collect(t)) == 5 == @inferred length(t) for j = t @test j == i*2 @@ -171,11 +171,11 @@ let i = 0 @test i == 10 end -@test isempty(take(0:2:8, 0)) +@test @inferred isempty(take(0:2:8, 0)) @test_throws ArgumentError take(0:2:8, -1) -@test length(take(1:3,typemax(Int))) == 3 -@test length(take(countfrom(1),3)) == 3 -@test length(take(1:6,3)) == 3 +@test (@inferred length(take(1:3,typemax(Int)))) == 3 +@test (@inferred length(take(countfrom(1),3))) == 3 +@test (@inferred length(take(1:6,3))) == 3 # drop # ---- @@ -187,15 +187,15 @@ let i = 0 @test i == 4 end -@test isempty(drop(0:2:10, 100)) -@test isempty(collect(drop(0:2:10, 100))) +@test @inferred isempty(drop(0:2:10, 100)) +@test @inferred isempty(collect(drop(0:2:10, 100))) @test_throws ArgumentError drop(0:2:8, -1) -@test length(drop(1:3,typemax(Int))) == 0 -@test length(drop(UInt(1):2, 3)) == 0 -@test length(drop(StepRangeLen(1, 1, UInt(2)), 3)) == 0 -@test Base.IteratorSize(drop(countfrom(1),3)) == Base.IsInfinite() +@test (@inferred length(drop(1:3,typemax(Int)))) == 0 +@test (@inferred length(drop(UInt(1):2, 3))) == 0 +@test (@inferred length(drop(StepRangeLen(1, 1, UInt(2)), 3))) == 0 +@test (@inferred Base.IteratorSize(drop(countfrom(1),3))) == Base.IsInfinite() @test_throws MethodError length(drop(countfrom(1), 3)) -@test Base.IteratorSize(Iterators.drop(Iterators.filter(i -> i>0, 1:10), 2)) == Base.SizeUnknown() +@test (@inferred Base.IteratorSize(Iterators.drop(Iterators.filter(i -> i>0, 1:10), 2))) == Base.SizeUnknown() let x = Iterators.drop(Iterators.Stateful("abc"), 2) @test !Base.isdone(x, nothing) @@ -212,7 +212,7 @@ for xs in Any["abc", [1, 2, 3]] @test drop(drop(xs, 1), 1) === drop(xs, 2) @test take(drop(xs, 1), 1) === drop(take(xs, 2), 1) @test take(drop(xs, 3), 0) === drop(take(xs, 2), 3) - @test isempty(drop(drop(xs, 2), 2)) + @test @inferred isempty(drop(drop(xs, 2), 2)) @test drop(take(drop(xs, 1), 2), 1) === take(drop(xs, 2), 1) @test take(drop(take(xs, 3), 1), 1) === take(drop(xs, 1), 1) end @@ -226,7 +226,7 @@ end @test collect(takewhile(Returns(true),5:10)) == 5:10 @test collect(takewhile(isodd,[1,1,2,3])) == [1,1] @test collect(takewhile(<(2), takewhile(<(3), [1,1,2,3]))) == [1,1] - @test Base.IteratorEltype(typeof(takewhile(<(4),Iterators.map(identity, 1:10)))) isa Base.EltypeUnknown + @test (@inferred Base.IteratorEltype(typeof(takewhile(<(4),Iterators.map(identity, 1:10))))) isa Base.EltypeUnknown end # dropwhile @@ -234,12 +234,12 @@ end @testset begin @test collect(dropwhile(<(4), 1:10)) == 4:10 @test collect(dropwhile(<(4), 1:10)) isa Vector{Int} - @test isempty(dropwhile(<(4), [])) + @test @inferred isempty(dropwhile(<(4), [])) @test collect(dropwhile(Returns(false),1:3)) == 1:3 - @test isempty(dropwhile(Returns(true), 1:3)) + @test @inferred isempty(dropwhile(Returns(true), 1:3)) @test collect(dropwhile(isodd,[1,1,2,3])) == [2,3] @test collect(dropwhile(iseven,dropwhile(isodd,[1,1,2,3]))) == [3] - @test Base.IteratorEltype(typeof(dropwhile(<(4),Iterators.map(identity, 1:10)))) isa Base.EltypeUnknown + @test (@inferred Base.IteratorEltype(typeof(dropwhile(<(4),Iterators.map(identity, 1:10))))) isa Base.EltypeUnknown end # cycle @@ -259,15 +259,15 @@ end @test collect(cycle(Iterators.filter(iseven, 1:4), 2)) == [2, 4, 2, 4] @test collect(take(cycle(countfrom(11), 3), 4)) == 11:14 - @test isempty(cycle(1:0)) == isempty(cycle(1:0, 3)) == true - @test isempty(cycle(1:5, 0)) - @test isempty(cycle(Iterators.filter(iseven, 1:4), 0)) + @test (@inferred isempty(cycle(1:0))) == (@inferred isempty(cycle(1:0, 3))) == true + @test @inferred isempty(cycle(1:5, 0)) + @test @inferred isempty(cycle(Iterators.filter(iseven, 1:4), 0)) - @test eltype(cycle(0:3, 2)) === Int - @test Base.IteratorEltype(cycle(0:3, 2)) == Base.HasEltype() + @test (@inferred eltype(cycle(0:3, 2))) === Int + @test (@inferred Base.IteratorEltype(cycle(0:3, 2))) == Base.HasEltype() Base.haslength(cycle(0:3, 2)) == false # but not sure we should test these - Base.IteratorSize(cycle(0:3, 2)) == Base.SizeUnknown() + (@inferred Base.IteratorSize(cycle(0:3, 2))) == Base.SizeUnknown() end # repeated @@ -286,13 +286,13 @@ let i = 0 i <= 10 || break end end -@test eltype(repeated(0)) == Int -@test eltype(repeated(0, 5)) == Int -@test Base.IteratorSize(repeated(0)) == Base.IsInfinite() -@test Base.IteratorSize(repeated(0, 5)) == Base.HasLength() -@test Base.IteratorEltype(repeated(0)) == Base.HasEltype() -@test Base.IteratorEltype(repeated(0, 5)) == Base.HasEltype() -@test Base.IteratorSize(zip(repeated(0), repeated(0))) == Base.IsInfinite() +@test (@inferred eltype(repeated(0))) == Int +@test (@inferred eltype(repeated(0, 5))) == Int +@test (@inferred Base.IteratorSize(repeated(0))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(repeated(0, 5))) == Base.HasLength() +@test (@inferred Base.IteratorEltype(repeated(0))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(repeated(0, 5))) == Base.HasEltype() +@test (@inferred Base.IteratorSize(zip(repeated(0), repeated(0)))) == Base.IsInfinite() # product # ------- @@ -304,8 +304,8 @@ for itr in [product(1:0), product(1:0, 1:1, 1:2), product(1:1, 1:0, 1:2), product(1:1, 1:2 ,1:0)] - @test isempty(itr) - @test isempty(collect(itr)) + @test @inferred isempty(itr) + @test @inferred isempty(collect(itr)) end # collect a product - first iterators runs faster @@ -325,10 +325,10 @@ end let (a, b) = (1:3, [4 6; 5 7]) p = product(a, b) - @test size(p) == (3, 2, 2) - @test length(p) == 12 - @test ndims(p) == 3 - @test eltype(p) == NTuple{2, Int} + @test (@inferred size(p)) == (3, 2, 2) + @test (@inferred length(p)) == 12 + @test (@inferred ndims(p)) == 3 + @test (@inferred eltype(p)) == NTuple{2, Int} cp = collect(p) for i = 1:3 @test cp[i, :, :] == [(i, 4) (i, 6); @@ -356,28 +356,28 @@ let a = 1:2, c = Int32(1):Int32(0) # length - @test length(product()) == 1 - @test length(product(a)) == 2 - @test length(product(a, b)) == 20 - @test length(product(a, b, c)) == 0 + @test (@inferred length(product())) == 1 + @test (@inferred length(product(a))) == 2 + @test (@inferred length(product(a, b))) == 20 + @test (@inferred length(product(a, b, c))) == 0 # size - @test size(product()) == tuple() - @test size(product(a)) == (2,) - @test size(product(a, b)) == (2, 10) - @test size(product(a, b, c)) == (2, 10, 0) + @test (@inferred size(product())) == tuple() + @test (@inferred size(product(a))) == (2,) + @test (@inferred size(product(a, b))) == (2, 10) + @test (@inferred size(product(a, b, c))) == (2, 10, 0) # eltype - @test eltype(product()) == Tuple{} - @test eltype(product(a)) == Tuple{Int} - @test eltype(product(a, b)) == Tuple{Int, Float64} - @test eltype(product(a, b, c)) == Tuple{Int, Float64, Int32} + @test (@inferred eltype(product())) == Tuple{} + @test (@inferred eltype(product(a))) == Tuple{Int} + @test (@inferred eltype(product(a, b))) == Tuple{Int, Float64} + @test (@inferred eltype(product(a, b, c))) == Tuple{Int, Float64, Int32} # ndims - @test ndims(product()) == 0 - @test ndims(product(a)) == 1 - @test ndims(product(a, b)) == 2 - @test ndims(product(a, b, c)) == 3 + @test (@inferred ndims(product())) == 0 + @test (@inferred ndims(product(a))) == 1 + @test (@inferred ndims(product(a, b))) == 2 + @test (@inferred ndims(product(a, b, c))) == 3 end # with multidimensional inputs @@ -397,7 +397,7 @@ let a = randn(4, 4), (4, 4, 3, 3, 3, 2, 2, 2, 2)] for (method, fun) in zip([size, ndims, length], [x->x, length, prod]) for i in 1:length(args) - @test method(product(args[i]...)) == method(collect(product(args[i]...))) == fun(sizes[i]) + @test (@inferred method(product(args[i]...))) == method(collect(product(args[i]...))) == fun(sizes[i]) end end end @@ -413,7 +413,7 @@ let iters = (1:2, for method in [size, length, ndims, eltype] for i = 1:length(iters) args = (iters[i],) - @test method(product(args...)) == method(collect(product(args...))) + @test (@inferred method(product(args...))) == method(collect(product(args...))) for j = 1:length(iters) args = iters[i], iters[j] @test method(product(args...)) == method(collect(product(args...))) @@ -455,48 +455,48 @@ end # IteratorSize trait business let f1 = Iterators.filter(i->i>0, 1:10) - @test Base.IteratorSize(product(f1)) == Base.SizeUnknown() - @test Base.IteratorSize(product(1:2, f1)) == Base.SizeUnknown() - @test Base.IteratorSize(product(f1, 1:2)) == Base.SizeUnknown() - @test Base.IteratorSize(product(f1, f1)) == Base.SizeUnknown() - @test Base.IteratorSize(product(f1, countfrom(1))) == Base.IsInfinite() - @test Base.IteratorSize(product(countfrom(1), f1)) == Base.IsInfinite() -end -@test Base.IteratorSize(product(1:2, countfrom(1))) == Base.IsInfinite() -@test Base.IteratorSize(product(countfrom(2), countfrom(1))) == Base.IsInfinite() -@test Base.IteratorSize(product(countfrom(1), 1:2)) == Base.IsInfinite() -@test Base.IteratorSize(product(1:2)) == Base.HasShape{1}() -@test Base.IteratorSize(product(1:2, 1:2)) == Base.HasShape{2}() -@test Base.IteratorSize(product(take(1:2, 1), take(1:2, 1))) == Base.HasShape{2}() -@test Base.IteratorSize(product(take(1:2, 2))) == Base.HasShape{1}() -@test Base.IteratorSize(product([1 2; 3 4])) == Base.HasShape{2}() -@test Base.IteratorSize(product((1,2,3,4), (5, 6, 7, 8))) == Base.HasShape{2}() # product of ::HasLength and ::HasLength -@test Base.IteratorSize(product(1:2, 3:5, 5:6)) == Base.HasShape{3}() # product of 3 iterators -@test Base.IteratorSize(product([1 2; 3 4], 1:4)) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasShape{1} -@test Base.IteratorSize(product([1 2; 3 4], (1,2))) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasLength + @test (@inferred Base.IteratorSize(product(f1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(1:2, f1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(f1, 1:2))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(f1, f1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(product(f1, countfrom(1)))) == Base.IsInfinite() + @test (@inferred Base.IteratorSize(product(countfrom(1), f1))) == Base.IsInfinite() +end +@test (@inferred Base.IteratorSize(product(1:2, countfrom(1)))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(product(countfrom(2), countfrom(1)))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(product(countfrom(1), 1:2))) == Base.IsInfinite() +@test (@inferred Base.IteratorSize(product(1:2))) == Base.HasShape{1}() +@test (@inferred Base.IteratorSize(product(1:2, 1:2))) == Base.HasShape{2}() +@test (@inferred Base.IteratorSize(product(take(1:2, 1), take(1:2, 1)))) == Base.HasShape{2}() +@test (@inferred Base.IteratorSize(product(take(1:2, 2)))) == Base.HasShape{1}() +@test (@inferred Base.IteratorSize(product([1 2; 3 4]))) == Base.HasShape{2}() +@test (@inferred Base.IteratorSize(product((1,2,3,4), (5, 6, 7, 8)))) == Base.HasShape{2}() # product of ::HasLength and ::HasLength +@test (@inferred Base.IteratorSize(product(1:2, 3:5, 5:6))) == Base.HasShape{3}() # product of 3 iterators +@test (@inferred Base.IteratorSize(product([1 2; 3 4], 1:4))) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasShape{1} +@test (@inferred Base.IteratorSize(product([1 2; 3 4], (1,2)))) == Base.HasShape{3}() # product of ::HasShape{2} with ::HasLength # IteratorEltype trait business let f1 = Iterators.filter(i->i>0, 1:10) - @test Base.IteratorEltype(product(f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(1:2, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(f1, 1:2)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(f1, f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(f1, countfrom(1))) == Base.HasEltype() # FIXME? eltype(f1) is Any - @test Base.IteratorEltype(product(countfrom(1), f1)) == Base.HasEltype() # FIXME? eltype(f1) is Any -end -@test Base.IteratorEltype(product(1:2, countfrom(1))) == Base.HasEltype() -@test Base.IteratorEltype(product(countfrom(1), 1:2)) == Base.HasEltype() -@test Base.IteratorEltype(product(1:2)) == Base.HasEltype() -@test Base.IteratorEltype(product(1:2, 1:2)) == Base.HasEltype() -@test Base.IteratorEltype(product(take(1:2, 1), take(1:2, 1))) == Base.HasEltype() -@test Base.IteratorEltype(product(take(1:2, 2))) == Base.HasEltype() -@test Base.IteratorEltype(product([1 2; 3 4])) == Base.HasEltype() -@test Base.IteratorEltype(product()) == Base.HasEltype() + @test (@inferred Base.IteratorEltype(product(f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(1:2, f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(f1, 1:2))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(f1, f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(f1, countfrom(1)))) == Base.HasEltype() # FIXME? eltype(f1) is Any + @test (@inferred Base.IteratorEltype(product(countfrom(1), f1))) == Base.HasEltype() # FIXME? eltype(f1) is Any +end +@test (@inferred Base.IteratorEltype(product(1:2, countfrom(1)))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(countfrom(1), 1:2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(1:2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(1:2, 1:2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(take(1:2, 1), take(1:2, 1)))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product(take(1:2, 2)))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product([1 2; 3 4]))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(product())) == Base.HasEltype() @test collect(product(1:2,3:4)) == [(1,3) (1,4); (2,3) (2,4)] -@test isempty(collect(product(1:0,1:2))) -@test length(product(1:2,1:10,4:6)) == 60 -@test Base.IteratorSize(product(1:2, countfrom(1))) == Base.IsInfinite() +@test @inferred isempty(collect(product(1:0,1:2))) +@test (@inferred length(product(1:2,1:10,4:6))) == 60 +@test (@inferred Base.IteratorSize(product(1:2, countfrom(1)))) == Base.IsInfinite() @test Base.iterate(product()) == ((), true) @test Base.iterate(product(), 1) === nothing @@ -512,31 +512,31 @@ end @test collect(flatten(Any[flatten(Any[1:2, 4:5]), flatten(Any[6:7, 8:9])])) == Any[1,2,4,5,6,7,8,9] @test collect(flatten(Any[flatten(Any[1:2, 6:5]), flatten(Any[6:7, 8:9])])) == Any[1,2,6,7,8,9] @test collect(flatten(Any[2:1])) == Any[] -@test eltype(flatten(UnitRange{Int8}[1:2, 3:4])) == Int8 -@test eltype(flatten(([1, 2], [3.0, 4.0]))) == Real -@test eltype(flatten((a = [1, 2], b = Int8[3, 4]))) == Signed -@test eltype(flatten((Int[], Nothing[], Int[]))) == Union{Int, Nothing} -@test eltype(flatten((String[],))) == String -@test eltype(flatten((Int[], UInt[], Int8[],))) == Integer -@test eltype(flatten((; a = Int[], b = Nothing[], c = Int[]))) == Union{Int, Nothing} -@test eltype(flatten((; a = String[],))) == String -@test eltype(flatten((; a = Int[], b = UInt[], c = Int8[],))) == Integer -@test eltype(flatten(())) == Union{} -@test eltype(flatten((;))) == Union{} -@test length(flatten(zip(1:3, 4:6))) == 6 -@test length(flatten(1:6)) == 6 +@test (@inferred eltype(flatten(UnitRange{Int8}[1:2, 3:4]))) == Int8 +@test (@inferred eltype(flatten(([1, 2], [3.0, 4.0])))) == Real +@test (@inferred eltype(flatten((a = [1, 2], b = Int8[3, 4])))) == Signed +@test (@inferred eltype(flatten((Int[], Nothing[], Int[])))) == Union{Int, Nothing} +@test (@inferred eltype(flatten((String[],)))) == String +@test (@inferred eltype(flatten((Int[], UInt[], Int8[],)))) == Integer +@test (@inferred eltype(flatten((; a = Int[], b = Nothing[], c = Int[])))) == Union{Int, Nothing} +@test (@inferred eltype(flatten((; a = String[],)))) == String +@test (@inferred eltype(flatten((; a = Int[], b = UInt[], c = Int8[],)))) == Integer +@test (@inferred eltype(flatten(()))) == Union{} +@test (@inferred eltype(flatten((;)))) == Union{} +@test (@inferred length(flatten(zip(1:3, 4:6)))) == 6 +@test (@inferred length(flatten(1:6))) == 6 @test collect(flatten(Any[])) == Any[] @test collect(flatten(())) == Union{}[] @test_throws ArgumentError length(flatten(NTuple[(1,), ()])) # #16680 @test_throws ArgumentError length(flatten([[1], [1]])) @testset "IteratorSize trait for flatten" begin - @test Base.IteratorSize(Base.Flatten((i for i=1:2) for j=1:1)) == Base.SizeUnknown() - @test Base.IteratorSize(Base.Flatten((1,2))) == Base.HasLength() - @test Base.IteratorSize(Base.Flatten(1:2:4)) == Base.HasLength() + @test (@inferred Base.IteratorSize(Base.Flatten((i for i=1:2) for j=1:1))) == Base.SizeUnknown() + @test (@inferred Base.IteratorSize(Base.Flatten((1,2)))) == Base.HasLength() + @test (@inferred Base.IteratorSize(Base.Flatten(1:2:4))) == Base.HasLength() end -@test Base.IteratorEltype(Base.Flatten((i for i=1:2) for j=1:1)) == Base.EltypeUnknown() +@test (@inferred Base.IteratorEltype(Base.Flatten((i for i=1:2) for j=1:1))) == Base.EltypeUnknown() # see #29112, #29464, #29548 @test Base.return_types(Base.IteratorEltype, Tuple{Array}) == [Base.HasEltype] @@ -656,21 +656,21 @@ end @test_throws ArgumentError partition(1:10, -1) @test_throws ArgumentError partition(1:0, 0) @test_throws ArgumentError partition(1:0, -1) - @test isempty(partition(1:0, 1)) - @test isempty(partition(CartesianIndices((0,1)), 1)) + @test @inferred isempty(partition(1:0, 1)) + @test @inferred isempty(partition(CartesianIndices((0,1)), 1)) end @testset "exact partition eltypes" for a in (Base.OneTo(24), 1:24, 1:1:24, LinRange(1,10,24), .1:.1:2.4, Vector(1:24), CartesianIndices((4, 6)), Dict((1:24) .=> (1:24))) P = partition(a, 2) - @test eltype(P) === typeof(first(P)) - @test Iterators.IteratorEltype(P) == Iterators.HasEltype() + @test (@inferred eltype(P)) === typeof(first(P)) + @test (@inferred Iterators.IteratorEltype(P)) == Iterators.HasEltype() if a isa AbstractArray P = partition(vec(a), 2) - @test eltype(P) === typeof(first(P)) + @test (@inferred eltype(P)) === typeof(first(P)) P = partition(reshape(a, 6, 4), 2) - @test eltype(P) === typeof(first(P)) + @test (@inferred eltype(P)) === typeof(first(P)) P = partition(reshape(a, 2, 3, 4), 2) - @test eltype(P) === typeof(first(P)) + @test (@inferred eltype(P)) === typeof(first(P)) end end @@ -691,19 +691,19 @@ let s = "Monkey 🙈🙊🙊" @test tf(1) == "M|o|n|k|e|y| |🙈|🙊|🙊" end -@test Base.IteratorEltype(partition([1,2,3,4], 2)) == Base.HasEltype() -@test Base.IteratorEltype(partition((2x for x in 1:3), 2)) == Base.EltypeUnknown() +@test (@inferred Base.IteratorEltype(partition([1,2,3,4], 2))) == Base.HasEltype() +@test (@inferred Base.IteratorEltype(partition((2x for x in 1:3), 2))) == Base.EltypeUnknown() # take and friends with arbitrary integers (#19214) for T in (UInt8, UInt16, UInt32, UInt64, UInt128, Int8, Int16, Int128, BigInt) - @test length(take(1:6, T(3))) == 3 - @test length(drop(1:6, T(3))) == 3 - @test length(repeated(1, T(5))) == 5 + @test (@inferred length(take(1:6, T(3)))) == 3 + @test (@inferred length(drop(1:6, T(3)))) == 3 + @test (@inferred length(repeated(1, T(5)))) == 5 @test collect(partition(1:5, T(5)))[1] == 1:5 end @testset "collect finite iterators issue #12009" begin - @test eltype(collect(enumerate(Iterators.Filter(x -> x>0, randn(10))))) == Tuple{Int, Float64} + @test (@inferred eltype(collect(enumerate(Iterators.Filter(x -> x>0, randn(10)))))) == Tuple{Int, Float64} end @testset "product iterator infinite loop" begin @@ -712,8 +712,8 @@ end @testset "filter empty iterable #16704" begin arr = filter(Returns(true), 1:0) - @test length(arr) == 0 - @test eltype(arr) == Int + @test (@inferred length(arr)) == 0 + @test (@inferred eltype(arr)) == Int end @testset "Pairs type" begin @@ -727,19 +727,19 @@ end ) d = pairs(A) @test d === pairs(d) - @test isempty(d) == isempty(A) - @test length(d) == length(A) + @test (@inferred isempty(d)) == isempty(A) + @test (@inferred length(d)) == length(A) @test keys(d) == keys(A) @test values(d) == A - @test Base.IteratorSize(d) == Base.IteratorSize(A) - @test Base.IteratorEltype(d) == Base.HasEltype() - @test Base.IteratorSize(pairs([1 2;3 4])) isa Base.HasShape{2} - @test isempty(d) || haskey(d, first(keys(d))) + @test (@inferred Base.IteratorSize(d)) == Base.IteratorSize(A) + @test (@inferred Base.IteratorEltype(d)) == Base.HasEltype() + @test (@inferred Base.IteratorSize(pairs([1 2;3 4]))) isa Base.HasShape{2} + @test (@inferred isempty(d)) || haskey(d, first(keys(d))) @test collect(v for (k, v) in d) == collect(A) if A isa NamedTuple K = Symbol V = isempty(d) ? Union{} : Float64 - @test isempty(d) || haskey(d, :a) + @test (@inferred isempty(d)) || haskey(d, :a) @test !haskey(d, :abc) @test !haskey(d, 1) @test get(A, :key) do; 99; end == 99 @@ -759,7 +759,7 @@ end end @test keytype(d) == K @test valtype(d) == V - @test eltype(d) == Pair{K, V} + @test (@inferred eltype(d)) == Pair{K, V} end let io = IOBuffer() @@ -806,7 +806,7 @@ end @testset "Iterators.Stateful" begin let a = @inferred(Iterators.Stateful("abcdef")) - @test !isempty(a) + @test !(@inferred isempty(a)) @test popfirst!(a) == 'a' @test collect(Iterators.take(a, 3)) == ['b','c','d'] @test collect(a) == ['e', 'f'] @@ -817,63 +817,63 @@ end @test peek(a) == 3 @test sum(a) == 7 end - @test eltype(Iterators.Stateful("a")) == Char + @test (@inferred eltype(Iterators.Stateful("a"))) == Char # Interaction of zip/Stateful let a = Iterators.Stateful("a"), b = "" - @test isempty(collect(zip(a,b))) - @test !isempty(a) - @test isempty(collect(zip(b,a))) - @test !isempty(a) + @test @inferred isempty(collect(zip(a,b))) + @test !(@inferred isempty(a)) + @test @inferred isempty(collect(zip(b,a))) + @test !(@inferred isempty(a)) end let a = Iterators.Stateful("a"), b = "", c = Iterators.Stateful("c") - @test isempty(collect(zip(a,b,c))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(a,c,b))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(b,a,c))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(b,c,a))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(c,a,b))) - @test !isempty(a) - @test !isempty(c) - @test isempty(collect(zip(c,b,a))) - @test !isempty(a) - @test !isempty(c) + @test @inferred isempty(collect(zip(a,b,c))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(a,c,b))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(b,a,c))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(b,c,a))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(c,a,b))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) + @test @inferred isempty(collect(zip(c,b,a))) + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(a,b,c))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(a,b,c)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(a,c,b))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(a,c,b)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(b,a,c))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(b,a,c)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(b,c,a))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(b,c,a)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(c,a,b))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(c,a,b)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let a = Iterators.Stateful("aa"), b = "b", c = Iterators.Stateful("cc") - @test length(collect(zip(c,b,a))) == 1 - @test !isempty(a) - @test !isempty(c) + @test (@inferred length(collect(zip(c,b,a)))) == 1 + @test !(@inferred isempty(a)) + @test !(@inferred isempty(c)) end let z = zip(Iterators.Stateful("ab"), Iterators.Stateful("b"), Iterators.Stateful("c")) v, s = iterate(z) @@ -894,10 +894,10 @@ end @testset "inference for large zip #26765" begin x = zip(1:2, ["a", "b"], (1.0, 2.0), Base.OneTo(2), Iterators.repeated("a"), 1.0:0.2:2.0, (1 for i in 1:2), Iterators.Stateful(["a", "b", "c"]), (1.0 for i in 1:2, j in 1:3)) - @test Base.IteratorSize(x) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(x)) isa Base.SizeUnknown x = zip(1:2, ["a", "b"], (1.0, 2.0), Base.OneTo(2), Iterators.repeated("a"), 1.0:0.2:2.0, (1 for i in 1:2), Iterators.cycle(Iterators.Stateful(["a", "b", "c"])), (1.0 for i in 1:2, j in 1:3)) - @test Base.IteratorSize(x) isa Base.HasLength + @test (@inferred Base.IteratorSize(x)) isa Base.HasLength @test @inferred(length(x)) == 2 z = Iterators.filter(x -> x[1] >= 1, x) @test @inferred(eltype(z)) <: Tuple{Int,String,Float64,Int,String,Float64,Any,String,Any} @@ -906,23 +906,23 @@ end end @testset "Stateful fix #30643" begin - @test Base.IteratorSize(1:10) isa Base.HasShape{1} + @test (@inferred Base.IteratorSize(1:10)) isa Base.HasShape{1} a = Iterators.Stateful(1:10) - @test Base.IteratorSize(a) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(a)) isa Base.SizeUnknown @test !Base.isdone(a) @test length(collect(a)) == 10 @test Base.isdone(a) b = Iterators.Stateful(Iterators.take(1:10,3)) - @test Base.IteratorSize(b) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(b)) isa Base.SizeUnknown @test !Base.isdone(b) @test length(collect(b)) == 3 @test Base.isdone(b) c = Iterators.Stateful(Iterators.countfrom(1)) - @test Base.IteratorSize(c) isa Base.IsInfinite + @test (@inferred Base.IteratorSize(c)) isa Base.IsInfinite @test !Base.isdone(Iterators.take(c,3)) @test length(collect(Iterators.take(c,3))) == 3 d = Iterators.Stateful(Iterators.filter(isodd,1:10)) - @test Base.IteratorSize(d) isa Base.SizeUnknown + @test (@inferred Base.IteratorSize(d)) isa Base.SizeUnknown @test length(collect(Iterators.take(d,3))) == 3 @test length(collect(d)) == 2 @test length(collect(d)) == 0 @@ -964,7 +964,7 @@ end end @testset "flatten empty tuple" begin - @test isempty(collect(Iterators.flatten(()))) + @test @inferred isempty(collect(Iterators.flatten(()))) end @testset "Iterators.accumulate" begin @@ -976,10 +976,10 @@ end @test collect(Iterators.accumulate(+, (x for x in [true])))::Vector{Int} == [1] @test collect(Iterators.accumulate(+, (x for x in [true, true, false])))::Vector{Int} == [1, 2, 2] @test collect(Iterators.accumulate(+, (x for x in [true]), init=10.0))::Vector{Float64} == [11.0] - @test length(Iterators.accumulate(+, [10,20,30])) == 3 - @test size(Iterators.accumulate(max, rand(2,3))) == (2,3) - @test Base.IteratorSize(Iterators.accumulate(max, rand(2,3))) === Base.IteratorSize(rand(2,3)) - @test Base.IteratorEltype(Iterators.accumulate(*, ())) isa Base.EltypeUnknown + @test (@inferred length(Iterators.accumulate(+, [10,20,30]))) == 3 + @test (@inferred size(Iterators.accumulate(max, rand(2,3)))) == (2,3) + @test (@inferred Base.IteratorSize(Iterators.accumulate(max, rand(2,3)))) === Base.IteratorSize(rand(2,3)) + @test (@inferred Base.IteratorEltype(Iterators.accumulate(*, ()))) isa Base.EltypeUnknown end @testset "Base.accumulate" begin @@ -989,13 +989,13 @@ end end @testset "IteratorSize trait for zip" begin - @test Base.IteratorSize(zip()) == Base.IsInfinite() # for zip of empty tuple - @test Base.IteratorSize(zip((1,2,3), repeated(0))) == Base.HasLength() # for zip of ::HasLength and ::IsInfinite - @test Base.IteratorSize(zip( 1:5, repeated(0) )) == Base.HasLength() # for zip of ::HasShape and ::IsInfinite - @test Base.IteratorSize(zip(repeated(0), (1,2,3))) == Base.HasLength() # for zip of ::IsInfinite and ::HasLength - @test Base.IteratorSize(zip(repeated(0), 1:5 )) == Base.HasLength() # for zip of ::IsInfinite and ::HasShape - @test Base.IteratorSize(zip((1,2,3), 1:5) ) == Base.HasLength() # for zip of ::HasLength and ::HasShape - @test Base.IteratorSize(zip(1:5, (1,2,3)) ) == Base.HasLength() # for zip of ::HasShape and ::HasLength + @test (@inferred Base.IteratorSize(zip())) == Base.IsInfinite() # for zip of empty tuple + @test (@inferred Base.IteratorSize(zip((1,2,3), repeated(0)))) == Base.HasLength() # for zip of ::HasLength and ::IsInfinite + @test (@inferred Base.IteratorSize(zip( 1:5, repeated(0) ))) == Base.HasLength() # for zip of ::HasShape and ::IsInfinite + @test (@inferred Base.IteratorSize(zip(repeated(0), (1,2,3)))) == Base.HasLength() # for zip of ::IsInfinite and ::HasLength + @test (@inferred Base.IteratorSize(zip(repeated(0), 1:5 ))) == Base.HasLength() # for zip of ::IsInfinite and ::HasShape + @test (@inferred Base.IteratorSize(zip((1,2,3), 1:5) )) == Base.HasLength() # for zip of ::HasLength and ::HasShape + @test (@inferred Base.IteratorSize(zip(1:5, (1,2,3)) )) == Base.HasLength() # for zip of ::HasShape and ::HasLength end @testset "proper partition for non-1-indexed vector" begin @@ -1018,7 +1018,7 @@ end @testset "isempty and isdone for Generators" begin itr = eachline(IOBuffer("foo\n")) gen = (x for x in itr) - @test !isempty(gen) + @test !(@inferred isempty(gen)) @test !Base.isdone(gen) @test collect(gen) == ["foo"] end From 316f0fe0b0e454093b44095bb99b273d4158bdc0 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Thu, 16 Jan 2025 08:05:28 -0500 Subject: [PATCH 32/65] Construct proper URIs for paths when run on WSL in tests (#57061) https://github.com/JuliaLang/julia/pull/55454 produces the correct URIs when run on WSL, but the tests don't use the same logic and so they fail on WSL at the moment. This fixes the tests on WSL. CC @tecosaur --- test/path.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/path.jl b/test/path.jl index 4c2c7034577d5..2515d765d8ca9 100644 --- a/test/path.jl +++ b/test/path.jl @@ -312,7 +312,14 @@ end @testset "uripath" begin - host = if Sys.iswindows() "" else gethostname() end + host = if Sys.iswindows() + "" + elseif ispath("/proc/sys/fs/binfmt_misc/WSLInterop") + distro = get(ENV, "WSL_DISTRO_NAME", "") # See + "wsl%24/$distro" # See and + else + gethostname() + end sysdrive, uridrive = if Sys.iswindows() "C:\\", "C:/" else "/", "" end @test Base.Filesystem.uripath("$(sysdrive)some$(sep)file.txt") == "file://$host/$(uridrive)some/file.txt" @test Base.Filesystem.uripath("$(sysdrive)another$(sep)$(sep)folder$(sep)file.md") == "file://$host/$(uridrive)another/folder/file.md" From 0c7dd964f67d5a31750f5779d858c3d52aba931e Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Fri, 17 Jan 2025 01:54:24 -0500 Subject: [PATCH 33/65] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20Sp?= =?UTF-8?q?arseArrays=20stdlib=20from=205f52721=20to=20212981b=20(#57065)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: 5f52721 New commit: 212981b Julia version: 1.12.0-DEV SparseArrays version: 1.12.0 Bump invoked by: @dkarrasch Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: https://github.com/JuliaSparse/SparseArrays.jl/compare/5f527215c188ee99247cdce31ba8ce9e11f35055...212981bf29b03ba460d3251ee9aa4399931b3f2d ``` $ git log --oneline 5f52721..212981b 212981b Solve with `AdjointFactorization` of Cholmod and `Adjoint` rhs (#595) ``` Co-authored-by: dkarrasch <26658441+dkarrasch@users.noreply.github.com> --- .../md5 | 1 + .../sha512 | 1 + .../md5 | 1 - .../sha512 | 1 - stdlib/SparseArrays.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 create mode 100644 deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 delete mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 delete mode 100644 deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 diff --git a/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 new file mode 100644 index 0000000000000..3fddcf07235f8 --- /dev/null +++ b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/md5 @@ -0,0 +1 @@ +621e67dc98707b587fb0f6e319dadbb2 diff --git a/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 new file mode 100644 index 0000000000000..68885439a1213 --- /dev/null +++ b/deps/checksums/SparseArrays-212981bf29b03ba460d3251ee9aa4399931b3f2d.tar.gz/sha512 @@ -0,0 +1 @@ +5608adf92eaf7479eacf5ed75b3139438d0d4acf53d55a38c73a553c7fd899f553e1648fa657d35b9a0289e69fc461025dae5f8d15ec891eafcab3a663a8413a diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 deleted file mode 100644 index 946bec189c1bd..0000000000000 --- a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -4b07db52a5a6d3cc6eeab380bd783a1e diff --git a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 b/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 deleted file mode 100644 index 846867193d932..0000000000000 --- a/deps/checksums/SparseArrays-5f527215c188ee99247cdce31ba8ce9e11f35055.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -4c631f1046ad0a6b972a4dce285c2092372ecbed269c83524c10b4be5124035670d703af53e1f8058d23230be20c06aa554097cc9bc7a12b3de3c039d3c545e8 diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index 3f6ab5b878069..0234c754191f8 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 5f527215c188ee99247cdce31ba8ce9e11f35055 +SPARSEARRAYS_SHA1 = 212981bf29b03ba460d3251ee9aa4399931b3f2d SPARSEARRAYS_GIT_URL := https://github.com/JuliaSparse/SparseArrays.jl.git SPARSEARRAYS_TAR_URL = https://api.github.com/repos/JuliaSparse/SparseArrays.jl/tarball/$1 From 81e79e5bfc5ccfd9d8a8d5825d5a508f1009d7b2 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Fri, 17 Jan 2025 06:31:59 -0500 Subject: [PATCH 34/65] codegen: handle recursive sparam calls in API (#57047) Fixes #56690 --- src/ccall.cpp | 5 +--- src/codegen.cpp | 56 +++++++++++++++++++-------------------- src/llvm-codegen-shared.h | 23 ++++++++-------- 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 1b635ca40840f..eb64adef447f4 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -461,10 +461,7 @@ static Value *runtime_apply_type_env(jl_codectx_t &ctx, jl_value_t *ty) Value *args[] = { literal_pointer_val(ctx, ty), literal_pointer_val(ctx, (jl_value_t*)ctx.linfo->def.method->sig), - ctx.builder.CreateInBoundsGEP( - ctx.types().T_prjlvalue, - ctx.spvals_ptr, - ConstantInt::get(ctx.types().T_size, sizeof(jl_svec_t) / sizeof(jl_value_t*))) + emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), sizeof(jl_svec_t)) }; auto call = ctx.builder.CreateCall(prepare_call(jlapplytype_func), ArrayRef(args)); addRetAttr(call, Attribute::getWithAlignment(ctx.builder.getContext(), Align(16))); diff --git a/src/codegen.cpp b/src/codegen.cpp index 7bc14d2d0347f..eefc675bdd665 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1263,12 +1263,11 @@ static const auto jlsubtype_func = new JuliaFunction<>{ static const auto jlapplytype_func = new JuliaFunction<>{ XSTR(jl_instantiate_type_in_env), [](LLVMContext &C) { - auto T_jlvalue = JuliaType::get_jlvalue_ty(C); - auto T_pjlvalue = PointerType::get(T_jlvalue, 0); - auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked); - auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0); - return FunctionType::get(T_prjlvalue, - {T_pjlvalue, T_pjlvalue, T_pprjlvalue}, false); + auto T_ptr = PointerType::get(C, 0); + auto T_tracked = PointerType::get(C, AddressSpace::Tracked); + auto T_derived = PointerType::get(C, AddressSpace::Derived); + return FunctionType::get(T_tracked, + {T_ptr, T_ptr, T_derived}, false); }, [](LLVMContext &C) { return AttributeList::get(C, @@ -1377,11 +1376,10 @@ static const auto jlfieldisdefinedchecked_func = new JuliaFunction{ XSTR(jl_get_cfunction_trampoline), [](LLVMContext &C) { - auto T_jlvalue = JuliaType::get_jlvalue_ty(C); - auto T_pjlvalue = PointerType::get(T_jlvalue, 0); - auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked); - auto T_ppjlvalue = PointerType::get(T_pjlvalue, 0); - auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0); + auto T_pjlvalue = PointerType::get(C, 0); + auto T_prjlvalue = PointerType::get(C, AddressSpace::Tracked); + auto T_ppjlvalue = PointerType::get(C, 0); + auto T_derived = PointerType::get(C, AddressSpace::Derived); return FunctionType::get(T_prjlvalue, { T_prjlvalue, // f (object) @@ -1390,7 +1388,7 @@ static const auto jlgetcfunctiontrampoline_func = new JuliaFunction<>{ T_pjlvalue, // fill FunctionType::get(getPointerTy(C), { getPointerTy(C), T_ppjlvalue }, false)->getPointerTo(), // trampoline T_pjlvalue, // env - T_pprjlvalue, // vals + T_derived, // vals }, false); }, [](LLVMContext &C) { return AttributeList::get(C, @@ -5610,18 +5608,23 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR assert(jl_is_method_instance(mi)); if (mi == ctx.linfo) { // handle self-recursion specially (TODO: assuming ci is a valid invoke for mi?) - jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; - FunctionType *ft = ctx.f->getFunctionType(); - StringRef protoname = ctx.f->getName(); + Function *f = ctx.f; + FunctionType *ft = f->getFunctionType(); if (ft == ctx.types().T_jlfunc) { - result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, nullptr, argv, nargs, rt, age_ok); - handled = true; + Value *ret = emit_jlcall(ctx, f, nullptr, argv, nargs, julia_call); + result = update_julia_type(ctx, mark_julia_type(ctx, ret, true, ctx.rettype), rt); } - else if (ft != ctx.types().T_jlfuncparams) { + else if (ft == ctx.types().T_jlfuncparams) { + Value *ret = emit_jlcall(ctx, f, ctx.spvals_ptr, argv, nargs, julia_call2); + result = update_julia_type(ctx, mark_julia_type(ctx, ret, true, ctx.rettype), rt); + } + else { unsigned return_roots = 0; + jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; + StringRef protoname = f->getName(); result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); - handled = true; } + handled = true; } else { if (ci) { @@ -5630,7 +5633,6 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR // check if we know how to handle this specptr if (invoke == jl_fptr_const_return_addr) { result = mark_julia_const(ctx, codeinst->rettype_const); - handled = true; } else { bool specsig, needsparams; @@ -5640,8 +5642,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR push_frames(ctx, ctx.linfo, mi); Value *r = emit_jlcall(ctx, jlinvoke_func, track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)mi)), argv, nargs, julia_call2); result = mark_julia_type(ctx, r, true, rt); - handled = true; - } else { + } + else { std::string name; StringRef protoname; bool need_to_emit = true; @@ -5689,7 +5691,6 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR result = emit_call_specfun_other(ctx, codeinst, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); else result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok); - handled = true; if (need_to_emit) { Function *trampoline_decl = cast(jl_Module->getNamedValue(protoname)); ctx.call_targets[codeinst] = {cc, return_roots, trampoline_decl, nullptr, specsig}; @@ -5698,6 +5699,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR } } } + handled = true; } } } @@ -6078,8 +6080,7 @@ static jl_cgval_t emit_sparam(jl_codectx_t &ctx, size_t i) return mark_julia_const(ctx, e); } } - assert(ctx.spvals_ptr != NULL); - Value *bp = emit_ptrgep(ctx, ctx.spvals_ptr, i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); + Value *bp = emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); Value *sp = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)))); setName(ctx.emission_context, sp, "sparam"); @@ -6131,8 +6132,7 @@ static jl_cgval_t emit_isdefined(jl_codectx_t &ctx, jl_value_t *sym, int allow_i return mark_julia_const(ctx, jl_true); } } - assert(ctx.spvals_ptr != NULL); - Value *bp = emit_ptrgep(ctx, ctx.spvals_ptr, i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); + Value *bp = emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), i * sizeof(jl_value_t*) + sizeof(jl_svec_t)); jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); Value *sp = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*)))); isnull = ctx.builder.CreateICmpNE(emit_typeof(ctx, sp, false, true), emit_tagfrom(ctx, jl_tvar_type)); @@ -8000,7 +8000,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con literal_pointer_val(ctx, (jl_value_t*)fill), F, closure_types ? literal_pointer_val(ctx, (jl_value_t*)unionall_env) : Constant::getNullValue(ctx.types().T_pjlvalue), - closure_types ? ctx.spvals_ptr : ConstantPointerNull::get(cast(ctx.types().T_pprjlvalue)) + closure_types ? decay_derived(ctx, ctx.spvals_ptr) : ConstantPointerNull::get(ctx.builder.getPtrTy(AddressSpace::Derived)) }); outboxed = true; } diff --git a/src/llvm-codegen-shared.h b/src/llvm-codegen-shared.h index d9551e0552f9c..ff6f5a97299d7 100644 --- a/src/llvm-codegen-shared.h +++ b/src/llvm-codegen-shared.h @@ -51,9 +51,9 @@ namespace JuliaType { static inline auto get_jlfunc_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); return llvm::FunctionType::get(T_prjlvalue, { - T_prjlvalue, // function + T_prjlvalue, // function T_pprjlvalue, // args[] llvm::Type::getInt32Ty(C)}, // nargs false); @@ -61,21 +61,21 @@ namespace JuliaType { static inline auto get_jlfunc2_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); return llvm::FunctionType::get(T_prjlvalue, { - T_prjlvalue, // function + T_prjlvalue, // function T_pprjlvalue, // args[] llvm::Type::getInt32Ty(C), // nargs - T_prjlvalue}, // linfo + T_prjlvalue}, // linfo false); } static inline auto get_jlfunc3_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); auto T = get_pjlvalue_ty(C, Derived); return llvm::FunctionType::get(T_prjlvalue, { - T, // function + T, // function T_pprjlvalue, // args[] llvm::Type::getInt32Ty(C)}, // nargs false); @@ -83,13 +83,12 @@ namespace JuliaType { static inline auto get_jlfuncparams_ty(llvm::LLVMContext &C) { auto T_prjlvalue = get_prjlvalue_ty(C); - auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0); + auto T_pprjlvalue = llvm::PointerType::get(C, 0); return llvm::FunctionType::get(T_prjlvalue, { - T_prjlvalue, // function + T_prjlvalue, // function T_pprjlvalue, // args[] - llvm::Type::getInt32Ty(C), - T_pprjlvalue, // linfo->sparam_vals - }, // nargs + llvm::Type::getInt32Ty(C), // nargs + T_prjlvalue}, // linfo->sparam_vals false); } From 9ea547a36e4d3e0d36bd45ec20552508a3075722 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Fri, 17 Jan 2025 10:28:20 -0700 Subject: [PATCH 35/65] Add try/catch around handle_message() to catch errors during logging. (#57004) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/JuliaLang/julia/issues/56889. Before this PR, an exception thrown while constructing the objects to log (the `msg`) would be caught and logged. However, an exception thrown while _printing_ the msg to an IO would _not_ be caught, and can abort the program. This breaks the promise that enabling verbose debug logging shouldn't introduce new crashes. After this PR, an exception thrown during handle_message is caught and logged, just like an exception during `msg` construction: ```julia julia> struct Foo end julia> Base.show(::IO, ::Foo) = error("oh no") julia> begin # Unexpectedly, the execption thrown while printing `Foo()` escapes @info Foo() # So we never reach this line! :'( println("~~~~~ ALL DONE ~~~~~~~~") end ┌ Error: Exception while generating log record in module Main at REPL[10]:3 │ exception = │ oh no │ Stacktrace: │ [1] error(s::String) │ @ Base ./error.jl:44 │ [2] show(::IOBuffer, ::Foo) │ @ Main ./REPL[9]:1 ... │ [30] repl_main │ @ ./client.jl:593 [inlined] │ [31] _start() │ @ Base ./client.jl:568 └ @ Main REPL[10]:3 ~~~~~ ALL DONE ~~~~~~~~ ``` This PR respects the change made in https://github.com/JuliaLang/julia/pull/36600 to keep the codegen as small as possible, by putting the new try/catch into a no-inlined function, so that we don't have to introduce a new try/catch in the macro-generated code body. --------- Co-authored-by: Jameson Nash --- base/logging/logging.jl | 14 +++++++++++++- test/corelogging.jl | 13 +++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/base/logging/logging.jl b/base/logging/logging.jl index 5cf3882a300ec..41721e84cc934 100644 --- a/base/logging/logging.jl +++ b/base/logging/logging.jl @@ -409,7 +409,7 @@ function logmsg_code(_module, file, line, level, message, exs...) end line = $(log_data._line) local msg, kwargs - $(logrecord) && invokelatest($handle_message, + $(logrecord) && $handle_message_nothrow( logger, level, msg, _module, group, id, file, line; kwargs...) end @@ -420,6 +420,18 @@ function logmsg_code(_module, file, line, level, message, exs...) end end +@noinline function handle_message_nothrow(logger, level, msg, _module, group, id, file, line; kwargs...) + @nospecialize + try + @invokelatest handle_message( + logger, level, msg, _module, group, id, file, line; + kwargs...) + + catch err + @invokelatest logging_error(logger, level, _module, group, id, file, line, err, true) + end +end + function process_logmsg_exs(_orig_module, _file, _line, level, message, exs...) @nospecialize local _group, _id diff --git a/test/corelogging.jl b/test/corelogging.jl index b8cd3716cad2e..154202da759c2 100644 --- a/test/corelogging.jl +++ b/test/corelogging.jl @@ -114,6 +114,19 @@ end @test only(collect_test_logs(logmsg)[1]).kwargs[:x] === "the y" end end +@testset "Log message handle_message exception handling" begin + # Exceptions in log handling (printing) of msg are caught by default. + struct Foo end + Base.show(::IO, ::Foo) = 1 ÷ 0 + + # We cannot use `@test_logs` here, since test_logs does not actually _print_ the message + # (i.e. it does not invoke handle_message). To test exception handling during printing, + # we have to use `@test_warn` to see what was printed. + @test_warn r"Error: Exception while generating log record in module .*DivideError: integer division error"s @info Foo() + + # Exceptions in log handling (printing) of attributes are caught by default + @test_warn r"Error: Exception while generating log record in module .*DivideError: integer division error"s @info "foo" x=Foo() +end @testset "Special keywords" begin logger = TestLogger() From 98f8aca9ac8eb1c9467b685c7e8594d981192d96 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Sat, 18 Jan 2025 04:53:52 +1100 Subject: [PATCH 36/65] Adding `precompile_field_replace` to MMTk's roots (#57073) Add `precompile_field_replace` and update the `mmtk_julia` binding version to account for the change from https://github.com/JuliaLang/julia/commit/b8ab9f37469d9c19eeac1f9b5d40a499d3a176e8. --- deps/checksums/mmtk_julia | 4 ++++ .../md5 | 1 - .../sha512 | 1 - deps/mmtk_julia.version | 4 ++-- src/gc-mmtk.c | 3 +++ 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 deps/checksums/mmtk_julia delete mode 100644 deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 delete mode 100644 deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 diff --git a/deps/checksums/mmtk_julia b/deps/checksums/mmtk_julia new file mode 100644 index 0000000000000..49b7a50a8e136 --- /dev/null +++ b/deps/checksums/mmtk_julia @@ -0,0 +1,4 @@ +mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5/1911cf084d26c48e2ed58af3d268b4b6 +mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512/75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe +mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/md5/38afb5db6d8c55413a4ec96aefa2ebb4 +mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/sha512/78525582a46a6baf8d33df7b622e55cf244439afcd7192ba55489c1bc18393d1237d2903d517c610484bf9e2a7338ad31435a9cbf70889d6bcf87c40cec829e5 \ No newline at end of file diff --git a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 deleted file mode 100644 index fc6955c8f2e7b..0000000000000 --- a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -1911cf084d26c48e2ed58af3d268b4b6 diff --git a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 b/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 deleted file mode 100644 index ea916976895a3..0000000000000 --- a/deps/checksums/mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe diff --git a/deps/mmtk_julia.version b/deps/mmtk_julia.version index 60f7cffe7b4de..4d821bffd5b9b 100644 --- a/deps/mmtk_julia.version +++ b/deps/mmtk_julia.version @@ -1,4 +1,4 @@ MMTK_JULIA_BRANCH = master -MMTK_JULIA_SHA1 = b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214 +MMTK_JULIA_SHA1 = f07d66aafc86af84ea988b35335acc9bbc770fa1 MMTK_JULIA_GIT_URL := https://github.com/mmtk/mmtk-julia.git -MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.2.tar.gz +MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.3.tar.gz diff --git a/src/gc-mmtk.c b/src/gc-mmtk.c index 78882c8eb0225..5ec1e34cc1acd 100644 --- a/src/gc-mmtk.c +++ b/src/gc-mmtk.c @@ -497,6 +497,9 @@ JL_DLLEXPORT void jl_gc_scan_vm_specific_roots(RootsWorkClosure* closure) add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, jl_global_roots_list); add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, jl_global_roots_keyset); + // FIXME: transivitely pinning for now, should be removed after we add moving Immix + add_node_to_tpinned_roots_buffer(closure, &tpinned_buf, &tpinned_len, precompile_field_replace); + // Push the result of the work. (closure->report_nodes_func)(buf.ptr, len, buf.cap, closure->data, false); (closure->report_tpinned_nodes_func)(tpinned_buf.ptr, tpinned_len, tpinned_buf.cap, closure->data, false); From 647b9f4c53f66fed106e2dcac3906fe55a280e7c Mon Sep 17 00:00:00 2001 From: Kiran Pamnany Date: Fri, 17 Jan 2025 18:19:01 -0500 Subject: [PATCH 37/65] Add timeout parameter to `wait(::Condition)` (#56974) We have a need for this capability. I believe this closes https://github.com/JuliaLang/julia/issues/36217. The implementation is straightforward and there are a couple of tests. --- base/condition.jl | 90 +++++++++++++++++++++++++++++++++++++++++++++-- test/channels.jl | 17 +++++++++ 2 files changed, 104 insertions(+), 3 deletions(-) diff --git a/base/condition.jl b/base/condition.jl index fd771c9be346a..90c53b7ad310d 100644 --- a/base/condition.jl +++ b/base/condition.jl @@ -125,20 +125,104 @@ proceeding. """ function wait end +# wait with timeout +# +# The behavior of wait changes if a timeout is specified. There are +# three concurrent entities that can interact: +# 1. Task W: the task that calls wait w/timeout. +# 2. Task T: the task created to handle a timeout. +# 3. Task N: the task that notifies the Condition being waited on. +# +# Typical flow: +# - W enters the Condition's wait queue. +# - W creates T and stops running (calls wait()). +# - T, when scheduled, waits on a Timer. +# - Two common outcomes: +# - N notifies the Condition. +# - W starts running, closes the Timer, sets waiter_left and returns +# the notify'ed value. +# - The closed Timer throws an EOFError to T which simply ends. +# - The Timer expires. +# - T starts running and locks the Condition. +# - T confirms that waiter_left is unset and that W is still in the +# Condition's wait queue; it then removes W from the wait queue, +# sets dosched to true and unlocks the Condition. +# - If dosched is true, T schedules W with the special :timed_out +# value. +# - T ends. +# - W runs and returns :timed_out. +# +# Some possible interleavings: +# - N notifies the Condition but the Timer expires and T starts running +# before W: +# - W closing the expired Timer is benign. +# - T will find that W is no longer in the Condition's wait queue +# (which is protected by a lock) and will not schedule W. +# - N notifies the Condition; W runs and calls wait on the Condition +# again before the Timer expires: +# - W sets waiter_left before leaving. When T runs, it will find that +# waiter_left is set and will not schedule W. +# +# The lock on the Condition's wait queue and waiter_left together +# ensure proper synchronization and behavior of the tasks involved. + """ - wait(c::GenericCondition; first::Bool=false) + wait(c::GenericCondition; first::Bool=false, timeout::Real=0.0) Wait for [`notify`](@ref) on `c` and return the `val` parameter passed to `notify`. If the keyword `first` is set to `true`, the waiter will be put _first_ in line to wake up on `notify`. Otherwise, `wait` has first-in-first-out (FIFO) behavior. + +If `timeout` is specified, cancel the `wait` when it expires and return +`:timed_out`. The minimum value for `timeout` is 0.001 seconds, i.e. 1 +millisecond. """ -function wait(c::GenericCondition; first::Bool=false) +function wait(c::GenericCondition; first::Bool=false, timeout::Real=0.0) + timeout == 0.0 || timeout ≥ 1e-3 || throw(ArgumentError("timeout must be ≥ 1 millisecond")) + ct = current_task() _wait2(c, ct, first) token = unlockall(c.lock) + + timer::Union{Timer, Nothing} = nothing + waiter_left::Union{Threads.Atomic{Bool}, Nothing} = nothing + if timeout > 0.0 + timer = Timer(timeout) + waiter_left = Threads.Atomic{Bool}(false) + # start a task to wait on the timer + t = Task() do + try + wait(timer) + catch e + # if the timer was closed, the waiting task has been scheduled; do nothing + e isa EOFError && return + end + dosched = false + lock(c.lock) + # Confirm that the waiting task is still in the wait queue and remove it. If + # the task is not in the wait queue, it must have been notified already so we + # don't do anything here. + if !waiter_left[] && ct.queue == c.waitq + dosched = true + Base.list_deletefirst!(c.waitq, ct) + end + unlock(c.lock) + # send the waiting task a timeout + dosched && schedule(ct, :timed_out) + end + t.sticky = false + Threads._spawn_set_thrpool(t, :interactive) + schedule(t) + end + try - return wait() + res = wait() + if timer !== nothing + close(timer) + waiter_left[] = true + end + return res catch q = ct.queue; q === nothing || Base.list_deletefirst!(q::IntrusiveLinkedList{Task}, ct) rethrow() diff --git a/test/channels.jl b/test/channels.jl index 4acf6c94da1b6..6e74a2079234c 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -1,6 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Random +using Base.Threads using Base: Experimental using Base: n_avail @@ -39,6 +40,22 @@ end @test fetch(t) == "finished" end +@testset "timed wait on Condition" begin + a = Threads.Condition() + @test_throws ArgumentError @lock a wait(a; timeout=0.0005) + @test @lock a wait(a; timeout=0.1)==:timed_out + lock(a) + @spawn begin + @lock a notify(a) + end + @test try + wait(a; timeout=2) + true + finally + unlock(a) + end +end + @testset "various constructors" begin c = Channel() @test eltype(c) == Any From 11c692e1084a631bb40d5348b7074ed58c634714 Mon Sep 17 00:00:00 2001 From: Diogo Netto <61364108+d-netto@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:54:15 -0300 Subject: [PATCH 38/65] add option to dump backtrace of stop-the-world straggler (#57045) This is still a work in progress, but it should help determine what a straggler thread was doing during the stop-the-world phase and why it failed to reach a safepoint in a timely manner. We've encountered long TTSP issues in production, and this tool should provide a valuable means to accurately diagnose them. --- base/options.jl | 1 + src/jloptions.c | 12 ++++++++++++ src/jloptions.h | 1 + src/julia_internal.h | 2 ++ src/safepoint.c | 31 +++++++++++++++++++++++++++---- src/stackwalk.c | 19 +++++++++++++++++++ test/cmdlineargs.jl | 6 ++++++ test/threads_exec.jl | 25 +++++++++++++++++++++++++ 8 files changed, 93 insertions(+), 4 deletions(-) diff --git a/base/options.jl b/base/options.jl index 7e7808bd5c047..3281ec0de98d2 100644 --- a/base/options.jl +++ b/base/options.jl @@ -62,6 +62,7 @@ struct JLOptions trace_compile_timing::Int8 trim::Int8 task_metrics::Int8 + timeout_for_safepoint_straggler_s::Int16 end # This runs early in the sysimage != is not defined yet diff --git a/src/jloptions.c b/src/jloptions.c index c68b5ce193d98..2c5a9074eb465 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -153,6 +153,7 @@ JL_DLLEXPORT void jl_init_options(void) 0, // trace_compile_timing JL_TRIM_NO, // trim 0, // task_metrics + -1, // timeout_for_safepoint_straggler_s }; jl_options_initialized = 1; } @@ -311,6 +312,8 @@ static const char opts_hidden[] = " --output-asm Generate an assembly file (.s)\n" " --output-incremental={yes|no*} Generate an incremental output file (rather than\n" " complete)\n" + " --timeout-for-safepoint-straggler If this value is set, then we will dump the backtrace for a thread\n" + " that fails to reach a safepoint within the specified time\n" " --trace-compile={stderr|name} Print precompile statements for methods compiled\n" " during execution or save to stderr or a path. Methods that\n" " were recompiled are printed in yellow or with a trailing\n" @@ -346,6 +349,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) opt_warn_scope, opt_inline, opt_polly, + opt_timeout_for_safepoint_straggler, opt_trace_compile, opt_trace_compile_timing, opt_trace_dispatch, @@ -427,6 +431,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) { "warn-scope", required_argument, 0, opt_warn_scope }, { "inline", required_argument, 0, opt_inline }, { "polly", required_argument, 0, opt_polly }, + { "timeout-for-safepoint-straggler", required_argument, 0, opt_timeout_for_safepoint_straggler }, { "trace-compile", required_argument, 0, opt_trace_compile }, { "trace-compile-timing", no_argument, 0, opt_trace_compile_timing }, { "trace-dispatch", required_argument, 0, opt_trace_dispatch }, @@ -970,6 +975,13 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) else jl_errorf("julia: invalid argument to --permalloc-pkgimg={yes|no} (%s)", optarg); break; + case opt_timeout_for_safepoint_straggler: + errno = 0; + long timeout = strtol(optarg, &endptr, 10); + if (errno != 0 || optarg == endptr || timeout < 1 || timeout > INT16_MAX) + jl_errorf("julia: --timeout-for-safepoint-straggler=; seconds must be an integer between 1 and %d", INT16_MAX); + jl_options.timeout_for_safepoint_straggler_s = (int16_t)timeout; + break; case opt_trim: if (optarg == NULL || !strcmp(optarg,"safe")) jl_options.trim = JL_TRIM_SAFE; diff --git a/src/jloptions.h b/src/jloptions.h index 211122242cbbd..a8cc4a9a9e33d 100644 --- a/src/jloptions.h +++ b/src/jloptions.h @@ -66,6 +66,7 @@ typedef struct { int8_t trace_compile_timing; int8_t trim; int8_t task_metrics; + int16_t timeout_for_safepoint_straggler_s; } jl_options_t; #endif diff --git a/src/julia_internal.h b/src/julia_internal.h index 00d603f26c7f2..3e4967c9d4dca 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -215,6 +215,8 @@ typedef struct { size_t bt_size; int tid; } jl_record_backtrace_result_t; +JL_DLLEXPORT JL_DLLEXPORT size_t jl_try_record_thread_backtrace(jl_ptls_t ptls2, struct _jl_bt_element_t *bt_data, + size_t max_bt_size) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, struct _jl_bt_element_t *bt_data, size_t max_bt_size, int all_tasks_profiler) JL_NOTSAFEPOINT; extern volatile struct _jl_bt_element_t *profile_bt_data_prof; diff --git a/src/safepoint.c b/src/safepoint.c index 7eab653edd089..66bea539861f8 100644 --- a/src/safepoint.c +++ b/src/safepoint.c @@ -149,10 +149,33 @@ void jl_gc_wait_for_the_world(jl_ptls_t* gc_all_tls_states, int gc_n_threads) // Use system mutexes rather than spin locking to minimize wasted CPU time // while we wait for other threads reach a safepoint. // This is particularly important when run under rr. - uv_mutex_lock(&safepoint_lock); - if (!jl_atomic_load_relaxed(&ptls2->gc_state)) - uv_cond_wait(&safepoint_cond_begin, &safepoint_lock); - uv_mutex_unlock(&safepoint_lock); + if (jl_options.timeout_for_safepoint_straggler_s == -1) { // timeout was not specified: no need to dump the backtrace + uv_mutex_lock(&safepoint_lock); + if (!jl_atomic_load_relaxed(&ptls2->gc_state)) { + uv_cond_wait(&safepoint_cond_begin, &safepoint_lock); + } + uv_mutex_unlock(&safepoint_lock); + } + else { + const int64_t timeout = jl_options.timeout_for_safepoint_straggler_s * 1000000000; // convert to nanoseconds + int ret = 0; + uv_mutex_lock(&safepoint_lock); + if (!jl_atomic_load_relaxed(&ptls2->gc_state)) { + ret = uv_cond_timedwait(&safepoint_cond_begin, &safepoint_lock, timeout); + } + uv_mutex_unlock(&safepoint_lock); + // If we woke up because of a timeout, print the backtrace of the straggler + if (ret == UV_ETIMEDOUT) { + jl_safe_printf("===== Thread %d failed to reach safepoint after %d seconds, printing backtrace below =====\n", ptls2->tid + 1, jl_options.timeout_for_safepoint_straggler_s); + // Try to record the backtrace of the straggler using `jl_try_record_thread_backtrace` + jl_ptls_t ptls = jl_current_task->ptls; + size_t bt_size = jl_try_record_thread_backtrace(ptls2, ptls->bt_data, JL_MAX_BT_SIZE); + // Print the backtrace of the straggler + for (size_t i = 0; i < bt_size; i += jl_bt_entry_size(ptls->bt_data + i)) { + jl_print_bt_entry_codeloc(ptls->bt_data + i); + } + } + } } } } diff --git a/src/stackwalk.c b/src/stackwalk.c index f1d807908cf42..14dc5709671dc 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -1260,6 +1260,25 @@ static void suspend(void *ctx) suspenddata->success = jl_thread_suspend_and_get_state(suspenddata->old, 1, suspenddata->c); } +JL_DLLEXPORT size_t jl_try_record_thread_backtrace(jl_ptls_t ptls2, jl_bt_element_t *bt_data, size_t max_bt_size) JL_NOTSAFEPOINT +{ + int16_t tid = ptls2->tid; + jl_task_t *t = NULL; + bt_context_t *context = NULL; + bt_context_t c; + suspend_t suspenddata = {tid, &c}; + jl_with_stackwalk_lock(suspend, &suspenddata); + if (!suspenddata.success) { + return 0; + } + // thread is stopped, safe to read the task it was running before we stopped it + t = jl_atomic_load_relaxed(&ptls2->current_task); + context = &c; + size_t bt_size = rec_backtrace_ctx(bt_data, max_bt_size, context, ptls2->previous_task ? NULL : t->gcstack); + jl_thread_resume(tid); + return bt_size; +} + JL_DLLEXPORT jl_record_backtrace_result_t jl_record_backtrace(jl_task_t *t, jl_bt_element_t *bt_data, size_t max_bt_size, int all_tasks_profiler) JL_NOTSAFEPOINT { int16_t tid = INT16_MAX; diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 74f953250cd37..3ff7836223b84 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -1238,3 +1238,9 @@ end @test parse(UInt64,read(`$exename --heap-size-hint=$str -E "Base.JLOptions().heap_size_hint"`, String)) == val end end + +@testset "--timeout-for-safepoint-straggler" begin + exename = `$(Base.julia_cmd())` + timeout = 120 + @test parse(Int,read(`$exename --timeout-for-safepoint-straggler=$timeout -E "Base.JLOptions().timeout_for_safepoint_straggler_s"`, String)) == timeout +end diff --git a/test/threads_exec.jl b/test/threads_exec.jl index d77cf06905f44..65e5ef57c911b 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -1536,4 +1536,29 @@ end end end +@testset "--timeout-for-safepoint-straggler command-line flag" begin + program = " + function main() + t = Threads.@spawn begin + ccall(:uv_sleep, Cvoid, (Cuint,), 5000) + end + # Force a GC + ccall(:uv_sleep, Cvoid, (Cuint,), 1000) + GC.gc() + wait(t) + end + main() + " + tmp_output_filename = tempname() + tmp_output_file = open(tmp_output_filename, "w") + if isnothing(tmp_output_file) + error("Failed to open file $tmp_output_filename") + end + run(pipeline(`$(Base.julia_cmd()) --threads=4 --timeout-for-safepoint-straggler=1 -e $program`, stderr=tmp_output_file)) + # Check whether we printed the straggler's backtrace + @test !isempty(read(tmp_output_filename, String)) + close(tmp_output_file) + rm(tmp_output_filename) +end + end # main testset From 1262bf8484f2d70226dd2345fd77475ff3d71c94 Mon Sep 17 00:00:00 2001 From: Eduardo Souza Date: Sat, 18 Jan 2025 15:57:49 +1100 Subject: [PATCH 39/65] Building Julia with MMTk using BinaryBuilder (#56989) Adding `mmtk-julia` as a BinaryBuilder dependency and using that as the default setup for building Julia with MMTk. ~NB: still have to update the version and checksum files after https://github.com/JuliaPackaging/Yggdrasil/pull/10288 gets merged.~ --- Make.inc | 2 +- Makefile | 4 ++++ deps/checksums/mmtk_julia | 4 +++- deps/mmtk_julia.mk | 8 ++++++++ deps/mmtk_julia.version | 2 ++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Make.inc b/Make.inc index 26b5ae7752555..16e238c6f0683 100644 --- a/Make.inc +++ b/Make.inc @@ -1402,7 +1402,7 @@ CSL_NEXT_GLIBCXX_VERSION=GLIBCXX_3\.4\.34|GLIBCXX_3\.5\.|GLIBCXX_4\. # Note: we explicitly _do not_ define `CSL` here, since it requires some more # advanced techniques to decide whether it should be installed from a BB source # or not. See `deps/csl.mk` for more detail. -BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP LLD LIBTRACYCLIENT BOLT +BB_PROJECTS := BLASTRAMPOLINE OPENBLAS LLVM LIBSUITESPARSE OPENLIBM GMP OPENSSL LIBSSH2 NGHTTP2 MPFR CURL LIBGIT2 PCRE LIBUV LIBUNWIND DSFMT OBJCONV ZLIB P7ZIP LLD LIBTRACYCLIENT BOLT MMTK_JULIA define SET_BB_DEFAULT # First, check to see if BB is disabled on a global setting ifeq ($$(USE_BINARYBUILDER),0) diff --git a/Makefile b/Makefile index 20d131ee8524c..b193b3849c6aa 100644 --- a/Makefile +++ b/Makefile @@ -281,6 +281,10 @@ endif endif endif +ifneq (${MMTK_PLAN},None) +JL_PRIVATE_LIBS-0 += libmmtk_julia +endif + # Note that we disable MSYS2's path munging here, as otherwise # it replaces our `:`-separated list as a `;`-separated one. define stringreplace diff --git a/deps/checksums/mmtk_julia b/deps/checksums/mmtk_julia index 49b7a50a8e136..979ab79e52207 100644 --- a/deps/checksums/mmtk_julia +++ b/deps/checksums/mmtk_julia @@ -1,4 +1,6 @@ mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/md5/1911cf084d26c48e2ed58af3d268b4b6 mmtk_julia-b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214.tar.gz/sha512/75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/md5/38afb5db6d8c55413a4ec96aefa2ebb4 -mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/sha512/78525582a46a6baf8d33df7b622e55cf244439afcd7192ba55489c1bc18393d1237d2903d517c610484bf9e2a7338ad31435a9cbf70889d6bcf87c40cec829e5 \ No newline at end of file +mmtk_julia-f07d66aafc86af84ea988b35335acc9bbc770fa1.tar.gz/sha512/78525582a46a6baf8d33df7b622e55cf244439afcd7192ba55489c1bc18393d1237d2903d517c610484bf9e2a7338ad31435a9cbf70889d6bcf87c40cec829e5 +mmtk_julia.v0.30.3+1.x86_64-linux-gnu.tar.gz/md5/631b204574da7062802dac501a4b711f +mmtk_julia.v0.30.3+1.x86_64-linux-gnu.tar.gz/sha512/daaed59d08fc49621479ed638dea0aac0cba123986e486571447e8e21e9a098776ce2e87fbd92ddea276782fc44621f23d40fa213296b28e1d4480553c7de4f7 diff --git a/deps/mmtk_julia.mk b/deps/mmtk_julia.mk index 7ec55426821c3..424113fd4164c 100644 --- a/deps/mmtk_julia.mk +++ b/deps/mmtk_julia.mk @@ -6,6 +6,7 @@ MMTK_MOVING := 0 MMTK_VARS := MMTK_PLAN=$(MMTK_PLAN) MMTK_MOVING=$(MMTK_MOVING) +ifneq ($(USE_BINARYBUILDER_MMTK_JULIA),1) $(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR))) get-mmtk_julia: $(MMTK_JULIA_SRC_FILE) @@ -70,3 +71,10 @@ $(build_prefix)/manifest/mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so @echo $(UNINSTALL_mmtk_julia) > $@ endif # MMTK_JULIA_DIR + +else +# We are building using the BinaryBuilder version of the binding + +$(eval $(call bb-install,mmtk_julia,MMTK_JULIA,false)) + +endif # USE_BINARYBUILDER_MMTK_JULIA diff --git a/deps/mmtk_julia.version b/deps/mmtk_julia.version index 4d821bffd5b9b..cb1e8064f9825 100644 --- a/deps/mmtk_julia.version +++ b/deps/mmtk_julia.version @@ -2,3 +2,5 @@ MMTK_JULIA_BRANCH = master MMTK_JULIA_SHA1 = f07d66aafc86af84ea988b35335acc9bbc770fa1 MMTK_JULIA_GIT_URL := https://github.com/mmtk/mmtk-julia.git MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.3.tar.gz +MMTK_JULIA_JLL_VER := 0.30.3+1 +MMTK_JULIA_JLL_NAME := mmtk_julia From 17402876ec235dd66452983a39f8521f9ff62936 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 17 Jan 2025 23:33:23 -0800 Subject: [PATCH 40/65] Block thread from receiving profile signal with stackwalk lock (#57089) This is Jameson's proposed amendment to the changes made in #57035 that introduced a deadlock on FreeBSD, amusingly in service of fixing a deadlock on Linux. On Linux and (non-macOS) BSD, instead of acquiring and releasing a lock on the profiler in `jl_with_stackwalk_lock`, we're just blocking the thread from receiving the profiler's `SIGUSR2` signal at all. This should fix #57058; I don't get the deadlock locally on FreeBSD with this change, but it's AArch64 instead of x86-64 like on CI, so let's see if this also makes CI happy. If so, closes #57059. Co-authored-by: Jameson Nash --- src/signals-unix.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/signals-unix.c b/src/signals-unix.c index 91d3378068f84..788539b1f5096 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -310,23 +310,14 @@ int exc_reg_is_write_fault(uintptr_t esr) { #include #include -typedef struct { - void (*f)(void*) JL_NOTSAFEPOINT; - void *ctx; -} callback_t; -static int with_dl_iterate_phdr_lock(struct dl_phdr_info *info, size_t size, void *data) -{ - jl_lock_profile(); - callback_t *callback = (callback_t*)data; - callback->f(callback->ctx); - jl_unlock_profile(); - return 1; // only call this once -} - void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { - callback_t callback = {f, ctx}; - dl_iterate_phdr(with_dl_iterate_phdr_lock, &callback); + sigset_t sset, oset; + sigemptyset(&sset); + sigaddset(&sset, SIGUSR2); + pthread_sigmask(SIG_BLOCK, &sset, &oset); + f(ctx); + pthread_sigmask(SIG_SETMASK, &oset, NULL); } #if defined(_OS_LINUX_) && (defined(_CPU_X86_64_) || defined(_CPU_X86_)) From fa9478b5178052ef00690732fe363601182b6922 Mon Sep 17 00:00:00 2001 From: Markus Hauru Date: Sat, 18 Jan 2025 12:00:51 +0000 Subject: [PATCH 41/65] Fix regular expressions in Test tests (#57085) Several tests for Test.jl weren't really testing for much because `|` characters were taken to be or operators in the regular expressions. Co-authored-by: Chengyu Han --- stdlib/Test/test/runtests.jl | 54 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 995d2c983437c..98755590a5291 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -870,12 +870,12 @@ let msg = read(pipeline(ignorestatus(`$(Base.julia_cmd()) --startup-file=no --co end end'`), stderr=devnull), String) @test occursin(r""" - Test Summary: | Pass Fail Total Time - Foo Tests | 2 2 4 \s*\d*.\ds - Animals | 1 1 2 \s*\d*.\ds - Felines | 1 1 \s*\d*.\ds - Canines | 1 1 \s*\d*.\ds - Arrays | 1 1 2 \s*\d*.\ds + Test Summary: \| Pass Fail Total Time + Foo Tests \| 2 2 4 \s*\d*\.\ds + Animals \| 1 1 2 \s*\d*\.\ds + Felines \| 1 1 \s*\d*\.\ds + Canines \| 1 1 \s*\d*\.\ds + Arrays \| 1 1 2 \s*\d*\.\ds """, msg) end @@ -1253,17 +1253,17 @@ end @testset "verbose option" begin expected = r""" - Test Summary: | Pass Total Time - Parent | 9 9 \s*\d*.\ds - Child 1 | 3 3 \s*\d*.\ds - Child 1.1 (long name) | 1 1 \s*\d*.\ds - Child 1.2 | 1 1 \s*\d*.\ds - Child 1.3 | 1 1 \s*\d*.\ds - Child 2 | 3 3 \s*\d*.\ds - Child 3 | 3 3 \s*\d*.\ds - Child 3.1 | 1 1 \s*\d*.\ds - Child 3.2 | 1 1 \s*\d*.\ds - Child 3.3 | 1 1 \s*\d*.\ds + Test Summary: \| Pass Total Time + Parent \| 9 9 \s*\d*\.\ds + Child 1 \| 3 3 \s*\d*\.\ds + Child 1\.1 \(long name\) \| 1 1 \s*\d*\.\ds + Child 1\.2 \| 1 1 \s*\d*\.\ds + Child 1\.3 \| 1 1 \s*\d*\.\ds + Child 2 \| 3 3 \s*\d*\.\ds + Child 3 \| 3 3 \s*\d*\.\ds + Child 3\.1 \| 1 1 \s*\d*\.\ds + Child 3\.2 \| 1 1 \s*\d*\.\ds + Child 3\.3 \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ @@ -1324,9 +1324,9 @@ end @testset "failfast option" begin @testset "non failfast (default)" begin expected = r""" - Test Summary: | Pass Fail Error Total Time - Foo | 1 2 1 4 \s*\d*.\ds - Bar | 1 1 2 \s*\d*.\ds + Test Summary: \| Pass Fail Error Total Time + Foo \| 1 2 1 4 \s*\d*\.\ds + Bar \| 1 1 2 \s*\d*\.\ds """ mktemp() do f, _ @@ -1350,8 +1350,8 @@ end end @testset "failfast" begin expected = r""" - Test Summary: | Fail Total Time - Foo | 1 1 \s*\d*.\ds + Test Summary: \| Fail Total Time + Foo \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ @@ -1375,9 +1375,9 @@ end end @testset "failfast passes to child testsets" begin expected = r""" - Test Summary: | Fail Total Time - PackageName | 1 1 \s*\d*.\ds - 1 | 1 1 \s*\d*.\ds + Test Summary: \| Fail Total Time + Foo \| 1 1 \s*\d*\.\ds + 1 \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ @@ -1401,8 +1401,8 @@ end end @testset "failfast via env var" begin expected = r""" - Test Summary: | Fail Total Time - Foo | 1 1 \s*\d*.\ds + Test Summary: \| Fail Total Time + Foo \| 1 1 \s*\d*\.\ds """ mktemp() do f, _ From cbc47c9fb852773e379cce062d6bd2aec743a7cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= <765740+giordano@users.noreply.github.com> Date: Sun, 19 Jan 2025 00:10:33 +0100 Subject: [PATCH 42/65] [Test] Improve regex matching expected test summaries (#57096) Allow for more spaces between the "Total" and "Time" columns, in case tests take occasionally longer than usual. Fix #57095. --- stdlib/Test/test/runtests.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 98755590a5291..02523dc6fd911 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -870,7 +870,7 @@ let msg = read(pipeline(ignorestatus(`$(Base.julia_cmd()) --startup-file=no --co end end'`), stderr=devnull), String) @test occursin(r""" - Test Summary: \| Pass Fail Total Time + Test Summary: \| Pass Fail Total +Time Foo Tests \| 2 2 4 \s*\d*\.\ds Animals \| 1 1 2 \s*\d*\.\ds Felines \| 1 1 \s*\d*\.\ds @@ -1253,7 +1253,7 @@ end @testset "verbose option" begin expected = r""" - Test Summary: \| Pass Total Time + Test Summary: \| Pass Total +Time Parent \| 9 9 \s*\d*\.\ds Child 1 \| 3 3 \s*\d*\.\ds Child 1\.1 \(long name\) \| 1 1 \s*\d*\.\ds @@ -1324,7 +1324,7 @@ end @testset "failfast option" begin @testset "non failfast (default)" begin expected = r""" - Test Summary: \| Pass Fail Error Total Time + Test Summary: \| Pass Fail Error Total +Time Foo \| 1 2 1 4 \s*\d*\.\ds Bar \| 1 1 2 \s*\d*\.\ds """ @@ -1350,7 +1350,7 @@ end end @testset "failfast" begin expected = r""" - Test Summary: \| Fail Total Time + Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds """ @@ -1375,7 +1375,7 @@ end end @testset "failfast passes to child testsets" begin expected = r""" - Test Summary: \| Fail Total Time + Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds 1 \| 1 1 \s*\d*\.\ds """ @@ -1401,7 +1401,7 @@ end end @testset "failfast via env var" begin expected = r""" - Test Summary: \| Fail Total Time + Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds """ @@ -1712,7 +1712,7 @@ end # this tests both the `TestCounts` parts as well as the fallback `x`s expected = r""" - Test Summary: \| Pass Fail Error Broken Total Time + Test Summary: \| Pass Fail Error Broken Total +Time outer \| 3 1 1 1 6 \s*\d*.\ds a \| 1 1 \s*\d*.\ds custom \| 1 1 1 1 4 \s*\?s From 2ca125f6f3d4e49d1ae0db762270edc1b4875bb0 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 20 Jan 2025 10:26:49 +0900 Subject: [PATCH 43/65] docs: show binding name for `No documentation found for ...` message (#57093) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Making it more informative. E.g., the difference for `help?> Base._wait` is: ```diff diff --git a/old b/new index 87f9b2d43a..5fb065658a 100644 --- a/old +++ b/new @@ -5,7 +5,7 @@ │ │ • `Base._wait` - No documentation found for private symbol. + No documentation found for private binding `Base._wait`. `Base._wait` is a `Function`. ``` --- stdlib/REPL/src/docview.jl | 5 +++-- test/docs.jl | 40 ++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 0868d3e80c824..e0710d89a67e2 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -301,10 +301,11 @@ function summarize(binding::Binding, sig) if defined(binding) binding_res = resolve(binding) if !isa(binding_res, Module) + varstr = "$(binding.mod).$(binding.var)" if Base.ispublic(binding.mod, binding.var) - println(io, "No documentation found for public symbol.\n") + println(io, "No documentation found for public binding `$varstr`.\n") else - println(io, "No documentation found for private symbol.\n") + println(io, "No documentation found for private binding `$varstr`.\n") end end summarize(io, binding_res, binding) diff --git a/test/docs.jl b/test/docs.jl index 8cfdbba3f2d97..0fff85e90cb59 100644 --- a/test/docs.jl +++ b/test/docs.jl @@ -684,9 +684,11 @@ end @doc "This should document @m1... since its the result of expansion" @m2_11993 @test (@doc @m1_11993) !== nothing let d = (@doc :@m2_11993), - macro_doc = Markdown.parse("`$(curmod_prefix == "Main." ? "" : curmod_prefix)@m2_11993` is a macro.") + varstr = "$(curmod_prefix == "Main." ? "" : curmod_prefix)@m2_11993" + docstr = Markdown.Code("", "$curmod_prefix@m2_11993") + macro_doc = Markdown.parse("`$varstr` is a macro.") @test docstring_startswith(d, doc""" - No documentation found for private symbol. + No documentation found for private binding $docstr. $macro_doc""") end @@ -901,7 +903,7 @@ Binding `$(curmod_prefix)Undocumented.bindingdoesnotexist` does not exist. @test docstrings_equal(@doc(Undocumented.bindingdoesnotexist), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for public symbol. +No documentation found for public binding `$(curmod_prefix)Undocumented.A`. # Summary ``` @@ -917,7 +919,7 @@ $(curmod_prefix)Undocumented.C @test docstrings_equal(@doc(Undocumented.A), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for public symbol. +No documentation found for public binding `$(curmod_prefix)Undocumented.B`. # Summary ``` @@ -937,7 +939,7 @@ $(curmod_prefix)Undocumented.B <: $(curmod_prefix)Undocumented.A <: Any @test docstrings_equal(@doc(Undocumented.B), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for public symbol. +No documentation found for public binding `$(curmod_prefix)Undocumented.C`. # Summary ``` @@ -952,7 +954,7 @@ $(curmod_prefix)Undocumented.C <: $(curmod_prefix)Undocumented.A <: Any @test docstrings_equal(@doc(Undocumented.C), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.D`. # Summary ``` @@ -974,7 +976,7 @@ $(curmod_prefix)Undocumented.D <: $(curmod_prefix)Undocumented.B <: $(curmod_pre @test docstrings_equal(@doc(Undocumented.D), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for public symbol. +No documentation found for public binding `$(curmod_prefix)Undocumented.at0`. # Summary @@ -994,7 +996,7 @@ $(curmod_prefix)Undocumented.st4{T<:Number, N} @test docstrings_equal(@doc(Undocumented.at0), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.at1`. # Summary @@ -1017,7 +1019,7 @@ $(curmod_prefix)Undocumented.at1{T>:Integer, N} <: $(curmod_prefix)Undocumented. @test docstrings_equal(@doc(Undocumented.at1), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.at_`. # Summary @@ -1036,7 +1038,7 @@ $(curmod_prefix)Undocumented.st4{Int64, N} @test docstrings_equal(@doc(Undocumented.at_), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for public symbol. +No documentation found for public binding `$(curmod_prefix)Undocumented.pt2`. # Summary @@ -1053,7 +1055,7 @@ $(curmod_prefix)Undocumented.pt2{T<:Number, N, A>:Integer} <: $(curmod_prefix)Un @test docstrings_equal(@doc(Undocumented.pt2), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.st3`. # Summary @@ -1076,7 +1078,7 @@ $(curmod_prefix)Undocumented.st3{T<:Integer, N} <: $(curmod_prefix)Undocumented. @test docstrings_equal(@doc(Undocumented.st3), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.st4`. # Summary @@ -1098,7 +1100,7 @@ $(curmod_prefix)Undocumented.st4{T, N} <: $(curmod_prefix)Undocumented.at0{T, N} @test docstrings_equal(@doc(Undocumented.st4), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.st5`. # Summary @@ -1119,7 +1121,7 @@ $(curmod_prefix)Undocumented.st5{T>:Int64, N} <: $(curmod_prefix)Undocumented.at @test docstrings_equal(@doc(Undocumented.st5), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.mt6`. # Summary @@ -1140,7 +1142,7 @@ $(curmod_prefix)Undocumented.mt6{T<:Integer, N} <: $(curmod_prefix)Undocumented. @test docstrings_equal(@doc(Undocumented.mt6), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.ut7`. # Summary @@ -1154,7 +1156,7 @@ No documentation found for private symbol. @test docstrings_equal(@doc(Undocumented.ut7), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.ut8`. # Summary @@ -1170,7 +1172,7 @@ No documentation found for private symbol. @test docstrings_equal(@doc(Undocumented.ut8), doc"$doc_str") doc_str = Markdown.parse(""" -No documentation found for private symbol. +No documentation found for private binding `$(curmod_prefix)Undocumented.ut9`. # Summary @@ -1189,7 +1191,7 @@ let d = @doc(Undocumented.f) io = IOBuffer() show(io, MIME"text/markdown"(), d) @test startswith(String(take!(io)),""" - No documentation found for private symbol. + No documentation found for private binding `$(curmod_prefix)Undocumented.f`. `$(curmod_prefix)Undocumented.f` is a `Function`. """) @@ -1199,7 +1201,7 @@ let d = @doc(Undocumented.undocumented) io = IOBuffer() show(io, MIME"text/markdown"(), d) @test startswith(String(take!(io)), """ - No documentation found for private symbol. + No documentation found for private binding `$(curmod_prefix)Undocumented.undocumented`. `$(curmod_prefix)Undocumented.undocumented` is a `Function`. """) From 755d7ece07d78f681c8d3cb07be489bb7104c847 Mon Sep 17 00:00:00 2001 From: DilumAluthgeBot <43731525+DilumAluthgeBot@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:10:10 -0500 Subject: [PATCH 44/65] =?UTF-8?q?=F0=9F=A4=96=20[master]=20Bump=20the=20SH?= =?UTF-8?q?A=20stdlib=20from=208fa221d=20to=204451e13=20(#57110)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/md5 | 1 + .../SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/sha512 | 1 + .../SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 | 1 - .../SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 | 1 - stdlib/SHA.version | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/md5 create mode 100644 deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/sha512 delete mode 100644 deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 delete mode 100644 deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 diff --git a/deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/md5 b/deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/md5 new file mode 100644 index 0000000000000..cbd2acb2c6f66 --- /dev/null +++ b/deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/md5 @@ -0,0 +1 @@ +7b511b7dab411685206d0d90cc1fb56e diff --git a/deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/sha512 b/deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/sha512 new file mode 100644 index 0000000000000..5201bbdcc40f9 --- /dev/null +++ b/deps/checksums/SHA-4451e1362e425bcbc1652ecf55fc0e525b18fb63.tar.gz/sha512 @@ -0,0 +1 @@ +960367406d80e46e8e742bcb0f7f0e4b089b664c2321ca82953eb760b325693ae57f431d891ccf56c3ab9146bc29682d2d1767bc635f4dbe6dd4d80030a42487 diff --git a/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 b/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 deleted file mode 100644 index 52e05f5e427ae..0000000000000 --- a/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -e52615827242aae56422a4f73a8c6878 diff --git a/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 b/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 deleted file mode 100644 index e6b8446587554..0000000000000 --- a/deps/checksums/SHA-8fa221ddc8f3b418d9929084f1644f4c32c9a27e.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -7b1df257616aaa9067f822a88dddf52bc10f9f61e3a0728e33e595455bd7167e680c50371c41cb25f8c8a9fb9cf40225847df1523a6c6f3571a471f7163f563c diff --git a/stdlib/SHA.version b/stdlib/SHA.version index 4b33964a6dcdb..a5d4372d5798b 100644 --- a/stdlib/SHA.version +++ b/stdlib/SHA.version @@ -1,4 +1,4 @@ SHA_BRANCH = master -SHA_SHA1 = 8fa221ddc8f3b418d9929084f1644f4c32c9a27e +SHA_SHA1 = 4451e1362e425bcbc1652ecf55fc0e525b18fb63 SHA_GIT_URL := https://github.com/JuliaCrypto/SHA.jl.git SHA_TAR_URL = https://api.github.com/repos/JuliaCrypto/SHA.jl/tarball/$1 From 2e6ffbccab206d5b3963f4396ba0d541cc2394d1 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 20 Jan 2025 21:23:42 -0500 Subject: [PATCH 45/65] Capture/silence some noisy test warnings (#57111) --- Compiler/test/codegen.jl | 2 +- test/ambiguous.jl | 2 +- test/boundscheck_exec.jl | 7 +++---- test/channel_threadpool.jl | 16 +++++++--------- test/spawn.jl | 2 +- test/syntax.jl | 3 ++- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Compiler/test/codegen.jl b/Compiler/test/codegen.jl index 9b92f560c64fc..ff61ac719c59e 100644 --- a/Compiler/test/codegen.jl +++ b/Compiler/test/codegen.jl @@ -1031,7 +1031,7 @@ end # Make sure that code that has unbound sparams works #https://github.com/JuliaLang/julia/issues/56739 -f56739(a) where {T} = a +@test_warn r"declares type variable T but does not use it" @eval f56739(a) where {T} = a @test f56739(1) == 1 g56739(x) = @noinline f56739(x) diff --git a/test/ambiguous.jl b/test/ambiguous.jl index 43ec1aab0557d..5f859e773f5d2 100644 --- a/test/ambiguous.jl +++ b/test/ambiguous.jl @@ -97,7 +97,7 @@ ambig(x::Union{Char, Int16}) = 's' # Automatic detection of ambiguities -const allowed_undefineds = Set([]) +const allowed_undefineds = Set([GlobalRef(Base, :active_repl)]) let Distributed = get(Base.loaded_modules, Base.PkgId(Base.UUID("8ba89e20-285c-5b6f-9357-94700520ee1b"), "Distributed"), diff --git a/test/boundscheck_exec.jl b/test/boundscheck_exec.jl index 85df1d64017b4..3b2f853999229 100644 --- a/test/boundscheck_exec.jl +++ b/test/boundscheck_exec.jl @@ -298,7 +298,7 @@ end end |> only === Type{Int} if bc_opt == bc_default -@testset "Array/Memory escape analysis" begin + # Array/Memory escape analysis function no_allocate(T::Type{<:Union{Memory, Vector}}) v = T(undef, 2) v[1] = 2 @@ -308,8 +308,8 @@ if bc_opt == bc_default function test_alloc(::Type{T}; broken=false) where T @test (@allocated no_allocate(T)) == 0 broken=broken end - @testset "$T" for T in [Memory, Vector] - @testset "$ET" for ET in [Int, Float32, Union{Int, Float64}] + for T in [Memory, Vector] + for ET in [Int, Float32, Union{Int, Float64}] no_allocate(T{ET}) #compile # allocations aren't removed for Union eltypes which they theoretically could be eventually test_alloc(T{ET}, broken=(ET==Union{Int, Float64})) @@ -345,6 +345,5 @@ if bc_opt == bc_default no_alias_prove(1) @test_broken (@allocated no_alias_prove(5)) == 0 end -end end diff --git a/test/channel_threadpool.jl b/test/channel_threadpool.jl index 4509604087fa8..54c2fc0f83e09 100644 --- a/test/channel_threadpool.jl +++ b/test/channel_threadpool.jl @@ -3,12 +3,10 @@ using Test using Base.Threads -@testset "Task threadpools" begin - c = Channel{Symbol}() do c; put!(c, threadpool(current_task())); end - @test take!(c) === threadpool(current_task()) - c = Channel{Symbol}(spawn = true) do c; put!(c, threadpool(current_task())); end - @test take!(c) === :default - c = Channel{Symbol}(threadpool = :interactive) do c; put!(c, threadpool(current_task())); end - @test take!(c) === :interactive - @test_throws ArgumentError Channel{Symbol}(threadpool = :foo) do c; put!(c, :foo); end -end +c = Channel{Symbol}() do c; put!(c, threadpool(current_task())); end +@test take!(c) === threadpool(current_task()) +c = Channel{Symbol}(spawn = true) do c; put!(c, threadpool(current_task())); end +@test take!(c) === :default +c = Channel{Symbol}(threadpool = :interactive) do c; put!(c, threadpool(current_task())); end +@test take!(c) === :interactive +@test_throws ArgumentError Channel{Symbol}(threadpool = :foo) do c; put!(c, :foo); end diff --git a/test/spawn.jl b/test/spawn.jl index c1802ba1f74da..0356cf9871424 100644 --- a/test/spawn.jl +++ b/test/spawn.jl @@ -78,7 +78,7 @@ out = read(`$echocmd hello` & `$echocmd world`, String) @test occursin("hello", out) @test read(pipeline(`$echocmd hello` & `$echocmd world`, sortcmd), String) == "hello\nworld\n" -@test (run(`$printfcmd " \033[34m[stdio passthrough ok]\033[0m\n"`); true) +@test_warn r"[stdio passthrough ok]" run(pipeline(`$printfcmd " \033[34m[stdio passthrough ok]\033[0m\n"`, stdout=stderr, stderr=stderr)) # Test for SIGPIPE being a failure condition @test_throws ProcessFailedException run(pipeline(yescmd, `head`, devnull)) diff --git a/test/syntax.jl b/test/syntax.jl index 9fd0204821eab..bdf9579b134eb 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3971,11 +3971,12 @@ end # Module Replacement module ReplacementContainer + using Test module ReplaceMe const x = 1 end const Old = ReplaceMe - module ReplaceMe + @test_warn r"WARNING: replacing module ReplaceMe" @eval module ReplaceMe const x = 2 end end From 90d346f9b9760584d94a3f16a76f56acb45cdf01 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:15:44 +0900 Subject: [PATCH 46/65] fix `help?> StructType.field` command (#57107) `help?> StructType.field` currently errors when `StructType` doesn't have any field documentation at all. This commit adds a proper guard against such cases. --- stdlib/REPL/src/docview.jl | 18 +++++++++++------- stdlib/REPL/test/docview.jl | 3 +++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index e0710d89a67e2..313994505b3ee 100644 --- a/stdlib/REPL/src/docview.jl +++ b/stdlib/REPL/src/docview.jl @@ -662,13 +662,17 @@ function fielddoc(binding::Binding, field::Symbol) for mod in modules dict = meta(mod; autoinit=false) isnothing(dict) && continue - if haskey(dict, binding) - multidoc = dict[binding] - if haskey(multidoc.docs, Union{}) - fields = multidoc.docs[Union{}].data[:fields] - if haskey(fields, field) - doc = fields[field] - return isa(doc, Markdown.MD) ? doc : Markdown.parse(doc) + multidoc = get(dict, binding, nothing) + if multidoc !== nothing + structdoc = get(multidoc.docs, Union{}, nothing) + if structdoc !== nothing + fieldsdoc = get(structdoc.data, :fields, nothing) + if fieldsdoc !== nothing + fielddoc = get(fieldsdoc, field, nothing) + if fielddoc !== nothing + return isa(fielddoc, Markdown.MD) ? + fielddoc : Markdown.parse(fielddoc) + end end end end diff --git a/stdlib/REPL/test/docview.jl b/stdlib/REPL/test/docview.jl index 02f1dc8238f04..c81715ad69921 100644 --- a/stdlib/REPL/test/docview.jl +++ b/stdlib/REPL/test/docview.jl @@ -92,6 +92,9 @@ end @test endswith(get_help_standard("StructWithOneField.not_a_field"), "StructWithOneField` has field `field1`.\n") @test endswith(get_help_standard("StructWithTwoFields.not_a_field"), "StructWithTwoFields` has fields `field1`, and `field2`.\n") @test endswith(get_help_standard("StructWithThreeFields.not_a_field"), "StructWithThreeFields` has fields `field1`, `field2`, and `field3`.\n") + + # Shouldn't error if the struct doesn't have any field documentations at all. + @test endswith(get_help_standard("Int.not_a_field"), "`$Int` has no fields.\n") end module InternalWarningsTests From ff5f66c655277636e7e27a7927611af2805d4a2e Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 21 Jan 2025 10:01:35 -0500 Subject: [PATCH 47/65] codegen: export all ABIs that we refer to in codegen (#57083) Since codegen may refer to these, it helps to have the linker able to resolve them, if that case ever happens. Fixes #56701 --- src/gf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gf.c b/src/gf.c index ba28edfbeeff7..ea25ed2eae4ff 100644 --- a/src/gf.c +++ b/src/gf.c @@ -3034,19 +3034,19 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t return codeinst; } -jl_value_t *jl_fptr_const_return(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m) +JL_DLLEXPORT jl_value_t *jl_fptr_const_return(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m) { return m->rettype_const; } -jl_value_t *jl_fptr_args(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m) +JL_DLLEXPORT jl_value_t *jl_fptr_args(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m) { jl_fptr_args_t invoke = jl_atomic_load_relaxed(&m->specptr.fptr1); assert(invoke && "Forgot to set specptr for jl_fptr_args!"); return invoke(f, args, nargs); } -jl_value_t *jl_fptr_sparam(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m) +JL_DLLEXPORT jl_value_t *jl_fptr_sparam(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *m) { jl_svec_t *sparams = jl_get_ci_mi(m)->sparam_vals; assert(sparams != jl_emptysvec); From 7a1a6f32ec89745844b93cfabe2fe48fcac03ded Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 21 Jan 2025 10:03:00 -0500 Subject: [PATCH 48/65] codegen: use correct rettype ABI for aotcompile (#57082) This only really can differ in aotcompile, so it was hard to notice that that the attempted code simplification in db25494f62 wasn't correct and could lead to ABI mismatches at runtime. Fixes #57018 --- src/aotcompile.cpp | 2 +- src/codegen.cpp | 17 ++++++++--------- src/jitlayers.h | 3 ++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 0235758979cd1..5524518da46fa 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -2223,7 +2223,7 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_ output.imaging_mode = jl_options.image_codegen; output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); JL_GC_PUSH1(&output.temporary_roots); - auto decls = jl_emit_code(m, mi, src, NULL, output); + auto decls = jl_emit_code(m, mi, src, mi->specTypes, src->rettype, output); output.temporary_roots = nullptr; JL_GC_POP(); // GC the global_targets array contents now since reflection doesn't need it diff --git a/src/codegen.cpp b/src/codegen.cpp index eefc675bdd665..7cfcc52db29c7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4381,7 +4381,7 @@ static jl_llvm_functions_t jl_method_instance_t *lam, jl_code_info_t *src, jl_value_t *abi, - jl_value_t *rettype, + jl_value_t *jlrettype, jl_codegen_params_t ¶ms); static void emit_hasnofield_error_ifnot(jl_codectx_t &ctx, Value *ok, jl_datatype_t *type, jl_cgval_t name); @@ -5533,12 +5533,12 @@ static jl_value_t *get_ci_abi(jl_code_instance_t *ci) return jl_get_ci_mi(ci)->specTypes; } -static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_code_instance_t *ci, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, +static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_code_instance_t *ci, StringRef specFunctionObject, jl_code_instance_t *fromexternal, ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *return_roots, jl_value_t *inferred_retty, Value *age_ok) { jl_method_instance_t *mi = jl_get_ci_mi(ci); bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; - return emit_call_specfun_other(ctx, is_opaque_closure, get_ci_abi(ci), jlretty, NULL, + return emit_call_specfun_other(ctx, is_opaque_closure, get_ci_abi(ci), ci->rettype, NULL, specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty, age_ok); } @@ -5688,7 +5688,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; unsigned return_roots = 0; if (specsig) - result = emit_call_specfun_other(ctx, codeinst, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); + result = emit_call_specfun_other(ctx, codeinst, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok); else result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok); if (need_to_emit) { @@ -10029,7 +10029,8 @@ jl_llvm_functions_t jl_emit_code( orc::ThreadSafeModule &m, jl_method_instance_t *li, jl_code_info_t *src, - jl_value_t *abi, + jl_value_t *abi_at, + jl_value_t *abi_rt, jl_codegen_params_t ¶ms) { JL_TIMING(CODEGEN, CODEGEN_LLVM); @@ -10038,10 +10039,8 @@ jl_llvm_functions_t jl_emit_code( assert((params.params == &jl_default_cgparams /* fast path */ || !params.cache || compare_cgparams(params.params, &jl_default_cgparams)) && "functions compiled with custom codegen params must not be cached"); - if (!abi) - abi = li->specTypes; JL_TRY { - decls = emit_function(m, li, src, abi, src->rettype, params); + decls = emit_function(m, li, src, abi_at, abi_rt, params); auto stream = *jl_ExecutionEngine->get_dump_emitted_mi_name_stream(); if (stream) { jl_printf(stream, "%s\t", decls.specFunctionObject.c_str()); @@ -10112,7 +10111,7 @@ jl_llvm_functions_t jl_emit_codeinst( return jl_llvm_functions_t(); // user error } //assert(jl_egal((jl_value_t*)jl_atomic_load_relaxed(&codeinst->debuginfo), (jl_value_t*)src->debuginfo) && "trying to generate code for a codeinst for an incompatible src"); - jl_llvm_functions_t decls = jl_emit_code(m, jl_get_ci_mi(codeinst), src, get_ci_abi(codeinst), params); + jl_llvm_functions_t decls = jl_emit_code(m, jl_get_ci_mi(codeinst), src, get_ci_abi(codeinst), codeinst->rettype, params); return decls; } diff --git a/src/jitlayers.h b/src/jitlayers.h index 7198c9b2f0210..4637670ec588c 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -278,7 +278,8 @@ jl_llvm_functions_t jl_emit_code( orc::ThreadSafeModule &M, jl_method_instance_t *mi, jl_code_info_t *src, - jl_value_t *abi, + jl_value_t *abi_at, + jl_value_t *abi_rt, jl_codegen_params_t ¶ms); jl_llvm_functions_t jl_emit_codeinst( From 4e13e0e449aee71a5ad7f335fbc8812d28c51cf2 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 21 Jan 2025 10:04:45 -0500 Subject: [PATCH 49/65] inference: fix lattice for unusual InterConditional return and Const Bool representations (#57080) Fixes #54886 Rule introduced by 55cee67 --- Compiler/src/abstractinterpretation.jl | 11 ++++++++++- Compiler/src/typelattice.jl | 7 +++++++ Compiler/test/inference.jl | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 59510dbfbb65a..a6c75ed411082 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -3785,7 +3785,7 @@ function update_bestguess!(interp::AbstractInterpreter, frame::InferenceState, slottypes = frame.slottypes rt = widenreturn(rt, BestguessInfo(interp, bestguess, nargs, slottypes, currstate)) # narrow representation of bestguess slightly to prepare for tmerge with rt - if rt isa InterConditional && bestguess isa Const + if rt isa InterConditional && bestguess isa Const && bestguess.val isa Bool slot_id = rt.slot old_id_type = widenconditional(slottypes[slot_id]) if bestguess.val === true && rt.elsetype !== Bottom @@ -3793,6 +3793,15 @@ function update_bestguess!(interp::AbstractInterpreter, frame::InferenceState, elseif bestguess.val === false && rt.thentype !== Bottom bestguess = InterConditional(slot_id, Bottom, old_id_type) end + # or narrow representation of rt slightly to prepare for tmerge with bestguess + elseif bestguess isa InterConditional && rt isa Const && rt.val isa Bool + slot_id = bestguess.slot + old_id_type = widenconditional(slottypes[slot_id]) + if rt.val === true && bestguess.elsetype !== Bottom + rt = InterConditional(slot_id, old_id_type, Bottom) + elseif rt.val === false && bestguess.thentype !== Bottom + rt = InterConditional(slot_id, Bottom, old_id_type) + end end # copy limitations to return value if !isempty(frame.pclimitations) diff --git a/Compiler/src/typelattice.jl b/Compiler/src/typelattice.jl index bd0d24167b75a..6f7612b836c89 100644 --- a/Compiler/src/typelattice.jl +++ b/Compiler/src/typelattice.jl @@ -395,6 +395,13 @@ end end a = Bool elseif isa(b, ConditionalT) + if isa(a, Const) && isa(a.val, Bool) + if (a.val === true && b.thentype === Any && b.elsetype === Bottom) || + (a.val === false && b.elsetype === Any && b.thentype === Bottom) + # this Conditional contains distinctly no lattice information, and is simply an alternative representation of the Const Bool used for internal tracking purposes + return true + end + end return false end return ⊑(widenlattice(lattice), a, b) diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index 21d29c376bb27..b74460203e66e 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -2734,6 +2734,26 @@ vacond(cnd, va...) = cnd ? va : 0 vacond(isa(x, Tuple{Int,Int}), x, x) end |> only == Union{Int,Tuple{Any,Any}} +let A = Core.Const(true) + B = Core.InterConditional(2, Tuple, Union{}) + C = Core.InterConditional(2, Any, Union{}) + L = ipo_lattice(Compiler.NativeInterpreter()) + @test !⊑(L, A, B) + @test ⊑(L, B, A) + @test tmerge(L, A, B) == C + @test ⊑(L, A, C) +end +function tail_is_ntuple((@nospecialize t::Tuple)) + if unknown + t isa Tuple + else + tail_is_ntuple(t) + end +end +tail_is_ntuple_val((@nospecialize t::Tuple)) = Val(tail_is_ntuple(t)) +@test Base.return_types(tail_is_ntuple, (Tuple,)) |> only === Bool +@test Base.return_types(tail_is_ntuple_val, (Tuple,)) |> only === Val{true} + # https://github.com/JuliaLang/julia/issues/47435 is_closed_ex(e::InvalidStateException) = true is_closed_ex(e) = false From 323ca86cb5ff614b713c3995ea11b7755b74190c Mon Sep 17 00:00:00 2001 From: Chengyu Han Date: Wed, 22 Jan 2025 00:15:50 +0800 Subject: [PATCH 50/65] base: add `Sys.detectwsl()` (#57069) Close #36425, fix #36354 ## How to detect WSL? There are a number of ways that can be used to detect WSL environments, but each can have false positives. We finally chose to use the same method as Snapd to detect WSL. Because Windows installs Ubuntu LTS as WSL by default. So we assume that Snapd's detection method will work for most users. - Ubuntu/Snapd: https://github.com/canonical/snapd/blob/03a578a5dff26467dcc80580fcd4720a486185a5/release/release.go#L151-L172 - microsoft/WSL#423 - microsoft/WSL#4071 - https://superuser.com/q/1749781/1460597 ## Known limitations - this is a runtime test, and thus cannot meaningfully be used in `@static if` constructs. - Linux users can create their own - `/proc/sys/fs/binfmt_misc/WSLInterop` file - or `/run/WSL/` folder to pretend to be a WSL environment. --- - I've tested this under: Ubuntu 22.04.5 LTS (default/Offical) and alpine-release-3.17.0 (win store) - [x] Add compat, NEWS, tests - [x] Take a look at different detect methods, figure out which one is more robust --------- Co-authored-by: Gautam Mishra Co-authored-by: Max Horn <241512+fingolfin@users.noreply.github.com> Co-authored-by: Chengyu Han Co-authored-by: Alex Arslan --- NEWS.md | 1 + base/sysinfo.jl | 24 +++++++++++++++++++++++- test/osutils.jl | 5 +++++ test/path.jl | 2 +- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6c378c8186007..71014e1e57695 100644 --- a/NEWS.md +++ b/NEWS.md @@ -97,6 +97,7 @@ New library functions * `uuid7()` creates an RFC 9652 compliant UUID with version 7 ([#54834]). * `insertdims(array; dims)` allows to insert singleton dimensions into an array which is the inverse operation to `dropdims`. ([#45793]) * The new `Fix` type is a generalization of `Fix1/Fix2` for fixing a single argument ([#54653]). +* `Sys.detectwsl()` allows to testing if Julia is running inside WSL at runtime. ([#57069]) New library features -------------------- diff --git a/base/sysinfo.jl b/base/sysinfo.jl index 7dab313cf4f57..c96c318ec053b 100644 --- a/base/sysinfo.jl +++ b/base/sysinfo.jl @@ -36,7 +36,8 @@ export BINDIR, isreadable, iswritable, username, - which + which, + detectwsl import ..Base: show @@ -532,6 +533,27 @@ including e.g. a WebAssembly JavaScript embedding in a web browser. """ isjsvm(os::Symbol) = (os === :Emscripten) +""" + Sys.detectwsl() + +Runtime predicate for testing if Julia is running inside +Windows Subsystem for Linux (WSL). + +!!! note + Unlike `Sys.iswindows`, `Sys.islinux` etc., this is a runtime test, and thus + cannot meaningfully be used in `@static if` constructs. + +!!! compat "Julia 1.12" + This function requires at least Julia 1.12. +""" +function detectwsl() + # We use the same approach as canonical/snapd do to detect WSL + islinux() && ( + isfile("/proc/sys/fs/binfmt_misc/WSLInterop") + || isdir("/run/WSL") + ) +end + for f in (:isunix, :islinux, :isbsd, :isapple, :iswindows, :isfreebsd, :isopenbsd, :isnetbsd, :isdragonfly, :isjsvm) @eval $f() = $(getfield(@__MODULE__, f)(KERNEL)) end diff --git a/test/osutils.jl b/test/osutils.jl index 5e72675279cbc..9eb708b670298 100644 --- a/test/osutils.jl +++ b/test/osutils.jl @@ -29,6 +29,11 @@ using Libdl else @test Sys.windows_version() >= v"1.0.0-" end + + # TODO: When we have a WSL CI, add a new test here `@test detectwsl()` + if !Sys.islinux() + @test !Sys.detectwsl() + end end @testset "@static" begin diff --git a/test/path.jl b/test/path.jl index 2515d765d8ca9..a2824a24c8bce 100644 --- a/test/path.jl +++ b/test/path.jl @@ -314,7 +314,7 @@ @testset "uripath" begin host = if Sys.iswindows() "" - elseif ispath("/proc/sys/fs/binfmt_misc/WSLInterop") + elseif Sys.detectwsl() distro = get(ENV, "WSL_DISTRO_NAME", "") # See "wsl%24/$distro" # See and else From eb9f24c8ceb964464939775e164366939755393c Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 21 Jan 2025 13:12:05 -0500 Subject: [PATCH 51/65] inference: ensure inferring reachable code methods (#57088) PR #51317 was a bit over-eager about inferring inferring unreachable code methods. Filter out the Vararg case, since that can be handled by simply removing it instead of discarding the whole call. Fixes #56628 --- Compiler/src/abstractinterpretation.jl | 4 ++- Compiler/src/ssair/inlining.jl | 1 + Compiler/src/tfuncs.jl | 36 ++++++++++++++------------ Compiler/src/typeutils.jl | 7 ++++- Compiler/test/inference.jl | 6 +++++ 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index a6c75ed411082..300feeae53e9a 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -368,6 +368,7 @@ function find_union_split_method_matches(interp::AbstractInterpreter, argtypes:: for i in 1:length(split_argtypes) arg_n = split_argtypes[i]::Vector{Any} sig_n = argtypes_to_type(arg_n) + sig_n === Bottom && continue mt = ccall(:jl_method_table_for, Any, (Any,), sig_n) mt === nothing && return FailedMethodMatch("Could not identify method table for call") mt = mt::MethodTable @@ -614,7 +615,7 @@ function abstract_call_method(interp::AbstractInterpreter, sigtuple = unwrap_unionall(sig) sigtuple isa DataType || return Future(MethodCallResult(Any, Any, Effects(), nothing, false, false)) - all(@nospecialize(x) -> valid_as_lattice(unwrapva(x), true), sigtuple.parameters) || + all(@nospecialize(x) -> isvarargtype(x) || valid_as_lattice(x, true), sigtuple.parameters) || return Future(MethodCallResult(Union{}, Any, EFFECTS_THROWS, nothing, false, false)) # catch bad type intersections early if is_nospecializeinfer(method) @@ -2840,6 +2841,7 @@ function abstract_call_unknown(interp::AbstractInterpreter, @nospecialize(ft), end # non-constant function, but the number of arguments is known and the `f` is not a builtin or intrinsic atype = argtypes_to_type(arginfo.argtypes) + atype === Bottom && return Future(CallMeta(Union{}, Union{}, EFFECTS_THROWS, NoCallInfo())) # accidentally unreachable return abstract_call_gf_by_type(interp, nothing, arginfo, si, atype, sv, max_methods)::Future end diff --git a/Compiler/src/ssair/inlining.jl b/Compiler/src/ssair/inlining.jl index 0c0d14bf8f25a..120b891f09a9f 100644 --- a/Compiler/src/ssair/inlining.jl +++ b/Compiler/src/ssair/inlining.jl @@ -1399,6 +1399,7 @@ function handle_call!(todo::Vector{Pair{Int,Any}}, cases === nothing && return nothing cases, handled_all_cases, fully_covered, joint_effects = cases atype = argtypes_to_type(sig.argtypes) + atype === Union{} && return nothing # accidentally actually unreachable handle_cases!(todo, ir, idx, stmt, atype, cases, handled_all_cases, fully_covered, joint_effects) end diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index cfb865b06e9e5..fe21f6381e8cd 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -3016,24 +3016,28 @@ function abstract_applicable(interp::AbstractInterpreter, argtypes::Vector{Any}, isvarargtype(argtypes[2]) && return Future(CallMeta(Bool, ArgumentError, EFFECTS_THROWS, NoCallInfo())) argtypes = argtypes[2:end] atype = argtypes_to_type(argtypes) - matches = find_method_matches(interp, argtypes, atype; max_methods) - info = NoCallInfo() - if isa(matches, FailedMethodMatch) - rt = Bool # too many matches to analyze + if atype === Union{} + rt = Union{} # accidentally unreachable code else - (; valid_worlds, applicable) = matches - update_valid_age!(sv, valid_worlds) - napplicable = length(applicable) - if napplicable == 0 - rt = Const(false) # never any matches - elseif !fully_covering(matches) || any_ambig(matches) - # Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature. - rt = Bool + matches = find_method_matches(interp, argtypes, atype; max_methods) + info = NoCallInfo() + if isa(matches, FailedMethodMatch) + rt = Bool # too many matches to analyze else - rt = Const(true) # has applicable matches - end - if rt !== Bool - info = VirtualMethodMatchInfo(matches.info) + (; valid_worlds, applicable) = matches + update_valid_age!(sv, valid_worlds) + napplicable = length(applicable) + if napplicable == 0 + rt = Const(false) # never any matches + elseif !fully_covering(matches) || any_ambig(matches) + # Account for the fact that we may encounter a MethodError with a non-covered or ambiguous signature. + rt = Bool + else + rt = Const(true) # has applicable matches + end + if rt !== Bool + info = VirtualMethodMatchInfo(matches.info) + end end end return Future(CallMeta(rt, Union{}, EFFECTS_TOTAL, info)) diff --git a/Compiler/src/typeutils.jl b/Compiler/src/typeutils.jl index 5175e00612270..d588a9aee1a6c 100644 --- a/Compiler/src/typeutils.jl +++ b/Compiler/src/typeutils.jl @@ -54,7 +54,12 @@ has_extended_info(@nospecialize x) = (!isa(x, Type) && !isvarargtype(x)) || isTy # certain combinations of `a` and `b` where one/both isa/are `Union`/`UnionAll` type(s)s. isnotbrokensubtype(@nospecialize(a), @nospecialize(b)) = (!iskindtype(b) || !isType(a) || hasuniquerep(a.parameters[1]) || b <: a) -argtypes_to_type(argtypes::Array{Any,1}) = Tuple{anymap(@nospecialize(a) -> isvarargtype(a) ? a : widenconst(a), argtypes)...} +function argtypes_to_type(argtypes::Array{Any,1}) + argtypes = anymap(@nospecialize(a) -> isvarargtype(a) ? a : widenconst(a), argtypes) + filter!(@nospecialize(x) -> !isvarargtype(x) || valid_as_lattice(unwrapva(x), true), argtypes) + all(@nospecialize(x) -> isvarargtype(x) || valid_as_lattice(x, true), argtypes) || return Bottom + return Tuple{argtypes...} +end function isknownlength(t::DataType) isvatuple(t) || return true diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index b74460203e66e..d4ea990e7d148 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -6182,3 +6182,9 @@ end <: Any end return out end == Union{Float64,DomainError} + +# issue #56628 +@test Compiler.argtypes_to_type(Any[ Int, UnitRange{Int}, Vararg{Pair{Any, Union{}}} ]) === Tuple{Int, UnitRange{Int}} +@test Compiler.argtypes_to_type(Any[ Int, UnitRange{Int}, Vararg{Pair{Any, Union{}}}, Float64 ]) === Tuple{Int, UnitRange{Int}, Float64} +@test Compiler.argtypes_to_type(Any[ Int, UnitRange{Int}, Vararg{Pair{Any, Union{}}}, Float64, Memory{2} ]) === Union{} +@test Base.return_types(Tuple{Tuple{Int, Vararg{Pair{Any, Union{}}}}},) do x; Returns(true)(x...); end |> only === Bool From cb553897e82f7bc6a51d30c1db531f54abae1a8b Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Tue, 21 Jan 2025 13:19:54 -0500 Subject: [PATCH 52/65] minor fma cleanup (#57041) This removes the redundant `fma_llvm` function, and makes it so systems with Float16 fma can actually use it rather than the Float32 fallback path. --- base/floatfuncs.jl | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/base/floatfuncs.jl b/base/floatfuncs.jl index 2c26f7cff1133..f373325770ef9 100644 --- a/base/floatfuncs.jl +++ b/base/floatfuncs.jl @@ -276,6 +276,9 @@ significantly more expensive than `x*y+z`. `fma` is used to improve accuracy in algorithms. See [`muladd`](@ref). """ function fma end +function fma_emulated(a::Float16, b::Float16, c::Float16) + Float16(muladd(Float32(a), Float32(b), Float32(c))) #don't use fma if the hardware doesn't have it. +end function fma_emulated(a::Float32, b::Float32, c::Float32)::Float32 ab = Float64(a) * b res = ab+c @@ -348,19 +351,14 @@ function fma_emulated(a::Float64, b::Float64,c::Float64) s = (abs(abhi) > abs(c)) ? (abhi-r+c+ablo) : (c-r+abhi+ablo) return r+s end -fma_llvm(x::Float32, y::Float32, z::Float32) = fma_float(x, y, z) -fma_llvm(x::Float64, y::Float64, z::Float64) = fma_float(x, y, z) # Disable LLVM's fma if it is incorrect, e.g. because LLVM falls back # onto a broken system libm; if so, use a software emulated fma -@assume_effects :consistent fma(x::Float32, y::Float32, z::Float32) = Core.Intrinsics.have_fma(Float32) ? fma_llvm(x,y,z) : fma_emulated(x,y,z) -@assume_effects :consistent fma(x::Float64, y::Float64, z::Float64) = Core.Intrinsics.have_fma(Float64) ? fma_llvm(x,y,z) : fma_emulated(x,y,z) - -function fma(a::Float16, b::Float16, c::Float16) - Float16(muladd(Float32(a), Float32(b), Float32(c))) #don't use fma if the hardware doesn't have it. +@assume_effects :consistent function fma(x::T, y::T, z::T) where {T<:IEEEFloat} + Core.Intrinsics.have_fma(T) ? fma_float(x,y,z) : fma_emulated(x,y,z) end -# This is necessary at least on 32-bit Intel Linux, since fma_llvm may +# This is necessary at least on 32-bit Intel Linux, since fma_float may # have called glibc, and some broken glibc fma implementations don't # properly restore the rounding mode Rounding.setrounding_raw(Float32, Rounding.JL_FE_TONEAREST) From b70761f76dee4fc4194f61ac6a53d7e05c6f3c92 Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Tue, 21 Jan 2025 21:19:16 +0100 Subject: [PATCH 53/65] allow `rand!` with explicit SIMD to be used for various dense arrays (#57101) --- stdlib/Random/src/XoshiroSimd.jl | 7 ++++--- stdlib/Random/test/runtests.jl | 4 +++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/stdlib/Random/src/XoshiroSimd.jl b/stdlib/Random/src/XoshiroSimd.jl index 58544714dd9f5..f77be4a347111 100644 --- a/stdlib/Random/src/XoshiroSimd.jl +++ b/stdlib/Random/src/XoshiroSimd.jl @@ -292,20 +292,21 @@ end return i end +const MutableDenseArray = Union{Base.MutableDenseArrayType{T}, UnsafeView{T}} where {T} -function rand!(rng::Union{TaskLocalRNG, Xoshiro}, dst::Array{T}, ::SamplerTrivial{CloseOpen01{T}}) where {T<:Union{Float16,Float32,Float64}} +function rand!(rng::Union{TaskLocalRNG, Xoshiro}, dst::MutableDenseArray{T}, ::SamplerTrivial{CloseOpen01{T}}) where {T<:Union{Float16,Float32,Float64}} GC.@preserve dst xoshiro_bulk(rng, convert(Ptr{UInt8}, pointer(dst)), length(dst)*sizeof(T), T, xoshiroWidth(), _bits2float) dst end for T in BitInteger_types - @eval function rand!(rng::Union{TaskLocalRNG, Xoshiro}, dst::Union{Array{$T}, UnsafeView{$T}}, ::SamplerType{$T}) + @eval function rand!(rng::Union{TaskLocalRNG, Xoshiro}, dst::MutableDenseArray{$T}, ::SamplerType{$T}) GC.@preserve dst xoshiro_bulk(rng, convert(Ptr{UInt8}, pointer(dst)), length(dst)*sizeof($T), UInt8, xoshiroWidth()) dst end end -function rand!(rng::Union{TaskLocalRNG, Xoshiro}, dst::Array{Bool}, ::SamplerType{Bool}) +function rand!(rng::Union{TaskLocalRNG, Xoshiro}, dst::MutableDenseArray{Bool}, ::SamplerType{Bool}) GC.@preserve dst xoshiro_bulk(rng, convert(Ptr{UInt8}, pointer(dst)), length(dst), Bool, xoshiroWidth()) dst end diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 9b46951f63ff5..13edf2e6553ec 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -370,9 +370,10 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) a8 = rand!(rng..., GenericArray{T}(undef, 2, 3), cc) ::GenericArray{T, 2} a9 = rand!(rng..., OffsetArray(Array{T}(undef, 5), 9), cc) ::OffsetArray{T, 1} a10 = rand!(rng..., OffsetArray(Array{T}(undef, 2, 3), (-2, 4)), cc) ::OffsetArray{T, 2} + a11 = rand!(rng..., Memory{T}(undef, 5), cc) ::Memory{T} @test size(a1) == (5,) @test size(a2) == size(a3) == (2, 3) - for a in [a0, a1..., a2..., a3..., a4..., a5..., a6..., a7..., a8..., a9..., a10...] + for a in [a0, a1..., a2..., a3..., a4..., a5..., a6..., a7..., a8..., a9..., a10..., a11...] if C isa Type @test a isa C else @@ -392,6 +393,7 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()]) (T <: Tuple || T <: Pair) && continue X = T == Bool ? T[0,1] : T[0,1,2] for A in (Vector{T}(undef, 5), + Memory{T}(undef, 5), Matrix{T}(undef, 2, 3), GenericArray{T}(undef, 5), GenericArray{T}(undef, 2, 3), From e03de0b883c044723d84cb4a4f93a6dd1ba99728 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 21 Jan 2025 23:22:37 +0100 Subject: [PATCH 54/65] Remove `jl_task_stack_buffer` (again) (#57116) This was removed previously in PR #54527 but had to be reverted in PR #54559 as one usage remained (more by accident then by design). This has since then been resolved. This is also part of PR #56477 but that seems stalled right now, and in fact merging parts of it now may make the review of it easier later on... --- src/jl_exported_funcs.inc | 1 - src/julia_gcext.h | 9 --------- src/task.c | 28 ---------------------------- 3 files changed, 38 deletions(-) diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index b92380df7a49c..c1b29a091511b 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -449,7 +449,6 @@ XX(jl_tagged_gensym) \ XX(jl_take_buffer) \ XX(jl_task_get_next) \ - XX(jl_task_stack_buffer) \ XX(jl_termios_size) \ XX(jl_test_cpu_feature) \ XX(jl_threadid) \ diff --git a/src/julia_gcext.h b/src/julia_gcext.h index 05140e4b09ace..e124f58a09402 100644 --- a/src/julia_gcext.h +++ b/src/julia_gcext.h @@ -135,15 +135,6 @@ JL_DLLEXPORT int jl_gc_conservative_gc_support_enabled(void); // NOTE: Only valid to call from within a GC context. JL_DLLEXPORT jl_value_t *jl_gc_internal_obj_base_ptr(void *p) JL_NOTSAFEPOINT; -// Return a non-null pointer to the start of the stack area if the task -// has an associated stack buffer. In that case, *size will also contain -// the size of that stack buffer upon return. Also, if task is a thread's -// current task, that thread's id will be stored in *tid; otherwise, -// *tid will be set to -1. -// -// DEPRECATED: use jl_active_task_stack() instead. -JL_DLLEXPORT void *jl_task_stack_buffer(jl_task_t *task, size_t *size, int *tid); - // Query the active and total stack range for the given task, and set // *active_start and *active_end respectively *total_start and *total_end // accordingly. The range for the active part is a best-effort approximation diff --git a/src/task.c b/src/task.c index d56d60eb58cb5..37e7f0e1f5440 100644 --- a/src/task.c +++ b/src/task.c @@ -352,34 +352,6 @@ void JL_NORETURN jl_finish_task(jl_task_t *ct) abort(); } -JL_DLLEXPORT void *jl_task_stack_buffer(jl_task_t *task, size_t *size, int *ptid) -{ - size_t off = 0; -#ifndef _OS_WINDOWS_ - jl_ptls_t ptls0 = jl_atomic_load_relaxed(&jl_all_tls_states)[0]; - if (ptls0->root_task == task) { - // See jl_init_root_task(). The root task of the main thread - // has its buffer enlarged by an artificial 3000000 bytes, but - // that means that the start of the buffer usually points to - // inaccessible memory. We need to correct for this. - off = ROOT_TASK_STACK_ADJUSTMENT; - } -#endif - jl_ptls_t ptls2 = task->ptls; - *ptid = -1; - if (ptls2) { - *ptid = jl_atomic_load_relaxed(&task->tid); -#ifdef COPY_STACKS - if (task->ctx.copy_stack) { - *size = ptls2->stacksize; - return (char *)ptls2->stackbase - *size; - } -#endif - } - *size = task->ctx.bufsz - off; - return (void *)((char *)task->ctx.stkbuf + off); -} - JL_DLLEXPORT void jl_active_task_stack(jl_task_t *task, char **active_start, char **active_end, char **total_start, char **total_end) From f91436eae7265a01bff17e35887cd9b8e15c8fdc Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:14:11 -0500 Subject: [PATCH 55/65] Add test for #57115 (#57120) Closes #57115. This issue was accidentally resolved on master by #54894, but it is important enough that we should have test coverage for it. --- test/precompile.jl | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/test/precompile.jl b/test/precompile.jl index 78a96250600a4..55e97f5608b08 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -1094,6 +1094,17 @@ precompile_test_harness("invoke") do dir f44320(::Any) = 2 g44320() = invoke(f44320, Tuple{Any}, 0) g44320() + # Issue #57115 + f57115(@nospecialize(::Any)) = error("unimplemented") + function g57115(@nospecialize(x)) + if @noinline rand(Bool) + # Add an 'invoke' edge from 'foo' to 'bar' + Core.invoke(f57115, Tuple{Any}, x) + else + # ... and also an identical 'call' edge + @noinline f57115(x) + end + end # Adding new specializations should not invalidate `invoke`s function getlast(itr) @@ -1110,6 +1121,8 @@ precompile_test_harness("invoke") do dir """ module $CallerModule using $InvokeModule + import $InvokeModule: f57115, g57115 + # involving external modules callf(x) = f(x) callg(x) = x < 5 ? g(x) : invoke(g, Tuple{Real}, x) @@ -1130,6 +1143,8 @@ precompile_test_harness("invoke") do dir # Issue #44320 f44320(::Real) = 3 + # Issue #57115 + f57115(::Int) = 1 call_getlast(x) = getlast(x) @@ -1150,6 +1165,7 @@ precompile_test_harness("invoke") do dir @noinline internalnc(3) @noinline call_getlast([1,2,3]) end + precompile(g57115, (Any,)) # Now that we've precompiled, invalidate with a new method that overrides the `invoke` dispatch $InvokeModule.h(x::Integer) = -1 @@ -1217,6 +1233,30 @@ precompile_test_harness("invoke") do dir m = only(methods(M.g44320)) @test (m.specializations::Core.MethodInstance).cache.max_world == typemax(UInt) + m = only(methods(M.g57115)) + mi = m.specializations::Core.MethodInstance + + f_m = get_method_for_type(M.f57115, Any) + f_mi = f_m.specializations::Core.MethodInstance + + # Make sure that f57115(::Any) has a 'call' backedge to 'g57115' + has_f_call_backedge = false + i = 1 + while i ≤ length(f_mi.backedges) + if f_mi.backedges[i] isa DataType + # invoke edge - skip + i += 2 + else + caller = f_mi.backedges[i]::Core.CodeInstance + if caller.def === mi + has_f_call_backedge = true + break + end + i += 1 + end + end + @test has_f_call_backedge + m = which(MI.getlast, (Any,)) @test (m.specializations::Core.MethodInstance).cache.max_world == typemax(UInt) From 294c4a63a0cd37dff72a51b2d9210a36ae2ff174 Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Wed, 22 Jan 2025 07:06:42 -0500 Subject: [PATCH 56/65] runtime_intrinsics.c: Remove duplicated line of code (#57123) --- src/runtime_intrinsics.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 1790b9bd8d106..90afa3fb6bddf 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -812,7 +812,6 @@ static void jl_##name##16(unsigned runtime_nbits, void *pa, void *pb, void *pr) runtime_nbits = 16; \ float R = OP(A, B); \ *(uint16_t*)pr = float_to_half(R); \ - *(uint16_t*)pr = float_to_half(R); \ } #define bi_intrinsic_bfloat(OP, name) \ @@ -903,7 +902,6 @@ static void jl_##name##16(unsigned runtime_nbits, void *pa, void *pb, void *pc, runtime_nbits = 16; \ float R = OP(A, B, C); \ *(uint16_t*)pr = float_to_half(R); \ - *(uint16_t*)pr = float_to_half(R); \ } #define ter_intrinsic_bfloat(OP, name) \ From 7f99e95377c61515a63aed6ca6500e837f34f69f Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 22 Jan 2025 13:40:53 +0100 Subject: [PATCH 57/65] bpart: Start enforcing minimum world age for const bparts (#57102) Currently, even though the binding partition system is implemented, it is largely enabled. New `const` definitions get magically "backdated" to the first world age in which the binding was undefined. Additionally, they do not get their own world age and there is currently no `latestworld` marker after `const` definitions. This PR changes this situation to give const markers their own world age with appropriate `latestworld` increments. Both of these are mandatory for `const` replacement to work. The other thing this PR does is prepare to remove the automatic "backdating". To see the difference, consider: ``` function foo($i) Core.eval(:(const x = $i)) x end ``` Without an intervening world age increment, this will throw an UndefVarError on this PR. I believe this is the best option for two reasons: 1. It will allow us infer these to `Union{}` in the future (thus letting inference prune dead code faster). 2. I think it is less confusing in terms of the world age semantics for `const` definitions to become active only after they are defined. To illustrate the second point, suppose we did keep the automatic backdating. Then we would have: ``` foo(1) => 1 foo(2) => 1 foo(3) => 2 ``` as opposed to on this PR: ``` foo(1) => UndefVarError foo(2) => 1 foo(3) => 2 ``` The semantics are consistent, of course, but I am concerned that an automatic backdating will give users the wrong mental model about world age, since it "fixes itself" the first time, but if you Revise it, it will give an unexpected answer. I think this would encourage accidentally bad code patterns that only break under Revise (where they are hard to debug). The counterpoint of course is that that not backdating is a more breaking choice. As with the rest of the 1.12-era world age semantics changes, I think taking a look at PkgEval will be helpful. --- Compiler/src/abstractinterpretation.jl | 11 ++-- Compiler/src/optimize.jl | 2 +- Compiler/src/ssair/ir.jl | 4 +- Compiler/src/ssair/legacy.jl | 2 +- Compiler/src/ssair/verify.jl | 12 +++- Compiler/src/tfuncs.jl | 2 +- Compiler/test/inline.jl | 4 +- base/Base.jl | 1 + base/client.jl | 12 ++-- base/essentials.jl | 6 ++ base/loading.jl | 22 +++++--- base/logging/logging.jl | 4 +- base/reflection.jl | 77 +++++++++++++++++++------- base/runtime_internals.jl | 16 ++++-- src/codegen.cpp | 34 ++++++++---- src/gf.c | 21 ++++--- src/init.c | 13 +++-- src/jlapi.c | 11 ++-- src/julia-syntax.scm | 14 ++++- src/julia.h | 1 - src/julia_internal.h | 14 +++-- src/method.c | 30 +++++++--- src/module.c | 43 +++++++------- src/staticdata.c | 15 ++++- src/toplevel.c | 38 +++++++++++-- stdlib/REPL/src/REPLCompletions.jl | 16 ++++-- stdlib/REPL/src/precompile.jl | 1 + stdlib/REPL/test/precompilation.jl | 2 +- stdlib/REPL/test/repl.jl | 8 +-- stdlib/Serialization/test/runtests.jl | 16 +++--- test/core.jl | 2 +- test/loading.jl | 1 + test/precompile.jl | 16 ++++-- test/runtests.jl | 6 +- test/syntax.jl | 1 + test/worlds.jl | 4 +- 36 files changed, 318 insertions(+), 164 deletions(-) diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 300feeae53e9a..2b1a7fb2dd448 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -3456,10 +3456,10 @@ world_range(ir::IRCode) = ir.valid_worlds world_range(ci::CodeInfo) = WorldRange(ci.min_world, ci.max_world) world_range(compact::IncrementalCompact) = world_range(compact.ir) -function force_binding_resolution!(g::GlobalRef) +function force_binding_resolution!(g::GlobalRef, world::UInt) # Force resolution of the binding # TODO: This will go away once we switch over to fully partitioned semantics - ccall(:jl_globalref_boundp, Cint, (Any,), g) + ccall(:jl_force_binding_resolution, Cvoid, (Any, Csize_t), g, world) return nothing end @@ -3477,7 +3477,7 @@ function abstract_eval_globalref_type(g::GlobalRef, src::Union{CodeInfo, IRCode, # This method is surprisingly hot. For performance, don't ask the runtime to resolve # the binding unless necessary - doing so triggers an additional lookup, which though # not super expensive is hot enough to show up in benchmarks. - force_binding_resolution!(g) + force_binding_resolution!(g, min_world(worlds)) return abstract_eval_globalref_type(g, src, false) end # return Union{} @@ -3490,7 +3490,7 @@ function abstract_eval_globalref_type(g::GlobalRef, src::Union{CodeInfo, IRCode, end function lookup_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState) - force_binding_resolution!(g) + force_binding_resolution!(g, get_inference_world(interp)) partition = lookup_binding_partition(get_inference_world(interp), g) update_valid_age!(sv, WorldRange(partition.min_world, partition.max_world)) partition @@ -3539,7 +3539,8 @@ function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, saw_ partition = abstract_eval_binding_partition!(interp, g, sv) ret = abstract_eval_partition_load(interp, partition) if ret.rt !== Union{} && ret.exct === UndefVarError && InferenceParams(interp).assume_bindings_static - if isdefined(g, :binding) && isdefined(g.binding, :value) + b = convert(Core.Binding, g) + if isdefined(b, :value) ret = RTEffects(ret.rt, Union{}, Effects(generic_getglobal_effects, nothrow=true)) end # We do not assume in general that assigned global bindings remain assigned. diff --git a/Compiler/src/optimize.jl b/Compiler/src/optimize.jl index 12b2f3c9a269f..9f74f028507cd 100644 --- a/Compiler/src/optimize.jl +++ b/Compiler/src/optimize.jl @@ -1286,7 +1286,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState) # types of call arguments only once `slot2reg` converts this `IRCode` to the SSA form # and eliminates slots (see below) argtypes = sv.slottypes - return IRCode(stmts, sv.cfg, di, argtypes, meta, sv.sptypes, WorldRange(ci.min_world, ci.max_world)) + return IRCode(stmts, sv.cfg, di, argtypes, meta, sv.sptypes, world_range(ci)) end function process_meta!(meta::Vector{Expr}, @nospecialize stmt) diff --git a/Compiler/src/ssair/ir.jl b/Compiler/src/ssair/ir.jl index 9103dba04fa54..f86ada2309ddc 100644 --- a/Compiler/src/ssair/ir.jl +++ b/Compiler/src/ssair/ir.jl @@ -434,7 +434,7 @@ struct IRCode function IRCode(stmts::InstructionStream, cfg::CFG, debuginfo::DebugInfoStream, argtypes::Vector{Any}, meta::Vector{Expr}, sptypes::Vector{VarState}, valid_worlds=WorldRange(typemin(UInt), typemax(UInt))) - return new(stmts, argtypes, sptypes, debuginfo, cfg, NewNodeStream(), meta) + return new(stmts, argtypes, sptypes, debuginfo, cfg, NewNodeStream(), meta, valid_worlds) end function IRCode(ir::IRCode, stmts::InstructionStream, cfg::CFG, new_nodes::NewNodeStream) di = ir.debuginfo @@ -1462,7 +1462,7 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr result[result_idx][:stmt] = GotoNode(label) result_idx += 1 elseif isa(stmt, GlobalRef) - total_flags = IR_FLAG_CONSISTENT | IR_FLAG_EFFECT_FREE + total_flags = IR_FLAG_CONSISTENT | IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW flag = result[result_idx][:flag] if has_flag(flag, total_flags) ssa_rename[idx] = stmt diff --git a/Compiler/src/ssair/legacy.jl b/Compiler/src/ssair/legacy.jl index 675ca2dea9b32..64a39c72ad9eb 100644 --- a/Compiler/src/ssair/legacy.jl +++ b/Compiler/src/ssair/legacy.jl @@ -44,7 +44,7 @@ function inflate_ir!(ci::CodeInfo, sptypes::Vector{VarState}, argtypes::Vector{A di = DebugInfoStream(nothing, ci.debuginfo, nstmts) stmts = InstructionStream(code, ssavaluetypes, info, di.codelocs, ci.ssaflags) meta = Expr[] - return IRCode(stmts, cfg, di, argtypes, meta, sptypes, WorldRange(ci.min_world, ci.max_world)) + return IRCode(stmts, cfg, di, argtypes, meta, sptypes, world_range(ci)) end """ diff --git a/Compiler/src/ssair/verify.jl b/Compiler/src/ssair/verify.jl index 12eb09be693f3..fa16bdcc7ab19 100644 --- a/Compiler/src/ssair/verify.jl +++ b/Compiler/src/ssair/verify.jl @@ -12,7 +12,7 @@ end if !isdefined(@__MODULE__, Symbol("@verify_error")) macro verify_error(arg) - arg isa String && return esc(:(print && println(stderr, $arg))) + arg isa String && return esc(:(print && println($(GlobalRef(Core, :stderr)), $arg))) isexpr(arg, :string) || error("verify_error macro expected a string expression") pushfirst!(arg.args, GlobalRef(Core, :stderr)) pushfirst!(arg.args, :println) @@ -61,8 +61,14 @@ function check_op(ir::IRCode, domtree::DomTree, @nospecialize(op), use_bb::Int, raise_error() end elseif isa(op, GlobalRef) - if !isdefined(op.mod, op.name) || !isconst(op.mod, op.name) - @verify_error "Unbound GlobalRef not allowed in value position" + force_binding_resolution!(op, min_world(ir.valid_worlds)) + bpart = lookup_binding_partition(min_world(ir.valid_worlds), op) + while is_some_imported(binding_kind(bpart)) && max_world(ir.valid_worlds) <= bpart.max_world + imported_binding = partition_restriction(bpart)::Core.Binding + bpart = lookup_binding_partition(min_world(ir.valid_worlds), imported_binding) + end + if !is_defined_const_binding(binding_kind(bpart)) || (bpart.max_world < max_world(ir.valid_worlds)) + @verify_error "Unbound or partitioned GlobalRef not allowed in value position" raise_error() end elseif isa(op, Expr) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index fe21f6381e8cd..74c8026ca0cf5 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -1109,7 +1109,7 @@ function _getfield_tfunc_const(@nospecialize(sv), name::Const) if isa(sv, DataType) && nv == DATATYPE_TYPES_FIELDINDEX && isdefined(sv, nv) return Const(getfield(sv, nv)) end - if isconst(typeof(sv), nv) + if !isa(sv, Module) && isconst(typeof(sv), nv) if isdefined(sv, nv) return Const(getfield(sv, nv)) end diff --git a/Compiler/test/inline.jl b/Compiler/test/inline.jl index 5f95fb761859e..b8ff14405391d 100644 --- a/Compiler/test/inline.jl +++ b/Compiler/test/inline.jl @@ -149,7 +149,7 @@ end (src, _) = only(code_typed(sum27403, Tuple{Vector{Int}})) @test !any(src.code) do x - x isa Expr && x.head === :invoke && x.args[2] !== Core.GlobalRef(Base, :throw_boundserror) + x isa Expr && x.head === :invoke && !(x.args[2] in (Core.GlobalRef(Base, :throw_boundserror), Base.throw_boundserror)) end end @@ -313,7 +313,7 @@ end const _a_global_array = [1] f_inline_global_getindex() = _a_global_array[1] let ci = code_typed(f_inline_global_getindex, Tuple{})[1].first - @test any(x->(isexpr(x, :call) && x.args[1] === GlobalRef(Base, :memoryrefget)), ci.code) + @test any(x->(isexpr(x, :call) && x.args[1] in (GlobalRef(Base, :memoryrefget), Base.memoryrefget)), ci.code) end # Issue #29114 & #36087 - Inlining of non-tuple splats diff --git a/base/Base.jl b/base/Base.jl index 20b1636c29a8d..04f732a4309c9 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -401,6 +401,7 @@ end # we know whether the .ji can just give the Base copy or not. # TODO: We may want to do this earlier to avoid TOCTOU issues. const _compiler_require_dependencies = Any[] +@Core.latestworld for i = 1:length(_included_files) isassigned(_included_files, i) || continue (mod, file) = _included_files[i] diff --git a/base/client.jl b/base/client.jl index e95d518d3e501..2527d382c695d 100644 --- a/base/client.jl +++ b/base/client.jl @@ -299,7 +299,7 @@ function exec_options(opts) elseif cmd == 'm' entrypoint = push!(split(arg, "."), "main") Base.eval(Main, Expr(:import, Expr(:., Symbol.(entrypoint)...))) - if !should_use_main_entrypoint() + if !invokelatest(should_use_main_entrypoint) error("`main` in `$arg` not declared as entry point (use `@main` to do so)") end return false @@ -408,8 +408,7 @@ function load_InteractiveUtils(mod::Module=Main) return nothing end end - Core.eval(mod, :(using Base.MainInclude.InteractiveUtils)) - return MainInclude.InteractiveUtils + return Core.eval(mod, :(using Base.MainInclude.InteractiveUtils; Base.MainInclude.InteractiveUtils)) end function load_REPL() @@ -556,11 +555,12 @@ function _start() local ret = 0 try repl_was_requested = exec_options(JLOptions()) - if should_use_main_entrypoint() && !is_interactive + if invokelatest(should_use_main_entrypoint) && !is_interactive + main = invokelatest(getglobal, Main, :main) if Base.generating_output() - precompile(Main.main, (typeof(ARGS),)) + precompile(main, (typeof(ARGS),)) else - ret = invokelatest(Main.main, ARGS) + ret = invokelatest(main, ARGS) end elseif (repl_was_requested || is_interactive) # Run the Base `main`, which will either load the REPL stdlib diff --git a/base/essentials.jl b/base/essentials.jl index fa5cf79192f56..58e4ce1125093 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -1266,6 +1266,9 @@ arbitrary code in fixed worlds. `world` may be `UnitRange`, in which case the ma will error unless the binding is valid and has the same value across the entire world range. +As a special case, the world `∞` always refers to the latest world, even if that world +is newer than the world currently running. + The `@world` macro is primarily used in the printing of bindings that are no longer available in the current world. @@ -1290,6 +1293,9 @@ julia> fold This functionality requires at least Julia 1.12. """ macro world(sym, world) + if world == :∞ + world = Expr(:call, get_world_counter) + end if isa(sym, Symbol) return :($(_resolve_in_world)($(esc(world)), $(QuoteNode(GlobalRef(__module__, sym))))) elseif isa(sym, GlobalRef) diff --git a/base/loading.jl b/base/loading.jl index 4193aae13b96a..240406292246b 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -2364,6 +2364,18 @@ function require(into::Module, mod::Symbol) return invoke_in_world(world, __require, into, mod) end +function check_for_hint(into, mod) + return begin + if isdefined(into, mod) && getfield(into, mod) isa Module + true, "." + elseif isdefined(parentmodule(into), mod) && getfield(parentmodule(into), mod) isa Module + true, ".." + else + false, "" + end + end +end + function __require(into::Module, mod::Symbol) if into === __toplevel__ && generating_output(#=incremental=#true) error("`using/import $mod` outside of a Module detected. Importing a package outside of a module \ @@ -2377,15 +2389,7 @@ function __require(into::Module, mod::Symbol) if uuidkey_env === nothing where = PkgId(into) if where.uuid === nothing - hint, dots = begin - if isdefined(into, mod) && getfield(into, mod) isa Module - true, "." - elseif isdefined(parentmodule(into), mod) && getfield(parentmodule(into), mod) isa Module - true, ".." - else - false, "" - end - end + hint, dots = invokelatest(check_for_hint, into, mod) hint_message = hint ? ", maybe you meant `import/using $(dots)$(mod)`" : "" install_message = if mod != :Pkg start_sentence = hint ? "Otherwise, run" : "Run" diff --git a/base/logging/logging.jl b/base/logging/logging.jl index 41721e84cc934..a1a8417bcb388 100644 --- a/base/logging/logging.jl +++ b/base/logging/logging.jl @@ -372,7 +372,7 @@ function logmsg_code(_module, file, line, level, message, exs...) kwargs = (;$(log_data.kwargs...)) true else - @invokelatest logging_error(logger, level, _module, group, id, file, line, err, false) + @invokelatest $(logging_error)(logger, level, _module, group, id, file, line, err, false) false end end @@ -384,7 +384,7 @@ function logmsg_code(_module, file, line, level, message, exs...) kwargs = (;$(log_data.kwargs...)) true catch err - @invokelatest logging_error(logger, level, _module, group, id, file, line, err, true) + @invokelatest $(logging_error)(logger, level, _module, group, id, file, line, err, true) false end end diff --git a/base/reflection.jl b/base/reflection.jl index f9c5dd9765533..78e701692a2a7 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -1362,6 +1362,18 @@ macro invoke(ex) return esc(out) end +apply_gr(gr::GlobalRef, @nospecialize args...) = getglobal(gr.mod, gr.name)(args...) +apply_gr_kw(@nospecialize(kwargs::NamedTuple), gr::GlobalRef, @nospecialize args...) = Core.kwcall(kwargs, getglobal(gr.mod, gr.name), args...) + +function invokelatest_gr(gr::GlobalRef, @nospecialize args...; kwargs...) + @inline + kwargs = merge(NamedTuple(), kwargs) + if isempty(kwargs) + return Core._call_latest(apply_gr, gr, args...) + end + return Core._call_latest(apply_gr_kw, kwargs, gr, args...) +end + """ @invokelatest f(args...; kwargs...) @@ -1375,22 +1387,11 @@ It also supports the following syntax: - `@invokelatest xs[i]` expands to `Base.invokelatest(getindex, xs, i)` - `@invokelatest xs[i] = v` expands to `Base.invokelatest(setindex!, xs, v, i)` -```jldoctest -julia> @macroexpand @invokelatest f(x; kw=kwv) -:(Base.invokelatest(f, x; kw = kwv)) - -julia> @macroexpand @invokelatest x.f -:(Base.invokelatest(Base.getproperty, x, :f)) - -julia> @macroexpand @invokelatest x.f = v -:(Base.invokelatest(Base.setproperty!, x, :f, v)) - -julia> @macroexpand @invokelatest xs[i] -:(Base.invokelatest(Base.getindex, xs, i)) - -julia> @macroexpand @invokelatest xs[i] = v -:(Base.invokelatest(Base.setindex!, xs, v, i)) -``` +!!! note + If `f` is a global, it will be resolved consistently + in the (latest) world as the call target. However, all other arguments + (as well as `f` itself if it is not a literal global) will be evaluated + in the current world age. !!! compat "Julia 1.7" This macro requires Julia 1.7 or later. @@ -1404,11 +1405,45 @@ julia> @macroexpand @invokelatest xs[i] = v macro invokelatest(ex) topmod = _topmod(__module__) f, args, kwargs = destructure_callex(topmod, ex) - out = Expr(:call, GlobalRef(Base, :invokelatest)) - isempty(kwargs) || push!(out.args, Expr(:parameters, kwargs...)) - push!(out.args, f) - append!(out.args, args) - return esc(out) + + if !isa(f, GlobalRef) + out_f = Expr(:call, GlobalRef(Base, :invokelatest)) + isempty(kwargs) || push!(out_f.args, Expr(:parameters, kwargs...)) + + if isexpr(f, :(.)) + s = gensym() + check = quote + $s = $(f.args[1]) + isa($s, Module) + end + push!(out_f.args, Expr(:(.), s, f.args[2])) + else + push!(out_f.args, f) + end + append!(out_f.args, args) + + if @isdefined(s) + f = :(GlobalRef($s, $(f.args[2]))) + elseif !isa(f, Symbol) + return esc(out_f) + else + check = :($(Expr(:isglobal, f))) + end + end + + out_gr = Expr(:call, GlobalRef(Base, :invokelatest_gr)) + isempty(kwargs) || push!(out_gr.args, Expr(:parameters, kwargs...)) + push!(out_gr.args, isa(f, GlobalRef) ? QuoteNode(f) : + isa(f, Symbol) ? QuoteNode(GlobalRef(__module__, f)) : + f) + append!(out_gr.args, args) + + if isa(f, GlobalRef) + return esc(out_gr) + end + + # f::Symbol + return esc(:($check ? $out_gr : $out_f)) end function destructure_callex(topmod::Module, @nospecialize(ex)) diff --git a/base/runtime_internals.jl b/base/runtime_internals.jl index 67694e533ac47..964e8063dd5af 100644 --- a/base/runtime_internals.jl +++ b/base/runtime_internals.jl @@ -239,12 +239,16 @@ function lookup_binding_partition(world::UInt, b::Core.Binding) ccall(:jl_get_binding_partition, Ref{Core.BindingPartition}, (Any, UInt), b, world) end -function lookup_binding_partition(world::UInt, gr::Core.GlobalRef) +function convert(::Type{Core.Binding}, gr::Core.GlobalRef) if isdefined(gr, :binding) - b = gr.binding + return gr.binding else - b = ccall(:jl_get_module_binding, Ref{Core.Binding}, (Any, Any, Cint), gr.mod, gr.name, true) + return ccall(:jl_get_module_binding, Ref{Core.Binding}, (Any, Any, Cint), gr.mod, gr.name, true) end +end + +function lookup_binding_partition(world::UInt, gr::Core.GlobalRef) + b = convert(Core.Binding, gr) return lookup_binding_partition(world, b) end @@ -420,7 +424,11 @@ end """ isconst(t::DataType, s::Union{Int,Symbol}) -> Bool -Determine whether a field `s` is declared `const` in a given type `t`. +Determine whether a field `s` is const in a given type `t` +in the sense that a read from said field is consistent +for egal objects. Note in particular that out-of-bounds +fields are considered const under this definition (because +they always throw). """ function isconst(@nospecialize(t::Type), s::Symbol) @_foldable_meta diff --git a/src/codegen.cpp b/src/codegen.cpp index 7cfcc52db29c7..e047632923f68 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3136,8 +3136,11 @@ static jl_value_t *static_eval(jl_codectx_t &ctx, jl_value_t *ex) { if (jl_is_symbol(ex)) { jl_sym_t *sym = (jl_sym_t*)ex; - if (jl_is_const(ctx.module, sym)) - return jl_get_global(ctx.module, sym); + jl_binding_t *bnd = jl_get_module_binding(ctx.module, sym, 0); + jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world); + jl_ptr_kind_union_t pku = jl_walk_binding_inplace_all(&bnd, &bpart, ctx.min_world, ctx.max_world); + if (jl_bkind_is_some_constant(decode_restriction_kind(pku))) + return decode_restriction_value(pku); return NULL; } if (jl_is_slotnumber(ex) || jl_is_argument(ex)) @@ -3158,11 +3161,15 @@ static jl_value_t *static_eval(jl_codectx_t &ctx, jl_value_t *ex) jl_sym_t *s = NULL; if (jl_is_globalref(ex)) { s = jl_globalref_name(ex); - jl_binding_t *b = jl_get_binding(jl_globalref_mod(ex), s); - jl_value_t *v = jl_get_binding_value_if_const(b); + jl_binding_t *bnd = jl_get_module_binding(jl_globalref_mod(ex), s, 0); + jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world); + jl_ptr_kind_union_t pku = jl_walk_binding_inplace_all(&bnd, &bpart, ctx.min_world, ctx.max_world); + jl_value_t *v = NULL; + if (jl_bkind_is_some_constant(decode_restriction_kind(pku))) + v = decode_restriction_value(pku); if (v) { - if (b->deprecated) - cg_bdw(ctx, s, b); + if (bnd->deprecated) + cg_bdw(ctx, s, bnd); return v; } return NULL; @@ -3181,11 +3188,15 @@ static jl_value_t *static_eval(jl_codectx_t &ctx, jl_value_t *ex) // Assumes that the module is rooted somewhere. s = (jl_sym_t*)static_eval(ctx, jl_exprarg(e, 2)); if (s && jl_is_symbol(s)) { - jl_binding_t *b = jl_get_binding(m, s); - jl_value_t *v = jl_get_binding_value_if_const(b); + jl_binding_t *bnd = jl_get_module_binding(m, s, 0); + jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world); + jl_ptr_kind_union_t pku = jl_walk_binding_inplace_all(&bnd, &bpart, ctx.min_world, ctx.max_world); + jl_value_t *v = NULL; + if (jl_bkind_is_some_constant(decode_restriction_kind(pku))) + v = decode_restriction_value(pku); if (v) { - if (b->deprecated) - cg_bdw(ctx, s, b); + if (bnd->deprecated) + cg_bdw(ctx, s, bnd); return v; } } @@ -3465,14 +3476,13 @@ static jl_cgval_t emit_globalref(jl_codectx_t &ctx, jl_module_t *mod, jl_sym_t * return mark_julia_const(ctx, constval); } } - if (!bpart) { + if (!bpart || decode_restriction_kind(pku) != BINDING_KIND_GLOBAL) { return emit_globalref_runtime(ctx, bnd, mod, name); } Value *bp = julia_binding_gv(ctx, bnd); if (bnd->deprecated) { cg_bdw(ctx, name, bnd); } - assert(decode_restriction_kind(pku) == BINDING_KIND_GLOBAL); jl_value_t *ty = decode_restriction_value(pku); bp = julia_binding_pvalue(ctx, bp); if (ty == nullptr) diff --git a/src/gf.c b/src/gf.c index ea25ed2eae4ff..710dda208f0b2 100644 --- a/src/gf.c +++ b/src/gf.c @@ -292,7 +292,8 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a { jl_sym_t *sname = jl_symbol(name); if (dt == NULL) { - jl_value_t *f = jl_new_generic_function_with_supertype(sname, jl_core_module, jl_builtin_type); + // Builtins are specially considered available from world 0 + jl_value_t *f = jl_new_generic_function_with_supertype(sname, jl_core_module, jl_builtin_type, 0); jl_set_const(jl_core_module, sname, f); dt = (jl_datatype_t*)jl_typeof(f); } @@ -3790,10 +3791,8 @@ jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t *gf, jl_value return _jl_invoke(gf, args, nargs - 1, mfunc, world); } -// Return value is rooted globally -jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_t *module, jl_datatype_t *st) +jl_sym_t *jl_gf_supertype_name(jl_sym_t *name) { - // type name is function name prefixed with # size_t l = strlen(jl_symbol_name(name)); char *prefixed; prefixed = (char*)malloc_s(l+2); @@ -3801,6 +3800,14 @@ jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_ strcpy(&prefixed[1], jl_symbol_name(name)); jl_sym_t *tname = jl_symbol(prefixed); free(prefixed); + return tname; +} + +// Return value is rooted globally +jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_t *module, jl_datatype_t *st, size_t new_world) +{ + // type name is function name prefixed with # + jl_sym_t *tname = jl_gf_supertype_name(name); jl_datatype_t *ftype = (jl_datatype_t*)jl_new_datatype( tname, module, st, jl_emptysvec, jl_emptysvec, jl_emptysvec, jl_emptysvec, 0, 0, 0); @@ -3808,7 +3815,7 @@ jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_ JL_GC_PUSH1(&ftype); ftype->name->mt->name = name; jl_gc_wb(ftype->name->mt, name); - jl_set_const(module, tname, (jl_value_t*)ftype); + jl_declare_constant_val3(NULL, module, tname, (jl_value_t*)ftype, BINDING_KIND_CONST, new_world); jl_value_t *f = jl_new_struct(ftype); ftype->instance = f; jl_gc_wb(ftype, f); @@ -3816,9 +3823,9 @@ jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_ return (jl_function_t*)f; } -jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t *module) +jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t *module, size_t new_world) { - return jl_new_generic_function_with_supertype(name, module, jl_function_type); + return jl_new_generic_function_with_supertype(name, module, jl_function_type, new_world); } struct ml_matches_env { diff --git a/src/init.c b/src/init.c index 7b41e63e98455..e69467c75bd73 100644 --- a/src/init.c +++ b/src/init.c @@ -249,6 +249,8 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode) JL_NOTSAFEPOINT_ENTER } if (jl_base_module) { + size_t last_age = ct->world_age; + ct->world_age = jl_get_world_counter(); jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit")); if (f != NULL) { jl_value_t **fargs; @@ -257,10 +259,7 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode) JL_NOTSAFEPOINT_ENTER fargs[1] = jl_box_int32(exitcode); JL_TRY { assert(ct); - size_t last_age = ct->world_age; - ct->world_age = jl_get_world_counter(); jl_apply(fargs, 2); - ct->world_age = last_age; } JL_CATCH { jl_printf((JL_STREAM*)STDERR_FILENO, "\natexit hook threw an error: "); @@ -270,10 +269,15 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode) JL_NOTSAFEPOINT_ENTER } JL_GC_POP(); } + ct->world_age = last_age; } - if (ct && exitcode == 0) + if (ct && exitcode == 0) { + size_t last_age = ct->world_age; + ct->world_age = jl_get_world_counter(); jl_write_compiler_output(); + ct->world_age = last_age; + } jl_print_gc_stats(JL_STDERR); if (jl_options.code_coverage) @@ -893,6 +897,7 @@ static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_ jl_init_primitives(); jl_init_main_module(); jl_load(jl_core_module, "boot.jl"); + jl_current_task->world_age = jl_atomic_load_acquire(&jl_world_counter); post_boot_hooks(); } diff --git a/src/jlapi.c b/src/jlapi.c index defb2db6ac911..b8fbda801f43b 100644 --- a/src/jlapi.c +++ b/src/jlapi.c @@ -910,26 +910,29 @@ static NOINLINE int true_main(int argc, char *argv[]) { jl_set_ARGS(argc, argv); + + jl_task_t *ct = jl_current_task; + size_t last_age = ct->world_age; + ct->world_age = jl_get_world_counter(); + jl_function_t *start_client = jl_base_module ? (jl_function_t*)jl_get_global(jl_base_module, jl_symbol("_start")) : NULL; - jl_task_t *ct = jl_current_task; if (start_client) { int ret = 1; JL_TRY { - size_t last_age = ct->world_age; - ct->world_age = jl_get_world_counter(); jl_value_t *r = jl_apply(&start_client, 1); if (jl_typeof(r) != (jl_value_t*)jl_int32_type) jl_type_error("typeassert", (jl_value_t*)jl_int32_type, r); ret = jl_unbox_int32(r); - ct->world_age = last_age; } JL_CATCH { jl_no_exc_handler(jl_current_exception(ct), ct); } + ct->world_age = last_age; return ret; } + ct->world_age = last_age; // run program if specified, otherwise enter REPL if (argc > 0) { diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index 7fd2dc7409c0e..57f67755df692 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -433,7 +433,7 @@ (inert ,loc))) ,body)))) (if (or (symbol? name) (globalref? name)) - `(block ,@generator (method ,name) ,mdef (unnecessary ,name)) ;; return the function + `(block ,@generator (method ,name) (latestworld-if-toplevel) ,mdef (unnecessary ,name)) ;; return the function (if (not (null? generator)) `(block ,@generator ,mdef) mdef)))))) @@ -531,6 +531,7 @@ `(call (core ifelse) (false) (false) (block ;; forward-declare function so its type can occur in the signature of the inner method below ,@(if (or (symbol? name) (globalref? name)) `((method ,name)) '()) + (latestworld-if-toplevel) ;; call with keyword args pre-sorted - original method code goes here ,(method-def-expr- @@ -1515,6 +1516,7 @@ (scope-block (block (hardscope) (local (= ,(cadr arg) ,rr)) ,.(map (lambda (v) `(,(car e) (globalref (thismodule) ,v) ,v)) (filter-not-underscore (lhs-vars (cadr arg)))) + (latestworld) ,rr)))))))) (else (error "expected assignment after \"const\""))))))) @@ -2473,7 +2475,7 @@ (error "Opaque closure argument type may not be specified both in the method signature and separately")) (if (or (varargexpr? lastarg) (vararg? lastarg)) '(true) '(false)))) - (meth (caddr (caddr (expand-forms F)))) ;; `method` expr + (meth (cadddr (caddr (expand-forms F)))) ;; `method` expr (lam (cadddr meth)) (sig-block (caddr meth)) (sig-block (if (and (pair? sig-block) (eq? (car sig-block) 'block)) @@ -3154,6 +3156,11 @@ (else `(globalref (thismodule) ,e))))) ((or (not (pair? e)) (quoted? e) (memq (car e) '(toplevel symbolicgoto symboliclabel toplevel-only))) e) + ((eq? (car e) 'isglobal) + (let ((val (and scope (get (scope:table scope) (cadr e) #f)))) + (cond (val `(false)) + ((underscore-symbol? (cadr e)) `(false)) + (else `(true))))) ((eq? (car e) 'global) (check-valid-name (cadr e)) e) @@ -3793,7 +3800,7 @@ f(x) = yt(x) (Set '(quote top core lineinfo line inert local-def unnecessary copyast meta inbounds boundscheck loopinfo decl aliasscope popaliasscope thunk with-static-parameters toplevel-only - global globalref assign-const-if-global thismodule + global globalref assign-const-if-global isglobal thismodule const atomic null true false ssavalue isdefined toplevel module lambda error gc_preserve_begin gc_preserve_end import using export public inline noinline purity))) @@ -4296,6 +4303,7 @@ f(x) = yt(x) `(toplevel-butfirst ,(convert-assignment name mk-closure fname lam interp opaq parsed-method-stack globals locals) ,@typedef + (latestworld) ,@(map (lambda (v) `(moved-local ,v)) moved-vars) ,@sp-inits ,@mk-method diff --git a/src/julia.h b/src/julia.h index b5416568b7ae9..699b3cc196411 100644 --- a/src/julia.h +++ b/src/julia.h @@ -2009,7 +2009,6 @@ JL_DLLEXPORT int jl_defines_or_exports_p(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT int jl_binding_resolved_p(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var); JL_DLLEXPORT int jl_globalref_is_const(jl_globalref_t *gr); -JL_DLLEXPORT int jl_globalref_boundp(jl_globalref_t *gr); JL_DLLEXPORT jl_value_t *jl_get_globalref_value(jl_globalref_t *gr); JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var); JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT); diff --git a/src/julia_internal.h b/src/julia_internal.h index 3e4967c9d4dca..0da6d412c8a49 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -828,8 +828,8 @@ jl_value_t *modify_value(jl_value_t *ty, _Atomic(jl_value_t*) *p, jl_value_t *pa jl_value_t *modify_bits(jl_value_t *ty, char *p, uint8_t *psel, jl_value_t *parent, jl_value_t *op, jl_value_t *rhs, enum atomic_kind isatomic); int setonce_bits(jl_datatype_t *rty, char *p, jl_value_t *owner, jl_value_t *rhs, enum atomic_kind isatomic); jl_expr_t *jl_exprn(jl_sym_t *head, size_t n); -jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t *module); -jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_t *module, jl_datatype_t *st); +jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t *module, size_t new_world); +jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_t *module, jl_datatype_t *st, size_t new_world); int jl_foreach_reachable_mtable(int (*visit)(jl_methtable_t *mt, void *env), void *env); int foreach_mtable_in_module(jl_module_t *m, int (*visit)(jl_methtable_t *mt, void *env), void *env); void jl_init_main_module(void); @@ -842,6 +842,7 @@ JL_DLLEXPORT void jl_eval_const_decl(jl_module_t *m, jl_value_t *arg, jl_value_t void jl_binding_set_type(jl_binding_t *b, jl_module_t *mod, jl_sym_t *sym, jl_value_t *ty); void jl_eval_global_expr(jl_module_t *m, jl_expr_t *ex, int set_type); JL_DLLEXPORT void jl_declare_global(jl_module_t *m, jl_value_t *arg, jl_value_t *set_type); +JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val3(jl_binding_t *b JL_ROOTING_ARGUMENT, jl_module_t *mod, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED, enum jl_partition_kind, size_t new_world) JL_GLOBALLY_ROOTED; JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *m, jl_value_t *e, int fast, int expanded, const char **toplevel_filename, int *toplevel_lineno); STATIC_INLINE struct _jl_module_using *module_usings_getidx(jl_module_t *m JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; @@ -985,15 +986,15 @@ STATIC_INLINE int jl_bkind_is_some_guard(enum jl_partition_kind kind) JL_NOTSAFE return kind == BINDING_KIND_FAILED || kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED; } -JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition(jl_binding_t *b JL_PROPAGATES_ROOT, size_t world); -JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition_all(jl_binding_t *b JL_PROPAGATES_ROOT, size_t min_world, size_t max_world); +JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition(jl_binding_t *b JL_PROPAGATES_ROOT, size_t world) JL_GLOBALLY_ROOTED; +JL_DLLEXPORT jl_binding_partition_t *jl_get_binding_partition_all(jl_binding_t *b JL_PROPAGATES_ROOT, size_t min_world, size_t max_world) JL_GLOBALLY_ROOTED; EXTERN_INLINE_DECLARE uint8_t jl_bpart_get_kind(jl_binding_partition_t *bpart) JL_NOTSAFEPOINT { return decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction)); } -STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace(jl_binding_t **bnd, jl_binding_partition_t **bpart, size_t world) JL_NOTSAFEPOINT; -STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace_all(jl_binding_t **bnd, jl_binding_partition_t **bpart, size_t min_world, size_t max_world) JL_NOTSAFEPOINT; +STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace(jl_binding_t **bnd, jl_binding_partition_t **bpart JL_PROPAGATES_ROOT, size_t world) JL_NOTSAFEPOINT; +STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace_all(jl_binding_t **bnd, jl_binding_partition_t **bpart JL_PROPAGATES_ROOT, size_t min_world, size_t max_world) JL_NOTSAFEPOINT; #ifndef __clang_analyzer__ STATIC_INLINE jl_ptr_kind_union_t jl_walk_binding_inplace(jl_binding_t **bnd, jl_binding_partition_t **bpart, size_t world) JL_NOTSAFEPOINT @@ -1669,6 +1670,7 @@ JL_DLLEXPORT void jl_set_next_task(jl_task_t *task) JL_NOTSAFEPOINT; // -- synchronization utilities -- // extern jl_mutex_t typecache_lock; +extern jl_mutex_t world_counter_lock; #if defined(__APPLE__) void jl_mach_gc_end(void) JL_NOTSAFEPOINT; diff --git a/src/method.c b/src/method.c index 0a58f0d5c482c..4b39de9aa67e1 100644 --- a/src/method.c +++ b/src/method.c @@ -1073,16 +1073,28 @@ JL_DLLEXPORT void jl_check_gf(jl_value_t *gf, jl_sym_t *name) JL_DLLEXPORT jl_value_t *jl_declare_const_gf(jl_binding_t *b, jl_module_t *mod, jl_sym_t *name) { - jl_value_t *gf = jl_get_binding_value_if_const(b); - if (gf) { - jl_check_gf(gf, b->globalref->name); - return gf; - } - jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); - if (!jl_bkind_is_some_guard(decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction)))) + JL_LOCK(&world_counter_lock); + size_t new_world = jl_atomic_load_relaxed(&jl_world_counter) + 1; + jl_binding_partition_t *bpart = jl_get_binding_partition(b, new_world); + jl_ptr_kind_union_t pku = jl_walk_binding_inplace(&b, &bpart, new_world); + jl_value_t *gf = NULL; + if (!jl_bkind_is_some_guard(decode_restriction_kind(pku))) { + if (jl_bkind_is_some_constant(decode_restriction_kind(pku))) { + gf = decode_restriction_value(pku); + JL_GC_PROMISE_ROOTED(gf); + jl_check_gf(gf, b->globalref->name); + JL_UNLOCK(&world_counter_lock); + return gf; + } jl_errorf("cannot define function %s; it already has a value", jl_symbol_name(name)); - gf = (jl_value_t*)jl_new_generic_function(name, mod); - jl_declare_constant_val(b, mod, name, gf); + } + gf = (jl_value_t*)jl_new_generic_function(name, mod, new_world); + // From this point on (if we didn't error), we're committed to raising the world age, + // because we've used it to declare the type name. + jl_atomic_store_release(&jl_world_counter, new_world); + jl_declare_constant_val3(b, mod, name, gf, BINDING_KIND_CONST, new_world); + JL_GC_PROMISE_ROOTED(gf); + JL_UNLOCK(&world_counter_lock); return gf; } diff --git a/src/module.c b/src/module.c index 66049031f8790..be6779727bfdc 100644 --- a/src/module.c +++ b/src/module.c @@ -411,13 +411,13 @@ typedef struct _modstack_t { jl_sym_t *var; struct _modstack_t *prev; } modstack_t; -static jl_binding_t *jl_resolve_owner(jl_binding_t *b/*optional*/, jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, modstack_t *st); +static jl_binding_t *jl_resolve_owner(jl_binding_t *b/*optional*/, jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, modstack_t *st, size_t world); JL_DLLEXPORT jl_value_t *jl_reresolve_binding_value_seqcst(jl_binding_t *b) { jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); if (jl_bkind_is_some_guard(decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction)))) { - jl_resolve_owner(b, b->globalref->mod, b->globalref->name, NULL); + jl_resolve_owner(b, b->globalref->mod, b->globalref->name, NULL, jl_current_task->world_age); } return jl_get_binding_value_seqcst(b); } @@ -473,7 +473,7 @@ static int eq_bindings(jl_binding_partition_t *owner, jl_binding_t *alias, size_ } // find a binding from a module's `usings` list -static jl_binding_t *using_resolve_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, jl_module_t **from, modstack_t *st, int warn) +static jl_binding_t *using_resolve_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *var, jl_module_t **from, modstack_t *st, int warn, size_t world) { jl_binding_t *b = NULL; jl_binding_partition_t *bpart = NULL; @@ -487,20 +487,20 @@ static jl_binding_t *using_resolve_binding(jl_module_t *m JL_PROPAGATES_ROOT, jl JL_UNLOCK(&m->lock); jl_binding_t *tempb = jl_get_module_binding(imp, var, 0); if (tempb != NULL && tempb->exportp) { - tempb = jl_resolve_owner(NULL, imp, var, st); // find the owner for tempb + tempb = jl_resolve_owner(NULL, imp, var, st, world); // find the owner for tempb if (tempb == NULL) // couldn't resolve; try next using (see issue #6105) continue; - jl_binding_partition_t *tempbpart = jl_get_binding_partition(tempb, jl_current_task->world_age); + jl_binding_partition_t *tempbpart = jl_get_binding_partition(tempb, world); jl_ptr_kind_union_t tempb_pku = jl_atomic_load_relaxed(&tempbpart->restriction); - assert(decode_restriction_kind(tempb_pku) == BINDING_KIND_GLOBAL || decode_restriction_kind(tempb_pku) == BINDING_KIND_DECLARED || jl_bkind_is_some_constant(decode_restriction_kind(tempb_pku))); + assert(jl_bkind_is_some_guard(decode_restriction_kind(tempb_pku)) || decode_restriction_kind(tempb_pku) == BINDING_KIND_GLOBAL || decode_restriction_kind(tempb_pku) == BINDING_KIND_DECLARED || jl_bkind_is_some_constant(decode_restriction_kind(tempb_pku))); (void)tempb_pku; - if (bpart != NULL && !tempb->deprecated && !b->deprecated && !eq_bindings(tempbpart, b, jl_current_task->world_age)) { + if (bpart != NULL && !tempb->deprecated && !b->deprecated && !eq_bindings(tempbpart, b, world)) { if (warn) { // set usingfailed=1 to avoid repeating this warning // the owner will still be NULL, so it can be later imported or defined tempb = jl_get_module_binding(m, var, 1); - tempbpart = jl_get_binding_partition(tempb, jl_current_task->world_age); + tempbpart = jl_get_binding_partition(tempb, world); jl_atomic_store_release(&tempbpart->restriction, encode_restriction(NULL, BINDING_KIND_FAILED)); } return NULL; @@ -524,7 +524,7 @@ static jl_module_t *jl_binding_dbgmodule(jl_binding_t *b, jl_module_t *m, jl_sym if (decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction)) != BINDING_KIND_GLOBAL) { // for implicitly imported globals, try to re-resolve it to find the module we got it from most directly jl_module_t *from = NULL; - jl_binding_t *b2 = using_resolve_binding(m, var, &from, NULL, 0); + jl_binding_t *b2 = using_resolve_binding(m, var, &from, NULL, 0, jl_current_task->world_age); if (b2) { jl_binding_partition_t *b2part = jl_get_binding_partition(b2, jl_current_task->world_age); if (eq_bindings(b2part, b, jl_current_task->world_age)) @@ -538,11 +538,11 @@ static jl_module_t *jl_binding_dbgmodule(jl_binding_t *b, jl_module_t *m, jl_sym static void jl_binding_dep_message(jl_module_t *m, jl_sym_t *name, jl_binding_t *b); // get binding for reading. might return NULL for unbound. -static jl_binding_t *jl_resolve_owner(jl_binding_t *b/*optional*/, jl_module_t *m, jl_sym_t *var, modstack_t *st) +static jl_binding_t *jl_resolve_owner(jl_binding_t *b/*optional*/, jl_module_t *m, jl_sym_t *var, modstack_t *st, size_t world) { if (b == NULL) b = jl_get_module_binding(m, var, 1); - jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); + jl_binding_partition_t *bpart = jl_get_binding_partition(b, world); jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction); retry: if (decode_restriction_kind(pku) == BINDING_KIND_FAILED) @@ -561,7 +561,7 @@ static jl_binding_t *jl_resolve_owner(jl_binding_t *b/*optional*/, jl_module_t * } } jl_module_t *from = NULL; // for error message printing - b2 = using_resolve_binding(m, var, &from, &top, 1); + b2 = using_resolve_binding(m, var, &from, &top, 1, world); if (b2 == NULL) return NULL; assert(from); @@ -594,7 +594,7 @@ static jl_binding_t *jl_resolve_owner(jl_binding_t *b/*optional*/, jl_module_t * } return b2; } - jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age); + jl_walk_binding_inplace(&b, &bpart, world); return b; } @@ -606,7 +606,7 @@ JL_DLLEXPORT jl_binding_t *jl_binding_owner(jl_module_t *m, jl_sym_t *var) jl_module_t *from = m; jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction); if (decode_restriction_kind(pku) == BINDING_KIND_GUARD) { - b = using_resolve_binding(m, var, &from, NULL, 0); + b = using_resolve_binding(m, var, &from, NULL, 0, jl_current_task->world_age); bpart = jl_get_binding_partition(b, jl_current_task->world_age); } pku = jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age); @@ -637,7 +637,7 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_type(jl_module_t *m, jl_sym_t *var) JL_DLLEXPORT jl_binding_t *jl_get_binding(jl_module_t *m, jl_sym_t *var) { - return jl_resolve_owner(NULL, m, var, NULL); + return jl_resolve_owner(NULL, m, var, NULL, jl_current_task->world_age); } JL_DLLEXPORT jl_binding_t *jl_get_binding_or_error(jl_module_t *m, jl_sym_t *var) @@ -1001,7 +1001,7 @@ JL_DLLEXPORT jl_binding_t *jl_get_module_binding(jl_module_t *m, jl_sym_t *var, JL_DLLEXPORT jl_value_t *jl_get_globalref_value(jl_globalref_t *gr) { jl_binding_t *b = gr->binding; - b = jl_resolve_owner(b, gr->mod, gr->name, NULL); + b = jl_resolve_owner(b, gr->mod, gr->name, NULL, jl_current_task->world_age); // ignores b->deprecated return b == NULL ? NULL : jl_get_binding_value(b); } @@ -1028,6 +1028,7 @@ JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var // this function is mostly only used during initialization, so the data races here are not too important to us jl_binding_t *bp = jl_get_module_binding(m, var, 1); jl_binding_partition_t *bpart = jl_get_binding_partition(bp, jl_current_task->world_age); + assert(jl_bkind_is_some_guard(decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction)))); jl_atomic_store_release(&bpart->restriction, encode_restriction(val, BINDING_KIND_CONST)); jl_gc_wb(bpart, val); } @@ -1047,11 +1048,10 @@ void jl_invalidate_binding_refs(jl_globalref_t *ref, jl_binding_partition_t *inv JL_GC_POP(); } -extern jl_mutex_t world_counter_lock; JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr) { jl_binding_t *b = gr->binding; - b = jl_resolve_owner(b, gr->mod, gr->name, NULL); + b = jl_resolve_owner(b, gr->mod, gr->name, NULL, jl_current_task->world_age); jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); if (decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction)) == BINDING_KIND_GUARD) { @@ -1074,18 +1074,17 @@ JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr) JL_DLLEXPORT int jl_globalref_is_const(jl_globalref_t *gr) { jl_binding_t *b = gr->binding; - b = jl_resolve_owner(b, gr->mod, gr->name, NULL); + b = jl_resolve_owner(b, gr->mod, gr->name, NULL, jl_current_task->world_age); jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); if (!bpart) return 0; return jl_bkind_is_some_constant(decode_restriction_kind(jl_atomic_load_relaxed(&bpart->restriction))); } -JL_DLLEXPORT int jl_globalref_boundp(jl_globalref_t *gr) +JL_DLLEXPORT void jl_force_binding_resolution(jl_globalref_t *gr, size_t world) { jl_binding_t *b = gr->binding; - b = jl_resolve_owner(b, gr->mod, gr->name, NULL); - return b && jl_get_binding_value(b) != NULL; + jl_resolve_owner(b, gr->mod, gr->name, NULL, world); } JL_DLLEXPORT int jl_is_const(jl_module_t *m, jl_sym_t *var) diff --git a/src/staticdata.c b/src/staticdata.c index 7fad87652b26a..ff352cd8c152f 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1674,8 +1674,18 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED #ifndef _P64 write_uint(f, decode_restriction_kind(pku)); #endif - write_uint(f, bpart->min_world); - write_uint(f, jl_atomic_load_relaxed(&bpart->max_world)); + size_t max_world = jl_atomic_load_relaxed(&bpart->max_world); + if (max_world == ~(size_t)0) { + // Still valid. Will be considered primordial after re-load. + // We could consider updating min_world to the loaded world, but + // there doesn't appear to be much point. + write_uint(f, 0); + write_uint(f, max_world); + } else { + // The world will not be reachable after loading + write_uint(f, 1); + write_uint(f, 0); + } write_pointerfield(s, (jl_value_t*)jl_atomic_load_relaxed(&bpart->next)); #ifdef _P64 write_uint(f, decode_restriction_kind(pku)); // This will be moved back into place during deserialization (if necessary) @@ -2714,7 +2724,6 @@ static void jl_strip_all_codeinfos(void) jl_genericmemory_t *jl_global_roots_list; jl_genericmemory_t *jl_global_roots_keyset; jl_mutex_t global_roots_lock; -extern jl_mutex_t world_counter_lock; jl_mutex_t precompile_field_replace_lock; jl_svec_t *precompile_field_replace JL_GLOBALLY_ROOTED; diff --git a/src/toplevel.c b/src/toplevel.c index fb217ec7cb52e..dee9029e2feb7 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -66,14 +66,13 @@ void jl_module_run_initializer(jl_module_t *m) { JL_TIMING(INIT_MODULE, INIT_MODULE); jl_timing_show_module(m, JL_TIMING_DEFAULT_BLOCK); - jl_function_t *f = jl_module_get_initializer(m); - if (f == NULL) - return; jl_task_t *ct = jl_current_task; size_t last_age = ct->world_age; JL_TRY { ct->world_age = jl_atomic_load_acquire(&jl_world_counter); - jl_apply(&f, 1); + jl_function_t *f = jl_module_get_initializer(m); + if (f != NULL) + jl_apply(&f, 1); ct->world_age = last_age; } JL_CATCH { @@ -740,10 +739,15 @@ static void jl_eval_errorf(jl_module_t *m, const char *filename, int lineno, con JL_GC_POP(); } -JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val2(jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val, enum jl_partition_kind constant_kind) +JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val3( + jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val, + enum jl_partition_kind constant_kind, size_t new_world) { JL_GC_PUSH1(&val); - jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); + if (!b) { + b = jl_get_module_binding(mod, var, 1); + } + jl_binding_partition_t *bpart = jl_get_binding_partition(b, new_world); jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction); int did_warn = 0; while (1) { @@ -780,10 +784,27 @@ JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val2(jl_binding_t *b, j break; } } + // N.B.: This backdates the first definition of the constant to world age 0 for backwards compatibility + // TODO: Mark this specially with a separate partition. + if (bpart->min_world != 0) + bpart->min_world = new_world; JL_GC_POP(); return bpart; } +JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val2( + jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val, + enum jl_partition_kind constant_kind) +{ + JL_LOCK(&world_counter_lock); + size_t new_world = jl_atomic_load_relaxed(&jl_world_counter) + 1; + jl_binding_partition_t *bpart = jl_declare_constant_val3(b, mod, var, val, constant_kind, new_world); + if (bpart->min_world == new_world) + jl_atomic_store_release(&jl_world_counter, new_world); + JL_UNLOCK(&world_counter_lock); + return bpart; +} + JL_DLLEXPORT jl_binding_partition_t *jl_declare_constant_val(jl_binding_t *b, jl_module_t *mod, jl_sym_t *var, jl_value_t *val) { return jl_declare_constant_val2(b, mod, var, val, val ? BINDING_KIND_CONST : BINDING_KIND_UNDEF_CONST); @@ -869,6 +890,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val else if (head == jl_using_sym) { jl_sym_t *name = NULL; jl_module_t *from = eval_import_from(m, ex, "using"); + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); size_t i = 0; if (from) { i = 1; @@ -908,6 +930,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val jl_expr_t *path = (jl_expr_t*)jl_exprarg(a, 0); name = NULL; jl_module_t *import = eval_import_path(m, from, ((jl_expr_t*)path)->args, &name, "using"); + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); assert(name); check_macro_rename(name, asname, "using"); // `using A: B as C` syntax @@ -919,11 +942,13 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val "syntax: malformed \"using\" statement"); } JL_GC_POP(); + ct->world_age = last_age; return jl_nothing; } else if (head == jl_import_sym) { jl_sym_t *name = NULL; jl_module_t *from = eval_import_from(m, ex, "import"); + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); size_t i = 0; if (from) { i = 1; @@ -967,6 +992,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val "syntax: malformed \"import\" statement"); } JL_GC_POP(); + ct->world_age = last_age; return jl_nothing; } else if (head == jl_export_sym || head == jl_public_sym) { diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index e8aa1188ec213..c63c5a557acd8 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -639,18 +639,24 @@ function is_call_graph_uncached(sv::CC.InferenceState) return is_call_graph_uncached(parent::CC.InferenceState) end -isdefined_globalref(g::GlobalRef) = !iszero(ccall(:jl_globalref_boundp, Cint, (Any,), g)) - # aggressive global binding resolution within `repl_frame` function CC.abstract_eval_globalref(interp::REPLInterpreter, g::GlobalRef, bailed::Bool, sv::CC.InferenceState) + # Ignore saw_latestworld + partition = CC.abstract_eval_binding_partition!(interp, g, sv) if (interp.limit_aggressive_inference ? is_repl_frame(sv) : is_call_graph_uncached(sv)) - if isdefined_globalref(g) + if CC.is_defined_const_binding(CC.binding_kind(partition)) return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( - CC.RTEffects(Const(ccall(:jl_get_globalref_value, Any, (Any,), g)), Union{}, CC.EFFECTS_TOTAL), nothing) + CC.RTEffects(Const(CC.partition_restriction(partition)), Union{}, CC.EFFECTS_TOTAL), partition) + else + b = convert(Core.Binding, g) + if CC.binding_kind(partition) == CC.BINDING_KIND_GLOBAL && isdefined(b, :value) + return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( + CC.RTEffects(Const(b.value), Union{}, CC.EFFECTS_TOTAL), partition) + end end return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( - CC.RTEffects(Union{}, UndefVarError, CC.EFFECTS_THROWS), nothing) + CC.RTEffects(Union{}, UndefVarError, CC.EFFECTS_THROWS), partition) end return @invoke CC.abstract_eval_globalref(interp::CC.AbstractInterpreter, g::GlobalRef, bailed::Bool, sv::CC.InferenceState) diff --git a/stdlib/REPL/src/precompile.jl b/stdlib/REPL/src/precompile.jl index daa01f626aeab..4f3b3a6eae083 100644 --- a/stdlib/REPL/src/precompile.jl +++ b/stdlib/REPL/src/precompile.jl @@ -8,6 +8,7 @@ import ..REPL Base._track_dependencies[] = false try Base.include(@__MODULE__, joinpath(Sys.BINDIR, "..", "share", "julia", "test", "testhelpers", "FakePTYs.jl")) + @Core.latestworld import .FakePTYs: open_fake_pty finally Base._track_dependencies[] = true diff --git a/stdlib/REPL/test/precompilation.jl b/stdlib/REPL/test/precompilation.jl index 7efcf0b5e8282..01a062644596c 100644 --- a/stdlib/REPL/test/precompilation.jl +++ b/stdlib/REPL/test/precompilation.jl @@ -33,7 +33,7 @@ if !Sys.iswindows() # given this test checks that startup is snappy, it's best to add workloads to # contrib/generate_precompile.jl rather than increase this number. But if that's not # possible, it'd be helpful to add a comment with the statement and a reason below - expected_precompiles = 0 + expected_precompiles = 1 n_precompiles = count(r"precompile\(", tracecompile_out) diff --git a/stdlib/REPL/test/repl.jl b/stdlib/REPL/test/repl.jl index 809913502c3d7..8944fd76f31de 100644 --- a/stdlib/REPL/test/repl.jl +++ b/stdlib/REPL/test/repl.jl @@ -769,9 +769,9 @@ fake_repl() do stdin_write, stdout_read, repl julia> A = 3\e[201~ """) @test Main.A == 3 - @test Base.invokelatest(Main.foo, 4) - @test Base.invokelatest(Main.T17599, 3).a == 3 - @test !Base.invokelatest(Main.foo, 2) + @test @invokelatest(Main.foo(4)) + @test @invokelatest(Main.T17599(3)).a == 3 + @test !@invokelatest(Main.foo(2)) sendrepl2("""\e[200~ julia> goo(x) = x + 1 @@ -781,7 +781,7 @@ fake_repl() do stdin_write, stdout_read, repl 4\e[201~ """) @test Main.A == 4 - @test Base.invokelatest(Main.goo, 4) == 5 + @test @invokelatest(Main.goo(4)) == 5 # Test prefix removal only active in bracket paste mode sendrepl2("julia = 4\n julia> 3 && (A = 1)\n") diff --git a/stdlib/Serialization/test/runtests.jl b/stdlib/Serialization/test/runtests.jl index 4d9b439e639d7..f1b83ca947c7e 100644 --- a/stdlib/Serialization/test/runtests.jl +++ b/stdlib/Serialization/test/runtests.jl @@ -130,7 +130,7 @@ create_serialization_stream() do s # user-defined module modtype = eval(Meta.parse("$(modstring)")) serialize(s, modtype) seek(s, 0) - @test deserialize(s) === modtype + @test invokelatest(deserialize, s) === modtype end # DataType @@ -151,7 +151,7 @@ create_serialization_stream() do s # user-defined type utype = eval(Meta.parse("$(usertype)")) serialize(s, utype) seek(s, 0) - @test deserialize(s) === utype + @test invokelatest(deserialize, s) === utype end create_serialization_stream() do s # user-defined type @@ -160,7 +160,7 @@ create_serialization_stream() do s # user-defined type utype = eval(Meta.parse("$(usertype)")) serialize(s, utype) seek(s, 0) - @test deserialize(s) === utype + @test invokelatest(deserialize, s) === utype end create_serialization_stream() do s # user-defined type @@ -169,7 +169,7 @@ create_serialization_stream() do s # user-defined type utype = eval(Meta.parse("$(usertype)")) serialize(s, utype) seek(s, 0) - @test deserialize(s) == utype + @test invokelatest(deserialize, s) == utype end create_serialization_stream() do s # immutable struct with 1 field @@ -178,7 +178,7 @@ create_serialization_stream() do s # immutable struct with 1 field utype = eval(Meta.parse("$(usertype)")) serialize(s, utype) seek(s, 0) - @test deserialize(s) == utype + @test invokelatest(deserialize, s) == utype end create_serialization_stream() do s # immutable struct with 2 field @@ -187,7 +187,7 @@ create_serialization_stream() do s # immutable struct with 2 field utval = eval(Meta.parse("$(usertype)(1,2)")) serialize(s, utval) seek(s, 0) - @test deserialize(s) === utval + @test invokelatest(deserialize, s) === utval end create_serialization_stream() do s # immutable struct with 3 field @@ -196,7 +196,7 @@ create_serialization_stream() do s # immutable struct with 3 field utval = eval(Meta.parse("$(usertype)(1,2,3)")) serialize(s, utval) seek(s, 0) - @test deserialize(s) === utval + @test invokelatest(deserialize, s) === utval end create_serialization_stream() do s # immutable struct with 4 field @@ -205,7 +205,7 @@ create_serialization_stream() do s # immutable struct with 4 field utval = eval(Meta.parse("$(usertype)(1,2,3,4)")) serialize(s, utval) seek(s, 0) - @test deserialize(s) === utval + @test invokelatest(deserialize, s) === utval end # Expression diff --git a/test/core.jl b/test/core.jl index 4bbb2ca368019..3886e6728df10 100644 --- a/test/core.jl +++ b/test/core.jl @@ -2622,7 +2622,7 @@ end # issue #8338 let ex = Expr(:(=), :(f8338(x;y=4)), :(x*y)) eval(ex) - @test invokelatest(f8338, 2) == 8 + @test (@invokelatest f8338(2)) == 8 end # call overloading (#2403) diff --git a/test/loading.jl b/test/loading.jl index 09f96e1f43578..be8f08b4bfe22 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -798,6 +798,7 @@ end @testset "`::AbstractString` constraint on the path argument to `include`" begin for m ∈ (NotPkgModule, evalfile("testhelpers/just_module.jl")) + @Core.latestworld let i = m.include @test !applicable(i, (nothing,)) @test !applicable(i, (identity, nothing,)) diff --git a/test/precompile.jl b/test/precompile.jl index 55e97f5608b08..f5a412b416ddc 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -610,13 +610,17 @@ precompile_test_harness(false) do dir @eval using UseBaz @test haskey(Base.loaded_modules, Base.PkgId("UseBaz")) @test haskey(Base.loaded_modules, Base.PkgId("Baz")) - @test Base.invokelatest(UseBaz.biz) === 1 - @test Base.invokelatest(UseBaz.buz) === 2 - @test UseBaz.generating == 0 - @test UseBaz.incremental == 0 + invokelatest() do + @test UseBaz.biz() === 1 + @test UseBaz.buz() === 2 + @test UseBaz.generating == 0 + @test UseBaz.incremental == 0 + end @eval using Baz - @test Base.invokelatest(Baz.baz) === 1 - @test Baz === UseBaz.Baz + invokelatest() do + @test Baz.baz() === 1 + @test Baz === UseBaz.Baz + end # should not throw if the cachefile does not exist @test !isfile("DoesNotExist.ji") diff --git a/test/runtests.jl b/test/runtests.jl index fd0326d48ee6c..f0c5e1b94c376 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -112,7 +112,7 @@ cd(@__DIR__) do @everywhere include("testdefs.jl") if use_revise - Base.invokelatest(revise_trackall) + @invokelatest revise_trackall() Distributed.remotecall_eval(Main, workers(), revise_init_expr) end @@ -250,7 +250,7 @@ cd(@__DIR__) do wrkr = p before = time() resp, duration = try - r = remotecall_fetch(runtests, wrkr, test, test_path(test); seed=seed) + r = remotecall_fetch(@Base.world(runtests, ∞), wrkr, test, test_path(test); seed=seed) r, time() - before catch e isa(e, InterruptException) && return @@ -310,7 +310,7 @@ cd(@__DIR__) do t == "SharedArrays" && (isolate = false) before = time() resp, duration = try - r = Base.invokelatest(runtests, t, test_path(t), isolate, seed=seed) # runtests is defined by the include above + r = @invokelatest runtests(t, test_path(t), isolate, seed=seed) # runtests is defined by the include above r, time() - before catch e isa(e, InterruptException) && rethrow() diff --git a/test/syntax.jl b/test/syntax.jl index bdf9579b134eb..aaeeea7aec161 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3303,6 +3303,7 @@ const typeof = error end let ex = :(const $(esc(:x)) = 1; (::typeof($(esc(:foo43993))))() = $(esc(:x))) Core.eval(M43993, Expr(:var"hygienic-scope", ex, Core)) + @Core.latestworld @test M43993.x === 1 @test invokelatest(M43993.foo43993) === 1 end diff --git a/test/worlds.jl b/test/worlds.jl index 268a6664571fb..8bc96f8303aef 100644 --- a/test/worlds.jl +++ b/test/worlds.jl @@ -115,14 +115,14 @@ wc265_41332a = Task(tls_world_age) global wc265_41332d = Task(tls_world_age) nothing end)() -@test wc265 + 2 == get_world_counter() == tls_world_age() +@test wc265 + 3 == get_world_counter() == tls_world_age() schedule(wc265_41332a) schedule(wc265_41332b) schedule(wc265_41332c) schedule(wc265_41332d) @test wc265 == fetch(wc265_41332a) @test wc265 + 1 == fetch(wc265_41332b) -@test wc265 + 2 == fetch(wc265_41332c) +@test wc265 + 3 == fetch(wc265_41332c) @test wc265 + 1 == fetch(wc265_41332d) chnls, tasks = Base.channeled_tasks(2, wfunc) t265 = tasks[1] From 61e8f1d3e561e480a05285745239c0df66f111ef Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 22 Jan 2025 14:55:49 +0100 Subject: [PATCH 58/65] Move `jl_task_t` to `julia_threads.h` (#57117) This is a subset of PR #56477 . I hope that it will be easier to get this merged first, as it just moves things around, afterwards we can update #56477 and it will be considerably smaller, and will thus hopefully break less often (and in less bad ways) over time. (I can perform the required update of that PR, too). See also PR #57116 which contains another independent part of that PR. --- src/julia.h | 85 +++++---------------------------------------- src/julia_threads.h | 70 +++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 77 deletions(-) diff --git a/src/julia.h b/src/julia.h index 699b3cc196411..4c699ba059c65 100644 --- a/src/julia.h +++ b/src/julia.h @@ -72,21 +72,20 @@ typedef struct _jl_tls_states_t *jl_ptls_t; #endif #include "gc-interface.h" #include "julia_atomics.h" -#include "julia_threads.h" #include "julia_assert.h" +// the common fields are hidden before the pointer, but the following macro is +// used to indicate which types below are subtypes of jl_value_t +#define JL_DATA_TYPE +typedef struct _jl_value_t jl_value_t; +#include "julia_threads.h" + #ifdef __cplusplus extern "C" { #endif // core data types ------------------------------------------------------------ -// the common fields are hidden before the pointer, but the following macro is -// used to indicate which types below are subtypes of jl_value_t -#define JL_DATA_TYPE - -typedef struct _jl_value_t jl_value_t; - struct _jl_taggedvalue_bits { uintptr_t gc:2; uintptr_t in_image:1; @@ -484,9 +483,6 @@ typedef struct _jl_abi_override_t { jl_method_instance_t *def; } jl_abi_override_t; -// all values are callable as Functions -typedef jl_value_t jl_function_t; - typedef struct { JL_DATA_TYPE jl_sym_t *name; @@ -2262,12 +2258,8 @@ JL_DLLEXPORT void jl_sigatomic_end(void); // tasks and exceptions ------------------------------------------------------- -typedef struct _jl_timing_block_t jl_timing_block_t; -typedef struct _jl_timing_event_t jl_timing_event_t; -typedef struct _jl_excstack_t jl_excstack_t; - // info describing an exception handler -typedef struct _jl_handler_t { +struct _jl_handler_t { jl_jmp_buf eh_ctx; jl_gcframe_t *gcstack; jl_value_t *scope; @@ -2277,68 +2269,7 @@ typedef struct _jl_handler_t { sig_atomic_t defer_signal; jl_timing_block_t *timing_stack; size_t world_age; -} jl_handler_t; - -#define JL_RNG_SIZE 5 // xoshiro 4 + splitmix 1 - -typedef struct _jl_task_t { - JL_DATA_TYPE - jl_value_t *next; // invasive linked list for scheduler - jl_value_t *queue; // invasive linked list for scheduler - jl_value_t *tls; - jl_value_t *donenotify; - jl_value_t *result; - jl_value_t *scope; - jl_function_t *start; - _Atomic(uint8_t) _state; - uint8_t sticky; // record whether this Task can be migrated to a new thread - uint16_t priority; - _Atomic(uint8_t) _isexception; // set if `result` is an exception to throw or that we exited with - uint8_t pad0[3]; - // === 64 bytes (cache line) - uint64_t rngState[JL_RNG_SIZE]; - // flag indicating whether or not to record timing metrics for this task - uint8_t metrics_enabled; - uint8_t pad1[3]; - // timestamp this task first entered the run queue - _Atomic(uint64_t) first_enqueued_at; - // timestamp this task was most recently scheduled to run - _Atomic(uint64_t) last_started_running_at; - // time this task has spent running; updated when it yields or finishes. - _Atomic(uint64_t) running_time_ns; - // === 64 bytes (cache line) - // timestamp this task finished (i.e. entered state DONE or FAILED). - _Atomic(uint64_t) finished_at; - -// hidden state: - - // id of owning thread - does not need to be defined until the task runs - _Atomic(int16_t) tid; - // threadpool id - int8_t threadpoolid; - // Reentrancy bits - // Bit 0: 1 if we are currently running inference/codegen - // Bit 1-2: 0-3 counter of how many times we've reentered inference - // Bit 3: 1 if we are writing the image and inference is illegal - uint8_t reentrant_timing; - // 2 bytes of padding on 32-bit, 6 bytes on 64-bit - // uint16_t padding2_32; - // uint48_t padding2_64; - // saved gc stack top for context switches - jl_gcframe_t *gcstack; - size_t world_age; - // quick lookup for current ptls - jl_ptls_t ptls; // == jl_all_tls_states[tid] -#ifdef USE_TRACY - const char *name; -#endif - // saved exception stack - jl_excstack_t *excstack; - // current exception handler - jl_handler_t *eh; - // saved thread state - jl_ucontext_t ctx; // pointer into stkbuf, if suspended -} jl_task_t; +}; #define JL_TASK_STATE_RUNNABLE 0 #define JL_TASK_STATE_DONE 1 diff --git a/src/julia_threads.h b/src/julia_threads.h index b6ef65dc7fe52..061eb9266e7a7 100644 --- a/src/julia_threads.h +++ b/src/julia_threads.h @@ -218,6 +218,76 @@ typedef struct _jl_tls_states_t { #endif } jl_tls_states_t; +#define JL_RNG_SIZE 5 // xoshiro 4 + splitmix 1 + +// all values are callable as Functions +typedef jl_value_t jl_function_t; + +typedef struct _jl_timing_block_t jl_timing_block_t; +typedef struct _jl_timing_event_t jl_timing_event_t; +typedef struct _jl_excstack_t jl_excstack_t; + +typedef struct _jl_handler_t jl_handler_t; + +typedef struct _jl_task_t { + JL_DATA_TYPE + jl_value_t *next; // invasive linked list for scheduler + jl_value_t *queue; // invasive linked list for scheduler + jl_value_t *tls; + jl_value_t *donenotify; + jl_value_t *result; + jl_value_t *scope; + jl_function_t *start; + _Atomic(uint8_t) _state; + uint8_t sticky; // record whether this Task can be migrated to a new thread + uint16_t priority; + _Atomic(uint8_t) _isexception; // set if `result` is an exception to throw or that we exited with + uint8_t pad0[3]; + // === 64 bytes (cache line) + uint64_t rngState[JL_RNG_SIZE]; + // flag indicating whether or not to record timing metrics for this task + uint8_t metrics_enabled; + uint8_t pad1[3]; + // timestamp this task first entered the run queue + _Atomic(uint64_t) first_enqueued_at; + // timestamp this task was most recently scheduled to run + _Atomic(uint64_t) last_started_running_at; + // time this task has spent running; updated when it yields or finishes. + _Atomic(uint64_t) running_time_ns; + // === 64 bytes (cache line) + // timestamp this task finished (i.e. entered state DONE or FAILED). + _Atomic(uint64_t) finished_at; + +// hidden state: + + // id of owning thread - does not need to be defined until the task runs + _Atomic(int16_t) tid; + // threadpool id + int8_t threadpoolid; + // Reentrancy bits + // Bit 0: 1 if we are currently running inference/codegen + // Bit 1-2: 0-3 counter of how many times we've reentered inference + // Bit 3: 1 if we are writing the image and inference is illegal + uint8_t reentrant_timing; + // 2 bytes of padding on 32-bit, 6 bytes on 64-bit + // uint16_t padding2_32; + // uint48_t padding2_64; + // saved gc stack top for context switches + jl_gcframe_t *gcstack; + size_t world_age; + // quick lookup for current ptls + jl_ptls_t ptls; // == jl_all_tls_states[tid] +#ifdef USE_TRACY + const char *name; +#endif + // saved exception stack + jl_excstack_t *excstack; + // current exception handler + jl_handler_t *eh; + // saved thread state + jl_ucontext_t ctx; // pointer into stkbuf, if suspended +} jl_task_t; + JL_DLLEXPORT void *jl_get_ptls_states(void); // Update codegen version in `ccall.cpp` after changing either `pause` or `wake` From eed336505356b51efc0ab6fa0daa46d339878efe Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Wed, 22 Jan 2025 12:51:09 -0500 Subject: [PATCH 59/65] Docs: Update version that version-named manifests works from (#56709) --- doc/src/manual/code-loading.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/manual/code-loading.md b/doc/src/manual/code-loading.md index 5c8315693c71e..24e64b0ca068e 100644 --- a/doc/src/manual/code-loading.md +++ b/doc/src/manual/code-loading.md @@ -63,7 +63,7 @@ Each kind of environment defines these three maps differently, as detailed in th ### Project environments -A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. However, from Julia v1.11 onwards, `(Julia)Manifest-v{major}.{minor}.toml` is recognized as a format to make a given julia version use a specific manifest file i.e. in the same folder, a `Manifest-v1.11.toml` would be used by v1.11 and `Manifest.toml` by any other julia version. +A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. However, from Julia v1.10.8 onwards, `(Julia)Manifest-v{major}.{minor}.toml` is recognized as a format to make a given julia version use a specific manifest file i.e. in the same folder, a `Manifest-v1.11.toml` would be used by v1.11 and `Manifest.toml` by any other julia version. The roots, graph and paths maps of a project environment are defined as follows: From 090e291eba1b7668bfc5234215750b4bd80f5387 Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Wed, 22 Jan 2025 17:30:00 -0500 Subject: [PATCH 60/65] runtime_intrinsics.c: Correct `max_double` (#57124) Closes #57119. --- src/runtime_intrinsics.c | 8 ++--- test/intrinsics.jl | 78 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 90afa3fb6bddf..49d510cc48c34 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -1424,17 +1424,17 @@ bi_fintrinsic(_min, min_float) float max_float(float x, float y) JL_NOTSAFEPOINT { float diff = x - y; - float argmin = signbit(diff) ? y : x; + float argmax = signbit(diff) ? y : x; int is_nan = isnan(x) || isnan(y); - return is_nan ? diff : argmin; + return is_nan ? diff : argmax; } double max_double(double x, double y) JL_NOTSAFEPOINT { double diff = x - y; - double argmin = signbit(diff) ? x : y; + double argmax = signbit(diff) ? y : x; int is_nan = isnan(x) || isnan(y); - return is_nan ? diff : argmin; + return is_nan ? diff : argmax; } #define _max(a, b) sizeof(a) == sizeof(float) ? max_float(a, b) : max_double(a, b) diff --git a/test/intrinsics.jl b/test/intrinsics.jl index 7a63cd1c0a62e..bc1838ce2c68b 100644 --- a/test/intrinsics.jl +++ b/test/intrinsics.jl @@ -147,9 +147,81 @@ macro test_intrinsic(intr, args...) end end +@testset "Float64 intrinsics" begin + # unary + @test_intrinsic Core.Intrinsics.abs_float Float64(-3.3) Float64(3.3) + @test_intrinsic Core.Intrinsics.neg_float Float64(3.3) Float64(-3.3) + @test_intrinsic Core.Intrinsics.fpext Float64 Float64(3.3) Float64(3.3) + + # binary + @test_intrinsic Core.Intrinsics.add_float Float64(3.3) Float64(2) Float64(5.3) + @test_intrinsic Core.Intrinsics.sub_float Float64(3.3) Float64(2) Float64(1.2999999999999998) + @test_intrinsic Core.Intrinsics.mul_float Float64(3.3) Float64(2) Float64(6.6) + @test_intrinsic Core.Intrinsics.div_float Float64(3.3) Float64(2) Float64(1.65) + @test_intrinsic Core.Intrinsics.max_float Float64(1.0) Float64(2.0) Float64(2.0) + @test_intrinsic Core.Intrinsics.min_float Float64(1.0) Float64(2.0) Float64(1.0) + + # ternary + @test_intrinsic Core.Intrinsics.fma_float Float64(3.3) Float64(4.4) Float64(5.5) Float64(20.02) + @test_intrinsic Core.Intrinsics.muladd_float Float64(3.3) Float64(4.4) Float64(5.5) Float64(20.02) + + # boolean + @test_intrinsic Core.Intrinsics.eq_float Float64(3.3) Float64(3.3) true + @test_intrinsic Core.Intrinsics.eq_float Float64(3.3) Float64(2) false + @test_intrinsic Core.Intrinsics.ne_float Float64(3.3) Float64(3.3) false + @test_intrinsic Core.Intrinsics.ne_float Float64(3.3) Float64(2) true + @test_intrinsic Core.Intrinsics.le_float Float64(3.3) Float64(3.3) true + @test_intrinsic Core.Intrinsics.le_float Float64(3.3) Float64(2) false + + # conversions + @test_intrinsic Core.Intrinsics.sitofp Float64 3 Float64(3.0) + @test_intrinsic Core.Intrinsics.uitofp Float64 UInt(3) Float64(3.0) + @test_intrinsic Core.Intrinsics.fptosi Int Float64(3.3) 3 + @test_intrinsic Core.Intrinsics.fptoui UInt Float64(3.3) UInt(3) +end + +@testset "Float32 intrinsics" begin + # unary + @test_intrinsic Core.Intrinsics.abs_float Float32(-3.3) Float32(3.3) + @test_intrinsic Core.Intrinsics.neg_float Float32(3.3) Float32(-3.3) + @test_intrinsic Core.Intrinsics.fpext Float32 Float32(3.3) Float32(3.3) + @test_intrinsic Core.Intrinsics.fpext Float64 Float32(3.3) 3.299999952316284 + @test_intrinsic Core.Intrinsics.fptrunc Float32 Float64(3.3) Float32(3.3) + + # binary + @test_intrinsic Core.Intrinsics.add_float Float32(3.3) Float32(2) Float32(5.3) + @test_intrinsic Core.Intrinsics.sub_float Float32(3.3) Float32(2) Float32(1.3) + @test_intrinsic Core.Intrinsics.mul_float Float32(3.3) Float32(2) Float32(6.6) + @test_intrinsic Core.Intrinsics.div_float Float32(3.3) Float32(2) Float32(1.65) + @test_intrinsic Core.Intrinsics.max_float Float32(1.0) Float32(2.0) Float32(2.0) + @test_intrinsic Core.Intrinsics.min_float Float32(1.0) Float32(2.0) Float32(1.0) + + # ternary + @test_intrinsic Core.Intrinsics.fma_float Float32(3.3) Float32(4.4) Float32(5.5) Float32(20.02) + @test_intrinsic Core.Intrinsics.muladd_float Float32(3.3) Float32(4.4) Float32(5.5) Float32(20.02) + + # boolean + @test_intrinsic Core.Intrinsics.eq_float Float32(3.3) Float32(3.3) true + @test_intrinsic Core.Intrinsics.eq_float Float32(3.3) Float32(2) false + @test_intrinsic Core.Intrinsics.ne_float Float32(3.3) Float32(3.3) false + @test_intrinsic Core.Intrinsics.ne_float Float32(3.3) Float32(2) true + @test_intrinsic Core.Intrinsics.le_float Float32(3.3) Float32(3.3) true + @test_intrinsic Core.Intrinsics.le_float Float32(3.3) Float32(2) false + + # conversions + @test_intrinsic Core.Intrinsics.sitofp Float32 3 Float32(3.0) + @test_intrinsic Core.Intrinsics.uitofp Float32 UInt(3) Float32(3.0) + @test_intrinsic Core.Intrinsics.fptosi Int Float32(3.3) 3 + @test_intrinsic Core.Intrinsics.fptoui UInt Float32(3.3) UInt(3) +end + @testset "Float16 intrinsics" begin # unary + @test_intrinsic Core.Intrinsics.abs_float Float16(-3.3) Float16(3.3) @test_intrinsic Core.Intrinsics.neg_float Float16(3.3) Float16(-3.3) + # See + #broken @test_intrinsic Core.Intrinsics.fpext Float16 Float16(3.3) Float16(3.3) + @test_broken Core.Intrinsics.fpext(Float16, Float16(3.3)) === Float16(3.3) @test_intrinsic Core.Intrinsics.fpext Float32 Float16(3.3) 3.3007812f0 @test_intrinsic Core.Intrinsics.fpext Float64 Float16(3.3) 3.30078125 @test_intrinsic Core.Intrinsics.fptrunc Float16 Float32(3.3) Float16(3.3) @@ -160,6 +232,8 @@ end @test_intrinsic Core.Intrinsics.sub_float Float16(3.3) Float16(2) Float16(1.301) @test_intrinsic Core.Intrinsics.mul_float Float16(3.3) Float16(2) Float16(6.6) @test_intrinsic Core.Intrinsics.div_float Float16(3.3) Float16(2) Float16(1.65) + @test_intrinsic Core.Intrinsics.max_float Float16(1.0) Float16(2.0) Float16(2.0) + @test_intrinsic Core.Intrinsics.min_float Float16(1.0) Float16(2.0) Float16(1.0) # ternary @test_intrinsic Core.Intrinsics.fma_float Float16(3.3) Float16(4.4) Float16(5.5) Float16(20.02) @@ -174,8 +248,8 @@ end @test_intrinsic Core.Intrinsics.le_float Float16(3.3) Float16(2) false # conversions - @test_intrinsic Core.Intrinsics.sitofp Float16 3 Float16(3f0) - @test_intrinsic Core.Intrinsics.uitofp Float16 UInt(3) Float16(3f0) + @test_intrinsic Core.Intrinsics.sitofp Float16 3 Float16(3.0) + @test_intrinsic Core.Intrinsics.uitofp Float16 UInt(3) Float16(3.0) @test_intrinsic Core.Intrinsics.fptosi Int Float16(3.3) 3 @test_intrinsic Core.Intrinsics.fptoui UInt Float16(3.3) UInt(3) end From f52c4ab7215d81d7fea1fd2f4043b1f20c92dce3 Mon Sep 17 00:00:00 2001 From: Jakob Nybo Nissen Date: Thu, 23 Jan 2025 12:12:15 +0100 Subject: [PATCH 61/65] Expand on docstring of GC.safepoint (#57128) Update the docstring to mention the following points: * Safepoints are very fast, but may still degrade performance in tight loops * Safepoints do not trigger the GC, but instead stops a task from blocking GC that would otherwise run. * Switch terminology from mentioning 'threads' to 'tasks' --- base/gcutils.jl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/base/gcutils.jl b/base/gcutils.jl index 84a184537ffc0..60b8ecdd17d65 100644 --- a/base/gcutils.jl +++ b/base/gcutils.jl @@ -243,12 +243,21 @@ end GC.safepoint() Inserts a point in the program where garbage collection may run. -This can be useful in rare cases in multi-threaded programs where some threads -are allocating memory (and hence may need to run GC) but other threads are doing -only simple operations (no allocation, task switches, or I/O). -Calling this function periodically in non-allocating threads allows garbage + +Safepoints are fast and do not themselves trigger garbage collection. +However, if another thread has requested the GC to run, reaching a safepoint will +cause the current thread to block and wait for the GC. + +This can be useful in rare cases in multi-threaded programs where some tasks +are allocating memory (and hence may need to run GC) but other tasks are doing +only simple operations (no allocation, task switches, or I/O), which do not +yield control to Julia's runtime, and therefore blocks the GC from running. +Calling this function periodically in the non-allocating tasks allows garbage collection to run. +Note that even though safepoints are fast (typically around 2 clock cycles), +they can still degrade performance if called in a tight loop. + !!! compat "Julia 1.4" This function is available as of Julia 1.4. """ From 88c71dd2164030ef9563a57ef3f1072581d8efca Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 23 Jan 2025 09:51:06 -0500 Subject: [PATCH 62/65] REPL: Handle message from `complete_methods!` when max methods is hit (#57138) --- stdlib/REPL/src/REPLCompletions.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index c63c5a557acd8..26ad6651cd880 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -1097,6 +1097,9 @@ function complete_keyword_argument(partial::String, last_idx::Int, context_modul last_word = partial[wordrange] # the word to complete kwargs = Set{String}() for m in methods + # if MAX_METHOD_COMPLETIONS is hit a single TextCompletion is return by complete_methods! with an explanation + # which can be ignored here + m isa TextCompletion && continue m::MethodCompletion possible_kwargs = Base.kwarg_decl(m.method) current_kwarg_candidates = String[] From b76fd9f3148b66d418c1fbac3d729c0d318a654d Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 23 Jan 2025 15:02:46 -0500 Subject: [PATCH 63/65] codegen: fix unsound mark_volatile_vars implementation (#57131) The previous implementation was incorrect, leading to failing to mark variables correctly. The new implementation is more conservative. This simple analysis assumes that inference has normally run or that performance doesn't matter for a particular block of code. Fixes #56996 --- Compiler/test/codegen.jl | 17 +++++ src/codegen.cpp | 149 ++++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 73 deletions(-) diff --git a/Compiler/test/codegen.jl b/Compiler/test/codegen.jl index ff61ac719c59e..57a9c26aefac6 100644 --- a/Compiler/test/codegen.jl +++ b/Compiler/test/codegen.jl @@ -1041,3 +1041,20 @@ struct Vec56937 x::NTuple{8, VecElement{Int}} end x56937 = Ref(Vec56937(ntuple(_->VecElement(1),8))) @test x56937[].x[1] == VecElement{Int}(1) # shouldn't crash + +# issue #56996 +let + ()->() # trigger various heuristics + Base.Experimental.@force_compile + default_rng_orig = [] # make a value in a Slot + try + # overwrite the gc-slots in the exception branch + throw(ErrorException("This test is supposed to throw an error")) + catch ex + # destroy any values that aren't referenced + GC.gc() + # make sure that default_rng_orig value is still valid + @noinline copy!([], default_rng_orig) + end + nothing +end diff --git a/src/codegen.cpp b/src/codegen.cpp index e047632923f68..60e53f75638ed 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3282,24 +3282,7 @@ static bool local_var_occurs(jl_value_t *e, int sl) return false; } -static std::set assigned_in_try(jl_array_t *stmts, int s, long l) -{ - std::set av; - for(int i=s; i < l; i++) { - jl_value_t *st = jl_array_ptr_ref(stmts,i); - if (jl_is_expr(st)) { - if (((jl_expr_t*)st)->head == jl_assign_sym) { - jl_value_t *ar = jl_exprarg(st, 0); - if (jl_is_slotnumber(ar)) { - av.insert(jl_slot_number(ar)-1); - } - } - } - } - return av; -} - -static void mark_volatile_vars(jl_array_t *stmts, SmallVectorImpl &slots) +static bool have_try_block(jl_array_t *stmts) { size_t slength = jl_array_dim0(stmts); for (int i = 0; i < (int)slength; i++) { @@ -3308,19 +3291,38 @@ static void mark_volatile_vars(jl_array_t *stmts, SmallVectorImpl int last = jl_enternode_catch_dest(st); if (last == 0) continue; - std::set as = assigned_in_try(stmts, i + 1, last - 1); - for (int j = 0; j < (int)slength; j++) { - if (j < i || j > last) { - std::set::iterator it = as.begin(); - for (; it != as.end(); it++) { - if (local_var_occurs(jl_array_ptr_ref(stmts, j), *it)) { - jl_varinfo_t &vi = slots[*it]; - vi.isVolatile = true; - } - } + return 1; + } + } + return 0; +} + +// conservative marking of all variables potentially used after a catch block that were assigned before it +static void mark_volatile_vars(jl_array_t *stmts, SmallVectorImpl &slots, const std::set &bbstarts) +{ + if (!have_try_block(stmts)) + return; + size_t slength = jl_array_dim0(stmts); + BitVector assigned_in_block(slots.size()); // conservatively only ignore slots assigned in the same basic block + for (int j = 0; j < (int)slength; j++) { + if (bbstarts.count(j + 1)) + assigned_in_block.reset(); + jl_value_t *stmt = jl_array_ptr_ref(stmts, j); + if (jl_is_expr(stmt)) { + jl_expr_t *e = (jl_expr_t*)stmt; + if (e->head == jl_assign_sym) { + jl_value_t *l = jl_exprarg(e, 0); + if (jl_is_slotnumber(l)) { + assigned_in_block.set(jl_slot_number(l)-1); } } } + for (int slot = 0; slot < (int)slots.size(); slot++) { + if (!assigned_in_block.test(slot) && local_var_occurs(stmt, slot)) { + jl_varinfo_t &vi = slots[slot]; + vi.isVolatile = true; + } + } } } @@ -8439,7 +8441,6 @@ static jl_llvm_functions_t ctx.code = src->code; ctx.source = src; - std::map labels; ctx.module = jl_is_method(lam->def.method) ? lam->def.method->module : lam->def.module; ctx.linfo = lam; ctx.name = name_from_method_instance(lam); @@ -8499,6 +8500,49 @@ static jl_llvm_functions_t if (dbgFuncName.empty()) // Should never happen anymore? debug_enabled = false; + // First go through and collect all branch targets, so we know where to + // split basic blocks. + std::set branch_targets; // 1-indexed, sorted + for (size_t i = 0; i < stmtslen; ++i) { + jl_value_t *stmt = jl_array_ptr_ref(stmts, i); + if (jl_is_gotoifnot(stmt)) { + int dest = jl_gotoifnot_label(stmt); + branch_targets.insert(dest); + // The next 1-indexed statement + branch_targets.insert(i + 2); + } + else if (jl_is_returnnode(stmt)) { + // We don't do dead branch elimination before codegen + // so we need to make sure to start a BB after any + // return node, even if they aren't otherwise branch + // targets. + if (i + 2 <= stmtslen) + branch_targets.insert(i + 2); + } + else if (jl_is_enternode(stmt)) { + branch_targets.insert(i + 1); + if (i + 2 <= stmtslen) + branch_targets.insert(i + 2); + size_t catch_dest = jl_enternode_catch_dest(stmt); + if (catch_dest) + branch_targets.insert(catch_dest); + } + else if (jl_is_gotonode(stmt)) { + int dest = jl_gotonode_label(stmt); + branch_targets.insert(dest); + if (i + 2 <= stmtslen) + branch_targets.insert(i + 2); + } + else if (jl_is_phinode(stmt)) { + jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(stmt, 0); + for (size_t j = 0; j < jl_array_nrows(edges); ++j) { + size_t edge = jl_array_data(edges, int32_t)[j]; + if (edge == i) + branch_targets.insert(i + 1); + } + } + } + // step 2. process var-info lists to see what vars need boxing int n_ssavalues = jl_is_long(src->ssavaluetypes) ? jl_unbox_long(src->ssavaluetypes) : jl_array_nrows(src->ssavaluetypes); size_t vinfoslen = jl_array_dim0(src->slotflags); @@ -8559,7 +8603,7 @@ static jl_llvm_functions_t simple_use_analysis(ctx, jl_array_ptr_ref(stmts, i)); // determine which vars need to be volatile - mark_volatile_vars(stmts, ctx.slots); + mark_volatile_vars(stmts, ctx.slots, branch_targets); // step 4. determine function signature if (!specsig) @@ -9310,8 +9354,8 @@ static jl_llvm_functions_t // step 11b. Do codegen in control flow order SmallVector workstack; - std::map BB; - std::map come_from_bb; + DenseMap BB; + DenseMap come_from_bb; int cursor = 0; int current_label = 0; auto find_next_stmt = [&] (int seq_next) { @@ -9430,47 +9474,6 @@ static jl_llvm_functions_t come_from_bb[0] = ctx.builder.GetInsertBlock(); - // First go through and collect all branch targets, so we know where to - // split basic blocks. - std::set branch_targets; // 1-indexed - { - for (size_t i = 0; i < stmtslen; ++i) { - jl_value_t *stmt = jl_array_ptr_ref(stmts, i); - if (jl_is_gotoifnot(stmt)) { - int dest = jl_gotoifnot_label(stmt); - branch_targets.insert(dest); - // The next 1-indexed statement - branch_targets.insert(i + 2); - } else if (jl_is_returnnode(stmt)) { - // We don't do dead branch elimination before codegen - // so we need to make sure to start a BB after any - // return node, even if they aren't otherwise branch - // targets. - if (i + 2 <= stmtslen) - branch_targets.insert(i + 2); - } else if (jl_is_enternode(stmt)) { - branch_targets.insert(i + 1); - if (i + 2 <= stmtslen) - branch_targets.insert(i + 2); - size_t catch_dest = jl_enternode_catch_dest(stmt); - if (catch_dest) - branch_targets.insert(catch_dest); - } else if (jl_is_gotonode(stmt)) { - int dest = jl_gotonode_label(stmt); - branch_targets.insert(dest); - if (i + 2 <= stmtslen) - branch_targets.insert(i + 2); - } else if (jl_is_phinode(stmt)) { - jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(stmt, 0); - for (size_t j = 0; j < jl_array_nrows(edges); ++j) { - size_t edge = jl_array_data(edges, int32_t)[j]; - if (edge == i) - branch_targets.insert(i + 1); - } - } - } - } - for (int label : branch_targets) { BasicBlock *bb = BasicBlock::Create(ctx.builder.getContext(), "L" + std::to_string(label), f); From 3054c681785473d689290da96205956a962fa283 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Thu, 23 Jan 2025 20:36:33 -0300 Subject: [PATCH 64/65] Don't use altstack for the sigusr2 handler (#57134) This works around an rr bug with nested signal handlers and syscalls. But it's also mostly unecessary as it doesn't need to handle stack overflows --- src/signals-unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/signals-unix.c b/src/signals-unix.c index 788539b1f5096..c730f27f16def 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -1208,7 +1208,7 @@ void jl_install_default_signal_handlers(void) memset(&act, 0, sizeof(struct sigaction)); sigemptyset(&act.sa_mask); act.sa_sigaction = usr2_handler; - act.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTART; + act.sa_flags = SA_SIGINFO | SA_RESTART; if (sigaction(SIGUSR2, &act, NULL) < 0) { jl_errorf("fatal error: sigaction: %s", strerror(errno)); } From 6eb42dbc69140e3bf4583a2b87b50bf3e7bdd29f Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 24 Jan 2025 02:23:29 +0100 Subject: [PATCH 65/65] Fix missing nargs setting in abioverride test (#57144) The only place that really reads this is the debug info generation, which is not enabled by default, but this test would crash if you ran it on a debug build of julia. --- Compiler/test/abioverride.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/Compiler/test/abioverride.jl b/Compiler/test/abioverride.jl index da9b1f92786e5..49907ea8e4c63 100644 --- a/Compiler/test/abioverride.jl +++ b/Compiler/test/abioverride.jl @@ -40,6 +40,7 @@ let world = Base.tls_world_age() ## Remove the argument resize!(new_source.slotnames, 2) resize!(new_source.slotflags, 2) + new_source.nargs = 2 # Construct the CodeInstance from the modified CodeInfo data global new_ci = Core.CodeInstance(Core.ABIOverride(Tuple{typeof(myplus), Int}, mi),