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" } 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" diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 8dd15462ed998..ea939f86422c5 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -41,36 +41,37 @@ ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Compiler, using Core.Intrinsics, Core.IR -import Core: print, println, show, write, unsafe_write, - _apply_iterate, svec, apply_type, Builtin, IntrinsicFunction, - MethodInstance, CodeInstance, MethodTable, MethodMatch, PartialOpaque, - TypeofVararg, Core, SimpleVector, donotdelete, compilerbarrier, - memoryref_isassigned, memoryrefnew, memoryrefoffset, memoryrefget, - memoryrefset!, typename +using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch, + MethodTable, PartialOpaque, SimpleVector, TypeofVararg, + _apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned, + memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec, + typename, unsafe_write, write using Base -using Base: Ordering, vect, EffectsOverride, BitVector, @_gc_preserve_begin, @_gc_preserve_end, RefValue, - @nospecializeinfer, @_foldable_meta, fieldindex, is_function_def, indexed_iterate, isexpr, methods, - get_world_counter, JLOptions, _methods_by_ftype, unwrap_unionall, cconvert, unsafe_convert, - issingletontype, isType, rewrap_unionall, has_free_typevars, isvarargtype, hasgenerator, - IteratorSize, SizeUnknown, _array_for, Bottom, generating_output, diff_names, - ismutationfree, NUM_EFFECTS_OVERRIDES, _NAMEDTUPLE_NAME, datatype_fieldtypes, - argument_datatype, isfieldatomic, unwrapva, iskindtype, _bits_findnext, copy_exprargs, - Generator, Filter, ismutabletypename, isvatuple, datatype_fieldcount, - isconcretedispatch, isdispatchelem, datatype_layoutsize, - datatype_arrayelem, unionlen, isidentityfree, _uniontypes, uniontypes, OneTo, Callable, - DataTypeFieldDesc, datatype_nfields, datatype_pointerfree, midpoint, is_valid_intrinsic_elptr, - allocatedinline, isbitsunion, widen_diagonal, unconstrain_vararg_length, - rename_unionall, may_invoke_generator, is_meta_expr_head, is_meta_expr, quoted, - specialize_method, hasintersect, is_nospecializeinfer, is_nospecialized, - get_nospecializeinfer_sig, tls_world_age, uniontype_layout, kwerr, - moduleroot, is_file_tracked, decode_effects_override, lookup_binding_partition, - is_some_imported, binding_kind, is_some_guard, is_some_const_binding, partition_restriction, - BINDING_KIND_GLOBAL, structdiff +using Base: @_foldable_meta, @_gc_preserve_begin, @_gc_preserve_end, @nospecializeinfer, + BINDING_KIND_GLOBAL, BINDING_KIND_UNDEF_CONST, Base, BitVector, Bottom, Callable, DataTypeFieldDesc, + EffectsOverride, Filter, Generator, IteratorSize, JLOptions, NUM_EFFECTS_OVERRIDES, + OneTo, Ordering, RefValue, SizeUnknown, _NAMEDTUPLE_NAME, + _array_for, _bits_findnext, _methods_by_ftype, _uniontypes, all, allocatedinline, any, + argument_datatype, binding_kind, cconvert, copy_exprargs, datatype_arrayelem, + datatype_fieldcount, datatype_fieldtypes, datatype_layoutsize, datatype_nfields, + datatype_pointerfree, decode_effects_override, diff_names, fieldindex, + generating_output, get_nospecializeinfer_sig, get_world_counter, has_free_typevars, + hasgenerator, hasintersect, indexed_iterate, isType, is_file_tracked, is_function_def, + is_meta_expr, is_meta_expr_head, is_nospecialized, is_nospecializeinfer, is_defined_const_binding, + is_some_const_binding, is_some_guard, is_some_imported, is_valid_intrinsic_elptr, + isbitsunion, isconcretedispatch, isdispatchelem, isexpr, isfieldatomic, isidentityfree, + iskindtype, ismutabletypename, ismutationfree, issingletontype, isvarargtype, isvatuple, + kwerr, lookup_binding_partition, may_invoke_generator, methods, midpoint, moduleroot, + partition_restriction, quoted, rename_unionall, rewrap_unionall, specialize_method, + structdiff, tls_world_age, unconstrain_vararg_length, unionlen, uniontype_layout, + uniontypes, unsafe_convert, unwrap_unionall, unwrapva, vect, widen_diagonal, + _uncompressed_ir using Base.Order -import Base: getindex, setindex!, length, iterate, push!, isempty, first, convert, ==, - copy, popfirst!, in, haskey, resize!, copy!, append!, last, get!, size, - get, iterate, findall, min_world, max_world, _topmod, isready + +import Base: ==, _topmod, append!, convert, copy, copy!, findall, first, get, get!, + getindex, haskey, in, isempty, isready, iterate, iterate, last, length, max_world, + min_world, popfirst!, push!, resize!, setindex!, size const getproperty = Core.getfield const setproperty! = Core.setfield! diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 2efd8a2b7264f..2b1a7fb2dd448 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) @@ -2212,6 +2213,18 @@ function abstract_call_unionall(interp::AbstractInterpreter, argtypes::Vector{An return CallMeta(ret, Any, Effects(EFFECTS_TOTAL; nothrow), call.info) end +function ci_abi(ci::CodeInstance) + def = ci.def + isa(def, ABIOverride) && return def.abi + (def::MethodInstance).specTypes +end + +function get_ci_mi(ci::CodeInstance) + def = ci.def + isa(def, ABIOverride) && return def.def + return def::MethodInstance +end + function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState) argtypes = arginfo.argtypes ft′ = argtype_by_index(argtypes, 2) @@ -2223,12 +2236,12 @@ function abstract_invoke(interp::AbstractInterpreter, arginfo::ArgInfo, si::Stmt if isa(method_or_ci, CodeInstance) our_world = sv.world.this argtype = argtypes_to_type(pushfirst!(argtype_tail(argtypes, 4), ft)) - specsig = method_or_ci.def.specTypes - defdef = method_or_ci.def.def + specsig = ci_abi(method_or_ci) + defdef = get_ci_mi(method_or_ci).def exct = method_or_ci.exctype if !hasintersect(argtype, specsig) return Future(CallMeta(Bottom, TypeError, EFFECTS_THROWS, NoCallInfo())) - elseif !(argtype <: specsig) || (isa(defdef, Method) && !(argtype <: defdef.sig)) + elseif !(argtype <: specsig) || ((!isa(method_or_ci.def, ABIOverride) && isa(defdef, Method)) && !(argtype <: defdef.sig)) exct = Union{exct, TypeError} end callee_valid_range = WorldRange(method_or_ci.min_world, method_or_ci.max_world) @@ -2383,7 +2396,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) @@ -2461,8 +2475,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 @@ -2500,7 +2514,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, @@ -2508,7 +2522,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}) @@ -2557,7 +2571,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 @@ -2625,21 +2639,14 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), elseif f === Core.getfield && argtypes_are_actually_getglobal(argtypes) return Future(abstract_eval_getglobal(interp, sv, si.saw_latestworld, argtypes)) elseif f === Core.isdefined && argtypes_are_actually_getglobal(argtypes) - exct = Bottom - if length(argtypes) == 4 - order = argtypes[4] - exct = global_order_exct(order, #=loading=#true, #=storing=#false) - if !(isa(order, Const) && get_atomic_order(order.val, #=loading=#true, #=storing=#false).x >= MEMORY_ORDER_UNORDERED.x) - exct = Union{exct, ConcurrencyViolationError} - end - end - return Future(merge_exct(CallMeta(abstract_eval_isdefined( - interp, - GlobalRef((argtypes[2]::Const).val::Module, - (argtypes[3]::Const).val::Symbol), - si.saw_latestworld, - sv), - NoCallInfo()), exct)) + return Future(abstract_eval_isdefinedglobal(interp, argtypes[2], argtypes[3], Const(true), + length(argtypes) == 4 ? argtypes[4] : Const(:unordered), + si.saw_latestworld, sv)) + elseif f === Core.isdefinedglobal && 3 <= length(argtypes) <= 5 + return Future(abstract_eval_isdefinedglobal(interp, argtypes[2], argtypes[3], + length(argtypes) >= 4 ? argtypes[4] : Const(true), + length(argtypes) >= 5 ? argtypes[5] : Const(:unordered), + si.saw_latestworld, sv)) elseif f === Core.get_binding_type return Future(abstract_eval_get_binding_type(interp, sv, argtypes)) end @@ -2656,7 +2663,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), if sv isa InferenceState && f === typeassert # perform very limited back-propagation of invariants after this type assertion if rt !== Bottom && isa(fargs, Vector{Any}) - farg2 = fargs[2] + farg2 = ssa_def_slot(fargs[2], sv) if farg2 isa SlotNumber refinements = SlotRefinement(farg2, rt) end @@ -2834,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 @@ -2894,20 +2902,21 @@ end function abstract_eval_cfunction(interp::AbstractInterpreter, e::Expr, sstate::StatementState, sv::AbsIntState) f = abstract_eval_value(interp, e.args[2], sstate, sv) - # rt = sp_type_rewrap(e.args[3], sv.linfo, true) + # rt = sp_type_rewrap(e.args[3], sv.linfo, true) # verify that the result type make sense? + # rt === Bottom && return RTEffects(Union{}, Any, EFFECTS_UNKNOWN) atv = e.args[4]::SimpleVector at = Vector{Any}(undef, length(atv) + 1) at[1] = f for i = 1:length(atv) - at[i + 1] = sp_type_rewrap(at[i], frame_instance(sv), false) - at[i + 1] === Bottom && return + atᵢ = at[i + 1] = sp_type_rewrap(atv[i], frame_instance(sv), false) + atᵢ === Bottom && return RTEffects(Union{}, Any, EFFECTS_UNKNOWN) end # this may be the wrong world for the call, # but some of the result is likely to be valid anyways # and that may help generate better codegen abstract_call(interp, ArgInfo(nothing, at), StmtInfo(false, false), sv)::Future rt = e.args[1] - isa(rt, Type) || (rt = Any) + isconcretetype(rt) || (rt = Any) return RTEffects(rt, Any, EFFECTS_UNKNOWN) end @@ -2931,7 +2940,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 @@ -3187,24 +3197,10 @@ 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) -end - -function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym), saw_latestworld::Bool, sv::AbsIntState) rt = Bool effects = EFFECTS_TOTAL exct = Union{} - isa(sym, Symbol) && (sym = GlobalRef(frame_module(sv), sym)) - if isa(sym, GlobalRef) - rte = abstract_eval_globalref(interp, sym, saw_latestworld, sv) - if rte.exct == Union{} - rt = Const(true) - elseif rte.rt === Union{} && rte.exct === UndefVarError - rt = Const(false) - else - effects = Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE) - end - elseif isexpr(sym, :static_parameter) + if isexpr(sym, :static_parameter) n = sym.args[1]::Int if 1 <= n <= length(sv.sptypes) sp = sv.sptypes[n] @@ -3216,10 +3212,73 @@ function abstract_eval_isdefined(interp::AbstractInterpreter, @nospecialize(sym) 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 CallMeta(RTEffects(rt, Union{}, Effects(generic_isdefinedglobal_effects, nothrow=true)), NoCallInfo()) + end + + effects = EFFECTS_TOTAL + partition = lookup_binding_partition!(interp, GlobalRef(mod, sym), sv) + if allow_import !== true && is_some_imported(binding_kind(partition)) + if allow_import === false + rt = Const(false) + else + effects = Effects(generic_isdefinedglobal_effects, nothrow=true) + end + else + partition = walk_binding_partition!(interp, partition, sv) + rte = abstract_eval_partition_load(interp, partition) + if rte.exct == Union{} + rt = Const(true) + elseif rte.rt === Union{} && rte.exct === UndefVarError + rt = Const(false) + else + effects = Effects(generic_isdefinedglobal_effects, nothrow=true) + end + end + 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) + exct = Bottom + allow_import = true + if allow_import_arg !== nothing + if !isa(allow_import_arg, Const) + allow_import = nothing + if widenconst(allow_import_arg) != Bool + exct = Union{exct, TypeError} + end + else + allow_import = allow_import_arg.val + end + end + if order_arg !== nothing + exct = global_order_exct(order_arg, #=loading=#true, #=storing=#false) + if !(isa(order_arg, Const) && get_atomic_order(order_arg.val, #=loading=#true, #=storing=#false).x >= MEMORY_ORDER_UNORDERED.x) + exct = Union{exct, ConcurrencyViolationError} + end + end + if M isa Const && s isa Const + M, s = M.val, s.val + if M isa Module && s isa Symbol + 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) + return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo()) + elseif M ⊑ Module && s ⊑ Symbol + return CallMeta(Bool, Union{exct, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo()) + end + return CallMeta(Bool, Union{exct, TypeError, UndefVarError}, generic_isdefinedglobal_effects, NoCallInfo()) +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) @@ -3240,8 +3299,16 @@ function abstract_eval_throw_undef_if_not(interp::AbstractInterpreter, e::Expr, end function abstract_eval_the_exception(::AbstractInterpreter, sv::InferenceState) - (;handlers, handler_at) = sv.handler_info::HandlerInfo - return the_exception_info(handlers[handler_at[sv.currpc][2]].exct) + (;handler_info) = sv + if handler_info === nothing + return the_exception_info(Any) + end + (;handlers, handler_at) = handler_info + handler_id = handler_at[sv.currpc][2] + if handler_id === 0 + return the_exception_info(Any) + end + return the_exception_info(handlers[handler_id].exct) end abstract_eval_the_exception(::AbstractInterpreter, ::IRInterpretationState) = the_exception_info(Any) the_exception_info(@nospecialize t) = RTEffects(t, Union{}, Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE)) @@ -3389,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 @@ -3410,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{} @@ -3422,22 +3489,31 @@ function abstract_eval_globalref_type(g::GlobalRef, src::Union{CodeInfo, IRCode, return partition_restriction(partition) end -function abstract_eval_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState) - force_binding_resolution!(g) +function lookup_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState) + 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 +end +function walk_binding_partition!(interp::AbstractInterpreter, partition::Core.BindingPartition, sv::AbsIntState) while is_some_imported(binding_kind(partition)) imported_binding = partition_restriction(partition)::Core.Binding partition = lookup_binding_partition(get_inference_world(interp), imported_binding) update_valid_age!(sv, WorldRange(partition.min_world, partition.max_world)) end + return partition +end +function abstract_eval_binding_partition!(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState) + partition = lookup_binding_partition!(interp, g, sv) + partition = walk_binding_partition!(interp, partition, sv) return partition end function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Core.BindingPartition) - if is_some_guard(binding_kind(partition)) + kind = binding_kind(partition) + if is_some_guard(kind) || kind == BINDING_KIND_UNDEF_CONST if InferenceParams(interp).assume_bindings_static return RTEffects(Union{}, UndefVarError, EFFECTS_THROWS) else @@ -3447,38 +3523,41 @@ function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Co end end - if is_some_const_binding(binding_kind(partition)) + if is_defined_const_binding(kind) rt = Const(partition_restriction(partition)) return RTEffects(rt, Union{}, Effects(EFFECTS_TOTAL, inaccessiblememonly=is_mutation_free_argtype(rt) ? ALWAYS_TRUE : ALWAYS_FALSE)) end rt = partition_restriction(partition) - return RTEffects(rt, UndefVarError, generic_getglobal_effects) 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)) + 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. # 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)) @@ -3499,18 +3578,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}) @@ -3644,7 +3711,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) @@ -3721,7 +3788,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 @@ -3729,6 +3796,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/bootstrap.jl b/Compiler/src/bootstrap.jl index 475c53e317152..26fcfde5f256f 100644 --- a/Compiler/src/bootstrap.jl +++ b/Compiler/src/bootstrap.jl @@ -15,10 +15,11 @@ function activate_codegen!() end) end +global bootstrapping_compiler::Bool = false function bootstrap!() + global bootstrapping_compiler = true let time() = ccall(:jl_clock_now, Float64, ()) println("Compiling the compiler. This may take several minutes ...") - interp = NativeInterpreter() ssa_inlining_pass!_tt = Tuple{typeof(ssa_inlining_pass!), IRCode, InliningState{NativeInterpreter}, Bool} optimize_tt = Tuple{typeof(optimize), NativeInterpreter, OptimizationState{NativeInterpreter}, InferenceResult} @@ -45,13 +46,15 @@ function bootstrap!() end end starttime = time() + methods = Any[] + world = get_world_counter() for f in fs if isa(f, DataType) && f.name === typename(Tuple) tt = f else tt = Tuple{typeof(f), Vararg{Any}} end - matches = _methods_by_ftype(tt, 10, get_world_counter())::Vector + matches = _methods_by_ftype(tt, 10, world)::Vector if isempty(matches) println(stderr, "WARNING: no matching method found for `", tt, "`") else @@ -62,14 +65,25 @@ function bootstrap!() for i = 1:length(params) params[i] = unwraptv(params[i]) end - typeinf_type(interp, m.method, Tuple{params...}, m.sparams) + mi = specialize_method(m.method, Tuple{params...}, m.sparams) + #isa_compileable_sig(mi) || println(stderr, "WARNING: inferring `", mi, "` which isn't expected to be called.") + push!(methods, mi) end end end + codeinfos = typeinf_ext_toplevel(methods, [world], false) + for i = 1:2:length(codeinfos) + ci = codeinfos[i]::CodeInstance + src = codeinfos[i + 1]::CodeInfo + isa_compileable_sig(ci.def) || continue # println(stderr, "WARNING: compiling `", ci.def, "` which isn't expected to be called.") + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), ci, src) + end endtime = time() println("Base.Compiler ──── ", sub_float(endtime,starttime), " seconds") end activate_codegen!() + global bootstrapping_compiler = false + nothing end function activate!(; reflection=true, codegen=false) diff --git a/Compiler/src/effects.jl b/Compiler/src/effects.jl index e521166fd61fa..9aea4cb204ec6 100644 --- a/Compiler/src/effects.jl +++ b/Compiler/src/effects.jl @@ -335,6 +335,7 @@ is_inaccessiblemem_or_argmemonly(effects::Effects) = effects.inaccessiblememonly is_consistent_overlay(effects::Effects) = effects.nonoverlayed === CONSISTENT_OVERLAY +# (sync this with codegen.cpp and staticdata.c effects_foldable functions) function encode_effects(e::Effects) return ((e.consistent % UInt32) << 0) | ((e.effect_free % UInt32) << 3) | diff --git a/Compiler/src/inferencestate.jl b/Compiler/src/inferencestate.jl index 6988e74310fc5..0ea0fc684b689 100644 --- a/Compiler/src/inferencestate.jl +++ b/Compiler/src/inferencestate.jl @@ -219,16 +219,29 @@ const CACHE_MODE_GLOBAL = 0x01 << 0 # cached globally, optimization required const CACHE_MODE_LOCAL = 0x01 << 1 # cached locally, optimization required const CACHE_MODE_VOLATILE = 0x01 << 2 # not cached, optimization required -mutable struct TryCatchFrame +abstract type Handler end +get_enter_idx(handler::Handler) = get_enter_idx_impl(handler)::Int + +mutable struct TryCatchFrame <: Handler exct scopet const enter_idx::Int scope_uses::Vector{Int} - TryCatchFrame(@nospecialize(exct), @nospecialize(scopet), enter_idx::Int) = new(exct, scopet, enter_idx) + TryCatchFrame(@nospecialize(exct), @nospecialize(scopet), enter_idx::Int) = + new(exct, scopet, enter_idx) +end +TryCatchFrame(stmt::EnterNode, pc::Int) = + TryCatchFrame(Bottom, isdefined(stmt, :scope) ? Bottom : nothing, pc) +get_enter_idx_impl((; enter_idx)::TryCatchFrame) = enter_idx + +struct SimpleHandler <: Handler + enter_idx::Int end +SimpleHandler(::EnterNode, pc::Int) = SimpleHandler(pc) +get_enter_idx_impl((; enter_idx)::SimpleHandler) = enter_idx -struct HandlerInfo - handlers::Vector{TryCatchFrame} +struct HandlerInfo{T<:Handler} + handlers::Vector{T} handler_at::Vector{Tuple{Int,Int}} # tuple of current (handler, exception stack) value at the pc end @@ -261,7 +274,7 @@ mutable struct InferenceState currbb::Int currpc::Int ip::BitSet#=TODO BoundedMinPrioritySet=# # current active instruction pointers - handler_info::Union{Nothing,HandlerInfo} + handler_info::Union{Nothing,HandlerInfo{TryCatchFrame}} ssavalue_uses::Vector{BitSet} # ssavalue sparsity and restart info # TODO: Could keep this sparsely by doing structural liveness analysis ahead of time. bb_vartables::Vector{Union{Nothing,VarTable}} # nothing if not analyzed yet @@ -318,7 +331,7 @@ mutable struct InferenceState currbb = currpc = 1 ip = BitSet(1) # TODO BitSetBoundedMinPrioritySet(1) - handler_info = compute_trycatch(code) + handler_info = ComputeTryCatch{TryCatchFrame}()(code) nssavalues = src.ssavaluetypes::Int ssavalue_uses = find_ssavalue_uses(code, nssavalues) nstmts = length(code) @@ -421,10 +434,16 @@ is_inferred(result::InferenceResult) = result.result !== nothing was_reached(sv::InferenceState, pc::Int) = sv.ssavaluetypes[pc] !== NOT_FOUND -compute_trycatch(ir::IRCode) = compute_trycatch(ir.stmts.stmt, ir.cfg.blocks) +struct ComputeTryCatch{T<:Handler} end + +const compute_trycatch = ComputeTryCatch{SimpleHandler}() + +(compute_trycatch::ComputeTryCatch{SimpleHandler})(ir::IRCode) = + compute_trycatch(ir.stmts.stmt, ir.cfg.blocks) """ - compute_trycatch(code, [, bbs]) -> handler_info::Union{Nothing,HandlerInfo} + (::ComputeTryCatch{Handler})(code, [, bbs]) -> handler_info::Union{Nothing,HandlerInfo{Handler}} + const compute_trycatch = ComputeTryCatch{SimpleHandler}() Given the code of a function, compute, at every statement, the current try/catch handler, and the current exception stack top. This function returns @@ -433,9 +452,9 @@ a tuple of: 1. `handler_info.handler_at`: A statement length vector of tuples `(catch_handler, exception_stack)`, which are indices into `handlers` - 2. `handler_info.handlers`: A `TryCatchFrame` vector of handlers + 2. `handler_info.handlers`: A `Handler` vector of handlers """ -function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothing}=nothing) +function (::ComputeTryCatch{Handler})(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothing}=nothing) where Handler # The goal initially is to record the frame like this for the state at exit: # 1: (enter 3) # == 0 # 3: (expr) # == 1 @@ -454,10 +473,10 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi stmt = code[pc] if isa(stmt, EnterNode) (;handlers, handler_at) = handler_info = - (handler_info === nothing ? HandlerInfo(TryCatchFrame[], fill((0, 0), n)) : handler_info) + (handler_info === nothing ? HandlerInfo{Handler}(Handler[], fill((0, 0), n)) : handler_info) l = stmt.catch_dest - (bbs !== nothing) && (l = first(bbs[l].stmts)) - push!(handlers, TryCatchFrame(Bottom, isdefined(stmt, :scope) ? Bottom : nothing, pc)) + (bbs !== nothing) && (l != 0) && (l = first(bbs[l].stmts)) + push!(handlers, Handler(stmt, pc)) handler_id = length(handlers) handler_at[pc + 1] = (handler_id, 0) push!(ip, pc + 1) @@ -500,7 +519,7 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi break elseif isa(stmt, EnterNode) l = stmt.catch_dest - (bbs !== nothing) && (l = first(bbs[l].stmts)) + (bbs !== nothing) && (l != 0) && (l = first(bbs[l].stmts)) # We assigned a handler number above. Here we just merge that # with out current handler information. if l != 0 @@ -526,7 +545,7 @@ function compute_trycatch(code::Vector{Any}, bbs::Union{Vector{BasicBlock},Nothi end cur_hand = cur_stacks[1] for i = 1:l - cur_hand = handler_at[handlers[cur_hand].enter_idx][1] + cur_hand = handler_at[get_enter_idx(handlers[cur_hand])][1] end cur_stacks = (cur_hand, cur_stacks[2]) cur_stacks == (0, 0) && break diff --git a/Compiler/src/optimize.jl b/Compiler/src/optimize.jl index 1c02bd67b5bd4..9f74f028507cd 100644 --- a/Compiler/src/optimize.jl +++ b/Compiler/src/optimize.jl @@ -647,9 +647,11 @@ struct GetNativeEscapeCache{CodeCache} GetNativeEscapeCache(code_cache::CodeCache) where CodeCache = new{CodeCache}(code_cache) end GetNativeEscapeCache(interp::AbstractInterpreter) = GetNativeEscapeCache(code_cache(interp)) -function ((; code_cache)::GetNativeEscapeCache)(mi::MethodInstance) - codeinst = get(code_cache, mi, nothing) - codeinst isa CodeInstance || return false +function ((; code_cache)::GetNativeEscapeCache)(codeinst::Union{CodeInstance,MethodInstance}) + if codeinst isa MethodInstance + codeinst = get(code_cache, codeinst, nothing) + codeinst isa CodeInstance || return false + end argescapes = traverse_analysis_results(codeinst) do @nospecialize result return result isa EscapeAnalysis.ArgEscapeCache ? result : nothing end @@ -1023,7 +1025,7 @@ function run_passes_ipo_safe( optimize_until = nothing, # run all passes by default ) __stage__ = 0 # used by @pass - # NOTE: The pass name MUST be unique for `optimize_until::AbstractString` to work + # NOTE: The pass name MUST be unique for `optimize_until::String` to work @pass "convert" ir = convert_to_ircode(ci, sv) @pass "slot2reg" ir = slot2reg(ir, ci, sv) # TODO: Domsorting can produce an updated domtree - no need to recompute here @@ -1284,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/EscapeAnalysis.jl b/Compiler/src/ssair/EscapeAnalysis.jl index 4f32550d056b2..af8e9b1a4959e 100644 --- a/Compiler/src/ssair/EscapeAnalysis.jl +++ b/Compiler/src/ssair/EscapeAnalysis.jl @@ -13,22 +13,21 @@ export using Base: Base # imports -import Base: ==, getindex, setindex! +import Base: ==, copy, getindex, setindex! # usings -using Core: MethodMatch, SimpleVector, ifelse, sizeof +using Core: Builtin, IntrinsicFunction, SimpleVector, ifelse, sizeof using Core.IR using Base: # Base definitions @__MODULE__, @assert, @eval, @goto, @inbounds, @inline, @label, @noinline, - @nospecialize, @specialize, BitSet, Callable, Csize_t, IdDict, IdSet, UnitRange, Vector, - copy, delete!, empty!, enumerate, error, first, get, get!, haskey, in, isassigned, - isempty, ismutabletype, keys, last, length, max, min, missing, pop!, push!, pushfirst!, - unwrap_unionall, !, !=, !==, &, *, +, -, :, <, <<, =>, >, |, ∈, ∉, ∩, ∪, ≠, ≤, ≥, ⊆, - hasintersect + @nospecialize, @specialize, BitSet, IdDict, IdSet, UnitRange, Vector, + delete!, empty!, enumerate, first, get, get!, hasintersect, haskey, isassigned, + isempty, length, max, min, missing, println, push!, pushfirst!, + !, !==, &, *, +, -, :, <, <<, >, |, ∈, ∉, ∩, ∪, ≠, ≤, ≥, ⊆ using ..Compiler: # Compiler specific definitions - AbstractLattice, Bottom, IRCode, IR_FLAG_NOTHROW, InferenceResult, SimpleInferenceLattice, - argextype, fieldcount_noerror, hasintersect, has_flag, intrinsic_nothrow, - is_meta_expr_head, is_identity_free_argtype, isexpr, println, setfield!_nothrow, - singleton_type, try_compute_field, try_compute_fieldidx, widenconst, ⊑, Compiler + AbstractLattice, Compiler, IRCode, IR_FLAG_NOTHROW, + argextype, fieldcount_noerror, has_flag, intrinsic_nothrow, is_meta_expr_head, + is_identity_free_argtype, isexpr, setfield!_nothrow, singleton_type, try_compute_field, + try_compute_fieldidx, widenconst function include(x::String) if !isdefined(Base, :end_base_include) @@ -53,14 +52,13 @@ A lattice for escape information, which holds the following properties: * `pc ∈ x.ThrownEscape`: `x` may be thrown at the SSA statement at `pc` * `-1 ∈ x.ThrownEscape`: `x` may be thrown at arbitrary points of this call frame (the top) This information will be used by `escape_exception!` to propagate potential escapes via exception. -- `x.AliasInfo::Union{Bool,IndexableFields,IndexableElements,Unindexable}`: maintains all possible values +- `x.AliasInfo::Union{Bool,IndexableFields,Unindexable}`: maintains all possible values that can be aliased to fields or array elements of `x`: * `x.AliasInfo === false` indicates the fields/elements of `x` aren't analyzed yet * `x.AliasInfo === true` indicates the fields/elements of `x` can't be analyzed, e.g. the type of `x` is not known or is not concrete and thus its fields/elements can't be known precisely * `x.AliasInfo::IndexableFields` records all the possible values that can be aliased to fields of object `x` with precise index information - * `x.AliasInfo::IndexableElements` records all the possible values that can be aliased to elements of array `x` with precise index information * `x.AliasInfo::Unindexable` records all the possible values that can be aliased to fields/elements of `x` without precise index information - `x.Liveness::BitSet`: records SSA statement numbers where `x` should be live, e.g. to be used as a call argument, to be returned to a caller, or preserved for `:foreigncall`: @@ -87,14 +85,14 @@ struct EscapeInfo Analyzed::Bool ReturnEscape::Bool ThrownEscape::BitSet - AliasInfo #::Union{IndexableFields,IndexableElements,Unindexable,Bool} + AliasInfo #::Union{IndexableFields,Unindexable,Bool} Liveness::BitSet function EscapeInfo( Analyzed::Bool, ReturnEscape::Bool, ThrownEscape::BitSet, - AliasInfo#=::Union{IndexableFields,IndexableElements,Unindexable,Bool}=#, + AliasInfo#=::Union{IndexableFields,Unindexable,Bool}=#, Liveness::BitSet) @nospecialize AliasInfo return new( @@ -108,7 +106,7 @@ struct EscapeInfo x::EscapeInfo, # non-concrete fields should be passed as default arguments # in order to avoid allocating non-concrete `NamedTuple`s - AliasInfo#=::Union{IndexableFields,IndexableElements,Unindexable,Bool}=# = x.AliasInfo; + AliasInfo#=::Union{IndexableFields,Unindexable,Bool}=# = x.AliasInfo; Analyzed::Bool = x.Analyzed, ReturnEscape::Bool = x.ReturnEscape, ThrownEscape::BitSet = x.ThrownEscape, @@ -149,11 +147,11 @@ const ⊥, ⊤ = NotAnalyzed(), AllEscape() # Convenience names for some ⊑ₑ queries has_no_escape(x::EscapeInfo) = !x.ReturnEscape && isempty(x.ThrownEscape) && 0 ∉ x.Liveness -has_arg_escape(x::EscapeInfo) = 0 in x.Liveness +has_arg_escape(x::EscapeInfo) = 0 ∈ x.Liveness has_return_escape(x::EscapeInfo) = x.ReturnEscape -has_return_escape(x::EscapeInfo, pc::Int) = x.ReturnEscape && (-1 ∈ x.Liveness || pc in x.Liveness) +has_return_escape(x::EscapeInfo, pc::Int) = x.ReturnEscape && (-1 ∈ x.Liveness || pc ∈ x.Liveness) has_thrown_escape(x::EscapeInfo) = !isempty(x.ThrownEscape) -has_thrown_escape(x::EscapeInfo, pc::Int) = -1 ∈ x.ThrownEscape || pc in x.ThrownEscape +has_thrown_escape(x::EscapeInfo, pc::Int) = -1 ∈ x.ThrownEscape || pc ∈ x.ThrownEscape has_all_escape(x::EscapeInfo) = ⊤ ⊑ₑ x # utility lattice constructors @@ -166,14 +164,13 @@ ignore_liveness(x::EscapeInfo) = EscapeInfo(x; Liveness=BOT_LIVENESS) struct IndexableFields infos::Vector{AInfo} end -struct IndexableElements - infos::IdDict{Int,AInfo} -end struct Unindexable info::AInfo end IndexableFields(nflds::Int) = IndexableFields(AInfo[AInfo() for _ in 1:nflds]) Unindexable() = Unindexable(AInfo()) +copy(AliasInfo::IndexableFields) = IndexableFields(AInfo[copy(info) for info in AliasInfo.infos]) +copy(AliasInfo::Unindexable) = Unindexable(copy(AliasInfo.info)) merge_to_unindexable(AliasInfo::IndexableFields) = Unindexable(merge_to_unindexable(AliasInfo.infos)) merge_to_unindexable(AliasInfo::Unindexable, AliasInfos::IndexableFields) = Unindexable(merge_to_unindexable(AliasInfo.info, AliasInfos.infos)) @@ -184,15 +181,6 @@ function merge_to_unindexable(info::AInfo, infos::Vector{AInfo}) end return info end -merge_to_unindexable(AliasInfo::IndexableElements) = Unindexable(merge_to_unindexable(AliasInfo.infos)) -merge_to_unindexable(AliasInfo::Unindexable, AliasInfos::IndexableElements) = Unindexable(merge_to_unindexable(AliasInfo.info, AliasInfos.infos)) -merge_to_unindexable(infos::IdDict{Int,AInfo}) = merge_to_unindexable(AInfo(), infos) -function merge_to_unindexable(info::AInfo, infos::IdDict{Int,AInfo}) - for idx in keys(infos) - info = info ∪ infos[idx] - end - return info -end # we need to make sure this `==` operator corresponds to lattice equality rather than object equality, # otherwise `propagate_changes` can't detect the convergence @@ -215,9 +203,6 @@ x::EscapeInfo == y::EscapeInfo = begin elseif isa(xa, IndexableFields) isa(ya, IndexableFields) || return false xa.infos == ya.infos || return false - elseif isa(xa, IndexableElements) - isa(ya, IndexableElements) || return false - xa.infos == ya.infos || return false else xa = xa::Unindexable isa(ya, Unindexable) || return false @@ -269,8 +254,6 @@ x::EscapeInfo ⊑ₑ y::EscapeInfo = begin for i in 1:xn xinfos[i] ⊆ yinfos[i] || return false end - elseif isa(ya, IndexableElements) - return false elseif isa(ya, Unindexable) xinfos, yinfo = xa.infos, ya.info for i = length(xinfos) @@ -279,23 +262,6 @@ x::EscapeInfo ⊑ₑ y::EscapeInfo = begin else ya === true || return false end - elseif isa(xa, IndexableElements) - if isa(ya, IndexableElements) - xinfos, yinfos = xa.infos, ya.infos - keys(xinfos) ⊆ keys(yinfos) || return false - for idx in keys(xinfos) - xinfos[idx] ⊆ yinfos[idx] || return false - end - elseif isa(ya, IndexableFields) - return false - elseif isa(ya, Unindexable) - xinfos, yinfo = xa.infos, ya.info - for idx in keys(xinfos) - xinfos[idx] ⊆ yinfo || return false - end - else - ya === true || return false - end else xa = xa::Unindexable if isa(ya, Unindexable) @@ -401,33 +367,10 @@ function merge_alias_info(@nospecialize(xa), @nospecialize(ya)) else return true # handle conflicting case conservatively end - elseif isa(xa, IndexableElements) - if isa(ya, IndexableElements) - xinfos, yinfos = xa.infos, ya.infos - infos = IdDict{Int,AInfo}() - for idx in keys(xinfos) - if !haskey(yinfos, idx) - infos[idx] = xinfos[idx] - else - infos[idx] = xinfos[idx] ∪ yinfos[idx] - end - end - for idx in keys(yinfos) - haskey(xinfos, idx) && continue # unioned already - infos[idx] = yinfos[idx] - end - return IndexableElements(infos) - elseif isa(ya, Unindexable) - return merge_to_unindexable(ya, xa) - else - return true # handle conflicting case conservatively - end else xa = xa::Unindexable if isa(ya, IndexableFields) return merge_to_unindexable(xa, ya) - elseif isa(ya, IndexableElements) - return merge_to_unindexable(xa, ya) else ya = ya::Unindexable xinfo, yinfo = xa.info, ya.info @@ -439,8 +382,6 @@ end const AliasSet = IntDisjointSet{Int} -const ArrayInfo = IdDict{Int,Vector{Int}} - """ estate::EscapeState @@ -451,13 +392,12 @@ struct EscapeState escapes::Vector{EscapeInfo} aliasset::AliasSet nargs::Int - arrayinfo::Union{Nothing,ArrayInfo} end -function EscapeState(nargs::Int, nstmts::Int, arrayinfo::Union{Nothing,ArrayInfo}) +function EscapeState(nargs::Int, nstmts::Int) escapes = EscapeInfo[ 1 ≤ i ≤ nargs ? ArgEscape() : ⊥ for i in 1:(nargs+nstmts)] aliasset = AliasSet(nargs+nstmts) - return EscapeState(escapes, aliasset, nargs, arrayinfo) + return EscapeState(escapes, aliasset, nargs) end function getindex(estate::EscapeState, @nospecialize(x)) xidx = iridx(x, estate) @@ -503,8 +443,7 @@ that is analyzable in the context of `estate`. `iridx(irval(xidx, state), state) === xidx`. """ function irval(xidx::Int, estate::EscapeState) - x = xidx > estate.nargs ? SSAValue(xidx-estate.nargs) : Argument(xidx) - return x + return xidx > estate.nargs ? SSAValue(xidx-estate.nargs) : Argument(xidx) end function getaliases(x::Union{Argument,SSAValue}, estate::EscapeState) @@ -621,8 +560,8 @@ function analyze_escapes(ir::IRCode, nargs::Int, 𝕃ₒ::AbstractLattice, get_e stmts = ir.stmts nstmts = length(stmts) + length(ir.new_nodes.stmts) - tryregions, arrayinfo = compute_frameinfo(ir) - estate = EscapeState(nargs, nstmts, arrayinfo) + tryregions = compute_frameinfo(ir) + estate = EscapeState(nargs, nstmts) changes = Changes() # keeps changes that happen at current statement astate = AnalysisState(ir, estate, changes, 𝕃ₒ, get_escape_cache) @@ -712,21 +651,15 @@ function analyze_escapes(ir::IRCode, nargs::Int, 𝕃ₒ::AbstractLattice, get_e end """ - compute_frameinfo(ir::IRCode) -> (tryregions, arrayinfo) - -A preparatory linear scan before the escape analysis on `ir` to find: -- `tryregions::Union{Nothing,Vector{UnitRange{Int}}}`: regions in which potential `throw`s can be caught (used by `escape_exception!`) -- `arrayinfo::Union{Nothing,IdDict{Int,Vector{Int}}}`: array allocations whose dimensions are known precisely (with some very simple local analysis) + compute_frameinfo(ir::IRCode) -> tryregions -!!! note - This array dimension analysis to compute `arrayinfo` is very local and doesn't account - for flow-sensitivity nor complex aliasing. - Ideally this dimension analysis should be done as a part of type inference that - propagates array dimensions in a flow sensitive way. +A preparatory linear scan before the escape analysis on `ir` to find +`tryregions::Union{Nothing,Vector{UnitRange{Int}}}`, that represent regions in which +potential `throw`s can be caught (used by `escape_exception!`) """ function compute_frameinfo(ir::IRCode) nstmts, nnewnodes = length(ir.stmts), length(ir.new_nodes.stmts) - tryregions, arrayinfo = nothing, nothing + tryregions = nothing for idx in 1:nstmts+nnewnodes inst = ir[SSAValue(idx)] stmt = inst[:stmt] @@ -738,41 +671,9 @@ function compute_frameinfo(ir::IRCode) leave_pc = first(ir.cfg.blocks[leave_block].stmts) push!(tryregions, idx:leave_pc) end - elseif arrayinfo !== nothing - # TODO this super limited alias analysis is able to handle only very simple cases - # this should be replaced with a proper forward dimension analysis - if isa(stmt, PhiNode) - values = stmt.values - local dims = nothing - for i = 1:length(values) - if isassigned(values, i) - val = values[i] - if isa(val, SSAValue) && haskey(arrayinfo, val.id) - if dims === nothing - dims = arrayinfo[val.id] - continue - elseif dims == arrayinfo[val.id] - continue - end - end - end - @goto next_stmt - end - if dims !== nothing - arrayinfo[idx] = dims - end - elseif isa(stmt, PiNode) - if isdefined(stmt, :val) - val = stmt.val - if isa(val, SSAValue) && haskey(arrayinfo, val.id) - arrayinfo[idx] = arrayinfo[val.id] - end - end - end end - @label next_stmt end - return tryregions, arrayinfo + return tryregions end # propagate changes, and check convergence @@ -826,7 +727,7 @@ end info = estate.escapes[xidx] Liveness = info.Liveness Liveness === TOP_LIVENESS && return false - livepc in Liveness && return false + livepc ∈ Liveness && return false if Liveness === BOT_LIVENESS || Liveness === ARG_LIVENESS # if this Liveness is a constant, we shouldn't modify it and propagate this change as a new EscapeInfo Liveness = copy(Liveness) @@ -976,19 +877,6 @@ end is_nothrow(ir::IRCode, pc::Int) = has_flag(ir[SSAValue(pc)], IR_FLAG_NOTHROW) -# NOTE if we don't maintain the alias set that is separated from the lattice state, we can do -# something like below: it essentially incorporates forward escape propagation in our default -# backward propagation, and leads to inefficient convergence that requires more iterations -# # lhs = rhs: propagate escape information of `rhs` to `lhs` -# function escape_alias!(astate::AnalysisState, @nospecialize(lhs), @nospecialize(rhs)) -# if isa(rhs, SSAValue) || isa(rhs, Argument) -# vinfo = astate.estate[rhs] -# else -# return -# end -# add_escape_change!(astate, lhs, vinfo) -# end - """ escape_exception!(astate::AnalysisState, tryregions::Vector{UnitRange{Int}}) @@ -1044,7 +932,7 @@ function escape_exception!(astate::AnalysisState, tryregions::Vector{UnitRange{I xt === TOP_THROWN_ESCAPE && @goto propagate_exception_escape # fast pass for pc in xt for region in tryregions - pc in region && @goto propagate_exception_escape # early break because of AllEscape + pc ∈ region && @goto propagate_exception_escape # early break because of AllEscape end end continue @@ -1056,14 +944,16 @@ end # escape statically-resolved call, i.e. `Expr(:invoke, ::MethodInstance, ...)` function escape_invoke!(astate::AnalysisState, pc::Int, args::Vector{Any}) - mi = first(args) - if !(mi isa MethodInstance) - mi = (mi::CodeInstance).def # COMBAK get escape info directly from CI instead? + codeinst = first(args) + if codeinst isa MethodInstance + mi = codeinst + else + mi = (codeinst::CodeInstance).def end first_idx, last_idx = 2, length(args) add_liveness_changes!(astate, pc, args, first_idx, last_idx) # TODO inspect `astate.ir.stmts[pc][:info]` and use const-prop'ed `InferenceResult` if available - cache = astate.get_escape_cache(mi) + cache = astate.get_escape_cache(codeinst) ret = SSAValue(pc) if cache isa Bool if cache @@ -1143,12 +1033,6 @@ function escape_foreigncall!(astate::AnalysisState, pc::Int, args::Vector{Any}) argtypes = args[3]::SimpleVector nargs = length(argtypes) name = args[1] - nn = normalize(name) - if isa(nn, Symbol) - # if nn === :jl_gc_add_finalizer_th - # # TODO add `FinalizerEscape` ? - # end - end # NOTE array allocations might have been proven as nothrow (https://github.com/JuliaLang/julia/pull/43565) nothrow = is_nothrow(astate.ir, pc) name_info = nothrow ? ⊥ : ThrownEscape(pc) @@ -1183,37 +1067,31 @@ function escape_gc_preserve!(astate::AnalysisState, pc::Int, args::Vector{Any}) add_liveness_changes!(astate, pc, beginargs) end -normalize(@nospecialize x) = isa(x, QuoteNode) ? x.value : x - function escape_call!(astate::AnalysisState, pc::Int, args::Vector{Any}) - ir = astate.ir - ft = argextype(first(args), ir, ir.sptypes, ir.argtypes) + ft = argextype(first(args), astate.ir) f = singleton_type(ft) - if isa(f, Core.IntrinsicFunction) - # XXX somehow `:call` expression can creep in here, ideally we should be able to do: - # argtypes = Any[argextype(args[i], astate.ir) for i = 2:length(args)] - argtypes = Any[] - for i = 2:length(args) - arg = args[i] - push!(argtypes, isexpr(arg, :call) ? Any : argextype(arg, ir)) + if f isa IntrinsicFunction + if is_nothrow(astate.ir, pc) + add_liveness_changes!(astate, pc, args, 2) + else + add_fallback_changes!(astate, pc, args, 2) end - if intrinsic_nothrow(f, argtypes) + # TODO needs to account for pointer operations? + elseif f isa Builtin + result = escape_builtin!(f, astate, pc, args) + if result === missing + # if this call hasn't been handled by any of pre-defined handlers, escape it conservatively + add_conservative_changes!(astate, pc, args) + elseif result === true + add_liveness_changes!(astate, pc, args, 2) + elseif is_nothrow(astate.ir, pc) add_liveness_changes!(astate, pc, args, 2) else add_fallback_changes!(astate, pc, args, 2) end - return # TODO accounts for pointer operations? - end - result = escape_builtin!(f, astate, pc, args) - if result === missing - # if this call hasn't been handled by any of pre-defined handlers, escape it conservatively - add_conservative_changes!(astate, pc, args) - elseif result === true - add_liveness_changes!(astate, pc, args, 2) - elseif is_nothrow(astate.ir, pc) - add_liveness_changes!(astate, pc, args, 2) else - add_fallback_changes!(astate, pc, args, 2) + # escape this generic function or unknown function call conservatively + add_conservative_changes!(astate, pc, args) end end @@ -1274,6 +1152,7 @@ function escape_new!(astate::AnalysisState, pc::Int, args::Vector{Any}) @goto escape_indexable_def end elseif isa(AliasInfo, IndexableFields) + AliasInfo = copy(AliasInfo) @label escape_indexable_def # fields are known precisely: propagate escape information imposed on recorded possibilities to the exact field values infos = AliasInfo.infos @@ -1290,6 +1169,7 @@ function escape_new!(astate::AnalysisState, pc::Int, args::Vector{Any}) end add_escape_change!(astate, obj, EscapeInfo(objinfo, AliasInfo)) # update with new AliasInfo elseif isa(AliasInfo, Unindexable) + AliasInfo = copy(AliasInfo) @label escape_unindexable_def # fields are known partially: propagate escape information imposed on recorded possibilities to all fields values info = AliasInfo.info @@ -1343,7 +1223,7 @@ function analyze_fields(ir::IRCode, @nospecialize(typ), @nospecialize(fld)) return IndexableFields(nflds), fidx end -function reanalyze_fields(ir::IRCode, AliasInfo::IndexableFields, @nospecialize(typ), @nospecialize(fld)) +function reanalyze_fields(AliasInfo::IndexableFields, ir::IRCode, @nospecialize(typ), @nospecialize(fld)) nflds = fieldcount_noerror(typ) if nflds === nothing return merge_to_unindexable(AliasInfo), 0 @@ -1357,6 +1237,7 @@ function reanalyze_fields(ir::IRCode, AliasInfo::IndexableFields, @nospecialize( if fidx === nothing return merge_to_unindexable(AliasInfo), 0 end + AliasInfo = copy(AliasInfo) infos = AliasInfo.infos ninfos = length(infos) if nflds > ninfos @@ -1393,12 +1274,13 @@ function escape_builtin!(::typeof(getfield), astate::AnalysisState, pc::Int, arg @goto record_unindexable_use end elseif isa(AliasInfo, IndexableFields) - AliasInfo, fidx = reanalyze_fields(ir, AliasInfo, typ, args[3]) + AliasInfo, fidx = reanalyze_fields(AliasInfo, ir, typ, args[3]) isa(AliasInfo, Unindexable) && @goto record_unindexable_use @label record_indexable_use push!(AliasInfo.infos[fidx], LocalUse(pc)) add_escape_change!(astate, obj, EscapeInfo(objinfo, AliasInfo)) # update with new AliasInfo elseif isa(AliasInfo, Unindexable) + AliasInfo = copy(AliasInfo) @label record_unindexable_use push!(AliasInfo.info, LocalUse(pc)) add_escape_change!(astate, obj, EscapeInfo(objinfo, AliasInfo)) # update with new AliasInfo @@ -1439,7 +1321,7 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar end elseif isa(AliasInfo, IndexableFields) typ = widenconst(argextype(obj, ir)) - AliasInfo, fidx = reanalyze_fields(ir, AliasInfo, typ, args[3]) + AliasInfo, fidx = reanalyze_fields(AliasInfo, ir, typ, args[3]) isa(AliasInfo, Unindexable) && @goto escape_unindexable_def @label escape_indexable_def add_alias_escapes!(astate, val, AliasInfo.infos[fidx]) @@ -1449,7 +1331,7 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar # propagate the escape information of this object ignoring field information add_escape_change!(astate, val, ignore_aliasinfo(objinfo)) elseif isa(AliasInfo, Unindexable) - info = AliasInfo.info + AliasInfo = copy(AliasInfo) @label escape_unindexable_def add_alias_escapes!(astate, val, AliasInfo.info) push!(AliasInfo.info, LocalDef(pc)) @@ -1483,64 +1365,6 @@ function escape_builtin!(::typeof(setfield!), astate::AnalysisState, pc::Int, ar end end -# NOTE this function models and thus should be synced with the implementation of: -# size_t array_nd_index(jl_array_t *a, jl_value_t **args, size_t nidxs, ...) -function array_nd_index(astate::AnalysisState, @nospecialize(ary), args::Vector{Any}, nidxs::Int = length(args)) - isa(ary, SSAValue) || return nothing - aryid = ary.id - arrayinfo = astate.estate.arrayinfo - isa(arrayinfo, ArrayInfo) || return nothing - haskey(arrayinfo, aryid) || return nothing - dims = arrayinfo[aryid] - local i = 0 - local k, stride = 0, 1 - local nd = length(dims) - while k < nidxs - arg = args[k+1] - argval = argextype(arg, astate.ir) - isa(argval, Const) || return nothing - argval = argval.val - isa(argval, Int) || return nothing - ii = argval - 1 - i += ii * stride - d = k ≥ nd ? 1 : dims[k+1] - k < nidxs - 1 && ii ≥ d && return nothing # BoundsError - stride *= d - k += 1 - end - while k < nd - stride *= dims[k+1] - k += 1 - end - i ≥ stride && return nothing # BoundsError - return i -end - -function mark_unindexable!(astate::AnalysisState, @nospecialize(ary)) - isa(ary, SSAValue) || return - aryinfo = astate.estate[ary] - AliasInfo = aryinfo.AliasInfo - isa(AliasInfo, IndexableElements) || return - AliasInfo = merge_to_unindexable(AliasInfo) - add_escape_change!(astate, ary, EscapeInfo(aryinfo, AliasInfo)) -end - -# FIXME this implementation is very conservative, improve the accuracy and solve broken test cases -function escape_array_copy!(astate::AnalysisState, pc::Int, args::Vector{Any}) - length(args) ≥ 6 || return add_fallback_changes!(astate, pc, args) - ary = args[6] - aryt = argextype(ary, astate.ir) - aryt ⊑ Array || return add_fallback_changes!(astate, pc, args) - if isa(ary, SSAValue) || isa(ary, Argument) - newary = SSAValue(pc) - aryinfo = astate.estate[ary] - newaryinfo = astate.estate[newary] - add_escape_change!(astate, newary, aryinfo) - add_escape_change!(astate, ary, newaryinfo) - end - add_liveness_changes!(astate, pc, args, 6) -end - function escape_builtin!(::typeof(Core.finalizer), astate::AnalysisState, pc::Int, args::Vector{Any}) if length(args) ≥ 3 obj = args[3] diff --git a/Compiler/src/ssair/disjoint_set.jl b/Compiler/src/ssair/disjoint_set.jl index 3f64fe643bd17..e000d7e8a582f 100644 --- a/Compiler/src/ssair/disjoint_set.jl +++ b/Compiler/src/ssair/disjoint_set.jl @@ -5,7 +5,7 @@ # imports import Base: length, eltype, union!, push! # usings -import Base: OneTo, collect, zero, zeros, one, typemax +using Base: OneTo, collect, zero, zeros, one, typemax # Disjoint-Set @@ -55,7 +55,7 @@ eltype(::Type{IntDisjointSet{T}}) where {T<:Integer} = T # path compression is implemented here function find_root_impl!(parents::Vector{T}, x::Integer) where {T<:Integer} p = parents[x] - @inbounds if parents[p] != p + @inbounds if parents[p] ≠ p parents[x] = p = _find_root_impl!(parents, p) end return p @@ -64,7 +64,7 @@ end # unsafe version of the above function _find_root_impl!(parents::Vector{T}, x::Integer) where {T<:Integer} @inbounds p = parents[x] - @inbounds if parents[p] != p + @inbounds if parents[p] ≠ p parents[x] = p = _find_root_impl!(parents, p) end return p @@ -95,7 +95,7 @@ function union!(s::IntDisjointSet{T}, x::T, y::T) where {T<:Integer} parents = s.parents xroot = find_root_impl!(parents, x) yroot = find_root_impl!(parents, y) - return xroot != yroot ? root_union!(s, xroot, yroot) : xroot + return xroot ≠ yroot ? root_union!(s, xroot, yroot) : xroot 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/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/show.jl b/Compiler/src/ssair/show.jl index 7d7b182655db7..e63d7b5cf640e 100644 --- a/Compiler/src/ssair/show.jl +++ b/Compiler/src/ssair/show.jl @@ -100,11 +100,17 @@ function print_stmt(io::IO, idx::Int, @nospecialize(stmt), code::Union{IRCode,Co if !(mi isa Core.MethodInstance) mi = (mi::Core.CodeInstance).def end + if isa(mi, Core.ABIOverride) + abi = mi.abi + mi = mi.def + else + abi = mi.specTypes + end show_unquoted(io, stmt.args[2], indent) print(io, "(") # XXX: this is wrong if `sig` is not a concretetype method # more correct would be to use `fieldtype(sig, i)`, but that would obscure / discard Varargs information in show - sig = mi.specTypes == Tuple ? Core.svec() : Base.unwrap_unionall(mi.specTypes).parameters::Core.SimpleVector + sig = abi == Tuple ? Core.svec() : Base.unwrap_unionall(abi).parameters::Core.SimpleVector print_arg(i) = sprint(; context=io) do io show_unquoted(io, stmt.args[i], indent) if (i - 1) <= length(sig) diff --git a/Compiler/src/ssair/slot2ssa.jl b/Compiler/src/ssair/slot2ssa.jl index 6fc87934d3bc5..80dffdab23243 100644 --- a/Compiler/src/ssair/slot2ssa.jl +++ b/Compiler/src/ssair/slot2ssa.jl @@ -801,9 +801,11 @@ function construct_ssa!(ci::CodeInfo, ir::IRCode, sv::OptimizationState, has_pinode[id] = false enter_idx = idx while (handler = gethandler(handler_info, enter_idx)) !== nothing - (; enter_idx) = handler - leave_block = block_for_inst(cfg, (code[enter_idx]::EnterNode).catch_dest) - cidx = findfirst((; slot)::NewPhiCNode2->slot_id(slot)==id, new_phic_nodes[leave_block]) + enter_idx = get_enter_idx(handler) + enter_node = code[enter_idx]::EnterNode + leave_block = block_for_inst(cfg, enter_node.catch_dest) + cidx = findfirst((; slot)::NewPhiCNode2->slot_id(slot)==id, + new_phic_nodes[leave_block]) if cidx !== nothing node = thisdef ? UpsilonNode(thisval) : UpsilonNode() if incoming_vals[id] === UNDEF_TOKEN diff --git a/Compiler/src/ssair/verify.jl b/Compiler/src/ssair/verify.jl index 072a564a31f78..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) @@ -366,7 +372,7 @@ function verify_ir(ir::IRCode, print::Bool=true, @verify_error "Assignment should have been removed during SSA conversion" raise_error() elseif stmt.head === :isdefined - if length(stmt.args) > 2 || (length(stmt.args) == 2 && !isa(stmt.args[2], Bool)) + if length(stmt.args) > 2 @verify_error "malformed isdefined" raise_error() end @@ -382,7 +388,7 @@ function verify_ir(ir::IRCode, print::Bool=true, elseif stmt.head === :foreigncall isforeigncall = true elseif stmt.head === :isdefined && length(stmt.args) == 1 && - (stmt.args[1] isa GlobalRef || isexpr(stmt.args[1], :static_parameter)) + isexpr(stmt.args[1], :static_parameter) # a GlobalRef or static_parameter isdefined check does not evaluate its argument continue elseif stmt.head === :call diff --git a/Compiler/src/stmtinfo.jl b/Compiler/src/stmtinfo.jl index 4f55f068e9456..e3f8e2f56c86b 100644 --- a/Compiler/src/stmtinfo.jl +++ b/Compiler/src/stmtinfo.jl @@ -71,7 +71,7 @@ function _add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, mi_edge::Boo mi = specialize_method(m) # don't allow `Method`-edge for this optimized format edge = mi else - mi = edge.def + mi = edge.def::MethodInstance end if mi.specTypes === m.spec_types add_one_edge!(edges, edge) @@ -103,7 +103,7 @@ function add_one_edge!(edges::Vector{Any}, edge::MethodInstance) while i <= length(edges) edgeᵢ = edges[i] edgeᵢ isa Int && (i += 2 + edgeᵢ; continue) - edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def) + edgeᵢ isa CodeInstance && (edgeᵢ = get_ci_mi(edgeᵢ)) edgeᵢ isa MethodInstance || (i += 1; continue) if edgeᵢ === edge && !(i > 1 && edges[i-1] isa Type) return # found existing covered edge @@ -118,7 +118,7 @@ function add_one_edge!(edges::Vector{Any}, edge::CodeInstance) while i <= length(edges) edgeᵢ_orig = edgeᵢ = edges[i] edgeᵢ isa Int && (i += 2 + edgeᵢ; continue) - edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def) + edgeᵢ isa CodeInstance && (edgeᵢ = get_ci_mi(edgeᵢ)) edgeᵢ isa MethodInstance || (i += 1; continue) if edgeᵢ === edge.def && !(i > 1 && edges[i-1] isa Type) if edgeᵢ_orig isa MethodInstance @@ -385,7 +385,7 @@ function add_inlining_edge!(edges::Vector{Any}, edge::CodeInstance) i += 1 end # add_invoke_edge alone - push!(edges, (edge.def.def::Method).sig) + push!(edges, (get_ci_mi(edge).def::Method).sig) push!(edges, edge) nothing end @@ -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/tfuncs.jl b/Compiler/src/tfuncs.jl index af8863c1b3a3a..74c8026ca0cf5 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -42,11 +42,10 @@ macro nospecs(ex) push!(names, arg) end @assert isexpr(body, :block) - if !isempty(names) - lin = first(body.args)::LineNumberNode - nospec = Expr(:macrocall, Symbol("@nospecialize"), lin, names...) - insert!(body.args, 2, nospec) - end + isempty(names) && throw(ArgumentError("no arguments for @nospec")) + lin = first(body.args)::LineNumberNode + nospec = Expr(:macrocall, GlobalRef(@__MODULE__, :var"@nospecialize"), lin, names...) + insert!(body.args, 2, nospec) return esc(ex) end @@ -190,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) @@ -199,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 # ----------------- @@ -1106,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 @@ -2017,6 +2020,15 @@ function tuple_tfunc(𝕃::AbstractLattice, argtypes::Vector{Any}) return anyinfo ? PartialStruct(𝕃, typ, argtypes) : typ end +@nospecs function memorynew_tfunc(𝕃::AbstractLattice, memtype, memlen) + hasintersect(widenconst(memlen), Int) || return Bottom + memt = tmeet(𝕃, instanceof_tfunc(memtype, true)[1], GenericMemory) + memt == Union{} && return memt + # PartialStruct so that loads of Const `length` get inferred + return PartialStruct(𝕃, memt, Any[memlen, Ptr{Nothing}]) +end +add_tfunc(Core.memorynew, 2, 2, memorynew_tfunc, 10) + @nospecs function memoryrefget_tfunc(𝕃::AbstractLattice, mem, order, boundscheck) memoryref_builtin_common_errorcheck(mem, order, boundscheck) || return Bottom return memoryref_elemtype(mem) @@ -2106,7 +2118,7 @@ add_tfunc(memoryrefoffset, 1, 1, memoryrefoffset_tfunc, 5) return true end -@nospecs function memoryref_elemtype(@nospecialize mem) +@nospecs function memoryref_elemtype(mem) m = widenconst(mem) if !has_free_typevars(m) && m <: GenericMemoryRef m0 = m @@ -2122,7 +2134,7 @@ end return Any end -@nospecs function _memoryref_elemtype(@nospecialize mem) +@nospecs function _memoryref_elemtype(mem) m = widenconst(mem) if !has_free_typevars(m) && m <: GenericMemoryRef m0 = m @@ -2157,7 +2169,7 @@ end end # whether getindex for the elements can potentially throw UndefRef -function array_type_undefable(@nospecialize(arytype)) +@nospecs function array_type_undefable(arytype) arytype = unwrap_unionall(arytype) if isa(arytype, Union) return array_type_undefable(arytype.a) || array_type_undefable(arytype.b) @@ -2238,13 +2250,32 @@ end return boundscheck ⊑ Bool && memtype ⊑ GenericMemoryRef && order ⊑ Symbol end +function memorynew_nothrow(argtypes::Vector{Any}) + if !(argtypes[1] isa Const && argtypes[2] isa Const) + return false + end + MemT = argtypes[1].val + if !(isconcretetype(MemT) && MemT <: GenericMemory) + return false + end + len = argtypes[2].val + if !(len isa Int && 0 <= len < typemax(Int)) + return false + end + elsz = datatype_layoutsize(MemT) + overflows = checked_smul_int(len, elsz)[2] + return !overflows +end + # Query whether the given builtin is guaranteed not to throw given the `argtypes`. # `argtypes` can be assumed not to contain varargs. function _builtin_nothrow(𝕃::AbstractLattice, @nospecialize(f::Builtin), argtypes::Vector{Any}, @nospecialize(rt)) ⊑ = partialorder(𝕃) na = length(argtypes) - if f === memoryrefnew + if f === Core.memorynew + return memorynew_nothrow(argtypes) + elseif f === memoryrefnew return memoryref_builtin_common_nothrow(argtypes) elseif f === memoryrefoffset length(argtypes) == 1 || return false @@ -2347,6 +2378,7 @@ const _EFFECT_FREE_BUILTINS = [ isa, UnionAll, getfield, + Core.memorynew, memoryrefnew, memoryrefoffset, memoryrefget, @@ -2381,6 +2413,7 @@ const _INACCESSIBLEMEM_BUILTINS = Any[ compilerbarrier, Core._typevar, donotdelete, + Core.memorynew, ] const _ARGMEM_BUILTINS = Any[ @@ -2543,7 +2576,7 @@ function builtin_effects(𝕃::AbstractLattice, @nospecialize(f::Builtin), argty consistent = ALWAYS_TRUE elseif f === memoryrefget || f === memoryrefset! || f === memoryref_isassigned consistent = CONSISTENT_IF_INACCESSIBLEMEMONLY - elseif f === Core._typevar + elseif f === Core._typevar || f === Core.memorynew consistent = CONSISTENT_IF_NOTRETURNED else consistent = ALWAYS_FALSE @@ -2983,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)) @@ -3099,16 +3136,7 @@ add_tfunc(Core.get_binding_type, 2, 2, @nospecs((𝕃::AbstractLattice, args...) const FOREIGNCALL_ARG_START = 6 -function foreigncall_effects(@specialize(abstract_eval), e::Expr) - args = e.args - name = args[1] - isa(name, QuoteNode) && (name = name.value) - if name === :jl_alloc_genericmemory - nothrow = new_genericmemory_nothrow(abstract_eval, args) - return Effects(EFFECTS_TOTAL; consistent=CONSISTENT_IF_NOTRETURNED, nothrow) - elseif name === :jl_genericmemory_copy_slice - return Effects(EFFECTS_TOTAL; consistent=CONSISTENT_IF_NOTRETURNED, nothrow=false) - end +function foreigncall_effects(@nospecialize(abstract_eval), e::Expr) # `:foreigncall` can potentially perform all sorts of operations, including calling # overlay methods, but the `:foreigncall` itself is not dispatched, and there is no # concern that the method calls that potentially occur within the `:foreigncall` will diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 20c0a5000bd39..e3896870d82b8 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -92,8 +92,7 @@ If set to `true`, record per-method-instance timings within type inference in th __set_measure_typeinf(onoff::Bool) = __measure_typeinf__[] = onoff const __measure_typeinf__ = RefValue{Bool}(false) -function finish!(interp::AbstractInterpreter, caller::InferenceState; - can_discard_trees::Bool=may_discard_trees(interp)) +function finish!(interp::AbstractInterpreter, caller::InferenceState) result = caller.result opt = result.src if opt isa OptimizationState @@ -120,39 +119,83 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState; store_backedges(ci, edges) end inferred_result = nothing - relocatability = 0x1 + uncompressed = inferred_result const_flag = is_result_constabi_eligible(result) - if !can_discard_trees || (is_cached(caller) && !const_flag) + discard_src = caller.cache_mode === CACHE_MODE_NULL || const_flag + if !discard_src inferred_result = transform_result_for_cache(interp, result) # TODO: do we want to augment edges here with any :invoke targets that we got from inlining (such that we didn't have a direct edge to it already)? - relocatability = 0x0 if inferred_result isa CodeInfo + if may_compress(interp) + nslots = length(inferred_result.slotflags) + resize!(inferred_result.slottypes::Vector{Any}, nslots) + resize!(inferred_result.slotnames, nslots) + end di = inferred_result.debuginfo uncompressed = inferred_result - inferred_result = maybe_compress_codeinfo(interp, result.linfo, inferred_result, can_discard_trees) - result.is_src_volatile |= uncompressed !== inferred_result + inferred_result = maybe_compress_codeinfo(interp, result.linfo, inferred_result) + result.is_src_volatile = false elseif ci.owner === nothing # The global cache can only handle objects that codegen understands inferred_result = nothing end - if isa(inferred_result, String) - t = @_gc_preserve_begin inferred_result - relocatability = unsafe_load(unsafe_convert(Ptr{UInt8}, inferred_result), Core.sizeof(inferred_result)) - @_gc_preserve_end t - end end - # n.b. relocatability = isa(inferred_result, String) && inferred_result[end] if !@isdefined di di = DebugInfo(result.linfo) end - ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), + ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), ci, inferred_result, const_flag, first(result.valid_worlds), last(result.valid_worlds), encode_effects(result.ipo_effects), - result.analysis_results, relocatability, di, edges) + result.analysis_results, di, edges) engine_reject(interp, ci) + if !discard_src && isdefined(interp, :codegen) && uncompressed isa CodeInfo + # record that the caller could use this result to generate code when required, if desired, to avoid repeating n^2 work + interp.codegen[ci] = uncompressed + if bootstrapping_compiler && inferred_result == nothing + # This is necessary to get decent bootstrapping performance + # when compiling the compiler to inject everything eagerly + # where codegen can start finding and using it right away + mi = result.linfo + if mi.def isa Method && isa_compileable_sig(mi) + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), ci, uncompressed) + end + end + end end return nothing end +function finish!(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInstance, src::CodeInfo) + user_edges = src.edges + edges = user_edges isa SimpleVector ? user_edges : user_edges === nothing ? Core.svec() : Core.svec(user_edges...) + const_flag = false + di = src.debuginfo + rettype = Any + exctype = Any + rettype_const = nothing + const_flags = 0x0 + ipo_effects = zero(UInt32) + min_world = src.min_world + max_world = src.max_world + if max_world >= get_world_counter() + max_world = typemax(UInt) + end + if max_world == typemax(UInt) + # if we can record all of the backedges in the global reverse-cache, + # we can now widen our applicability in the global cache too + store_backedges(ci, edges) + end + ccall(:jl_fill_codeinst, Cvoid, (Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), + ci, rettype, exctype, nothing, const_flags, min_world, max_world, ipo_effects, nothing, di, edges) + ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), + ci, nothing, const_flag, min_world, max_world, ipo_effects, nothing, di, edges) + code_cache(interp)[mi] = ci + if isdefined(interp, :codegen) + interp.codegen[ci] = src + end + engine_reject(interp, ci) + return nothing +end + function finish_nocycle(::AbstractInterpreter, frame::InferenceState) finishinfer!(frame, frame.interp) opt = frame.result.src @@ -223,19 +266,13 @@ end transform_result_for_cache(::AbstractInterpreter, result::InferenceResult) = result.src -function maybe_compress_codeinfo(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInfo, - can_discard_trees::Bool=may_discard_trees(interp)) +function maybe_compress_codeinfo(interp::AbstractInterpreter, mi::MethodInstance, ci::CodeInfo) def = mi.def isa(def, Method) || return ci # don't compress toplevel code - cache_the_tree = true - if can_discard_trees - cache_the_tree = is_inlineable(ci) || isa_compileable_sig(mi.specTypes, mi.sparam_vals, def) - end + can_discard_trees = may_discard_trees(interp) + cache_the_tree = !can_discard_trees || is_inlineable(ci) if cache_the_tree if may_compress(interp) - nslots = length(ci.slotflags) - resize!(ci.slottypes::Vector{Any}, nslots) - resize!(ci.slotnames, nslots) return ccall(:jl_compress_ir, String, (Any, Any), def, ci) else return ci @@ -476,7 +513,6 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter) rettype_const = nothing const_flags = 0x0 end - relocatability = 0x0 di = nothing edges = empty_edges # `edges` will be updated within `finish!` ci = result.ci @@ -484,10 +520,10 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter) ci, widenconst(result_type), widenconst(result.exc_result), rettype_const, const_flags, first(result.valid_worlds), last(result.valid_worlds), encode_effects(result.ipo_effects), result.analysis_results, di, edges) - if is_cached(me) + if is_cached(me) # CACHE_MODE_GLOBAL cached_result = cache_result!(me.interp, result, ci) if !cached_result - me.cache_mode = CACHE_MODE_NULL + me.cache_mode = CACHE_MODE_VOLATILE end end end @@ -508,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 @@ -521,14 +560,13 @@ 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 = callee.def + callee = get_ci_mi(callee) end ccall(:jl_method_instance_add_backedge, Cvoid, (Any, Any, Any), callee, item, caller) i += 2 @@ -705,7 +743,7 @@ function resolve_call_cycle!(interp::AbstractInterpreter, mi::MethodInstance, pa for frameid = reverse(1:length(frames)) frame = frames[frameid] isa(frame, InferenceState) || break - uncached |= !is_cached(frame) # ensure we never add an uncached frame to a cycle + uncached |= !is_cached(frame) # ensure we never add a (globally) uncached frame to a cycle if is_same_frame(interp, mi, frame) if uncached # our attempt to speculate into a constant call lead to an undesired self-cycle @@ -780,7 +818,7 @@ function codeinst_as_edge(interp::AbstractInterpreter, sv::InferenceState, @nosp end end ci = CodeInstance(mi, cache_owner(interp), Any, Any, nothing, nothing, zero(Int32), - min_world, max_world, zero(UInt32), nothing, zero(UInt8), nothing, edges) + min_world, max_world, zero(UInt32), nothing, nothing, edges) if max_world == typemax(UInt) # if we can record all of the backedges in the global reverse-cache, # we can now widen our applicability in the global cache too @@ -796,6 +834,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize cache_mode = CACHE_MODE_GLOBAL # cache edge targets globally by default force_inline = is_stmt_inline(get_curr_ssaflag(caller)) edge_ci = nothing + # check cache with SOURCE_MODE_NOT_REQUIRED source_mode let codeinst = get(code_cache(interp), mi, nothing) if codeinst isa CodeInstance # return existing rettype if the code is already inferred inferred = @atomic :monotonic codeinst.inferred @@ -811,7 +850,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize end end end - if ccall(:jl_get_module_infer, Cint, (Any,), method.module) == 0 && !generating_output(#=incremental=#false) + if ccall(:jl_get_module_infer, Cint, (Any,), method.module) == 0 add_remark!(interp, caller, "[typeinf_edge] Inference is disabled for the target module") return Future(MethodCallResult(interp, caller, method, Any, Any, Effects(), nothing, edgecycle, edgelimited)) end @@ -945,21 +984,6 @@ function codeinfo_for_const(interp::AbstractInterpreter, mi::MethodInstance, @no return tree end -""" - codeinstance_for_const_with_code(interp::AbstractInterpreter, code::CodeInstance) - -Given a constabi `CodeInstance`, create another (uncached) CodeInstance that contains the dummy code created -by [`codeinfo_for_const`](@ref) for use in reflection functions that require this. See [`codeinfo_for_const`](@ref) for -more details. -""" -function codeinstance_for_const_with_code(interp::AbstractInterpreter, code::CodeInstance) - src = codeinfo_for_const(interp, code.def, code.rettype_const) - return CodeInstance(code.def, cache_owner(interp), code.rettype, code.exctype, code.rettype_const, src, - Int32(0x3), code.min_world, code.max_world, - code.ipo_purity_bits, code.analysis_results, - code.relocatability, src.debuginfo, src.edges) -end - result_is_constabi(interp::AbstractInterpreter, result::InferenceResult) = may_discard_trees(interp) && is_result_constabi_eligible(result) @@ -977,23 +1001,23 @@ end """ typeinf_ircode(interp::AbstractInterpreter, match::MethodMatch, - optimize_until::Union{Integer,AbstractString,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) + optimize_until::Union{Int,String,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) typeinf_ircode(interp::AbstractInterpreter, method::Method, atype, sparams::SimpleVector, - optimize_until::Union{Integer,AbstractString,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) + optimize_until::Union{Int,String,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) typeinf_ircode(interp::AbstractInterpreter, mi::MethodInstance, - optimize_until::Union{Integer,AbstractString,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) + optimize_until::Union{Int,String,Nothing}) -> (ir::Union{IRCode,Nothing}, returntype::Type) Infer a `method` and return an `IRCode` with inferred `returntype` on success. """ typeinf_ircode(interp::AbstractInterpreter, match::MethodMatch, - optimize_until::Union{Integer,AbstractString,Nothing}) = + optimize_until::Union{Int,String,Nothing}) = typeinf_ircode(interp, specialize_method(match), optimize_until) typeinf_ircode(interp::AbstractInterpreter, method::Method, @nospecialize(atype), sparams::SimpleVector, - optimize_until::Union{Integer,AbstractString,Nothing}) = + optimize_until::Union{Int,String,Nothing}) = typeinf_ircode(interp, specialize_method(method, atype, sparams), optimize_until) function typeinf_ircode(interp::AbstractInterpreter, mi::MethodInstance, - optimize_until::Union{Integer,AbstractString,Nothing}) + optimize_until::Union{Int,String,Nothing}) frame = typeinf_frame(interp, mi, false) if frame === nothing return nothing, Any @@ -1051,61 +1075,44 @@ it has constabi) or one that can be made so by compiling its `->inferred` field. N.B.: The `->inferred` field is volatile and the compiler may delete it. -In such a case, it will first set the `invoke` field to a method that -will block the thread until compilation is completed. """ const SOURCE_MODE_ABI = 0x1 -""" - SOURCE_MODE_FORCE_SOURCE - -Indicates that inference must always produce source in the `->inferred` field. -This may mean that inference will need to re-do inference (if the `->inferred` -field was previously deleted by the JIT) or may need to synthesize source for -other kinds of CodeInstances. - -N.B.: The same caching considerations as SOURCE_MODE_ABI apply. -""" -const SOURCE_MODE_FORCE_SOURCE = 0x2 - -function ci_has_source(code::CodeInstance) - inf = @atomic :monotonic code.inferred - return code.owner === nothing ? (isa(inf, CodeInfo) || isa(inf, String)) : inf !== nothing -end - """ ci_has_abi(code::CodeInstance) Determine whether this CodeInstance is something that could be invoked if we gave it -to the runtime system (either because it already has an ->invoke ptr, or because it -has source that could be compiled). +to the runtime system (either because it already has an ->invoke ptr, or +because it has source that could be compiled). Note that this information may +be stale by the time the user see it, so the user will need to perform their +own checks if they actually need the abi from it. """ function ci_has_abi(code::CodeInstance) - ci_has_source(code) && return true - return code.invoke !== C_NULL + (@atomic :acquire code.invoke) !== C_NULL && return true + inf = @atomic :monotonic code.inferred + if code.owner === nothing ? (isa(inf, CodeInfo) || isa(inf, String)) : inf !== nothing + # interp.codegen[code] = maybe_uncompress(code, inf) # TODO: the correct way to ensure this information doesn't become stale would be to push it into the stable codegen cache + return true + end + return false +end + +function ci_has_invoke(code::CodeInstance) + return (@atomic :monotonic code.invoke) !== C_NULL end function ci_meets_requirement(code::CodeInstance, source_mode::UInt8) source_mode == SOURCE_MODE_NOT_REQUIRED && return true source_mode == SOURCE_MODE_ABI && return ci_has_abi(code) - source_mode == SOURCE_MODE_FORCE_SOURCE && return ci_has_source(code) return false end -_uncompressed_ir(codeinst::CodeInstance, s::String) = - ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Any, Any), codeinst.def.def::Method, codeinst, s) - # compute (and cache) an inferred AST and return type function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mode::UInt8) start_time = ccall(:jl_typeinf_timing_begin, UInt64, ()) let code = get(code_cache(interp), mi, nothing) if code isa CodeInstance # see if this code already exists in the cache - if source_mode == SOURCE_MODE_FORCE_SOURCE && use_const_api(code) - code = codeinstance_for_const_with_code(interp, code) - ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) - return code - end if ci_meets_requirement(code, source_mode) ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) return code @@ -1113,26 +1120,11 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod end end def = mi.def - if isa(def, Method) - if ccall(:jl_get_module_infer, Cint, (Any,), def.module) == 0 && !generating_output(#=incremental=#false) - src = retrieve_code_info(mi, get_inference_world(interp)) - src isa CodeInfo || return nothing - return CodeInstance(mi, cache_owner(interp), Any, Any, nothing, src, Int32(0), - get_inference_world(interp), get_inference_world(interp), - UInt32(0), nothing, UInt8(0), src.debuginfo, src.edges) - end - end ci = engine_reserve(interp, mi) # check cache again if it is still new after reserving in the engine let code = get(code_cache(interp), mi, nothing) if code isa CodeInstance # see if this code already exists in the cache - if source_mode == SOURCE_MODE_FORCE_SOURCE && use_const_api(code) - engine_reject(interp, ci) - code = codeinstance_for_const_with_code(interp, code) - ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) - return code - end if ci_meets_requirement(code, source_mode) engine_reject(interp, ci) ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) @@ -1140,37 +1132,37 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod end end end + if isa(def, Method) && ccall(:jl_get_module_infer, Cint, (Any,), def.module) == 0 + src = retrieve_code_info(mi, get_inference_world(interp)) + if src isa CodeInfo + finish!(interp, mi, ci, src) + else + engine_reject(interp, ci) + end + ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) + return ci + end result = InferenceResult(mi, typeinf_lattice(interp)) result.ci = ci frame = InferenceState(result, #=cache_mode=#:global, interp) if frame === nothing engine_reject(interp, ci) + ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) return nothing end typeinf(interp, frame) ccall(:jl_typeinf_timing_end, Cvoid, (UInt64,), start_time) ci = result.ci # reload from result in case it changed - if source_mode == SOURCE_MODE_ABI && frame.cache_mode != CACHE_MODE_GLOBAL - # XXX: jl_type_infer somewhat ambiguously assumes this must be cached, while jl_ci_cache_lookup sort of ambiguously re-caches it + @assert frame.cache_mode != CACHE_MODE_NULL + @assert is_result_constabi_eligible(result) || (!isdefined(interp, :codegen) || haskey(interp.codegen, ci)) + @assert is_result_constabi_eligible(result) == use_const_api(ci) + @assert isdefined(ci, :inferred) "interpreter did not fulfill our expectations" + if !is_cached(frame) && source_mode == SOURCE_MODE_ABI + # XXX: jl_type_infer somewhat ambiguously assumes this must be cached # XXX: this should be using the CI from the cache, if possible instead: haskey(cache, mi) && (ci = cache[mi]) - @assert isdefined(ci, :inferred) "interpreter did not fulfill its requirements" code_cache(interp)[mi] = ci end - if source_mode == SOURCE_MODE_FORCE_SOURCE && use_const_api(ci) - # If the caller cares about the code and this is constabi, still use our synthesis function - # anyway, because we will have not finished inferring the code inside the CodeInstance once - # we realized it was constabi, but we want reflection to pretend that we did. - # XXX: the one user of this does not actually want this behavior, but it is required by the flag definition currently - ci = codeinstance_for_const_with_code(interp, ci) - @assert ci_meets_requirement(ci, source_mode) - return ci - end - if !ci_meets_requirement(ci, source_mode) - can_discard_trees = false - finish!(interp, frame; can_discard_trees) # redo finish! with the correct can_discard_trees parameter value - @assert ci_meets_requirement(ci, source_mode) - end return ci end @@ -1215,10 +1207,115 @@ function typeinf_type(interp::AbstractInterpreter, mi::MethodInstance) return widenconst(ignorelimited(result.result)) end -# This is a bridge for the C code calling `jl_typeinf_func()` -typeinf_ext_toplevel(mi::MethodInstance, world::UInt, source_mode::UInt8) = typeinf_ext_toplevel(NativeInterpreter(world), mi, source_mode) -function typeinf_ext_toplevel(interp::AbstractInterpreter, mi::MethodInstance, source_mode::UInt8) - return typeinf_ext(interp, mi, source_mode) +# collect a list of all code that is needed along with CodeInstance to codegen it fully +function collectinvokes!(wq::Vector{CodeInstance}, ci::CodeInfo) + src = ci.code + for i = 1:length(src) + stmt = src[i] + isexpr(stmt, :(=)) && (stmt = stmt.args[2]) + if isexpr(stmt, :invoke) || isexpr(stmt, :invoke_modify) + edge = stmt.args[1] + edge isa CodeInstance && isdefined(edge, :inferred) && push!(wq, edge) + end + # TODO: handle other StmtInfo like @cfunction and OpaqueClosure? + end +end + +# This is a bridge for the C code calling `jl_typeinf_func()` on a single Method match +function typeinf_ext_toplevel(mi::MethodInstance, world::UInt, source_mode::UInt8) + interp = NativeInterpreter(world) + ci = typeinf_ext(interp, mi, source_mode) + if source_mode == SOURCE_MODE_ABI && ci isa CodeInstance && !ci_has_invoke(ci) + inspected = IdSet{CodeInstance}() + tocompile = Vector{CodeInstance}() + push!(tocompile, ci) + while !isempty(tocompile) + # ci_has_real_invoke(ci) && return ci # optimization: cease looping if ci happens to get compiled (not just jl_fptr_wait_for_compiled, but fully jl_is_compiled_codeinst) + callee = pop!(tocompile) + ci_has_invoke(callee) && continue + callee in inspected && continue + src = get(interp.codegen, callee, nothing) + if !isa(src, CodeInfo) + src = @atomic :monotonic callee.inferred + if isa(src, String) + src = _uncompressed_ir(callee, src) + end + if !isa(src, CodeInfo) + newcallee = typeinf_ext(interp, callee.def, source_mode) + if newcallee isa CodeInstance + callee === ci && (ci = newcallee) # ci stopped meeting the requirements after typeinf_ext last checked, try again with newcallee + push!(tocompile, newcallee) + #else + # println("warning: could not get source code for ", callee.def) + end + continue + end + end + push!(inspected, callee) + collectinvokes!(tocompile, src) + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), callee, src) + end + end + return ci +end + +# This is a bridge for the C code calling `jl_typeinf_func()` on set of Method matches +function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim::Bool) + inspected = IdSet{CodeInstance}() + tocompile = Vector{CodeInstance}() + codeinfos = [] + # first compute the ABIs of everything + for this_world in reverse(sort!(worlds)) + interp = NativeInterpreter(this_world) + for i = 1:length(methods) + # each item in this list is either a MethodInstance indicating something + # to compile, or an svec(rettype, sig) describing a C-callable alias to create. + item = methods[i] + if item isa MethodInstance + # if this method is generally visible to the current compilation world, + # and this is either the primary world, or not applicable in the primary world + # then we want to compile and emit this + if item.def.primary_world <= this_world <= item.def.deleted_world + ci = typeinf_ext(interp, item, SOURCE_MODE_NOT_REQUIRED) + ci isa CodeInstance && !use_const_api(ci) && push!(tocompile, ci) + end + elseif item isa SimpleVector + push!(codeinfos, item[1]::Type) + push!(codeinfos, item[2]::Type) + end + end + while !isempty(tocompile) + callee = pop!(tocompile) + callee in inspected && continue + push!(inspected, callee) + # now make sure everything has source code, if desired + mi = get_ci_mi(callee) + def = mi.def + if use_const_api(callee) + src = codeinfo_for_const(interp, mi, code.rettype_const) + elseif haskey(interp.codegen, callee) + src = interp.codegen[callee] + elseif isa(def, Method) && ccall(:jl_get_module_infer, Cint, (Any,), def.module) == 0 && !trim + src = retrieve_code_info(mi, get_inference_world(interp)) + else + # TODO: typeinf_code could return something with different edges/ages/owner/abi (needing an update to callee), which we don't handle here + src = typeinf_code(interp, mi, true) + end + if src isa CodeInfo + collectinvokes!(tocompile, src) + # It is somewhat ambiguous if typeinf_ext might have callee in the caches, + # but for the purpose of native compile, we always want them put there. + if iszero(ccall(:jl_mi_cache_has_ci, Cint, (Any, Any), mi, callee)) + code_cache(interp)[mi] = callee + end + push!(codeinfos, callee) + push!(codeinfos, src) + elseif trim + println("warning: failed to get code for ", mi) + end + end + end + return codeinfos end function return_type(@nospecialize(f), t::DataType) # this method has a special tfunc 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/src/typelimits.jl b/Compiler/src/typelimits.jl index e420db030715b..536b5fb34d1b1 100644 --- a/Compiler/src/typelimits.jl +++ b/Compiler/src/typelimits.jl @@ -587,7 +587,7 @@ end @nospecializeinfer function tmerge_partial_struct(𝕃::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) aty = widenconst(typea) bty = widenconst(typeb) - if aty === bty + if aty === bty && !isType(aty) if typea isa PartialStruct if typeb isa PartialStruct nflds = min(length(typea.fields), length(typeb.fields)) @@ -601,13 +601,10 @@ 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)) - # N.B.: We're assuming here that !isType(aty), because that case - # only arises when typea === typeb, which should have been caught - # before calling this. ft = fieldtype(aty, i) if is_lattice_equal(𝕃, ai, bi) || is_lattice_equal(𝕃, ai, ft) # Since ai===bi, the given type has no restrictions on complexity. diff --git a/Compiler/src/types.jl b/Compiler/src/types.jl index 5669ec3175c9e..6ffb5402682f3 100644 --- a/Compiler/src/types.jl +++ b/Compiler/src/types.jl @@ -366,6 +366,7 @@ struct NativeInterpreter <: AbstractInterpreter # Cache of inference results for this particular interpreter inf_cache::Vector{InferenceResult} + codegen::IdDict{CodeInstance,CodeInfo} # Parameters for inference and optimization inf_params::InferenceParams @@ -386,16 +387,8 @@ function NativeInterpreter(world::UInt = get_world_counter(); @assert world <= curr_max_world method_table = CachedMethodTable(InternalMethodTable(world)) inf_cache = Vector{InferenceResult}() # Initially empty cache - return NativeInterpreter(world, method_table, inf_cache, inf_params, opt_params) -end - -function NativeInterpreter(interp::NativeInterpreter; - world::UInt = interp.world, - method_table::CachedMethodTable{InternalMethodTable} = interp.method_table, - inf_cache::Vector{InferenceResult} = interp.inf_cache, - inf_params::InferenceParams = interp.inf_params, - opt_params::OptimizationParams = interp.opt_params) - return NativeInterpreter(world, method_table, inf_cache, inf_params, opt_params) + codegen = IdDict{CodeInstance,CodeInfo}() + return NativeInterpreter(world, method_table, inf_cache, codegen, inf_params, opt_params) end # Quickly and easily satisfy the AbstractInterpreter API contract diff --git a/Compiler/src/typeutils.jl b/Compiler/src/typeutils.jl index 4af8fed0e40c3..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 @@ -64,7 +69,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] diff --git a/Compiler/src/utilities.jl b/Compiler/src/utilities.jl index da20f9aafbfb2..c322d1062cea1 100644 --- a/Compiler/src/utilities.jl +++ b/Compiler/src/utilities.jl @@ -12,25 +12,6 @@ if !@isdefined(var"@timeit") end end -# avoid cycle due to over-specializing `any` when used by inference -function _any(@nospecialize(f), a) - for x in a - f(x) && return true - end - return false -end -any(@nospecialize(f), itr) = _any(f, itr) -any(itr) = _any(identity, itr) - -function _all(@nospecialize(f), a) - for x in a - f(x) || return false - end - return true -end -all(@nospecialize(f), itr) = _all(f, itr) -all(itr) = _all(identity, itr) - function contains_is(itr, @nospecialize(x)) for y in itr if y === x @@ -168,6 +149,9 @@ end isa_compileable_sig(@nospecialize(atype), sparams::SimpleVector, method::Method) = !iszero(ccall(:jl_isa_compileable_sig, Int32, (Any, Any, Any), atype, sparams, method)) +isa_compileable_sig(m::MethodInstance) = (def = m.def; !isa(def, Method) || isa_compileable_sig(m.specTypes, m.sparam_vals, def)) +isa_compileable_sig(m::ABIOverride) = false + has_typevar(@nospecialize(t), v::TypeVar) = ccall(:jl_has_typevar, Cint, (Any, Any), t, v) != 0 """ diff --git a/Compiler/test/EAUtils.jl b/Compiler/test/EAUtils.jl index f124aea2544fd..990a7de3b8141 100644 --- a/Compiler/test/EAUtils.jl +++ b/Compiler/test/EAUtils.jl @@ -14,27 +14,12 @@ import .Compiler: AbstractInterpreter, NativeInterpreter, WorldView, WorldRange, InferenceParams, OptimizationParams, get_world_counter, get_inference_cache, ipo_dataflow_analysis! # usings -using Core: - CodeInstance, MethodInstance, CodeInfo -using .Compiler: - InferenceResult, InferenceState, OptimizationState, IRCode +using Core.IR +using .Compiler: InferenceResult, InferenceState, OptimizationState, IRCode using .EA: analyze_escapes, ArgEscapeCache, ArgEscapeInfo, EscapeInfo, EscapeState -struct EAToken end - -# when working outside of CC, -# cache entire escape state for later inspection and debugging -struct EscapeCacheInfo - argescapes::ArgEscapeCache - state::EscapeState # preserved just for debugging purpose - ir::IRCode # preserved just for debugging purpose -end - -struct EscapeCache - cache::IdDict{MethodInstance,EscapeCacheInfo} # TODO(aviatesk) Should this be CodeInstance to EscapeCacheInfo? -end -EscapeCache() = EscapeCache(IdDict{MethodInstance,EscapeCacheInfo}()) -const GLOBAL_ESCAPE_CACHE = EscapeCache() +mutable struct EscapeAnalyzerCacheToken end +global GLOBAL_EA_CACHE_TOKEN::EscapeAnalyzerCacheToken = EscapeAnalyzerCacheToken() struct EscapeResultForEntry ir::IRCode @@ -47,15 +32,15 @@ mutable struct EscapeAnalyzer <: AbstractInterpreter const inf_params::InferenceParams const opt_params::OptimizationParams const inf_cache::Vector{InferenceResult} - const escape_cache::EscapeCache + const token::EscapeAnalyzerCacheToken const entry_mi::Union{Nothing,MethodInstance} result::EscapeResultForEntry - function EscapeAnalyzer(world::UInt, escape_cache::EscapeCache; + function EscapeAnalyzer(world::UInt, cache_token::EscapeAnalyzerCacheToken; entry_mi::Union{Nothing,MethodInstance}=nothing) inf_params = InferenceParams() opt_params = OptimizationParams() inf_cache = InferenceResult[] - return new(world, inf_params, opt_params, inf_cache, escape_cache, entry_mi) + return new(world, inf_params, opt_params, inf_cache, cache_token, entry_mi) end end @@ -63,20 +48,19 @@ Compiler.InferenceParams(interp::EscapeAnalyzer) = interp.inf_params Compiler.OptimizationParams(interp::EscapeAnalyzer) = interp.opt_params Compiler.get_inference_world(interp::EscapeAnalyzer) = interp.world Compiler.get_inference_cache(interp::EscapeAnalyzer) = interp.inf_cache -Compiler.cache_owner(::EscapeAnalyzer) = EAToken() -Compiler.get_escape_cache(interp::EscapeAnalyzer) = GetEscapeCache(interp) +Compiler.cache_owner(interp::EscapeAnalyzer) = interp.token +Compiler.get_escape_cache(::EscapeAnalyzer) = GetEscapeCache() function Compiler.ipo_dataflow_analysis!(interp::EscapeAnalyzer, opt::OptimizationState, - ir::IRCode, caller::InferenceResult) + ir::IRCode, caller::InferenceResult) # run EA on all frames that have been optimized nargs = Int(opt.src.nargs) 𝕃ₒ = Compiler.optimizer_lattice(interp) - get_escape_cache = GetEscapeCache(interp) estate = try - analyze_escapes(ir, nargs, 𝕃ₒ, get_escape_cache) + analyze_escapes(ir, nargs, 𝕃ₒ, GetEscapeCache()) catch err @error "error happened within EA, inspect `Main.failedanalysis`" - failedanalysis = FailedAnalysis(caller, ir, nargs, get_escape_cache) + failedanalysis = FailedAnalysis(caller, ir, nargs) Core.eval(Main, :(failedanalysis = $failedanalysis)) rethrow(err) end @@ -84,25 +68,31 @@ function Compiler.ipo_dataflow_analysis!(interp::EscapeAnalyzer, opt::Optimizati # return back the result interp.result = EscapeResultForEntry(Compiler.copy(ir), estate, caller.linfo) end - record_escapes!(interp, caller, estate, ir) + record_escapes!(caller, estate, ir) @invoke Compiler.ipo_dataflow_analysis!(interp::AbstractInterpreter, opt::OptimizationState, - ir::IRCode, caller::InferenceResult) + ir::IRCode, caller::InferenceResult) end -function record_escapes!(interp::EscapeAnalyzer, - caller::InferenceResult, estate::EscapeState, ir::IRCode) +# cache entire escape state for inspection and debugging +struct EscapeCacheInfo + argescapes::ArgEscapeCache + state::EscapeState # preserved just for debugging purpose + ir::IRCode # preserved just for debugging purpose +end + +function record_escapes!(caller::InferenceResult, estate::EscapeState, ir::IRCode) argescapes = ArgEscapeCache(estate) ecacheinfo = EscapeCacheInfo(argescapes, estate, ir) return Compiler.stack_analysis_result!(caller, ecacheinfo) end -struct GetEscapeCache - escape_cache::EscapeCache - GetEscapeCache(interp::EscapeAnalyzer) = new(interp.escape_cache) -end -function ((; escape_cache)::GetEscapeCache)(mi::MethodInstance) - ecacheinfo = get(escape_cache.cache, mi, nothing) +struct GetEscapeCache end +function (::GetEscapeCache)(codeinst::Union{CodeInstance,MethodInstance}) + codeinst isa CodeInstance || return false + ecacheinfo = Compiler.traverse_analysis_results(codeinst) do @nospecialize result + return result isa EscapeCacheInfo ? result : nothing + end return ecacheinfo === nothing ? false : ecacheinfo.argescapes end @@ -110,15 +100,6 @@ struct FailedAnalysis caller::InferenceResult ir::IRCode nargs::Int - get_escape_cache::GetEscapeCache -end - -function Compiler.finish!(interp::EscapeAnalyzer, state::InferenceState; can_discard_trees::Bool=Compiler.may_discard_trees(interp)) - ecacheinfo = Compiler.traverse_analysis_results(state.result) do @nospecialize result - return result isa EscapeCacheInfo ? result : nothing - end - ecacheinfo isa EscapeCacheInfo && (interp.escape_cache.cache[state.linfo] = ecacheinfo) - return @invoke Compiler.finish!(interp::AbstractInterpreter, state::InferenceState; can_discard_trees) end # printing @@ -313,23 +294,29 @@ while caching the analysis results. - `world::UInt = Base.get_world_counter()`: controls the world age to use when looking up methods, use current world age if not specified. -- `interp::EscapeAnalyzer = EscapeAnalyzer(world)`: - specifies the escape analyzer to use, by default a new analyzer with the global cache is created. +- `cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN`: + specifies the cache token to use, by default a global token is used so that the analysis + can use the caches from previous invocations. If you with to use a fresh cache and perform + a new analysis, specify a new `EscapeAnalyzerCacheToken` instance. +- `interp::EscapeAnalyzer = EscapeAnalyzer(world, cache_token)`: + specifies the escape analyzer to use. - `debuginfo::Symbol = :none`: controls the amount of code metadata present in the output, possible options are `:none` or `:source`. """ function code_escapes(@nospecialize(f), @nospecialize(types=Base.default_tt(f)); world::UInt = get_world_counter(), + cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN, debuginfo::Symbol = :none) tt = Base.signature_type(f, types) match = Base._which(tt; world, raise=true) mi = Compiler.specialize_method(match) - return code_escapes(mi; world, debuginfo) + return code_escapes(mi; world, cache_token, debuginfo) end function code_escapes(mi::MethodInstance; world::UInt = get_world_counter(), - interp::EscapeAnalyzer=EscapeAnalyzer(world, GLOBAL_ESCAPE_CACHE; entry_mi=mi), + cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN, + interp::EscapeAnalyzer=EscapeAnalyzer(world, cache_token; entry_mi=mi), debuginfo::Symbol = :none) frame = Compiler.typeinf_frame(interp, mi, #=run_optimizer=#true) isdefined(interp, :result) || error("optimization didn't happen: maybe everything has been constant folded?") @@ -351,12 +338,17 @@ Note that this version does not cache the analysis results. - `world::UInt = Base.get_world_counter()`: controls the world age to use when looking up methods, use current world age if not specified. -- `interp::AbstractInterpreter = EscapeAnalyzer(world, EscapeCache())`: +- `cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN`: + specifies the cache token to use, by default a global token is used so that the analysis + can use the caches from previous invocations. If you with to use a fresh cache and perform + a new analysis, specify a new `EscapeAnalyzerCacheToken` instance. +- `interp::AbstractInterpreter = EscapeAnalyzer(world, cache_token)`: specifies the abstract interpreter to use, by default a new `EscapeAnalyzer` with an empty cache is created. """ function code_escapes(ir::IRCode, nargs::Int; world::UInt = get_world_counter(), - interp::AbstractInterpreter=EscapeAnalyzer(world, EscapeCache())) + cache_token::EscapeAnalyzerCacheToken = GLOBAL_EA_CACHE_TOKEN, + interp::AbstractInterpreter=EscapeAnalyzer(world, cache_token)) estate = analyze_escapes(ir, nargs, Compiler.optimizer_lattice(interp), Compiler.get_escape_cache(interp)) return EscapeResult(ir, estate) # return back the result end diff --git a/Compiler/test/EscapeAnalysis.jl b/Compiler/test/EscapeAnalysis.jl index 1831bd355cd48..60364769c95a8 100644 --- a/Compiler/test/EscapeAnalysis.jl +++ b/Compiler/test/EscapeAnalysis.jl @@ -34,24 +34,9 @@ let utils_ex = quote Core.eval(@__MODULE__, utils_ex) end -using .EscapeAnalysis: - EscapeInfo, IndexableElements, IndexableFields, normalize +using .EscapeAnalysis: EscapeInfo, IndexableFields isϕ(@nospecialize x) = isa(x, Core.PhiNode) -function with_normalized_name(@nospecialize(f), @nospecialize(x)) - if Meta.isexpr(x, :foreigncall) - name = x.args[1] - nn = normalize(name) - return isa(nn, Symbol) && f(nn) - end - return false -end -isarrayalloc(@nospecialize x) = - with_normalized_name(nn::Symbol->false, x) -isarrayresize(@nospecialize x) = - with_normalized_name(nn::Symbol->false, x) -isarraycopy(@nospecialize x) = - with_normalized_name(nn::Symbol->false, x) """ is_load_forwardable(x::EscapeInfo) -> Bool @@ -61,7 +46,7 @@ function is_load_forwardable(x::EscapeInfo) AliasInfo = x.AliasInfo # NOTE technically we also need to check `!has_thrown_escape(x)` here as well, # but we can also do equivalent check during forwarding - return isa(AliasInfo, IndexableFields) || isa(AliasInfo, IndexableElements) + return isa(AliasInfo, IndexableFields) end @testset "EAUtils" begin @@ -1501,585 +1486,6 @@ let result = @code_escapes compute!(MPoint(1+.5im, 2+.5im), MPoint(2+.25im, 4+.7 end end -@testset "array primitives" begin - # arrayref - @test_skip let result = code_escapes((Vector{String},Int)) do xs, i - s = Base.arrayref(true, xs, i) - return s - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test has_thrown_escape(result.state[Argument(2)]) # xs - @test !has_return_escape(result.state[Argument(3)], r) # i - end - @test_skip let result = code_escapes((Vector{String},Int)) do xs, i - s = Base.arrayref(false, xs, i) - return s - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test !has_thrown_escape(result.state[Argument(2)]) # xs - @test !has_return_escape(result.state[Argument(3)], r) # i - end - @test_skip let result = code_escapes((Vector{String},Bool)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError will happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((String,Int)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError will happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((AbstractVector{String},Int)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError may happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((Vector{String},Any)) do xs, i - c = Base.arrayref(true, xs, i) # TypeError may happen here - return c - end - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - - # arrayset - @test_skip let result = code_escapes((Vector{String},String,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) - return xs - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test has_thrown_escape(result.state[Argument(2)]) # xs - @test has_return_escape(result.state[Argument(3)], r) # x - end - @test_skip let result = code_escapes((Vector{String},String,Int,)) do xs, x, i - Base.arrayset(false, xs, x, i) - return xs - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[Argument(2)], r) # xs - @test !has_thrown_escape(result.state[Argument(2)]) # xs - @test has_return_escape(result.state[Argument(3)], r) # x - end - @test_skip let result = code_escapes((String,String,String,)) do s, t, u - xs = Vector{String}(undef, 3) - Base.arrayset(true, xs, s, 1) - Base.arrayset(true, xs, t, 2) - Base.arrayset(true, xs, u, 3) - return xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - for i in 2:result.state.nargs - @test has_return_escape(result.state[Argument(i)], r) - end - end - @test_skip let result = code_escapes((Vector{String},String,Bool,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError will happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - @test has_thrown_escape(result.state[Argument(3)], t) # x - end - @test_skip let result = code_escapes((String,String,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError will happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs::String - @test has_thrown_escape(result.state[Argument(3)], t) # x::String - end - @test_skip let result = code_escapes((AbstractVector{String},String,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError may happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - @test has_thrown_escape(result.state[Argument(3)], t) # x - end - @test_skip let result = code_escapes((Vector{String},AbstractString,Int,)) do xs, x, i - Base.arrayset(true, xs, x, i) # TypeError may happen here - return xs - end - t = only(findall(iscall((result.ir, Base.arrayset)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - @test has_thrown_escape(result.state[Argument(3)], t) # x - end - - # arrayref and arrayset - @test_skip let result = code_escapes() do - a = Vector{Vector{Any}}(undef, 1) - b = Any[] - a[1] = b - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - ai = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Vector{Any}} - end) - bi = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Any} - end) - @test !has_return_escape(result.state[SSAValue(ai)], r) - @test has_return_escape(result.state[SSAValue(bi)], r) - end - @test_skip let result = code_escapes() do - a = Vector{Vector{Any}}(undef, 1) - b = Any[] - a[1] = b - return a - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - ai = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Vector{Any}} - end) - bi = only(findall(result.ir.stmts.stmt) do @nospecialize x - isarrayalloc(x) && x.args[2] === Vector{Any} - end) - @test has_return_escape(result.state[SSAValue(ai)], r) - @test has_return_escape(result.state[SSAValue(bi)], r) - end - @test_skip let result = code_escapes((Vector{Any},String,Int,Int)) do xs, s, i, j - x = SafeRef(s) - xs[i] = x - xs[j] # potential error - end - i = only(findall(isnew, result.ir.stmts.stmt)) - t = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(3)], t) # s - @test has_thrown_escape(result.state[SSAValue(i)], t) # x - end - - # arraysize - @test_skip let result = code_escapes((Vector{Any},)) do xs - Core.arraysize(xs, 1) - end - t = only(findall(iscall((result.ir, Core.arraysize)), result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) - end - @test_skip let result = code_escapes((Vector{Any},Int,)) do xs, dim - Core.arraysize(xs, dim) - end - t = only(findall(iscall((result.ir, Core.arraysize)), result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) - end - @test_skip let result = code_escapes((Any,)) do xs - Core.arraysize(xs, 1) - end - t = only(findall(iscall((result.ir, Core.arraysize)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) - end - - # arraylen - @test_skip let result = code_escapes((Vector{Any},)) do xs - Base.arraylen(xs) - end - t = only(findall(iscall((result.ir, Base.arraylen)), result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((String,)) do xs - Base.arraylen(xs) - end - t = only(findall(iscall((result.ir, Base.arraylen)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - @test_skip let result = code_escapes((Vector{Any},)) do xs - Base.arraylen(xs, 1) - end - t = only(findall(iscall((result.ir, Base.arraylen)), result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[Argument(2)], t) # xs - end - - # array resizing - # without BoundsErrors - @test_skip let result = code_escapes((Vector{Any},String)) do xs, x - @ccall jl_array_grow_beg(xs::Any, 2::UInt)::Cvoid - xs[1] = x - xs - end - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) # xs - @test !has_thrown_escape(result.state[Argument(3)], t) # x - end - @test_skip let result = code_escapes((Vector{Any},String)) do xs, x - @ccall jl_array_grow_end(xs::Any, 2::UInt)::Cvoid - xs[1] = x - xs - end - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test !has_thrown_escape(result.state[Argument(2)], t) # xs - @test !has_thrown_escape(result.state[Argument(3)], t) # x - end - # with possible BoundsErrors - @test_skip let result = code_escapes((String,)) do x - xs = Any[1,2,3] - xs[3] = x - @ccall jl_array_del_beg(xs::Any, 2::UInt)::Cvoid # can potentially throw - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - @test_skip let result = code_escapes((String,)) do x - xs = Any[1,2,3] - xs[1] = x - @ccall jl_array_del_end(xs::Any, 2::UInt)::Cvoid # can potentially throw - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - @test_skip let result = code_escapes((String,)) do x - xs = Any[x] - @ccall jl_array_grow_at(xs::Any, 1::UInt, 2::UInt)::Cvoid # can potentially throw - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - @test_skip let result = code_escapes((String,)) do x - xs = Any[x] - @ccall jl_array_del_at(xs::Any, 1::UInt, 2::UInt)::Cvoid # can potentially throw - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - t = only(findall(isarrayresize, result.ir.stmts.stmt)) - @test has_thrown_escape(result.state[SSAValue(i)], t) # xs - @test has_thrown_escape(result.state[Argument(2)], t) # x - end - - # array copy - @test_skip let result = code_escapes((Vector{Any},)) do xs - return copy(xs) - end - i = only(findall(isarraycopy, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - @test !has_return_escape(result.state[Argument(2)], r) - end - @test_skip let result = code_escapes((String,)) do s - xs = String[s] - xs′ = copy(xs) - return xs′[1] - end - i1 = only(findall(isarrayalloc, result.ir.stmts.stmt)) - i2 = only(findall(isarraycopy, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i1)]) - @test !has_return_escape(result.state[SSAValue(i2)]) - @test has_return_escape(result.state[Argument(2)], r) # s - end - @test_skip let result = code_escapes((Vector{Any},)) do xs - xs′ = copy(xs) - return xs′[1] # may potentially throw BoundsError, should escape `xs` conservatively (i.e. escape its elements) - end - i = only(findall(isarraycopy, result.ir.stmts.stmt)) - ref = only(findall(iscall((result.ir, Base.arrayref)), result.ir.stmts.stmt)) - ret = only(findall(isreturn, result.ir.stmts.stmt)) - @test_broken !has_thrown_escape(result.state[SSAValue(i)], ref) - @test_broken !has_return_escape(result.state[SSAValue(i)], ret) - @test has_thrown_escape(result.state[Argument(2)], ref) - @test has_return_escape(result.state[Argument(2)], ret) - end - @test_skip let result = code_escapes((String,)) do s - xs = Vector{String}(undef, 1) - xs[1] = s - xs′ = copy(xs) - length(xs′) > 2 && throw(xs′) - return xs′ - end - i1 = only(findall(isarrayalloc, result.ir.stmts.stmt)) - i2 = only(findall(isarraycopy, result.ir.stmts.stmt)) - t = only(findall(iscall((result.ir, throw)), result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test_broken !has_thrown_escape(result.state[SSAValue(i1)], t) - @test_broken !has_return_escape(result.state[SSAValue(i1)], r) - @test has_thrown_escape(result.state[SSAValue(i2)], t) - @test has_return_escape(result.state[SSAValue(i2)], r) - @test has_thrown_escape(result.state[Argument(2)], t) - @test has_return_escape(result.state[Argument(2)], r) - end - - # isassigned - let result = code_escapes((Vector{Any},Int)) do xs, i - return isassigned(xs, i) - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test_broken !has_return_escape(result.state[Argument(2)], r) - @test_broken !has_thrown_escape(result.state[Argument(2)]) - end - - # indexing analysis - # ----------------- - - # safe case - @test_skip let result = code_escapes((String,String)) do s, t - a = Vector{Any}(undef, 2) - a[1] = s - a[2] = t - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test !has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((String,String)) do s, t - a = Matrix{Any}(undef, 1, 2) - a[1, 1] = s - a[1, 2] = t - return a[1, 1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test !has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((Bool,String,String,String)) do c, s, t, u - a = Vector{Any}(undef, 2) - if c - a[1] = s - a[2] = u - else - a[1] = t - a[2] = u - end - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test is_load_forwardable(result.state[SSAValue(i)]) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test has_return_escape(result.state[Argument(3)], r) # s - @test has_return_escape(result.state[Argument(4)], r) # t - @test !has_return_escape(result.state[Argument(5)], r) # u - end - @test_skip let result = code_escapes((Bool,String,String,String)) do c, s, t, u - a = Any[nothing, nothing] # TODO how to deal with loop indexing? - if c - a[1] = s - a[2] = u - else - a[1] = t - a[2] = u - end - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test_broken is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(3)], r) # s - @test has_return_escape(result.state[Argument(4)], r) # t - @test_broken !has_return_escape(result.state[Argument(5)], r) # u - end - @test_skip let result = code_escapes((String,)) do s - a = Vector{Vector{Any}}(undef, 1) - b = Any[s] - a[1] = b - return a[1][1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - is = findall(isarrayalloc, result.ir.stmts.stmt) - @assert length(is) == 2 - ia, ib = is - @test !has_return_escape(result.state[SSAValue(ia)], r) - @test is_load_forwardable(result.state[SSAValue(ia)]) - @test !has_return_escape(result.state[SSAValue(ib)], r) - @test_broken is_load_forwardable(result.state[SSAValue(ib)]) - @test has_return_escape(result.state[Argument(2)], r) # s - end - @test_skip let result = code_escapes((Bool,String,String,Regex,Regex,)) do c, s1, s2, t1, t2 - if c - a = Vector{String}(undef, 2) - a[1] = s1 - a[2] = s2 - else - a = Vector{Regex}(undef, 2) - a[1] = t1 - a[2] = t2 - end - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - for i in findall(isarrayalloc, result.ir.stmts.stmt) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test is_load_forwardable(result.state[SSAValue(i)]) - end - @test has_return_escape(result.state[Argument(3)], r) # s1 - @test !has_return_escape(result.state[Argument(4)], r) # s2 - @test has_return_escape(result.state[Argument(5)], r) # t1 - @test !has_return_escape(result.state[Argument(6)], r) # t2 - end - @test_skip let result = code_escapes((String,String,Int)) do s, t, i - a = Any[s] - push!(a, t) - return a[2] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test_broken is_load_forwardable(result.state[SSAValue(i)]) - @test_broken !has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - end - # unsafe cases - @test_skip let result = code_escapes((String,String,Int)) do s, t, i - a = Vector{Any}(undef, 2) - a[1] = s - a[2] = t - return a[i] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((String,String,Int)) do s, t, i - a = Vector{Any}(undef, 2) - a[1] = s - a[i] = t - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - end - @test_skip let result = code_escapes((String,String,Int,Int,Int)) do s, t, i, j, k - a = Vector{Any}(undef, 2) - a[3] = s # BoundsError - a[1] = t - return a[1] - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - end - @test_skip let result = @eval Module() begin - @noinline some_resize!(a) = pushfirst!(a, nothing) - $code_escapes((String,String,Int)) do s, t, i - a = Vector{Any}(undef, 2) - a[1] = s - some_resize!(a) - return a[2] - end - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - @test_broken !has_return_escape(result.state[SSAValue(i)], r) - @test !is_load_forwardable(result.state[SSAValue(i)]) - end - - # circular reference - @test_skip let result = code_escapes() do - xs = Vector{Any}(undef, 1) - xs[1] = xs - return xs[1] - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - end - @test_skip let result = @eval Module() begin - const Ax = Vector{Any}(undef, 1) - Ax[1] = Ax - $code_escapes() do - xs = Ax[1]::Vector{Any} - return xs[1] - end - end - r = only(findall(isreturn, result.ir.stmts.stmt)) - for i in findall(iscall((result.ir, Core.arrayref)), result.ir.stmts.stmt) - @test has_return_escape(result.state[SSAValue(i)], r) - end - end - let result = @eval Module() begin - @noinline function genxs() - xs = Vector{Any}(undef, 1) - xs[1] = xs - return xs - end - $code_escapes() do - xs = genxs() - return xs[1] - end - end - i = only(findall(isinvoke(:genxs), result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - end -end - -# demonstrate array primitive support with a realistic end to end example -@test_skip let result = code_escapes((Int,String,)) do n,s - xs = String[] - for i in 1:n - push!(xs, s) - end - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - @test !has_thrown_escape(result.state[SSAValue(i)]) - @test has_return_escape(result.state[Argument(3)], r) # s - @test !has_thrown_escape(result.state[Argument(3)]) # s -end -@test_skip let result = code_escapes((Int,String,)) do n,s - xs = String[] - for i in 1:n - pushfirst!(xs, s) - end - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) # xs - @test !has_thrown_escape(result.state[SSAValue(i)]) # xs - @test has_return_escape(result.state[Argument(3)], r) # s - @test !has_thrown_escape(result.state[Argument(3)]) # s -end -@test_skip let result = code_escapes((String,String,String)) do s, t, u - xs = String[] - resize!(xs, 3) - xs[1] = s - xs[1] = t - xs[1] = u - xs - end - i = only(findall(isarrayalloc, result.ir.stmts.stmt)) - r = only(findall(isreturn, result.ir.stmts.stmt)) - @test has_return_escape(result.state[SSAValue(i)], r) - @test has_thrown_escape(result.state[SSAValue(i)]) # xs - @test has_return_escape(result.state[Argument(2)], r) # s - @test has_return_escape(result.state[Argument(3)], r) # t - @test has_return_escape(result.state[Argument(4)], r) # u -end - # demonstrate a simple type level analysis can sometimes improve the analysis accuracy # by compensating the lack of yet unimplemented analyses @testset "special-casing bitstype" begin @@ -2111,25 +1517,6 @@ end end end -# # TODO implement a finalizer elision pass -# mutable struct WithFinalizer -# v -# function WithFinalizer(v) -# x = new(v) -# f(t) = @async println("Finalizing $t.") -# return finalizer(x, x) -# end -# end -# make_m(v = 10) = MyMutable(v) -# function simple(cond) -# m = make_m() -# if cond -# # println(m.v) -# return nothing # <= insert `finalize` call here -# end -# return m -# end - # interprocedural analysis # ======================== @@ -2140,7 +1527,17 @@ let result = code_escapes() do end i = last(findall(isnew, result.ir.stmts.stmt)) @test_broken !has_return_escape(result.state[SSAValue(i)]) # TODO interprocedural alias analysis - @test !has_thrown_escape(result.state[SSAValue(i)]) + @test_broken !has_thrown_escape(result.state[SSAValue(i)]) # IDEA embed const-prop'ed `CodeInstance` for `:invoke`? +end +let result = code_escapes((Base.RefValue{Base.RefValue{String}},)) do x + out1 = broadcast_noescape2(Ref(Ref("Hi"))) + out2 = broadcast_noescape2(x) + return out1, out2 + end + i = last(findall(isnew, result.ir.stmts.stmt)) + @test_broken !has_return_escape(result.state[SSAValue(i)]) # TODO interprocedural alias analysis + @test_broken !has_thrown_escape(result.state[SSAValue(i)]) # IDEA embed const-prop'ed `CodeInstance` for `:invoke`? + @test has_thrown_escape(result.state[Argument(2)]) end @noinline allescape_argument(a) = (global GV = a) # obvious escape let result = code_escapes() do diff --git a/Compiler/test/abioverride.jl b/Compiler/test/abioverride.jl new file mode 100644 index 0000000000000..da9b1f92786e5 --- /dev/null +++ b/Compiler/test/abioverride.jl @@ -0,0 +1,60 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Base.Meta +include("irutils.jl") + +# In this test, we will manually construct a CodeInstance that specializes the `myplus` +# method on a constant for the second argument and test various, interfaces surrounding +# CodeInstances with ABI overrides. +myplus(x::Int, y::Int) = x + y + +struct SecondArgConstOverride + arg2::Int +end + +function is_known_call(@nospecialize(x), @nospecialize(func), src::Core.CodeInfo) + isexpr(x, :call) || return false + ft = Compiler.argextype(x.args[1], src, Compiler.VarState[]) + return Compiler.singleton_type(ft) === func +end + + +# Construct a CodeInstance with an ABI override +let world = Base.tls_world_age() + # Get some inferred source code to give to the compiler + # Do not look at a CodeInstance here, since those fields are only valid to + # use while attached to a cache, and are thus invalid to make copies of + # (since you'd have to have made the copy to insert into the cache before + # making the original CodeInstance to copy from, which is obviously + # rather temporally-challenged) + new_source = only(code_typed(myplus, (Int, Int)))[1] + mi = new_source.parent + ## Sanity check + @assert length(new_source.code) == 2 + add = new_source.code[1] + @assert is_known_call(add, Core.Intrinsics.add_int, new_source) && add.args[3] == Core.Argument(3) + + ## Replace x + y by x + 1 + add.args[3] = 1 + + ## Remove the argument + resize!(new_source.slotnames, 2) + resize!(new_source.slotflags, 2) + + # Construct the CodeInstance from the modified CodeInfo data + global new_ci = Core.CodeInstance(Core.ABIOverride(Tuple{typeof(myplus), Int}, mi), + #=owner=#SecondArgConstOverride(1), new_source.rettype, Any#=new_source.exctype is missing=#, + #=inferred_const=#nothing, #=code=#nothing, #=const_flags=#Int32(0), + new_source.min_world, new_source.max_world, #=new_source.ipo_purity_bits is missing=#UInt32(0), + #=analysis_results=#nothing, new_source.debuginfo, new_source.edges) + + # Poke the CI into the global cache + # This isn't necessary, but does conveniently give it the mandatory permanent GC-root before calling `invoke` + ccall(:jl_mi_cache_insert, Cvoid, (Any, Any), mi, new_ci) + + # Poke the source code into the JIT for it + ccall(:jl_add_codeinst_to_jit, Cvoid, (Any, Any), new_ci, new_source) +end + +@test contains(repr(new_ci), "ABI Overridden") +@test invoke(myplus, new_ci, 10) == 11 diff --git a/Compiler/test/codegen.jl b/Compiler/test/codegen.jl index b6805a77124ca..ff61ac719c59e 100644 --- a/Compiler/test/codegen.jl +++ b/Compiler/test/codegen.jl @@ -1027,3 +1027,17 @@ for a in ((@noinline Ref{Int}(2)), @test ex === a end end + +# Make sure that code that has unbound sparams works +#https://github.com/JuliaLang/julia/issues/56739 + +@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) +@test g56739(1) == 1 + +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 diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index c8b599adb1323..d4ea990e7d148 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -2295,6 +2295,7 @@ let 𝕃ᵢ = InferenceLattice(MustAliasesLattice(BaseInferenceLattice.instance) @test tmerge(MustAlias(2, AliasableField{Any}, 1, Int), Const(nothing)) === Union{Int,Nothing} @test tmerge(Const(nothing), MustAlias(2, AliasableField{Any}, 1, Any)) === Any @test tmerge(Const(nothing), MustAlias(2, AliasableField{Any}, 1, Int)) === Union{Int,Nothing} + tmerge(Const(AbstractVector{<:Any}), Const(AbstractVector{T} where {T})) # issue #56913 @test isa_tfunc(MustAlias(2, AliasableField{Any}, 1, Bool), Const(Bool)) === Const(true) @test isa_tfunc(MustAlias(2, AliasableField{Any}, 1, Bool), Type{Bool}) === Const(true) @test isa_tfunc(MustAlias(2, AliasableField{Any}, 1, Int), Type{Bool}) === Const(false) @@ -2302,6 +2303,12 @@ let 𝕃ᵢ = InferenceLattice(MustAliasesLattice(BaseInferenceLattice.instance) @test ifelse_tfunc(MustAlias(2, AliasableField{Any}, 1, Int), Int, Int) === Union{} end +@testset "issue #56913: `BoundsError` in type inference" begin + R = UnitRange{Int} + @test Type{AbstractVector} == Base.infer_return_type(Base.promote_typeof, Tuple{R, R, Vector{Any}, Vararg{R}}) + @test Type{AbstractVector} == Base.infer_return_type(Base.promote_typeof, Tuple{R, R, Vector{Any}, R, Vararg{R}}) +end + maybeget_mustalias_tmerge(x::AliasableField) = x.f maybeget_mustalias_tmerge(x) = x @test Base.return_types((Union{Nothing,AliasableField{Any}},); interp=MustAliasInterpreter()) do x @@ -2727,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 @@ -4103,6 +4130,22 @@ end == [Union{Some{Float64}, Some{Int}, Some{UInt8}}] end return a end == Union{Int32,Int64} + + @test Base.infer_return_type((Vector{Any},)) do args + codeinst = first(args) + if codeinst isa Core.MethodInstance + mi = codeinst + else + codeinst::Core.CodeInstance + def = codeinst.def + if isa(def, Core.ABIOverride) + mi = def.def + else + mi = def::Core.MethodInstance + end + end + return mi + end == Core.MethodInstance end callsig_backprop_basic(::Int) = nothing @@ -4436,7 +4479,7 @@ let x = Tuple{Int,Any}[ #=20=# (0, Core.ReturnNode(Core.SlotNumber(3))) ] (;handler_at, handlers) = Compiler.compute_trycatch(last.(x)) - @test map(x->x[1] == 0 ? 0 : handlers[x[1]].enter_idx, handler_at) == first.(x) + @test map(x->x[1] == 0 ? 0 : Compiler.get_enter_idx(handlers[x[1]]), handler_at) == first.(x) end @test only(Base.return_types((Bool,)) do y @@ -6125,3 +6168,23 @@ function func_swapglobal!_must_throw(x) end @test Base.infer_return_type(func_swapglobal!_must_throw, (Int,); interp=SwapGlobalInterp()) === Union{} @test !Compiler.is_effect_free(Base.infer_effects(func_swapglobal!_must_throw, (Int,); interp=SwapGlobalInterp()) ) + +@eval get_exception() = $(Expr(:the_exception)) +@test Base.infer_return_type() do + get_exception() +end <: Any +@test @eval Base.infer_return_type((Float64,)) do x + out = $(Expr(:the_exception)) + try + out = sin(x) + catch + out = $(Expr(:the_exception)) + 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 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/Compiler/test/irpasses.jl b/Compiler/test/irpasses.jl index e9d6f57337530..27b6d75f86c93 100644 --- a/Compiler/test/irpasses.jl +++ b/Compiler/test/irpasses.jl @@ -1083,12 +1083,13 @@ end # test `flags_for_effects` and DCE # ================================ -let # effect-freeness computation for array allocation +@testset "effect-freeness computation for array allocation" begin # should eliminate dead allocations good_dims = [1, 2, 3, 4, 10] Ns = [1, 2, 3, 4, 10] - for dim = good_dims, N = Ns + Ts = Any[Int, Union{Missing,Nothing}, Nothing, Any] + @testset "$dim, $N" for dim in good_dims, N in Ns Int64(dim)^N > typemax(Int) && continue dims = ntuple(i->dim, N) @test @eval fully_eliminated() do @@ -1099,7 +1100,7 @@ let # effect-freeness computation for array allocation # shouldn't eliminate erroneous dead allocations bad_dims = [-1, typemax(Int)] - for dim in bad_dims, N in [1, 2, 3, 4, 10], T in Any[Int, Union{Missing,Nothing}, Nothing, Any] + @testset "$dim, $N, $T" for dim in bad_dims, N in Ns, T in Ts dims = ntuple(i->dim, N) @test @eval !fully_eliminated() do Array{$T,$N}(undef, $(dims...)) @@ -1715,6 +1716,12 @@ end @test scope_folding_opt() == 1 @test_broken fully_eliminated(scope_folding) @test_broken fully_eliminated(scope_folding_opt) +let ir = first(only(Base.code_ircode(scope_folding, ()))) + @test Compiler.compute_trycatch(ir) isa Compiler.HandlerInfo +end +let ir = first(only(Base.code_ircode(scope_folding_opt, ()))) + @test Compiler.compute_trycatch(ir) isa Compiler.HandlerInfo +end # Function that happened to have lots of sroa that # happened to trigger a bad case in the renamer. We diff --git a/Compiler/test/testgroups b/Compiler/test/testgroups index 5075caa8b34cf..d17735a52a025 100644 --- a/Compiler/test/testgroups +++ b/Compiler/test/testgroups @@ -15,3 +15,4 @@ ssair tarjan validation special_loading +abioverride diff --git a/Make.inc b/Make.inc index 29512bbbe7f45..16e238c6f0683 100644 --- a/Make.inc +++ b/Make.inc @@ -51,7 +51,7 @@ USE_SYSTEM_MPFR:=0 USE_SYSTEM_LIBSUITESPARSE:=0 USE_SYSTEM_LIBUV:=0 USE_SYSTEM_UTF8PROC:=0 -USE_SYSTEM_MBEDTLS:=0 +USE_SYSTEM_OPENSSL:=0 USE_SYSTEM_LIBSSH2:=0 USE_SYSTEM_NGHTTP2:=0 USE_SYSTEM_CURL:=0 @@ -80,6 +80,9 @@ HAVE_SSP := 0 WITH_GC_VERIFY := 0 WITH_GC_DEBUG_ENV := 0 +# Use stock if MMTK_PLAN hasn't been defined +MMTK_PLAN ?= None + # Enable DTrace support WITH_DTRACE := 0 @@ -486,11 +489,15 @@ endif # Set to 1 to enable profiling with perf ifeq ("$(OS)", "Linux") USE_PERF_JITEVENTS ?= 1 +ifeq ($(ARCH),x86_64) USE_INTEL_JITEVENTS ?= 1 -else +else # ARCH x86_64 +USE_INTEL_JITEVENTS ?= 0 +endif # ARCH x86_64 +else # OS Linux USE_PERF_JITEVENTS ?= 0 USE_INTEL_JITEVENTS ?= 0 -endif +endif # OS Linux JULIACODEGEN := LLVM @@ -829,6 +836,31 @@ JCXXFLAGS += -DGC_DEBUG_ENV JCFLAGS += -DGC_DEBUG_ENV endif +ifneq (${MMTK_PLAN},None) +JCXXFLAGS += -DMMTK_GC +JCFLAGS += -DMMTK_GC +# Do a release build on the binding by default +MMTK_BUILD ?= release +ifeq (${MMTK_PLAN},Immix) +JCXXFLAGS += -DMMTK_PLAN_IMMIX +JCFLAGS += -DMMTK_PLAN_IMMIX +else +$(error "Unsupported MMTk plan: $(MMTK_PLAN)") +endif + +# Location of mmtk-julia binding +# (needed for api/*.h and .so file) +MMTK_JULIA_DIR ?= $(BUILDROOT)/usr/lib/mmtk_julia + +MMTK_DIR = ${MMTK_JULIA_DIR}/mmtk +MMTK_API_INC = ${MMTK_DIR}/api + +MMTK_LIB := -lmmtk_julia +else +MMTK_JULIA_INC := +MMTK_LIB := +endif + ifeq ($(WITH_DTRACE), 1) JCXXFLAGS += -DUSE_DTRACE JCFLAGS += -DUSE_DTRACE @@ -929,6 +961,21 @@ ARCH := $(BUILD_OS) endif endif +# MMTk is only available on x86_64 Linux for now +ifneq (${MMTK_PLAN},None) + +ifeq ($(OS),Linux) +MMTK_LIB_NAME := libmmtk_julia.so +else +$(error "Unsupported OS for MMTk") +endif + +ifneq ($(ARCH),x86_64) +$(error "Unsupported build architecture for MMTk") +endif + +endif + # Detect common pre-SSE2 JULIA_CPU_TARGET values known not to work (#7185) ifeq ($(MARCH),) ifneq ($(findstring $(ARCH),i386 i486 i586 i686),) @@ -1348,14 +1395,14 @@ 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. # 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 MBEDTLS 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) @@ -1470,7 +1517,7 @@ ifeq (,$(findstring aarch64,$(ARCH))) OSLIBS += -lgcc_s endif -OSLIBS += -Wl,--export-dynamic -Wl,--undefined-version -Wl,--version-script=$(BUILDROOT)/src/julia.expmap \ +OSLIBS += -Wl,--export-dynamic -Wl,--version-script=$(BUILDROOT)/src/julia.expmap \ $(NO_WHOLE_ARCHIVE) endif diff --git a/Makefile b/Makefile index f0b1dfaa708e4..b193b3849c6aa 100644 --- a/Makefile +++ b/Makefile @@ -228,7 +228,7 @@ JL_PRIVATE_LIBS-$(USE_SYSTEM_GMP) += libgmp libgmpxx JL_PRIVATE_LIBS-$(USE_SYSTEM_MPFR) += libmpfr JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBSSH2) += libssh2 JL_PRIVATE_LIBS-$(USE_SYSTEM_NGHTTP2) += libnghttp2 -JL_PRIVATE_LIBS-$(USE_SYSTEM_MBEDTLS) += libmbedtls libmbedcrypto libmbedx509 +JL_PRIVATE_LIBS-$(USE_SYSTEM_OPENSSL) += libcrypto libssl JL_PRIVATE_LIBS-$(USE_SYSTEM_CURL) += libcurl JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBGIT2) += libgit2 JL_PRIVATE_LIBS-$(USE_SYSTEM_LIBUV) += libuv @@ -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/NEWS.md b/NEWS.md index 641b84b480bb4..71014e1e57695 100644 --- a/NEWS.md +++ b/NEWS.md @@ -22,6 +22,7 @@ New language features The available metrics are: - actual running time for the task (`Base.Experimental.task_running_time_ns`), and - wall-time for the task (`Base.Experimental.task_wall_time_ns`). +- Support for Unicode 16 ([#56925]). Language changes ---------------- @@ -36,7 +37,7 @@ Language changes may pave the way for inference to be able to intelligently re-use the old results, once the new method is deleted. ([#53415]) - - Macro expansion will no longer eagerly recurse into into `Expr(:toplevel)` + - Macro expansion will no longer eagerly recurse into `Expr(:toplevel)` expressions returned from macros. Instead, macro expansion of `:toplevel` expressions will be delayed until evaluation time. This allows a later expression within a given `:toplevel` expression to make use of macros @@ -46,6 +47,9 @@ Language changes behavior. Infinite loops that actually do things (e.g. have side effects or sleep) were never and are still not undefined behavior. ([#52999]) + - It is now an error to mark a symbol as both `public` and `export`ed. + ([#53664]) + Compiler/Runtime improvements ----------------------------- @@ -93,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 -------------------- @@ -108,8 +113,12 @@ New library features * New `ltruncate`, `rtruncate` and `ctruncate` functions for truncating strings to text width, accounting for char widths ([#55351]) * `isless` (and thus `cmp`, sorting, etc.) is now supported for zero-dimensional `AbstractArray`s ([#55772]) * `invoke` now supports passing a Method instead of a type signature making this interface somewhat more flexible for certain uncommon use cases ([#56692]). +* `Timer(f, ...)` will now match the stickiness of the parent task when creating timer tasks, which can be overridden + by the new `spawn` kwarg. This avoids the issue where sticky tasks i.e. `@async` make their parent sticky ([#56745]) * `invoke` now supports passing a CodeInstance instead of a type, which can enable certain compiler plugin workflows ([#56660]). +* `sort` now supports `NTuple`s ([#54494]) +* `map!(f, A)` now stores the results in `A`, like `map!(f, A, A)`. or `A .= f.(A)` ([#40632]). Standard library changes ------------------------ @@ -171,6 +180,7 @@ Standard library changes in the REPL will now issue a warning the first time occurs. ([#54872]) - When an object is printed automatically (by being returned in the REPL), its display is now truncated after printing 20 KiB. This does not affect manual calls to `show`, `print`, and so forth. ([#53959]) +- Backslash completions now print the respective glyph or emoji next to each matching backslash shortcode. ([#54800]) #### SuiteSparse @@ -178,6 +188,15 @@ Standard library changes #### Test +* A failing `DefaultTestSet` now prints to screen the random number generator (RNG) of the failed test, to help reproducing a stochastic failure which only depends on the state of the RNG. + It is also possible seed a test set by passing the `rng` keyword argument to `@testset`: + ```julia + using Test, Random + @testset rng=Xoshiro(0x2e026445595ed28e, 0x07bb81ac4c54926d, 0x83d7d70843e8bad6, 0xdbef927d150af80b, 0xdbf91ddf2534f850) begin + @test rand() == 0.559472630416976 + end + ``` + #### Dates #### Statistics 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. diff --git a/THIRDPARTY.md b/THIRDPARTY.md index 3a74afec4a283..f3f59ca4ff3f7 100644 --- a/THIRDPARTY.md +++ b/THIRDPARTY.md @@ -36,7 +36,7 @@ Julia's `stdlib` uses the following external libraries, which have their own lic - [LIBGIT2](https://github.com/libgit2/libgit2/blob/development/COPYING) [GPL2+ with unlimited linking exception] - [CURL](https://curl.haxx.se/docs/copyright.html) [MIT/X derivative] - [LIBSSH2](https://github.com/libssh2/libssh2/blob/master/COPYING) [BSD-3] -- [MBEDTLS](https://github.com/ARMmbed/mbedtls/blob/development/LICENSE) [Apache 2.0] +- [OPENSSL](https://www.openssl.org/source/license.html) [Apache 2.0] - [MPFR](https://www.mpfr.org/mpfr-current/mpfr.html#Copying) [LGPL3+] - [OPENBLAS](https://raw.github.com/xianyi/OpenBLAS/master/LICENSE) [BSD-3] - [LAPACK](https://netlib.org/lapack/LICENSE.txt) [BSD-3] diff --git a/base/Base.jl b/base/Base.jl index 1f737452fa17a..04f732a4309c9 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") @@ -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 @@ -400,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/Base_compiler.jl b/base/Base_compiler.jl index 6014a6b7c9dd0..db3ebb0232e38 100644 --- a/base/Base_compiler.jl +++ b/base/Base_compiler.jl @@ -249,10 +249,13 @@ using .Iterators: Flatten, Filter, product # for generators using .Iterators: Stateful # compat (was formerly used in reinterpretarray.jl) include("namedtuple.jl") +include("anyall.jl") + include("ordering.jl") using .Order include("coreir.jl") +include("invalidation.jl") # For OS specific stuff # We need to strcat things here, before strings are really defined @@ -274,7 +277,6 @@ baremodule BuildSettings end function process_sysimg_args!() let i = 2 # skip file name while i <= length(Core.ARGS) - Core.println(Core.ARGS[i]) if Core.ARGS[i] == "--buildsettings" include(BuildSettings, ARGS[i+1]) elseif Core.ARGS[i] == "--buildroot" diff --git a/base/Makefile b/base/Makefile index febee53a9ddfc..09f79e5b98611 100644 --- a/base/Makefile +++ b/base/Makefile @@ -264,9 +264,8 @@ $(eval $(call symlink_system_library,LAPACK,$(LIBLAPACKNAME))) endif $(eval $(call symlink_system_library,GMP,libgmp)) $(eval $(call symlink_system_library,MPFR,libmpfr)) -$(eval $(call symlink_system_library,MBEDTLS,libmbedtls)) -$(eval $(call symlink_system_library,MBEDTLS,libmbedcrypto)) -$(eval $(call symlink_system_library,MBEDTLS,libmbedx509)) +$(eval $(call symlink_system_library,OPENSSL,libcrypto)) +$(eval $(call symlink_system_library,OPENSSL,libssl)) $(eval $(call symlink_system_library,LIBSSH2,libssh2)) $(eval $(call symlink_system_library,NGHTTP2,libnghttp2)) $(eval $(call symlink_system_library,CURL,libcurl)) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 6102a0a8a00fa..1ab78a55c93b5 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -828,7 +828,6 @@ similar(a::AbstractArray, ::Type{T}, dims::DimOrInd...) where {T} = similar(a, # define this method to convert supported axes to Ints, with the expectation that an offset array # package will define a method with dims::Tuple{Union{Integer, UnitRange}, Vararg{Union{Integer, UnitRange}}} similar(a::AbstractArray, ::Type{T}, dims::Tuple{Union{Integer, OneTo}, Vararg{Union{Integer, OneTo}}}) where {T} = similar(a, T, to_shape(dims)) -similar(a::AbstractArray, ::Type{T}, dims::Tuple{Integer, Vararg{Integer}}) where {T} = similar(a, T, to_shape(dims)) # similar creates an Array by default similar(a::AbstractArray, ::Type{T}, dims::Dims{N}) where {T,N} = Array{T,N}(undef, dims) @@ -2190,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}() @@ -2289,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 ## @@ -2646,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) @@ -2740,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 @@ -3504,11 +3454,32 @@ julia> map!(+, zeros(Int, 5), 100:999, 1:3) ``` """ function map!(f::F, dest::AbstractArray, As::AbstractArray...) where {F} - isempty(As) && throw(ArgumentError( - """map! requires at least one "source" argument""")) + @assert !isempty(As) # should dispatch to map!(f, A) map_n!(f, dest, As) end +""" + map!(function, array) + +Like [`map`](@ref), but stores the result in the same array. +!!! compat "Julia 1.12" + This method requires Julia 1.12 or later. To support previous versions too, + use the equivalent `map!(function, array, array)`. + +# Examples +```jldoctest +julia> a = [1 2 3; 4 5 6]; + +julia> map!(x -> x^3, a); + +julia> a +2×3 Matrix{$Int}: + 1 8 27 + 64 125 216 +``` +""" +map!(f::F, inout::AbstractArray) where F = map!(f, inout, inout) + """ map(f, A::AbstractArray...) -> N-array diff --git a/base/abstractdict.jl b/base/abstractdict.jl index 85a726b4cdbf4..3be930151d4d4 100644 --- a/base/abstractdict.jl +++ b/base/abstractdict.jl @@ -88,8 +88,8 @@ Return an iterator over all keys in a dictionary. When the keys are stored internally in a hash table, as is the case for `Dict`, the order in which they are returned may vary. -But `keys(a)` and `values(a)` both iterate `a` and -return the elements in the same order. +But `keys(a)`, `values(a)` and `pairs(a)` all iterate `a` +and return the elements in the same order. # Examples ```jldoctest @@ -114,8 +114,8 @@ Return an iterator over all values in a collection. When the values are stored internally in a hash table, as is the case for `Dict`, the order in which they are returned may vary. -But `keys(a)` and `values(a)` both iterate `a` and -return the elements in the same order. +But `keys(a)`, `values(a)` and `pairs(a)` all iterate `a` +and return the elements in the same order. # Examples ```jldoctest @@ -138,6 +138,10 @@ values(a::AbstractDict) = ValueIterator(a) Return an iterator over `key => value` pairs for any collection that maps a set of keys to a set of values. This includes arrays, where the keys are the array indices. +When the entries are stored internally in a hash table, +as is the case for `Dict`, the order in which they are returned may vary. +But `keys(a)`, `values(a)` and `pairs(a)` all iterate `a` +and return the elements in the same order. # Examples ```jldoctest diff --git a/base/anyall.jl b/base/anyall.jl new file mode 100644 index 0000000000000..e51515bb3187d --- /dev/null +++ b/base/anyall.jl @@ -0,0 +1,231 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +## all & any + +""" + any(itr) -> Bool + +Test whether any elements of a boolean collection are `true`, returning `true` as +soon as the first `true` value in `itr` is encountered (short-circuiting). To +short-circuit on `false`, use [`all`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `false` (or equivalently, if the input contains no `true` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +See also: [`all`](@ref), [`count`](@ref), [`sum`](@ref), [`|`](@ref), [`||`](@ref). + +# Examples +```jldoctest +julia> a = [true,false,false,true] +4-element Vector{Bool}: + 1 + 0 + 0 + 1 + +julia> any(a) +true + +julia> any((println(i); v) for (i, v) in enumerate(a)) +1 +true + +julia> any([missing, true]) +true + +julia> any([false, missing]) +missing +``` +""" +any(itr) = any(identity, itr) + +""" + all(itr) -> Bool + +Test whether all elements of a boolean collection are `true`, returning `false` as +soon as the first `false` value in `itr` is encountered (short-circuiting). To +short-circuit on `true`, use [`any`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `true` (or equivalently, if the input contains no `false` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +See also: [`all!`](@ref), [`any`](@ref), [`count`](@ref), [`&`](@ref), [`&&`](@ref), [`allunique`](@ref). + +# Examples +```jldoctest +julia> a = [true,false,false,true] +4-element Vector{Bool}: + 1 + 0 + 0 + 1 + +julia> all(a) +false + +julia> all((println(i); v) for (i, v) in enumerate(a)) +1 +2 +false + +julia> all([missing, false]) +false + +julia> all([true, missing]) +missing +``` +""" +all(itr) = all(identity, itr) + +""" + any(p, itr) -> Bool + +Determine whether predicate `p` returns `true` for any elements of `itr`, returning +`true` as soon as the first item in `itr` for which `p` returns `true` is encountered +(short-circuiting). To short-circuit on `false`, use [`all`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `false` (or equivalently, if the input contains no `true` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +# Examples +```jldoctest +julia> any(i->(4<=i<=6), [3,5,7]) +true + +julia> any(i -> (println(i); i > 3), 1:10) +1 +2 +3 +4 +true + +julia> any(i -> i > 0, [1, missing]) +true + +julia> any(i -> i > 0, [-1, missing]) +missing + +julia> any(i -> i > 0, [-1, 0]) +false +``` +""" +any(f, itr) = _any(f, itr, :) + +for ItrT = (Tuple,Any) + # define a generic method and a specialized version for `Tuple`, + # whose method bodies are identical, while giving better effects to the later + @eval function _any(f, itr::$ItrT, ::Colon) + $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) + anymissing = false + for x in itr + v = f(x) + if ismissing(v) + anymissing = true + else + v && return true + end + end + return anymissing ? missing : false + end +end + +# Specialized versions of any(f, ::Tuple) +# We fall back to the for loop implementation all elements have the same type or +# if the tuple is too large. +function any(f, itr::Tuple) + if itr isa NTuple || length(itr) > 32 + return _any(f, itr, :) + end + _any_tuple(f, false, itr...) +end + +@inline function _any_tuple(f, anymissing, x, rest...) + v = f(x) + if ismissing(v) + anymissing = true + elseif v + return true + end + return _any_tuple(f, anymissing, rest...) +end +@inline _any_tuple(f, anymissing) = anymissing ? missing : false + +""" + all(p, itr) -> Bool + +Determine whether predicate `p` returns `true` for all elements of `itr`, returning +`false` as soon as the first item in `itr` for which `p` returns `false` is encountered +(short-circuiting). To short-circuit on `true`, use [`any`](@ref). + +If the input contains [`missing`](@ref) values, return `missing` if all non-missing +values are `true` (or equivalently, if the input contains no `false` value), following +[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). + +# Examples +```jldoctest +julia> all(i->(4<=i<=6), [4,5,6]) +true + +julia> all(i -> (println(i); i < 3), 1:10) +1 +2 +3 +false + +julia> all(i -> i > 0, [1, missing]) +missing + +julia> all(i -> i > 0, [-1, missing]) +false + +julia> all(i -> i > 0, [1, 2]) +true +``` +""" +all(f, itr) = _all(f, itr, :) + +for ItrT = (Tuple,Any) + # define a generic method and a specialized version for `Tuple`, + # whose method bodies are identical, while giving better effects to the later + @eval function _all(f, itr::$ItrT, ::Colon) + $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) + anymissing = false + for x in itr + v = f(x) + if ismissing(v) + anymissing = true + else + v || return false + end + end + return anymissing ? missing : true + end +end + +# Specialized versions of all(f, ::Tuple), +# This is similar to any(f, ::Tuple) defined above. +function all(f, itr::Tuple) + if itr isa NTuple || length(itr) > 32 + return _all(f, itr, :) + end + _all_tuple(f, false, itr...) +end + +@inline function _all_tuple(f, anymissing, x, rest...) + v = f(x) + if ismissing(v) + anymissing = true + # this syntax allows throwing a TypeError for non-Bool, for consistency with any + elseif v + nothing + else + return false + end + return _all_tuple(f, anymissing, rest...) +end +@inline _all_tuple(f, anymissing) = anymissing ? missing : true + +all(::Tuple{Missing}) = missing diff --git a/base/array.jl b/base/array.jl index 4c3dde73d52ba..aafcfc182124b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -346,12 +346,13 @@ See also [`copy!`](@ref Base.copy!), [`copyto!`](@ref), [`deepcopy`](@ref). """ copy -@eval function copy(a::Array{T}) where {T} - # `jl_genericmemory_copy_slice` only throws when the size exceeds the max allocation - # size, but since we're copying an existing array, we're guaranteed that this will not happen. +@eval function copy(a::Array) + # `copy` only throws when the size exceeds the max allocation size, + # but since we're copying an existing array, we're guaranteed that this will not happen. @_nothrow_meta ref = a.ref - newmem = ccall(:jl_genericmemory_copy_slice, Ref{Memory{T}}, (Any, Ptr{Cvoid}, Int), ref.mem, ref.ptr_or_offset, length(a)) + newmem = typeof(ref.mem)(undef, length(a)) + @inbounds unsafe_copyto!(memoryref(newmem), ref, length(a)) return $(Expr(:new, :(typeof(a)), :(memoryref(newmem)), :(a.size))) end diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 3bc69e563a967..623111ef0883d 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -41,7 +41,7 @@ Accept keyword args `c` for alternate single character marker. """ function replace_with_centered_mark(s::AbstractString;c::AbstractChar = '⋅') N = textwidth(ANSIIterator(s)) - return join(setindex!([" " for i=1:N],string(c),ceil(Int,N/2))) + return N == 0 ? string(c) : join(setindex!([" " for i=1:N],string(c),ceil(Int,N/2))) end const undef_ref_alignment = (3,3) diff --git a/base/asyncevent.jl b/base/asyncevent.jl index c6cb3d3fa73bb..8c708455976e2 100644 --- a/base/asyncevent.jl +++ b/base/asyncevent.jl @@ -275,7 +275,7 @@ end # timer with repeated callback """ - Timer(callback::Function, delay; interval = 0) + Timer(callback::Function, delay; interval = 0, spawn::Union{Nothing,Bool}=nothing) Create a timer that runs the function `callback` at each timer expiration. @@ -285,6 +285,13 @@ callback is only run once. The function `callback` is called with a single argum itself. Stop a timer by calling `close`. The `callback` may still be run one final time, if the timer has already expired. +If `spawn` is `true`, the created task will be spawned, meaning that it will be allowed +to move thread, which avoids the side-effect of forcing the parent task to get stuck to the thread +it is on. If `spawn` is `nothing` (default), the task will be spawned if the parent task isn't sticky. + +!!! compat "Julia 1.12" + The `spawn` argument was introduced in Julia 1.12. + # Examples Here the first number is printed after a delay of two seconds, then the following numbers are @@ -304,7 +311,8 @@ julia> begin 3 ``` """ -function Timer(cb::Function, timeout; kwargs...) +function Timer(cb::Function, timeout; spawn::Union{Nothing,Bool}=nothing, kwargs...) + sticky = spawn === nothing ? current_task().sticky : !spawn timer = Timer(timeout; kwargs...) t = @task begin unpreserve_handle(timer) @@ -319,6 +327,7 @@ function Timer(cb::Function, timeout; kwargs...) isopen(timer) || return end end + t.sticky = sticky # here we are mimicking parts of _trywait, in coordination with task `t` preserve_handle(timer) @lock timer.cond begin diff --git a/base/asyncmap.jl b/base/asyncmap.jl index 02e515d2e0c6c..1914ddc645f31 100644 --- a/base/asyncmap.jl +++ b/base/asyncmap.jl @@ -28,11 +28,11 @@ The following examples highlight execution in different tasks by returning the `objectid` of the tasks in which the mapping function is executed. First, with `ntasks` undefined, each element is processed in a different task. -``` +```julia-repl julia> tskoid() = objectid(current_task()); julia> asyncmap(x->tskoid(), 1:5) -5-element Array{UInt64,1}: +5-element Vector{UInt64}: 0x6e15e66c75c75853 0x440f8819a1baa682 0x9fb3eeadd0c83985 @@ -44,9 +44,9 @@ julia> length(unique(asyncmap(x->tskoid(), 1:5))) ``` With `ntasks=2` all elements are processed in 2 tasks. -``` +```julia-repl julia> asyncmap(x->tskoid(), 1:5; ntasks=2) -5-element Array{UInt64,1}: +5-element Vector{UInt64}: 0x027ab1680df7ae94 0xa23d2f80cd7cf157 0x027ab1680df7ae94 @@ -60,12 +60,12 @@ julia> length(unique(asyncmap(x->tskoid(), 1:5; ntasks=2))) With `batch_size` defined, the mapping function needs to be changed to accept an array of argument tuples and return an array of results. `map` is used in the modified mapping function to achieve this. -``` +```julia-repl julia> batch_func(input) = map(x->string("args_tuple: ", x, ", element_val: ", x[1], ", task: ", tskoid()), input) batch_func (generic function with 1 method) julia> asyncmap(batch_func, 1:5; ntasks=2, batch_size=2) -5-element Array{String,1}: +5-element Vector{String}: "args_tuple: (1,), element_val: 1, task: 9118321258196414413" "args_tuple: (2,), element_val: 2, task: 4904288162898683522" "args_tuple: (3,), element_val: 3, task: 9118321258196414413" diff --git a/base/binaryplatforms.jl b/base/binaryplatforms.jl index a372137edeb98..598b618f0d1ed 100644 --- a/base/binaryplatforms.jl +++ b/base/binaryplatforms.jl @@ -631,9 +631,6 @@ const arch_march_isa_mapping = let "a64fx" => get_set("aarch64", "a64fx"), "apple_m1" => get_set("aarch64", "apple_m1"), ], - "riscv64" => [ - "riscv64" => get_set("riscv64", "riscv64") - ], "powerpc64le" => [ "power8" => get_set("powerpc64le", "power8"), ], diff --git a/base/boot.jl b/base/boot.jl index 4badedae3cfb7..53e439d83ebe2 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -231,7 +231,7 @@ export fieldtype, getfield, setfield!, swapfield!, modifyfield!, replacefield!, setfieldonce!, nfields, throw, tuple, ===, isdefined, eval, # access to globals - getglobal, setglobal!, swapglobal!, modifyglobal!, replaceglobal!, setglobalonce!, + getglobal, setglobal!, swapglobal!, modifyglobal!, replaceglobal!, setglobalonce!, isdefinedglobal, # ifelse, sizeof # not exported, to avoid conflicting with Base # type reflection <:, typeof, isa, typeassert, @@ -465,6 +465,12 @@ struct InitError <: WrappedException error end +struct ABIOverride + abi::Type + def::MethodInstance + ABIOverride(@nospecialize(abi::Type), def::MethodInstance) = new(abi, def) +end + struct PrecompilableError <: Exception end String(s::String) = s # no constructor yet @@ -552,14 +558,14 @@ end function CodeInstance( - mi::MethodInstance, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const), + mi::Union{MethodInstance, ABIOverride}, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const), @nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt, effects::UInt32, @nospecialize(analysis_results), - relocatability::UInt8, di::Union{DebugInfo,Nothing}, edges::SimpleVector) + di::Union{DebugInfo,Nothing}, edges::SimpleVector) return ccall(:jl_new_codeinst, Ref{CodeInstance}, - (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any, Any), + (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, Any, Any), mi, owner, rettype, exctype, inferred_const, inferred, const_flags, min_world, max_world, - effects, analysis_results, relocatability, di, edges) + effects, analysis_results, di, edges) end GlobalRef(m::Module, s::Symbol) = ccall(:jl_module_globalref, Ref{GlobalRef}, (Any, Any), m, s) Module(name::Symbol=:anonymous, std_imports::Bool=true, default_names::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, default_names) @@ -575,12 +581,7 @@ struct UndefInitializer end const undef = UndefInitializer() # type and dimensionality specified -(self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, m::Int) where {T,addrspace,kind} = - if isdefined(self, :instance) && m === 0 - self.instance - else - ccall(:jl_alloc_genericmemory, Ref{GenericMemory{kind,T,addrspace}}, (Any, Int), self, m) - end +(self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, m::Int) where {T,addrspace,kind} = memorynew(self, m) (self::Type{GenericMemory{kind,T,addrspace}})(::UndefInitializer, d::NTuple{1,Int}) where {T,kind,addrspace} = self(undef, getfield(d,1)) # empty vector constructor (self::Type{GenericMemory{kind,T,addrspace}})() where {T,kind,addrspace} = self(undef, 0) diff --git a/base/broadcast.jl b/base/broadcast.jl index 927c946e53e02..512b397352040 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -250,9 +250,11 @@ BroadcastStyle(::Type{<:Broadcasted{S}}) where {S<:Union{Nothing,Unknown}} = argtype(::Type{BC}) where {BC<:Broadcasted} = fieldtype(BC, :args) argtype(bc::Broadcasted) = argtype(typeof(bc)) -@inline Base.eachindex(bc::Broadcasted) = _eachindex(axes(bc)) -_eachindex(t::Tuple{Any}) = t[1] -_eachindex(t::Tuple) = CartesianIndices(t) +@inline Base.eachindex(bc::Broadcasted) = eachindex(IndexStyle(bc), bc) +@inline Base.eachindex(s::IndexStyle, bc::Broadcasted) = _eachindex(s, axes(bc)) +_eachindex(::IndexCartesian, t::Tuple) = CartesianIndices(t) +_eachindex(s::IndexLinear, t::Tuple) = eachindex(s, LinearIndices(t)) +_eachindex(::IndexLinear, t::Tuple{Any}) = t[1] Base.IndexStyle(bc::Broadcasted) = IndexStyle(typeof(bc)) Base.IndexStyle(::Type{<:Broadcasted{<:Any,<:Tuple{Any}}}) = IndexLinear() @@ -278,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} @@ -604,18 +611,32 @@ Base.@propagate_inbounds _newindex(ax::Tuple{}, I::Tuple{}) = () (Base.length(ind1)::Integer != 1, keep...), (first(ind1), Idefault...) end -@inline function Base.getindex(bc::Broadcasted, Is::Vararg{Union{Integer,CartesianIndex},N}) where {N} +Base.@propagate_inbounds function Base.getindex(bc::Broadcasted, Is::Vararg{Union{Integer,CartesianIndex},N}) where {N} I = to_index(Base.IteratorsMD.flatten(Is)) + _getindex(IndexStyle(bc), bc, I) +end +@inline function _getindex(::IndexStyle, bc, I) @boundscheck checkbounds(bc, I) @inbounds _broadcast_getindex(bc, I) end +Base.@propagate_inbounds function _getindex(s::IndexCartesian, bc, I::Integer) + C = CartesianIndices(axes(bc)) + _getindex(s, bc, C[I]) +end +Base.@propagate_inbounds function _getindex(s::IndexLinear, bc, I::CartesianIndex) + L = LinearIndices(axes(bc)) + _getindex(s, bc, L[I]) +end to_index(::Tuple{}) = CartesianIndex() to_index(Is::Tuple{Any}) = Is[1] to_index(Is::Tuple) = CartesianIndex(Is) -@inline Base.checkbounds(bc::Broadcasted, I::Union{Integer,CartesianIndex}) = +@inline Base.checkbounds(bc::Broadcasted, I::CartesianIndex) = Base.checkbounds_indices(Bool, axes(bc), (I,)) || Base.throw_boundserror(bc, (I,)) +@inline Base.checkbounds(bc::Broadcasted, I::Integer) = + Base.checkindex(Bool, eachindex(IndexLinear(), bc), I) || Base.throw_boundserror(bc, (I,)) + """ _broadcast_getindex(A, I) 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/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/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/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/base/deepcopy.jl b/base/deepcopy.jl index c4f9ae1a6cb10..f60ce2043dd5a 100644 --- a/base/deepcopy.jl +++ b/base/deepcopy.jl @@ -120,11 +120,14 @@ function _deepcopy_memory_t(@nospecialize(x::Memory), T, stackdict::IdDict) end return dest end -@eval function deepcopy_internal(x::Array{T, N}, stackdict::IdDict) where {T, N} +function deepcopy_internal(x::Array{T, N}, stackdict::IdDict) where {T, N} if haskey(stackdict, x) return stackdict[x]::typeof(x) end - stackdict[x] = $(Expr(:new, :(Array{T, N}), :(deepcopy_internal(x.ref, stackdict)), :(x.size))) + y = stackdict[x] = Array{T, N}(undef, ntuple(Returns(0), Val{N}())) + setfield!(y, :ref, deepcopy_internal(x.ref, stackdict)) + setfield!(y, :size, x.size) + y end function deepcopy_internal(x::GenericMemoryRef, stackdict::IdDict) if haskey(stackdict, x) diff --git a/base/deprecated.jl b/base/deprecated.jl index 84ef89e44b473..cffff05d954d1 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -4,7 +4,7 @@ # Instructions for Julia Core Developers: # 1. When making a breaking change that is known to be depnedet upon by an # important and closely coupled package, decide on a unique `change_name` -# for your PR and add it to the list below. In general, is is better to +# for your PR and add it to the list below. In general, it is better to # err on the side of caution and assign a `change_name` even if it is not # clear that it is required. `change_name`s may also be assigned after the # fact in a separate PR. (Note that this may cause packages to misbehave diff --git a/base/docs/basedocs.jl b/base/docs/basedocs.jl index c62c980fae1e1..88ed34de02b64 100644 --- a/base/docs/basedocs.jl +++ b/base/docs/basedocs.jl @@ -406,11 +406,11 @@ Assigning `a` to `b` does not create a copy of `b`; instead use [`copy`](@ref) o ```jldoctest julia> b = [1]; a = b; b[1] = 2; a -1-element Array{Int64, 1}: +1-element Vector{Int64}: 2 julia> b = [1]; a = copy(b); b[1] = 2; a -1-element Array{Int64, 1}: +1-element Vector{Int64}: 1 ``` @@ -420,7 +420,7 @@ julia> function f!(x); x[:] .+= 1; end f! (generic function with 1 method) julia> a = [1]; f!(a); a -1-element Array{Int64, 1}: +1-element Vector{Int64}: 2 ``` @@ -439,7 +439,7 @@ julia> a, b Assignment can operate on multiple variables in series, and will return the value of the right-hand-most expression: ```jldoctest julia> a = [1]; b = [2]; c = [3]; a = b = c -1-element Array{Int64, 1}: +1-element Vector{Int64}: 3 julia> b[1] = 2; a, b, c @@ -449,11 +449,11 @@ julia> b[1] = 2; a, b, c Assignment at out-of-bounds indices does not grow a collection. If the collection is a [`Vector`](@ref) it can instead be grown with [`push!`](@ref) or [`append!`](@ref). ```jldoctest julia> a = [1, 1]; a[3] = 2 -ERROR: BoundsError: attempt to access 2-element Array{Int64, 1} at index [3] +ERROR: BoundsError: attempt to access 2-element Vector{Int64} at index [3] [...] julia> push!(a, 2, 3) -4-element Array{Int64, 1}: +4-element Vector{Int64}: 1 1 2 @@ -467,7 +467,7 @@ ERROR: DimensionMismatch: tried to assign 0 elements to 1 destinations [...] julia> filter!(x -> x > 1, a) # in-place & thus more efficient than a = a[a .> 1] -2-element Array{Int64, 1}: +2-element Vector{Int64}: 2 3 @@ -490,14 +490,14 @@ assignment expression is converted into a single loop. julia> A = zeros(4, 4); B = [1, 2, 3, 4]; julia> A .= B -4×4 Array{Float64, 2}: +4×4 Matrix{Float64}: 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 3.0 3.0 3.0 3.0 4.0 4.0 4.0 4.0 julia> A -4×4 Array{Float64, 2}: +4×4 Matrix{Float64}: 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 3.0 3.0 3.0 3.0 @@ -1018,12 +1018,12 @@ collection or the last index of a dimension of an array. # Examples ```jldoctest julia> A = [1 2; 3 4] -2×2 Array{Int64, 2}: +2×2 Matrix{Int64}: 1 2 3 4 julia> A[end, :] -2-element Array{Int64, 1}: +2-element Vector{Int64}: 3 4 ``` @@ -1429,12 +1429,12 @@ collection or the first index of a dimension of an array. For example, # Examples ```jldoctest julia> A = [1 2; 3 4] -2×2 Array{Int64,2}: +2×2 Matrix{Int64}: 1 2 3 4 julia> A[begin, :] -2-element Array{Int64,1}: +2-element Matrix{Int64}: 1 2 ``` @@ -1515,7 +1515,7 @@ kw"new" """ where -The `where` keyword creates a type that is an iterated union of other types, over all +The `where` keyword creates a [`UnionAll`](@ref) type, which may be thought of as an iterated union of other types, over all values of some variable. For example `Vector{T} where T<:Real` includes all [`Vector`](@ref)s where the element type is some kind of `Real` number. @@ -2754,6 +2754,9 @@ compatible with the stores to that location. Otherwise, if not declared as To test whether an array element is defined, use [`isassigned`](@ref) instead. +The global variable variant is supported for compatibility with older julia +releases. For new code, prefer [`isdefinedglobal`](@ref). + See also [`@isdefined`](@ref). # Examples @@ -2781,6 +2784,37 @@ false """ isdefined + +""" + isdefinedglobal(m::Module, s::Symbol, [allow_import::Bool=true, [order::Symbol=:unordered]]) + +Tests whether a global variable `s` is defined in module `m` (in the current world age). +A variable is considered defined if and only if a value may be read from this global variable +and an access will not throw. This includes both constants and global variables that have +a value set. + +If `allow_import` is `false`, the global variable must be defined inside `m` +and may not be imported from another module. + +See also [`@isdefined`](@ref). + +# Examples +```jldoctest +julia> isdefinedglobal(Base, :sum) +true + +julia> isdefinedglobal(Base, :NonExistentMethod) +false + +julia> isdefinedglobal(Base, :sum, false) +true + +julia> isdefinedglobal(Main, :sum, false) +false +``` +""" +isdefinedglobal + """ Memory{T}(undef, n) @@ -2826,7 +2860,7 @@ Construct an uninitialized [`Vector{T}`](@ref) of length `n`. # Examples ```julia-repl julia> Vector{Float64}(undef, 3) -3-element Array{Float64, 1}: +3-element Vector{Float64}: 6.90966e-310 6.90966e-310 6.90966e-310 @@ -2876,7 +2910,7 @@ Construct an uninitialized [`Matrix{T}`](@ref) of size `m`×`n`. # Examples ```julia-repl julia> Matrix{Float64}(undef, 2, 3) -2×3 Array{Float64, 2}: +2×3 Matrix{Float64}: 2.36365e-314 2.28473e-314 5.0e-324 2.26704e-314 2.26711e-314 NaN @@ -3014,7 +3048,7 @@ an alias for `UndefInitializer()`. # Examples ```julia-repl julia> Array{Float64, 1}(UndefInitializer(), 3) -3-element Array{Float64, 1}: +3-element Vector{Float64}: 2.2752528595e-314 2.202942107e-314 2.275252907e-314 diff --git a/base/errorshow.jl b/base/errorshow.jl index 70ac8105feb21..d4b9b3666fbb7 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -915,9 +915,9 @@ function _collapse_repeated_frames(trace) [3] g(x::Int64) <-- useless @ Main ./REPL[1]:1 =# - if frame.linfo isa MethodInstance && last_frame.linfo isa MethodInstance && - frame.linfo.def isa Method && last_frame.linfo.def isa Method - m, last_m = frame.linfo.def::Method, last_frame.linfo.def::Method + m, last_m = StackTraces.frame_method_or_module(frame), + StackTraces.frame_method_or_module(last_frame) + if m isa Method && last_m isa Method params, last_params = Base.unwrap_unionall(m.sig).parameters, Base.unwrap_unionall(last_m.sig).parameters if last_m.nkw != 0 pos_sig_params = last_params[(last_m.nkw+2):end] @@ -944,7 +944,6 @@ function _collapse_repeated_frames(trace) return trace[kept_frames] end - function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true) n = 0 last_frame = StackTraces.UNKNOWN @@ -965,9 +964,8 @@ function process_backtrace(t::Vector, limit::Int=typemax(Int); skipC = true) if (lkup.from_c && skipC) continue end - code = lkup.linfo - if code isa MethodInstance - def = code.def + if lkup.linfo isa Union{MethodInstance, CodeInstance} + def = StackTraces.frame_method_or_module(lkup) if def isa Method && def.name !== :kwcall && def.sig <: Tuple{typeof(Core.kwcall),NamedTuple,Any,Vararg} # hide kwcall() methods, which are probably internal keyword sorter methods # (we print the internal method instead, after demangling diff --git a/base/essentials.jl b/base/essentials.jl index 3574116261968..58e4ce1125093 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -93,7 +93,7 @@ f(y) = [x for x in y] # Examples -```julia +```julia-repl julia> f(A::AbstractArray) = g(A) f (generic function with 1 method) @@ -1266,11 +1266,14 @@ 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. ## Example -``` +```julia-repl julia> struct Foo; a::Int; end Foo @@ -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/expr.jl b/base/expr.jl index 354fae3f0a592..84078829f77ed 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -401,13 +401,14 @@ macro constprop(setting) end function constprop_setting(@nospecialize setting) + s = setting isa(setting, QuoteNode) && (setting = setting.value) if setting === :aggressive return :aggressive_constprop elseif setting === :none return :no_constprop end - throw(ArgumentError(LazyString("@constprop "), setting, "not supported")) + throw(ArgumentError(LazyString("`Base.@constprop ", s, "` not supported"))) end """ 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/file.jl b/base/file.jl index c69a598f42623..66e8114aba4ba 100644 --- a/base/file.jl +++ b/base/file.jl @@ -128,7 +128,7 @@ julia> pwd() "/home/JuliaUser" julia> cd(readdir, "/home/JuliaUser/Projects/julia") -34-element Array{String,1}: +34-element Vector{String}: ".circleci" ".freebsdci.sh" ".git" @@ -211,17 +211,17 @@ julia> mkpath("my/test/dir") # creates three directories "my/test/dir" julia> readdir() -1-element Array{String,1}: +1-element Vector{String}: "my" julia> cd("my") julia> readdir() -1-element Array{String,1}: +1-element Vector{String}: "test" julia> readdir("test") -1-element Array{String,1}: +1-element Vector{String}: "dir" julia> mkpath("intermediate_dir/actually_a_directory.txt") # creates two directories @@ -943,7 +943,7 @@ See also: [`walkdir`](@ref). julia> cd("/home/JuliaUser/dev/julia") julia> readdir() -30-element Array{String,1}: +30-element Vector{String}: ".appveyor.yml" ".git" ".gitattributes" @@ -953,7 +953,7 @@ julia> readdir() "usr-staging" julia> readdir(join=true) -30-element Array{String,1}: +30-element Vector{String}: "/home/JuliaUser/dev/julia/.appveyor.yml" "/home/JuliaUser/dev/julia/.git" "/home/JuliaUser/dev/julia/.gitattributes" @@ -963,7 +963,7 @@ julia> readdir(join=true) "/home/JuliaUser/dev/julia/usr-staging" julia> readdir("base") -145-element Array{String,1}: +145-element Vector{String}: ".gitignore" "Base.jl" "Enums.jl" @@ -973,7 +973,7 @@ julia> readdir("base") "weakkeydict.jl" julia> readdir("base", join=true) -145-element Array{String,1}: +145-element Vector{String}: "base/.gitignore" "base/Base.jl" "base/Enums.jl" @@ -983,7 +983,7 @@ julia> readdir("base", join=true) "base/weakkeydict.jl" julia> readdir(abspath("base"), join=true) -145-element Array{String,1}: +145-element Vector{String}: "/home/JuliaUser/dev/julia/base/.gitignore" "/home/JuliaUser/dev/julia/base/Base.jl" "/home/JuliaUser/dev/julia/base/Enums.jl" diff --git a/base/float.jl b/base/float.jl index c7230459d0822..faded5cd5978c 100644 --- a/base/float.jl +++ b/base/float.jl @@ -122,13 +122,16 @@ significand_mask(::Type{Float16}) = 0x03ff mantissa(x::T) where {T} = reinterpret(Unsigned, x) & significand_mask(T) for T in (Float16, Float32, Float64) - @eval significand_bits(::Type{$T}) = $(trailing_ones(significand_mask(T))) - @eval exponent_bits(::Type{$T}) = $(sizeof(T)*8 - significand_bits(T) - 1) - @eval exponent_bias(::Type{$T}) = $(Int(exponent_one(T) >> significand_bits(T))) + sb = trailing_ones(significand_mask(T)) + em = exponent_mask(T) + eb = Int(exponent_one(T) >> sb) + @eval significand_bits(::Type{$T}) = $(sb) + @eval exponent_bits(::Type{$T}) = $(sizeof(T)*8 - sb - 1) + @eval exponent_bias(::Type{$T}) = $(eb) # maximum float exponent - @eval exponent_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T)) - exponent_bias(T) - 1) + @eval exponent_max(::Type{$T}) = $(Int(em >> sb) - eb - 1) # maximum float exponent without bias - @eval exponent_raw_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T))) + @eval exponent_raw_max(::Type{$T}) = $(Int(em >> sb)) end """ 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) diff --git a/base/genericmemory.jl b/base/genericmemory.jl index fbf60255935a3..2a33336c0aad6 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -10,7 +10,7 @@ Fixed-size [`DenseVector{T}`](@ref DenseVector). `kind` can currently be either `:not_atomic` or `:atomic`. For details on what `:atomic` implies, see [`AtomicMemory`](@ref) `addrspace` can currently only be set to `Core.CPU`. It is designed to permit extension by other systems such as GPUs, which might define values such as: -``` +```julia module CUDA const Generic = bitcast(Core.AddrSpace{CUDA}, 0) const Global = bitcast(Core.AddrSpace{CUDA}, 1) @@ -144,6 +144,7 @@ function unsafe_copyto!(dest::Memory{T}, doffs, src::Memory{T}, soffs, n) where{ return dest end +#fallback method when types don't match function unsafe_copyto!(dest::Memory, doffs, src::Memory, soffs, n) @_terminates_locally_meta n == 0 && return dest @@ -171,7 +172,13 @@ function unsafe_copyto!(dest::Memory, doffs, src::Memory, soffs, n) return dest end -copy(a::T) where {T<:Memory} = ccall(:jl_genericmemory_copy, Ref{T}, (Any,), a) +function copy(a::T) where {T<:Memory} + # `copy` only throws when the size exceeds the max allocation size, + # but since we're copying an existing array, we're guaranteed that this will not happen. + @_nothrow_meta + newmem = T(undef, length(a)) + @inbounds unsafe_copyto!(newmem, 1, a, 1, length(a)) +end copyto!(dest::Memory, src::Memory) = copyto!(dest, 1, src, 1, length(src)) function copyto!(dest::Memory, doffs::Integer, src::Memory, soffs::Integer, n::Integer) diff --git a/base/gmp.jl b/base/gmp.jl index df0d9fee49348..4d2b4b66ac41b 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -174,8 +174,8 @@ end invert!(x::BigInt, a::BigInt, b::BigInt) = ccall((:__gmpz_invert, libgmp), Cint, (mpz_t, mpz_t, mpz_t), x, a, b) -invert(a::BigInt, b::BigInt) = invert!(BigInt(), a, b) invert!(x::BigInt, b::BigInt) = invert!(x, x, b) +invert(a::BigInt, b::BigInt) = (ret=BigInt(); invert!(ret, a, b); ret) for op in (:add_ui, :sub_ui, :mul_ui, :mul_2exp, :fdiv_q_2exp, :pow_ui, :bin_ui) op! = Symbol(op, :!) @@ -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/base/intfuncs.jl b/base/intfuncs.jl index db3b1fdeeb521..dc81f2bd3e489 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -97,6 +97,9 @@ end Least common (positive) multiple (or zero if any argument is zero). The arguments may be integer and rational numbers. +``a`` is a multiple of ``b`` if there exists an integer ``m`` such +that ``a=mb``. + !!! compat "Julia 1.4" Rational arguments require Julia 1.4 or later. @@ -150,7 +153,16 @@ gcd(a::T, b::T) where T<:Real = throw(MethodError(gcd, (a,b))) lcm(a::T, b::T) where T<:Real = throw(MethodError(lcm, (a,b))) gcd(abc::AbstractArray{<:Real}) = reduce(gcd, abc; init=zero(eltype(abc))) -lcm(abc::AbstractArray{<:Real}) = reduce(lcm, abc; init=one(eltype(abc))) +function lcm(abc::AbstractArray{<:Real}) + # Using reduce with init=one(eltype(abc)) is buggy for Rationals. + l = length(abc) + if l == 0 + eltype(abc) <: Integer && return one(eltype(abc)) + throw(ArgumentError("lcm has no identity for $(eltype(abc))")) + end + l == 1 && return abs(only(abc)) + return reduce(lcm, abc) +end function gcd(abc::AbstractArray{<:Integer}) a = zero(eltype(abc)) diff --git a/base/invalidation.jl b/base/invalidation.jl new file mode 100644 index 0000000000000..5abb0b74ad884 --- /dev/null +++ b/base/invalidation.jl @@ -0,0 +1,130 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +struct GlobalRefIterator + mod::Module +end +IteratorSize(::Type{GlobalRefIterator}) = SizeUnknown() +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 + b = table[i] + b === nothing && return iterate(gri, i+1) + return ((b::Core.Binding).globalref, i+1) +end + +const TYPE_TYPE_MT = Type.body.name.mt +const NONFUNCTION_MT = Core.MethodTable.name.mt +function foreach_module_mtable(visit, m::Module, world::UInt) + for gb in globalrefs(m) + binding = gb.binding + bpart = lookup_binding_partition(world, binding) + if is_defined_const_binding(binding_kind(bpart)) + v = partition_restriction(bpart) + uw = unwrap_unionall(v) + name = gb.name + if isa(uw, DataType) + tn = uw.name + if tn.module === m && tn.name === name && tn.wrapper === v && isdefined(tn, :mt) + # this is the original/primary binding for the type (name/wrapper) + mt = tn.mt + if mt !== nothing && mt !== TYPE_TYPE_MT && mt !== NONFUNCTION_MT + @assert mt.module === m + visit(mt) || return false + end + end + elseif isa(v, Module) && v !== m && parentmodule(v) === m && _nameof(v) === name + # this is the original/primary binding for the submodule + foreach_module_mtable(visit, v, world) || return false + elseif isa(v, Core.MethodTable) && v.module === m && v.name === name + # this is probably an external method table here, so let's + # assume so as there is no way to precisely distinguish them + visit(v) || return false + end + end + end + return true +end + +function foreach_reachable_mtable(visit, world::UInt) + visit(TYPE_TYPE_MT) || return + visit(NONFUNCTION_MT) || return + for mod in loaded_modules_array() + foreach_module_mtable(visit, mod, world) + end +end + +function should_invalidate_code_for_globalref(gr::GlobalRef, src::CodeInfo) + found_any = false + labelchangemap = nothing + stmts = src.code + isgr(g::GlobalRef) = gr.mod == g.mod && gr.name === g.name + isgr(g) = false + for i = 1:length(stmts) + stmt = stmts[i] + if isgr(stmt) + found_any = true + continue + end + for ur in Compiler.userefs(stmt) + arg = ur[] + # If any of the GlobalRefs in this stmt match the one that + # we are about, we need to move out all GlobalRefs to preserve + # effect order, in case we later invalidate a different GR + if isa(arg, GlobalRef) + if isgr(arg) + @assert !isa(stmt, PhiNode) + found_any = true + break + end + end + end + end + return found_any +end + +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 && (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 + ci = ci.next + end + end + end + end + return true + end + catch err + bt = catch_backtrace() + invokelatest(Base.println, "Internal Error during invalidation:") + invokelatest(Base.display_error, err, bt) + end +end 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/base/iterators.jl b/base/iterators.jl index 6b8d9fe75e302..c6278e6284d70 100644 --- a/base/iterators.jl +++ b/base/iterators.jl @@ -15,7 +15,8 @@ using .Base: AbstractRange, AbstractUnitRange, UnitRange, LinearIndices, TupleOrBottom, (:), |, +, -, *, !==, !, ==, !=, <=, <, >, >=, =>, missing, any, _counttuple, eachindex, ntuple, zero, prod, reduce, in, firstindex, lastindex, - tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape, LazyString + tail, fieldtypes, min, max, minimum, zero, oneunit, promote, promote_shape, LazyString, + afoldl using Core: @doc using .Base: @@ -1202,8 +1203,13 @@ julia> [(x,y) for x in 0:1 for y in 'a':'c'] # collects generators involving It flatten(itr) = Flatten(itr) eltype(::Type{Flatten{I}}) where {I} = eltype(eltype(I)) -eltype(::Type{Flatten{I}}) where {I<:Union{Tuple,NamedTuple}} = promote_typejoin(map(eltype, fieldtypes(I))...) -eltype(::Type{Flatten{Tuple{}}}) = eltype(Tuple{}) + +# For tuples, we statically know the element type of each index, so we can compute +# this at compile time. +function eltype(::Type{Flatten{I}}) where {I<:Union{Tuple,NamedTuple}} + afoldl((T, i) -> promote_typejoin(T, eltype(i)), Union{}, fieldtypes(I)...) +end + IteratorEltype(::Type{Flatten{I}}) where {I} = _flatteneltype(I, IteratorEltype(I)) IteratorEltype(::Type{Flatten{Tuple{}}}) = IteratorEltype(Tuple{}) _flatteneltype(I, ::HasEltype) = IteratorEltype(eltype(I)) diff --git a/base/loading.jl b/base/loading.jl index 8ed43e4539c20..240406292246b 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) @@ -1828,7 +1831,7 @@ function compilecache_path(pkg::PkgId; path = nothing isnothing(sourcepath) && error("Cannot locate source for $(repr("text/plain", pkg))") for path_to_try in cachepaths - staledeps = stale_cachefile(sourcepath, path_to_try, ignore_loaded = true, requested_flags=flags) + staledeps = stale_cachefile(sourcepath, path_to_try; ignore_loaded, requested_flags=flags) if staledeps === true continue end @@ -2361,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 \ @@ -2374,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" @@ -2649,7 +2656,7 @@ function __require_prelocked(pkg::PkgId, env) parallel_precompile_attempted = true unlock(require_lock) try - Precompilation.precompilepkgs([pkg.name]; _from_loading=true) + Precompilation.precompilepkgs([pkg.name]; _from_loading=true, ignore_loaded=false) finally lock(require_lock) end @@ -4198,7 +4205,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 +4221,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/lock.jl b/base/lock.jl index a44cd4c0d63cf..59e554c01c24a 100644 --- a/base/lock.jl +++ b/base/lock.jl @@ -9,6 +9,14 @@ Get the currently running [`Task`](@ref). """ current_task() = ccall(:jl_get_current_task, Ref{Task}, ()) +# This bit is set in the `havelock` of a `ReentrantLock` when that lock is locked by some task. +const LOCKED_BIT = 0b01 +# This bit is set in the `havelock` of a `ReentrantLock` just before parking a task. A task is being +# parked if it wants to lock the lock, but it is currently being held by some other task. +const PARKED_BIT = 0b10 + +const MAX_SPIN_ITERS = 40 + # Advisory reentrant lock """ ReentrantLock() @@ -43,7 +51,28 @@ mutable struct ReentrantLock <: AbstractLock # offset32 = 20, offset64 = 24 reentrancy_cnt::UInt32 # offset32 = 24, offset64 = 28 - @atomic havelock::UInt8 # 0x0 = none, 0x1 = lock, 0x2 = conflict + # + # This atomic integer holds the current state of the lock instance. Only the two lowest bits + # are used. See `LOCKED_BIT` and `PARKED_BIT` for the bitmask for these bits. + # + # # State table: + # + # PARKED_BIT | LOCKED_BIT | Description + # 0 | 0 | The lock is not locked, nor is anyone waiting for it. + # -----------+------------+------------------------------------------------------------------ + # 0 | 1 | The lock is locked by exactly one task. No other task is + # | | waiting for it. + # -----------+------------+------------------------------------------------------------------ + # 1 | 0 | The lock is not locked. One or more tasks are parked. + # -----------+------------+------------------------------------------------------------------ + # 1 | 1 | The lock is locked by exactly one task. One or more tasks are + # | | parked waiting for the lock to become available. + # | | In this state, PARKED_BIT is only ever cleared when the cond_wait lock + # | | is held (i.e. on unlock). This ensures that + # | | we never end up in a situation where there are parked tasks but + # | | PARKED_BIT is not set (which would result in those tasks + # | | potentially never getting woken up). + @atomic havelock::UInt8 # offset32 = 28, offset64 = 32 cond_wait::ThreadSynchronizer # 2 words # offset32 = 36, offset64 = 48 @@ -112,7 +141,7 @@ function islocked end # `ReentrantLock`. function islocked(rl::ReentrantLock) - return (@atomic :monotonic rl.havelock) != 0 + return (@atomic :monotonic rl.havelock) & LOCKED_BIT != 0 end """ @@ -136,7 +165,6 @@ function trylock end @inline function trylock(rl::ReentrantLock) ct = current_task() if rl.locked_by === ct - #@assert rl.havelock !== 0x00 rl.reentrancy_cnt += 0x0000_0001 return true end @@ -144,9 +172,8 @@ function trylock end end @noinline function _trylock(rl::ReentrantLock, ct::Task) GC.disable_finalizers() - if (@atomicreplace :acquire rl.havelock 0x00 => 0x01).success - #@assert rl.locked_by === nothing - #@assert rl.reentrancy_cnt === 0 + state = (@atomic :monotonic rl.havelock) & PARKED_BIT + if (@atomicreplace :acquire rl.havelock state => (state | LOCKED_BIT)).success rl.reentrancy_cnt = 0x0000_0001 @atomic :release rl.locked_by = ct return true @@ -168,23 +195,69 @@ Each `lock` must be matched by an [`unlock`](@ref). trylock(rl) || (@noinline function slowlock(rl::ReentrantLock) Threads.lock_profiling() && Threads.inc_lock_conflict_count() c = rl.cond_wait - lock(c.lock) - try - while true - if (@atomicreplace rl.havelock 0x01 => 0x02).old == 0x00 # :sequentially_consistent ? # now either 0x00 or 0x02 - # it was unlocked, so try to lock it ourself - _trylock(rl, current_task()) && break - else # it was locked, so now wait for the release to notify us - wait(c) + ct = current_task() + iteration = 1 + while true + state = @atomic :monotonic rl.havelock + # Grab the lock if it isn't locked, even if there is a queue on it + if state & LOCKED_BIT == 0 + GC.disable_finalizers() + result = (@atomicreplace :acquire :monotonic rl.havelock state => (state | LOCKED_BIT)) + if result.success + rl.reentrancy_cnt = 0x0000_0001 + @atomic :release rl.locked_by = ct + return end + GC.enable_finalizers() + continue end - finally - unlock(c.lock) + + if state & PARKED_BIT == 0 + # If there is no queue, try spinning a few times + if iteration <= MAX_SPIN_ITERS + Base.yield() + iteration += 1 + continue + end + + # If still not locked, try setting the parked bit + @atomicreplace :monotonic :monotonic rl.havelock state => (state | PARKED_BIT) + end + + # lock the `cond_wait` + lock(c.lock) + + # Last check before we wait to make sure `unlock` did not win the race + # to the `cond_wait` lock and cleared the parked bit + state = @atomic :acquire rl.havelock + if state != LOCKED_BIT | PARKED_BIT + unlock(c.lock) + continue + end + + # It was locked, so now wait for the unlock to notify us + wait_no_relock(c) + + # Loop back and try locking again + iteration = 1 end end)(rl) return end +function wait_no_relock(c::GenericCondition) + ct = current_task() + _wait2(c, ct) + token = unlockall(c.lock) + try + return wait() + catch + ct.queue === nothing || list_deletefirst!(ct.queue, ct) + rethrow() + end +end + + """ unlock(lock) @@ -201,18 +274,27 @@ internal counter and return immediately. rl.reentrancy_cnt = n if n == 0x0000_00000 @atomic :monotonic rl.locked_by = nothing - if (@atomicswap :release rl.havelock = 0x00) == 0x02 + result = (@atomicreplace :release :monotonic rl.havelock LOCKED_BIT => 0x00) + if result.success + return true + else (@noinline function notifywaiters(rl) cond_wait = rl.cond_wait lock(cond_wait) - try - notify(cond_wait) - finally - unlock(cond_wait) + + notify(cond_wait, all=false) + if !isempty(cond_wait.waitq) + @atomic :release rl.havelock = PARKED_BIT + else + # We may have won the race to the `cond_wait` lock as a task was about to park + # but we unlock anyway as any parking task will retry + @atomic :release rl.havelock = 0x00 end + + unlock(cond_wait) end)(rl) + return true end - return true end return false end)(rl) && GC.enable_finalizers() diff --git a/base/logging/logging.jl b/base/logging/logging.jl index 5cf3882a300ec..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 @@ -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/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/base/mathconstants.jl b/base/mathconstants.jl index de6b98cea634d..d26f5115b5ccb 100644 --- a/base/mathconstants.jl +++ b/base/mathconstants.jl @@ -29,7 +29,7 @@ end Base.@assume_effects :foldable function (::Type{T})(x::_KnownIrrational, r::RoundingMode) where {T<:Union{Float32,Float64}} Base._irrational_to_float(T, x, r) end -Base.@assume_effects :foldable function rationalize(::Type{T}, x::_KnownIrrational; tol::Real=0) where {T<:Integer} +Base.@assume_effects :foldable function Base.rationalize(::Type{T}, x::_KnownIrrational; tol::Real=0) where {T<:Integer} Base._rationalize_irrational(T, x, tol) end Base.@assume_effects :foldable function Base.lessrational(rx::Rational, x::_KnownIrrational) diff --git a/base/meta.jl b/base/meta.jl index bcf4fbf632ab2..36875b8e2c625 100644 --- a/base/meta.jl +++ b/base/meta.jl @@ -16,6 +16,8 @@ export quot, show_sexpr, @dump +public parse + using Base: isidentifier, isoperator, isunaryoperator, isbinaryoperator, ispostfixoperator import Base: isexpr @@ -362,11 +364,29 @@ 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) + return x + else return Core.ReturnNode( _partially_inline!(x.val, slot_replacements, type_signature, static_param_values, slot_offset, statement_offset, boundscheck), ) + end end if isa(x, Core.GotoIfNot) return Core.GotoIfNot( @@ -376,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) diff --git a/base/multidimensional.jl b/base/multidimensional.jl index c82f1c1ba75d7..ba08f0679590b 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1313,16 +1313,16 @@ See also: [`circshift`](@ref). # Examples ```julia-repl julia> src = reshape(Vector(1:16), (4,4)) -4×4 Array{Int64,2}: +4×4 Matrix{Int64}: 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 -julia> dest = OffsetArray{Int}(undef, (0:3,2:5)) +julia> dest = OffsetArray{Int}(undef, (0:3,2:5)); julia> circcopy!(dest, src) -OffsetArrays.OffsetArray{Int64,2,Array{Int64,2}} with indices 0:3×2:5: +4×4 OffsetArray(::Matrix{Int64}, 0:3, 2:5) with eltype Int64 with indices 0:3×2:5: 8 12 16 4 5 9 13 1 6 10 14 2 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/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/pointer.jl b/base/pointer.jl index b1580ef17d562..de2f413d8f881 100644 --- a/base/pointer.jl +++ b/base/pointer.jl @@ -169,7 +169,7 @@ The `unsafe` prefix on this function indicates that no validation is performed o pointer `p` to ensure that it is valid. Like C, the programmer is responsible for ensuring that referenced memory is not freed or garbage collected while invoking this function. Incorrect usage may segfault your program. Unlike C, storing memory region allocated as -different type may be valid provided that that the types are compatible. +different type may be valid provided that the types are compatible. !!! compat "Julia 1.10" The `order` argument is available as of Julia 1.10. diff --git a/base/precompilation.jl b/base/precompilation.jl index 6eebded8b2f93..820cf260df71f 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -418,11 +418,12 @@ function precompilepkgs(pkgs::Vector{String}=String[]; io::IO=stderr, # asking for timing disables fancy mode, as timing is shown in non-fancy mode fancyprint::Bool = can_fancyprint(io) && !timing, - manifest::Bool=false,) + manifest::Bool=false, + ignore_loaded::Bool=true) # monomorphize this to avoid latency problems _precompilepkgs(pkgs, internal_call, strict, warn_loaded, timing, _from_loading, configs isa Vector{Config} ? configs : [configs], - IOContext{IO}(io), fancyprint, manifest) + IOContext{IO}(io), fancyprint, manifest, ignore_loaded) end function _precompilepkgs(pkgs::Vector{String}, @@ -434,7 +435,8 @@ function _precompilepkgs(pkgs::Vector{String}, configs::Vector{Config}, io::IOContext{IO}, fancyprint::Bool, - manifest::Bool) + manifest::Bool, + ignore_loaded::Bool) requested_pkgs = copy(pkgs) # for understanding user intent time_start = time_ns() @@ -918,7 +920,7 @@ function _precompilepkgs(pkgs::Vector{String}, wait(was_processed[(dep,config)]) end circular = pkg in circular_deps - is_stale = !Base.isprecompiled(pkg; ignore_loaded=true, stale_cache, cachepath_cache, cachepaths, sourcepath, flags=cacheflags) + is_stale = !Base.isprecompiled(pkg; ignore_loaded, stale_cache, cachepath_cache, cachepaths, sourcepath, flags=cacheflags) if !circular && is_stale Base.acquire(parallel_limiter) is_project_dep = pkg in project_deps @@ -944,10 +946,10 @@ function _precompilepkgs(pkgs::Vector{String}, try # allows processes to wait if another process is precompiling a given package to # a functionally identical package cache (except for preferences, which may differ) - t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor) do + t = @elapsed ret = precompile_pkgs_maybe_cachefile_lock(io, print_lock, fancyprint, pkg_config, pkgspidlocked, hascolor, parallel_limiter, ignore_loaded) do Base.with_logger(Base.NullLogger()) do - # The false here means we ignore loaded modules, so precompile for a fresh session - keep_loaded_modules = false + # whether to respect already loaded dependency versions + keep_loaded_modules = !ignore_loaded # for extensions, any extension in our direct dependencies is one we have a right to load # for packages, we may load any extension (all possible triggers are accounted for above) loadable_exts = haskey(ext_to_parent, pkg) ? filter((dep)->haskey(ext_to_parent, dep), direct_deps[pkg]) : nothing @@ -1037,9 +1039,13 @@ function _precompilepkgs(pkgs::Vector{String}, plural1 = length(configs) > 1 ? "dependency configurations" : n_loaded == 1 ? "dependency" : "dependencies" plural2 = n_loaded == 1 ? "a different version is" : "different versions are" plural3 = n_loaded == 1 ? "" : "s" + plural4 = n_loaded == 1 ? "this package" : "these packages" print(iostr, "\n ", color_string(string(n_loaded), Base.warn_color()), - " $(plural1) precompiled but $(plural2) currently loaded. Restart julia to access the new version$(plural3)" + " $(plural1) precompiled but ", + color_string("$(plural2) currently loaded", Base.warn_color()), + ". Restart julia to access the new version$(plural3). \ + Otherwise, loading dependents of $(plural4) may trigger further precompilation to work with the unexpected version$(plural3)." ) end if !isempty(precomperr_deps) @@ -1098,7 +1104,7 @@ function _precompilepkgs(pkgs::Vector{String}, direct = strict ? "" : "direct " err_msg = "The following $n_direct_errs $(direct)dependenc$(pluralde) failed to precompile:\n$(String(take!(err_str)))" if internal_call # aka. auto-precompilation - if isinteractive() && !get(ENV, "CI", false) + if isinteractive() plural1 = length(failed_deps) == 1 ? "y" : "ies" println(io, " ", color_string("$(length(failed_deps))", Base.error_color()), " dependenc$(plural1) errored.") println(io, " For a report of the errors see `julia> err`. To retry use `pkg> precompile`") @@ -1130,7 +1136,7 @@ function _color_string(cstr::String, col::Union{Int64, Symbol}, hascolor) end # Can be merged with `maybe_cachefile_lock` in loading? -function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor) +function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLock, fancyprint::Bool, pkg_config, pkgspidlocked, hascolor, parallel_limiter::Base.Semaphore, ignore_loaded::Bool) if !(isdefined(Base, :mkpidlock_hook) && isdefined(Base, :trymkpidlock_hook) && Base.isdefined(Base, :parse_pidfile_hook)) return f() end @@ -1153,17 +1159,22 @@ function precompile_pkgs_maybe_cachefile_lock(f, io::IO, print_lock::ReentrantLo !fancyprint && lock(print_lock) do println(io, " ", pkg.name, _color_string(" Being precompiled by $(pkgspidlocked[pkg_config])", Base.info_color(), hascolor)) end - # wait until the lock is available - @invokelatest Base.mkpidlock_hook(() -> begin - # double-check in case the other process crashed or the lock expired - if Base.isprecompiled(pkg; ignore_loaded=true, flags=cacheflags) # don't use caches for this as the env state will have changed - return nothing # returning nothing indicates a process waited for another - else - delete!(pkgspidlocked, pkg_config) - return f() # precompile - end - end, - pidfile; stale_age) + Base.release(parallel_limiter) # release so other work can be done while waiting + try + # wait until the lock is available + @invokelatest Base.mkpidlock_hook(() -> begin + # double-check in case the other process crashed or the lock expired + if Base.isprecompiled(pkg; ignore_loaded, flags=cacheflags) # don't use caches for this as the env state will have changed + return nothing # returning nothing indicates a process waited for another + else + delete!(pkgspidlocked, pkg_config) + Base.acquire(f, parallel_limiter) # precompile + end + end, + pidfile; stale_age) + finally + Base.acquire(parallel_limiter) # re-acquire so the outer release is balanced + end end return cachefile end diff --git a/base/range.jl b/base/range.jl index b05dddb025a7c..39428ab741955 100644 --- a/base/range.jl +++ b/base/range.jl @@ -954,7 +954,7 @@ function _getindex(v::UnitRange{T}, i::Integer) where {T<:OverflowSafe} end let BitInteger64 = Union{Int8,Int16,Int32,Int64,UInt8,UInt16,UInt32,UInt64} # for bootstrapping - function checkbounds(::Type{Bool}, v::StepRange{<:BitInteger64, <:BitInteger64}, i::BitInteger64) + global function checkbounds(::Type{Bool}, v::StepRange{<:BitInteger64, <:BitInteger64}, i::BitInteger64) res = widemul(step(v), i-oneunit(i)) + first(v) (0 < i) & ifelse(0 < step(v), res <= last(v), res >= last(v)) end diff --git a/base/reduce.jl b/base/reduce.jl index 6ceb76089d59c..25466eed4a105 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -1105,236 +1105,6 @@ julia> argmin([7, 1, 1, NaN]) """ argmin(itr) = findmin(itr)[2] -## all & any - -""" - any(itr) -> Bool - -Test whether any elements of a boolean collection are `true`, returning `true` as -soon as the first `true` value in `itr` is encountered (short-circuiting). To -short-circuit on `false`, use [`all`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `false` (or equivalently, if the input contains no `true` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -See also: [`all`](@ref), [`count`](@ref), [`sum`](@ref), [`|`](@ref), [`||`](@ref). - -# Examples -```jldoctest -julia> a = [true,false,false,true] -4-element Vector{Bool}: - 1 - 0 - 0 - 1 - -julia> any(a) -true - -julia> any((println(i); v) for (i, v) in enumerate(a)) -1 -true - -julia> any([missing, true]) -true - -julia> any([false, missing]) -missing -``` -""" -any(itr) = any(identity, itr) - -""" - all(itr) -> Bool - -Test whether all elements of a boolean collection are `true`, returning `false` as -soon as the first `false` value in `itr` is encountered (short-circuiting). To -short-circuit on `true`, use [`any`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `true` (or equivalently, if the input contains no `false` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -See also: [`all!`](@ref), [`any`](@ref), [`count`](@ref), [`&`](@ref), [`&&`](@ref), [`allunique`](@ref). - -# Examples -```jldoctest -julia> a = [true,false,false,true] -4-element Vector{Bool}: - 1 - 0 - 0 - 1 - -julia> all(a) -false - -julia> all((println(i); v) for (i, v) in enumerate(a)) -1 -2 -false - -julia> all([missing, false]) -false - -julia> all([true, missing]) -missing -``` -""" -all(itr) = all(identity, itr) - -""" - any(p, itr) -> Bool - -Determine whether predicate `p` returns `true` for any elements of `itr`, returning -`true` as soon as the first item in `itr` for which `p` returns `true` is encountered -(short-circuiting). To short-circuit on `false`, use [`all`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `false` (or equivalently, if the input contains no `true` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -# Examples -```jldoctest -julia> any(i->(4<=i<=6), [3,5,7]) -true - -julia> any(i -> (println(i); i > 3), 1:10) -1 -2 -3 -4 -true - -julia> any(i -> i > 0, [1, missing]) -true - -julia> any(i -> i > 0, [-1, missing]) -missing - -julia> any(i -> i > 0, [-1, 0]) -false -``` -""" -any(f, itr) = _any(f, itr, :) - -for ItrT = (Tuple,Any) - # define a generic method and a specialized version for `Tuple`, - # whose method bodies are identical, while giving better effects to the later - @eval function _any(f, itr::$ItrT, ::Colon) - $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) - anymissing = false - for x in itr - v = f(x) - if ismissing(v) - anymissing = true - else - v && return true - end - end - return anymissing ? missing : false - end -end - -# Specialized versions of any(f, ::Tuple) -# We fall back to the for loop implementation all elements have the same type or -# if the tuple is too large. -function any(f, itr::Tuple) - if itr isa NTuple || length(itr) > 32 - return _any(f, itr, :) - end - _any_tuple(f, false, itr...) -end - -@inline function _any_tuple(f, anymissing, x, rest...) - v = f(x) - if ismissing(v) - anymissing = true - elseif v - return true - end - return _any_tuple(f, anymissing, rest...) -end -@inline _any_tuple(f, anymissing) = anymissing ? missing : false - -""" - all(p, itr) -> Bool - -Determine whether predicate `p` returns `true` for all elements of `itr`, returning -`false` as soon as the first item in `itr` for which `p` returns `false` is encountered -(short-circuiting). To short-circuit on `true`, use [`any`](@ref). - -If the input contains [`missing`](@ref) values, return `missing` if all non-missing -values are `true` (or equivalently, if the input contains no `false` value), following -[three-valued logic](https://en.wikipedia.org/wiki/Three-valued_logic). - -# Examples -```jldoctest -julia> all(i->(4<=i<=6), [4,5,6]) -true - -julia> all(i -> (println(i); i < 3), 1:10) -1 -2 -3 -false - -julia> all(i -> i > 0, [1, missing]) -missing - -julia> all(i -> i > 0, [-1, missing]) -false - -julia> all(i -> i > 0, [1, 2]) -true -``` -""" -all(f, itr) = _all(f, itr, :) - -for ItrT = (Tuple,Any) - # define a generic method and a specialized version for `Tuple`, - # whose method bodies are identical, while giving better effects to the later - @eval function _all(f, itr::$ItrT, ::Colon) - $(ItrT === Tuple ? :(@_terminates_locally_meta) : :nothing) - anymissing = false - for x in itr - v = f(x) - if ismissing(v) - anymissing = true - else - v || return false - end - end - return anymissing ? missing : true - end -end - -# Specialized versions of all(f, ::Tuple), -# This is similar to any(f, ::Tuple) defined above. -function all(f, itr::Tuple) - if itr isa NTuple || length(itr) > 32 - return _all(f, itr, :) - end - _all_tuple(f, false, itr...) -end - -@inline function _all_tuple(f, anymissing, x, rest...) - v = f(x) - if ismissing(v) - anymissing = true - # this syntax allows throwing a TypeError for non-Bool, for consistency with any - elseif v - nothing - else - return false - end - return _all_tuple(f, anymissing, rest...) -end -@inline _all_tuple(f, anymissing) = anymissing ? missing : true - -all(::Tuple{Missing}) = missing - ## count _bool(f) = x->f(x)::Bool diff --git a/base/reflection.jl b/base/reflection.jl index 9246b4cb0ac71..78e701692a2a7 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -131,13 +131,6 @@ isempty(mt::Core.MethodTable) = (mt.defs === nothing) uncompressed_ir(m::Method) = isdefined(m, :source) ? _uncompressed_ir(m) : isdefined(m, :generator) ? error("Method is @generated; try `code_lowered` instead.") : error("Code for this Method is not available.") -function _uncompressed_ir(m::Method) - s = m.source - if s isa String - s = ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Ptr{Cvoid}, Any), m, C_NULL, s) - end - return s::CodeInfo -end # for backwards compat const uncompressed_ast = uncompressed_ir @@ -462,7 +455,7 @@ internals. when looking up methods, use current world age if not specified. - `interp::Core.Compiler.AbstractInterpreter = Core.Compiler.NativeInterpreter(world)`: optional, controls the abstract interpreter to use, use the native interpreter if not specified. -- `optimize_until::Union{Integer,AbstractString,Nothing} = nothing`: optional, +- `optimize_until::Union{Int,String,Nothing} = nothing`: optional, controls the optimization passes to run. If it is a string, it specifies the name of the pass up to which the optimizer is run. If it is an integer, it specifies the number of passes to run. @@ -506,7 +499,7 @@ function code_ircode_by_type( @nospecialize(tt::Type); world::UInt=get_world_counter(), interp=nothing, - optimize_until::Union{Integer,AbstractString,Nothing}=nothing, + optimize_until::Union{Int,String,Nothing}=nothing, ) passed_interp = interp interp = passed_interp === nothing ? invoke_default_compiler(:_default_interp, world) : interp @@ -1369,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...) @@ -1382,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. @@ -1411,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/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 diff --git a/base/runtime_internals.jl b/base/runtime_internals.jl index cbbde7d9535a2..964e8063dd5af 100644 --- a/base/runtime_internals.jl +++ b/base/runtime_internals.jl @@ -228,21 +228,27 @@ const BINDING_KIND_IMPORTED = 0x5 const BINDING_KIND_FAILED = 0x6 const BINDING_KIND_DECLARED = 0x7 const BINDING_KIND_GUARD = 0x8 +const BINDING_KIND_UNDEF_CONST = 0x9 -is_some_const_binding(kind::UInt8) = (kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT) +is_defined_const_binding(kind::UInt8) = (kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT) +is_some_const_binding(kind::UInt8) = (is_defined_const_binding(kind) || kind == BINDING_KIND_UNDEF_CONST) is_some_imported(kind::UInt8) = (kind == BINDING_KIND_IMPLICIT || kind == BINDING_KIND_EXPLICIT || kind == BINDING_KIND_IMPORTED) -is_some_guard(kind::UInt8) = (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED) +is_some_guard(kind::UInt8) = (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED || kind == BINDING_KIND_UNDEF_CONST) 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 @@ -418,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 @@ -1391,6 +1401,17 @@ end hasgenerator(m::Method) = isdefined(m, :generator) hasgenerator(m::Core.MethodInstance) = hasgenerator(m.def::Method) +function _uncompressed_ir(m::Method) + s = m.source + if s isa String + s = ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Ptr{Cvoid}, Any), m, C_NULL, s) + end + return s::CodeInfo +end + +_uncompressed_ir(codeinst::CodeInstance, s::String) = + ccall(:jl_uncompress_ir, Ref{CodeInfo}, (Any, Any, Any), codeinst.def.def::Method, codeinst, s) + """ Base.generating_output([incremental::Bool])::Bool diff --git a/base/show.jl b/base/show.jl index cb36488b92bc1..de45ca07e3131 100644 --- a/base/show.jl +++ b/base/show.jl @@ -1045,7 +1045,7 @@ function check_world_bounded(tn::Core.TypeName) isdefined(bnd, :partitions) || return nothing partition = @atomic bnd.partitions while true - if is_some_const_binding(binding_kind(partition)) && partition_restriction(partition) <: tn.wrapper + if is_defined_const_binding(binding_kind(partition)) && partition_restriction(partition) <: tn.wrapper max_world = @atomic partition.max_world max_world == typemax(UInt) && return nothing return Int(partition.min_world):Int(max_world) @@ -1353,7 +1353,13 @@ end show(io::IO, mi::Core.MethodInstance) = show_mi(io, mi) function show(io::IO, codeinst::Core.CodeInstance) print(io, "CodeInstance for ") - show_mi(io, codeinst.def) + def = codeinst.def + if isa(def, Core.ABIOverride) + show_mi(io, def.def) + print(io, " (ABI Overridden)") + else + show_mi(io, def::MethodInstance) + end end function show_mi(io::IO, mi::Core.MethodInstance, from_stackframe::Bool=false) @@ -3144,7 +3150,7 @@ Print to a stream `io`, or return a string `str`, giving a brief description of a value. By default returns `string(typeof(x))`, e.g. [`Int64`](@ref). For arrays, returns a string of size and type info, -e.g. `10-element Array{Int64,1}`. +e.g. `10-element Vector{Int64}` or `9×4×5 Array{Float64, 3}`. # Examples ```jldoctest @@ -3259,7 +3265,9 @@ showindices(io) = nothing function showarg(io::IO, r::ReshapedArray, toplevel) print(io, "reshape(") showarg(io, parent(r), false) - print(io, ", ", join(r.dims, ", ")) + if !isempty(r.dims) + print(io, ", ", join(r.dims, ", ")) + end print(io, ')') toplevel && print(io, " with eltype ", eltype(r)) return nothing @@ -3356,9 +3364,11 @@ function print_partition(io::IO, partition::Core.BindingPartition) end print(io, " - ") kind = binding_kind(partition) - if is_some_const_binding(kind) + if is_defined_const_binding(kind) print(io, "constant binding to ") print(io, partition_restriction(partition)) + elseif kind == BINDING_KIND_UNDEF_CONST + print(io, "undefined const binding") elseif kind == BINDING_KIND_GUARD print(io, "undefined binding - guard entry") elseif kind == BINDING_KIND_FAILED diff --git a/base/sort.jl b/base/sort.jl index 29e67a3eb8d8c..8254f56b3f952 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -4,7 +4,7 @@ module Sort using Base.Order -using Base: copymutable, midpoint, require_one_based_indexing, uinttype, +using Base: copymutable, midpoint, require_one_based_indexing, uinttype, tail, sub_with_overflow, add_with_overflow, OneTo, BitSigned, BitIntegerType, top_set_bit import Base: @@ -186,10 +186,10 @@ partialsort(v::AbstractVector, k::Union{Integer,OrdinalRange}; kws...) = function searchsortedfirst(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keytype(v) where T<:Integer hi = hi + T(1) len = hi - lo - @inbounds while len != 0 + while len != 0 half_len = len >>> 0x01 m = lo + half_len - if lt(o, v[m], x) + if lt(o, @inbounds(v[m]), x) lo = m + 1 len -= half_len + 1 else @@ -206,9 +206,9 @@ function searchsortedlast(v::AbstractVector, x, lo::T, hi::T, o::Ordering)::keyt u = T(1) lo = lo - u hi = hi + u - @inbounds while lo != hi - u + while lo != hi - u m = midpoint(lo, hi) - if lt(o, x, v[m]) + if lt(o, x, @inbounds(v[m])) hi = m else lo = m @@ -224,11 +224,11 @@ function searchsorted(v::AbstractVector, x, ilo::T, ihi::T, o::Ordering)::UnitRa u = T(1) lo = ilo - u hi = ihi + u - @inbounds while lo != hi - u + while lo != hi - u m = midpoint(lo, hi) - if lt(o, v[m], x) + if lt(o, @inbounds(v[m]), x) lo = m - elseif lt(o, x, v[m]) + elseif lt(o, x, @inbounds(v[m])) hi = m else a = searchsortedfirst(v, x, lo+u, m, o) @@ -1482,8 +1482,9 @@ InitialOptimizations(next) = SubArrayOptimization( `DefaultStable` is an algorithm which indicates that a fast, general purpose sorting algorithm should be used, but does not specify exactly which algorithm. -Currently, it is composed of two parts: the [`InitialOptimizations`](@ref) and a hybrid of -Radix, Insertion, Counting, Quick sorts. +Currently, when sorting short NTuples, this is an unrolled mergesort, and otherwise it is +composed of two parts: the [`InitialOptimizations`](@ref) and a hybrid of Radix, Insertion, +Counting, Quick sorts. We begin with MissingOptimization because it has no runtime cost when it is not triggered and can enable other optimizations to be applied later. For example, @@ -1619,6 +1620,7 @@ defalg(v::AbstractArray) = DEFAULT_STABLE defalg(v::AbstractArray{<:Union{Number, Missing}}) = DEFAULT_UNSTABLE defalg(v::AbstractArray{Missing}) = DEFAULT_UNSTABLE # for method disambiguation defalg(v::AbstractArray{Union{}}) = DEFAULT_UNSTABLE # for method disambiguation +defalg(v::NTuple) = DEFAULT_STABLE """ sort!(v; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward) @@ -1698,13 +1700,16 @@ julia> v = [(1, "c"), (3, "a"), (2, "b")]; sort!(v, by = x -> x[2]); v (2, "b") (1, "c") -julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) # same as sort(0:3, by=abs(x->x-2)) +julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) 4-element Vector{Int64}: 2 1 3 0 +julia> sort(0:3, by=x->x-2, order=Base.Order.By(abs)) == sort(0:3, by=x->abs(x-2)) +true + julia> sort([2, NaN, 1, NaN, 3]) # correct sort with default lt=isless 5-element Vector{Float64}: 1.0 @@ -1734,10 +1739,13 @@ function sort!(v::AbstractVector{T}; end """ - sort(v; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward) + sort(v::Union{AbstractVector, NTuple}; alg::Base.Sort.Algorithm=Base.Sort.defalg(v), lt=isless, by=identity, rev::Bool=false, order::Base.Order.Ordering=Base.Order.Forward) Variant of [`sort!`](@ref) that returns a sorted copy of `v` leaving `v` itself unmodified. +!!! compat "Julia 1.12" + Sorting `NTuple`s requires Julia 1.12 or later. + # Examples ```jldoctest julia> v = [3, 1, 2]; @@ -1757,6 +1765,41 @@ julia> v """ sort(v::AbstractVector; kws...) = sort!(copymutable(v); kws...) +function sort(x::NTuple; + alg::Algorithm=defalg(x), + lt=isless, + by=identity, + rev::Union{Bool,Nothing}=nothing, + order::Ordering=Forward, + scratch::Union{Vector, Nothing}=nothing) + # Can't do this check with type parameters because of https://github.com/JuliaLang/julia/issues/56698 + scratch === nothing || eltype(x) == eltype(scratch) || throw(ArgumentError("scratch has the wrong eltype")) + _sort(x, alg, ord(lt,by,rev,order), (;scratch))::typeof(x) +end +# Folks who want to hack internals can define a new _sort(x::NTuple, ::TheirAlg, o::Ordering) +# or _sort(x::NTuple{N, TheirType}, ::DefaultStable, o::Ordering) where N +function _sort(x::NTuple, a::Union{DefaultStable, DefaultUnstable}, o::Ordering, kw) + # The unrolled tuple sort is prohibitively slow to compile for length > 9. + # See https://github.com/JuliaLang/julia/pull/46104#issuecomment-1435688502 for benchmarks + if length(x) > 9 + v = copymutable(x) + _sort!(v, a, o, kw) + typeof(x)(v) + else + _mergesort(x, o) + end +end +_mergesort(x::Union{NTuple{0}, NTuple{1}}, o::Ordering) = x +function _mergesort(x::NTuple, o::Ordering) + a, b = Base.IteratorsMD.split(x, Val(length(x)>>1)) + merge(_mergesort(a, o), _mergesort(b, o), o) +end +merge(x::NTuple, y::NTuple{0}, o::Ordering) = x +merge(x::NTuple{0}, y::NTuple, o::Ordering) = y +merge(x::NTuple{0}, y::NTuple{0}, o::Ordering) = x # Method ambiguity +merge(x::NTuple, y::NTuple, o::Ordering) = + (lt(o, y[1], x[1]) ? (y[1], merge(x, tail(y), o)...) : (x[1], merge(tail(x), y, o)...)) + ## partialsortperm: the permutation to sort the first k elements of an array ## """ diff --git a/base/special/exp.jl b/base/special/exp.jl index 312197339a086..38d7509807aed 100644 --- a/base/special/exp.jl +++ b/base/special/exp.jl @@ -216,6 +216,7 @@ end small_part = muladd(jU, expm1b_kernel(base, r), jL) + jU if !(abs(x) <= SUBNORM_EXP(base, T)) + isnan(x) && return x x >= MAX_EXP(base, T) && return Inf x <= MIN_EXP(base, T) && return 0.0 if k <= -53 @@ -243,6 +244,7 @@ end hi, lo = Base.canonicalize2(1.0, kern) small_part = fma(jU, hi, muladd(jU, (lo+xlo), very_small)) if !(abs(x) <= SUBNORM_EXP(base, T)) + isnan(x) && return x x >= MAX_EXP(base, T) && return Inf x <= MIN_EXP(base, T) && return 0.0 if k <= -53 diff --git a/base/stacktraces.jl b/base/stacktraces.jl index e16757541cfc9..01e8a3cf62e72 100644 --- a/base/stacktraces.jl +++ b/base/stacktraces.jl @@ -7,7 +7,7 @@ module StackTraces import Base: hash, ==, show -import Core: CodeInfo, MethodInstance +import Core: CodeInfo, MethodInstance, CodeInstance using Base.IRShow: normalize_method_name, append_scopes!, LineInfoNode export StackTrace, StackFrame, stacktrace @@ -21,9 +21,9 @@ Stack information representing execution context, with the following fields: The name of the function containing the execution context. -- `linfo::Union{Method, Core.MethodInstance, Core.CodeInfo, Nothing}` +- `linfo::Union{Method, Core.MethodInstance, Core.CodeInstance, Core.CodeInfo, Nothing}` - The Method, MethodInstance, or CodeInfo containing the execution context (if it could be found), \ + The Method, MethodInstance, CodeInstance, or CodeInfo containing the execution context (if it could be found), \ or nothing (for example, if the inlining was a result of macro expansion). - `file::Symbol` @@ -54,9 +54,9 @@ struct StackFrame # this type should be kept platform-agnostic so that profiles file::Symbol "the line number in the file containing the execution context" line::Int - "the MethodInstance or CodeInfo containing the execution context (if it could be found), \ + "the CodeInstance or CodeInfo containing the execution context (if it could be found), \ or nothing (for example, if the inlining was a result of macro expansion)." - linfo::Union{MethodInstance, Method, CodeInfo, Nothing} + linfo::Union{Core.MethodInstance, Core.CodeInstance, Method, CodeInfo, Nothing} "true if the code is from C" from_c::Bool "true if the code is from an inlined frame" @@ -137,16 +137,26 @@ function lookup(ip::Base.InterpreterIP) line = meth.line codeinfo = meth.source else + func = top_level_scope_sym + file = empty_sym + line = Int32(0) if code isa Core.CodeInstance codeinfo = code.inferred::CodeInfo + def = code.def + if isa(def, Core.ABIOverride) + def = def.def + end + if isa(def, MethodInstance) && isa(def.def, Method) + meth = def.def + func = meth.name + file = meth.file + line = meth.line + end else codeinfo = code::CodeInfo end - func = top_level_scope_sym - file = empty_sym - line = Int32(0) end - def = (code isa MethodInstance ? code : StackTraces) # Module just used as a token for top-level code + def = (code isa CodeInfo ? StackTraces : code) # Module just used as a token for top-level code pc::Int = max(ip.stmt + 1, 0) # n.b. ip.stmt is 0-indexed scopes = LineInfoNode[] append_scopes!(scopes, pc, codeinfo.debuginfo, def) @@ -157,7 +167,7 @@ function lookup(ip::Base.InterpreterIP) scopes = map(scopes) do lno if inlined def = lno.method - def isa Union{Method,MethodInstance} || (def = nothing) + def isa Union{Method,Core.CodeInstance,MethodInstance} || (def = nothing) else def = codeinfo end @@ -227,6 +237,23 @@ end is_top_level_frame(f::StackFrame) = f.linfo isa CodeInfo || (f.linfo === nothing && f.func === top_level_scope_sym) +function frame_method_or_module(lkup::StackFrame) + code = lkup.linfo + code isa Method && return code + code isa Module && return code + mi = frame_mi(lkup) + mi isa MethodInstance || return nothing + return mi.def +end + +function frame_mi(lkup::StackFrame) + code = lkup.linfo + code isa Core.CodeInstance && (code = code.def) + code isa Core.ABIOverride && (code = code.def) + code isa MethodInstance || return nothing + return code +end + function show_spec_linfo(io::IO, frame::StackFrame) linfo = frame.linfo if linfo === nothing @@ -241,16 +268,18 @@ function show_spec_linfo(io::IO, frame::StackFrame) print(io, "top-level scope") elseif linfo isa Module Base.print_within_stacktrace(io, Base.demangle_function_name(string(frame.func)), bold=true) - elseif linfo isa MethodInstance - def = linfo.def - if def isa Module - Base.show_mi(io, linfo, #=from_stackframe=#true) + else + if linfo isa Union{MethodInstance, CodeInstance} + def = frame_method_or_module(frame) + if def isa Module + Base.show_mi(io, linfo, #=from_stackframe=#true) + else + show_spec_sig(io, def, frame_mi(frame).specTypes) + end else - show_spec_sig(io, def, linfo.specTypes) + m = linfo::Method + show_spec_sig(io, m, m.sig) end - else - m = linfo::Method - show_spec_sig(io, m, m.sig) end end @@ -302,6 +331,12 @@ end function Base.parentmodule(frame::StackFrame) linfo = frame.linfo + if linfo isa CodeInstance + linfo = linfo.def + if isa(linfo, Core.ABIOverride) + linfo = linfo.def + end + end if linfo isa MethodInstance def = linfo.def if def isa Module 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/base/stream.jl b/base/stream.jl index 488acd41d2a9e..e81f65685df72 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -76,7 +76,7 @@ function getproperty(stream::LibuvStream, name::Symbol) end # IO -# +- GenericIOBuffer{T<:AbstractArray{UInt8,1}} (not exported) +# +- GenericIOBuffer{T<:AbstractVector{UInt8}} (not exported) # +- AbstractPipe (not exported) # . +- Pipe # . +- Process (not exported) @@ -89,7 +89,7 @@ end # . +- TTY (not exported) # . +- UDPSocket # . +- BufferStream (FIXME: 2.0) -# +- IOBuffer = Base.GenericIOBuffer{Array{UInt8,1}} +# +- IOBuffer = Base.GenericIOBuffer{Vector{UInt8}} # +- IOStream # IOServer diff --git a/base/strings/io.jl b/base/strings/io.jl index 116bcf71eeb7a..b4a3c7ad3e0c2 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -250,7 +250,9 @@ print(io::IO, s::Union{String,SubString{String}}) = (write(io, s); nothing) """ repr(x; context=nothing) -Create a string from any value using the 2-argument `show(io, x)` function. +Create a string representation of any value using the 2-argument `show(io, x)` function, +which aims to produce a string that is parseable Julia code, where possible. +i.e. `eval(Meta.parse(repr(x))) == x` should hold true. You should not add methods to `repr`; define a [`show`](@ref) method instead. The optional keyword argument `context` can be set to a `:key=>value` pair, a 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) diff --git a/base/strings/util.jl b/base/strings/util.jl index 1b73fbbbab5cf..87c2abab5344c 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -100,7 +100,6 @@ Base.startswith(io::IO, prefix::AbstractString) = startswith(io, String(prefix)) function endswith(a::Union{String, SubString{String}}, b::Union{String, SubString{String}}) - cub = ncodeunits(b) astart = ncodeunits(a) - ncodeunits(b) + 1 if astart < 1 false 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/base/sysimg.jl b/base/sysimg.jl index e57ec1c99bfe6..42f54a849f157 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -# Can be be loaded on top of either an existing system image built from +# Can be loaded on top of either an existing system image built from # `Base_compiler.jl` or standalone, in which case we will build it now. let had_compiler = isdefined(Main, :Base) if had_compiler; else 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/base/threadingconstructs.jl b/base/threadingconstructs.jl index 07ff814af1570..3d86e203ef72e 100644 --- a/base/threadingconstructs.jl +++ b/base/threadingconstructs.jl @@ -3,7 +3,7 @@ export threadid, nthreads, @threads, @spawn, threadpool, nthreadpools -public Condition +public Condition, threadpoolsize, ngcthreads """ Threads.threadid([t::Task]) -> Int diff --git a/base/timing.jl b/base/timing.jl index 1de3727756829..65c2a643d6a52 100644 --- a/base/timing.jl +++ b/base/timing.jl @@ -24,6 +24,9 @@ struct GC_Num mark_time ::Int64 stack_pool_sweep_time ::Int64 total_sweep_time ::Int64 + total_sweep_page_walk_time ::Int64 + total_sweep_madvise_time ::Int64 + total_sweep_free_mallocd_memory_time ::Int64 total_mark_time ::Int64 total_stack_pool_sweep_time::Int64 last_full_sweep ::Int64 @@ -106,9 +109,14 @@ function gc_page_utilization_data() return Base.unsafe_wrap(Array, page_utilization_raw, JL_GC_N_MAX_POOLS, own=false) end + +const USING_STOCK_GC = occursin("stock", unsafe_string(ccall(:jl_gc_active_impl, Ptr{UInt8}, ()))) +# Full sweep reasons are currently only available for the stock GC +@static if USING_STOCK_GC # must be kept in sync with `src/gc-stock.h`` const FULL_SWEEP_REASONS = [:FULL_SWEEP_REASON_SWEEP_ALWAYS_FULL, :FULL_SWEEP_REASON_FORCED_FULL_SWEEP, :FULL_SWEEP_REASON_USER_MAX_EXCEEDED, :FULL_SWEEP_REASON_LARGE_PROMOTION_RATE] +end """ Base.full_sweep_reasons() @@ -124,11 +132,15 @@ The reasons are: Note that the set of reasons is not guaranteed to be stable across minor versions of Julia. """ function full_sweep_reasons() - reason = cglobal(:jl_full_sweep_reasons, UInt64) - reasons_as_array = Base.unsafe_wrap(Vector{UInt64}, reason, length(FULL_SWEEP_REASONS), own=false) d = Dict{Symbol, Int64}() - for (i, r) in enumerate(FULL_SWEEP_REASONS) - d[r] = reasons_as_array[i] + # populate the dictionary according to the reasons above for the stock GC + # otherwise return an empty dictionary for now + @static if USING_STOCK_GC + reason = cglobal(:jl_full_sweep_reasons, UInt64) + reasons_as_array = Base.unsafe_wrap(Vector{UInt64}, reason, length(FULL_SWEEP_REASONS), own=false) + for (i, r) in enumerate(FULL_SWEEP_REASONS) + d[r] = reasons_as_array[i] + end end return d end diff --git a/contrib/generate_precompile.jl b/contrib/generate_precompile.jl index ffbbfd620997f..b075223d9c7e4 100644 --- a/contrib/generate_precompile.jl +++ b/contrib/generate_precompile.jl @@ -136,60 +136,56 @@ for match = Base._methods(+, (Int, Int), -1, Base.get_world_counter()) m = match.method delete!(push!(Set{Method}(), m), m) copy(Core.Compiler.retrieve_code_info(Core.Compiler.specialize_method(match), typemax(UInt))) - - empty!(Set()) - push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two)) - (setindex!(Dict{String,Base.PkgId}(), Base.PkgId(Base), "file.jl"))["file.jl"] - (setindex!(Dict{Symbol,Vector{Int}}(), [1], :two))[:two] - (setindex!(Dict{Base.PkgId,String}(), "file.jl", Base.PkgId(Base)))[Base.PkgId(Base)] - (setindex!(Dict{Union{GlobalRef,Symbol}, Vector{Int}}(), [1], :two))[:two] - (setindex!(IdDict{Type, Union{Missing, Vector{Tuple{LineNumberNode, Expr}}}}(), missing, Int))[Int] - Dict{Symbol, Union{Nothing, Bool, Symbol}}(:one => false)[:one] - Dict(Base => [:(1+1)])[Base] - Dict(:one => [1])[:one] - Dict("abc" => Set())["abc"] - pushfirst!([], sum) - get(Base.pkgorigins, Base.PkgId(Base), nothing) - sort!([1,2,3]) - unique!([1,2,3]) - cumsum([1,2,3]) - append!(Int[], BitSet()) - isempty(BitSet()) - delete!(BitSet([1,2]), 3) - deleteat!(Int32[1,2,3], [1,3]) - deleteat!(Any[1,2,3], [1,3]) - Core.svec(1, 2) == Core.svec(3, 4) - any(t->t[1].line > 1, [(LineNumberNode(2,:none), :(1+1))]) - - # Code loading uses this - sortperm(mtime.(readdir(".")), rev=true) - # JLLWrappers uses these - Dict{Base.UUID,Set{String}}()[Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")] = Set{String}() - get!(Set{String}, Dict{Base.UUID,Set{String}}(), Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")) - eachindex(IndexLinear(), Expr[]) - push!(Expr[], Expr(:return, false)) - vcat(String[], String[]) - k, v = (:hello => nothing) - Base.print_time_imports_report(Base) - Base.print_time_imports_report_init(Base) - - # Preferences uses these - get(Dict{String,Any}(), "missing", nothing) - delete!(Dict{String,Any}(), "missing") - for (k, v) in Dict{String,Any}() - println(k) - end - - # interactive startup uses this - write(IOBuffer(), "") - - # Not critical, but helps hide unrelated compilation from @time when using --trace-compile. - f55729() = Base.Experimental.@force_compile - @time @eval f55729() - @time @eval f55729() - break # only actually need to do this once end +empty!(Set()) +push!(push!(Set{Union{GlobalRef,Symbol}}(), :two), GlobalRef(Base, :two)) +(setindex!(Dict{String,Base.PkgId}(), Base.PkgId(Base), "file.jl"))["file.jl"] +(setindex!(Dict{Symbol,Vector{Int}}(), [1], :two))[:two] +(setindex!(Dict{Base.PkgId,String}(), "file.jl", Base.PkgId(Base)))[Base.PkgId(Base)] +(setindex!(Dict{Union{GlobalRef,Symbol}, Vector{Int}}(), [1], :two))[:two] +(setindex!(IdDict{Type, Union{Missing, Vector{Tuple{LineNumberNode, Expr}}}}(), missing, Int))[Int] +Dict{Symbol, Union{Nothing, Bool, Symbol}}(:one => false)[:one] +Dict(Base => [:(1+1)])[Base] +Dict(:one => [1])[:one] +Dict("abc" => Set())["abc"] +pushfirst!([], sum) +get(Base.pkgorigins, Base.PkgId(Base), nothing) +sort!([1,2,3]) +unique!([1,2,3]) +cumsum([1,2,3]) +append!(Int[], BitSet()) +isempty(BitSet()) +delete!(BitSet([1,2]), 3) +deleteat!(Int32[1,2,3], [1,3]) +deleteat!(Any[1,2,3], [1,3]) +Core.svec(1, 2) == Core.svec(3, 4) +any(t->t[1].line > 1, [(LineNumberNode(2,:none), :(1+1))]) + +# Code loading uses this +sortperm(mtime.(readdir(".")), rev=true) +# JLLWrappers uses these +Dict{Base.UUID,Set{String}}()[Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")] = Set{String}() +get!(Set{String}, Dict{Base.UUID,Set{String}}(), Base.UUID("692b3bcd-3c85-4b1f-b108-f13ce0eb3210")) +eachindex(IndexLinear(), Expr[]) +push!(Expr[], Expr(:return, false)) +vcat(String[], String[]) +k, v = (:hello => nothing) +Base.print_time_imports_report(Base) +Base.print_time_imports_report_init(Base) + +# Preferences uses these +get(Dict{String,Any}(), "missing", nothing) +delete!(Dict{String,Any}(), "missing") +for (k, v) in Dict{String,Any}() + println(k) +end + +# interactive startup uses this +write(IOBuffer(), "") + +# precompile @time report generation and printing +@time @eval Base.Experimental.@force_compile """ julia_exepath() = joinpath(Sys.BINDIR, Base.julia_exename()) diff --git a/contrib/refresh_checksums.mk b/contrib/refresh_checksums.mk index e7bf2fd7c2efc..5a787b0b67cb1 100644 --- a/contrib/refresh_checksums.mk +++ b/contrib/refresh_checksums.mk @@ -19,12 +19,12 @@ all: checksum pack-checksum # Get this list via: # using BinaryBuilder # print("TRIPLETS=\"$(join(sort(triplet.(BinaryBuilder.supported_platforms(;experimental=true))), " "))\"") -TRIPLETS=aarch64-apple-darwin aarch64-linux-gnu aarch64-linux-musl aarch64-unknown-freebsd armv6l-linux-gnueabihf armv6l-linux-musleabihf armv7l-linux-gnueabihf armv7l-linux-musleabihf i686-linux-gnu i686-linux-musl i686-w64-mingw32 powerpc64le-linux-gnu x86_64-apple-darwin x86_64-linux-gnu x86_64-linux-musl x86_64-unknown-freebsd x86_64-w64-mingw32 +TRIPLETS=aarch64-apple-darwin aarch64-linux-gnu aarch64-linux-musl aarch64-unknown-freebsd armv6l-linux-gnueabihf armv6l-linux-musleabihf armv7l-linux-gnueabihf armv7l-linux-musleabihf i686-linux-gnu i686-linux-musl i686-w64-mingw32 powerpc64le-linux-gnu riscv64-linux-gnu x86_64-apple-darwin x86_64-linux-gnu x86_64-linux-musl x86_64-unknown-freebsd x86_64-w64-mingw32 CLANG_TRIPLETS=$(filter %-darwin %-freebsd,$(TRIPLETS)) NON_CLANG_TRIPLETS=$(filter-out %-darwin %-freebsd,$(TRIPLETS)) # These are the projects currently using BinaryBuilder; both GCC-expanded and non-GCC-expanded: -BB_PROJECTS=mbedtls libssh2 nghttp2 mpfr curl libgit2 pcre libuv unwind llvmunwind dsfmt objconv p7zip zlib libsuitesparse openlibm blastrampoline libtracyclient +BB_PROJECTS=openssl libssh2 nghttp2 mpfr curl libgit2 pcre libuv unwind llvmunwind dsfmt objconv p7zip zlib libsuitesparse openlibm blastrampoline libtracyclient BB_GCC_EXPANDED_PROJECTS=openblas csl BB_CXX_EXPANDED_PROJECTS=gmp llvm clang llvm-tools lld # These are non-BB source-only deps diff --git a/deps/JuliaSyntax.version b/deps/JuliaSyntax.version index 7f124715024ce..86f94135884a0 100644 --- a/deps/JuliaSyntax.version +++ b/deps/JuliaSyntax.version @@ -1,4 +1,4 @@ JULIASYNTAX_BRANCH = main -JULIASYNTAX_SHA1 = 4f1731d6ce7c2465fc21ea245110b7a39f34658a +JULIASYNTAX_SHA1 = dfd1d69b153eb119873035e62993a109b27192f0 JULIASYNTAX_GIT_URL := https://github.com/JuliaLang/JuliaSyntax.jl.git JULIASYNTAX_TAR_URL = https://api.github.com/repos/JuliaLang/JuliaSyntax.jl/tarball/$1 diff --git a/deps/Makefile b/deps/Makefile index b87a3e1e58609..396b1021c2ddd 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -22,11 +22,11 @@ BUILDDIR := $(BUILDDIR)$(MAYBE_HOST) # additionally all targets should be listed in the getall target for easier off-line compilation # if you are adding a new target, it can help to copy an similar, existing target # -# autoconf configure-driven scripts: pcre unwind gmp mpfr patchelf libuv curl +# autoconf configure-driven scripts: pcre unwind gmp mpfr patchelf libuv curl openssl # custom Makefile rules: openlibm dsfmt libsuitesparse lapack blastrampoline openblas utf8proc objconv libwhich -# CMake libs: llvm llvmunwind libgit2 libssh2 mbedtls libtracyclient +# CMake libs: llvm llvmunwind libgit2 libssh2 libtracyclient # -# downloadable via git: llvm-svn, libuv, libopenlibm, utf8proc, libgit2, libssh2, libtracyclient +# downloadable via git: llvm-svn, libuv, libopenlibm, utf8proc, libgit2, libssh2, libtracyclient, mmtk_julia # # to debug 'define' rules, replace eval at the usage site with info or error @@ -119,8 +119,8 @@ ifeq ($(USE_SYSTEM_GMP), 0) DEP_LIBS += gmp endif -ifeq ($(USE_SYSTEM_MBEDTLS), 0) -DEP_LIBS += mbedtls +ifeq ($(USE_SYSTEM_OPENSSL), 0) +DEP_LIBS += openssl endif ifeq ($(USE_SYSTEM_LIBSSH2), 0) @@ -195,14 +195,18 @@ DEP_LIBS += libwhich endif endif +ifneq (${MMTK_PLAN},None) +DEP_LIBS += mmtk_julia +endif + DEP_LIBS_STAGED := $(DEP_LIBS) # list all targets DEP_LIBS_STAGED_ALL := llvm llvm-tools clang llvmunwind unwind libuv pcre \ openlibm dsfmt blastrampoline openblas lapack gmp mpfr patchelf utf8proc \ - objconv mbedtls libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \ + objconv openssl libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \ sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax \ - terminfo + terminfo mmtk_julia DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL) ifneq ($(USE_BINARYBUILDER_OPENBLAS),0) @@ -256,7 +260,7 @@ include $(SRCDIR)/unwind.mk include $(SRCDIR)/gmp.mk include $(SRCDIR)/mpfr.mk include $(SRCDIR)/patchelf.mk -include $(SRCDIR)/mbedtls.mk +include $(SRCDIR)/openssl.mk include $(SRCDIR)/libssh2.mk include $(SRCDIR)/nghttp2.mk include $(SRCDIR)/curl.mk @@ -266,6 +270,9 @@ include $(SRCDIR)/p7zip.mk include $(SRCDIR)/libtracyclient.mk include $(SRCDIR)/terminfo.mk +# MMTk +include $(SRCDIR)/mmtk_julia.mk + # vendored Julia libs include $(SRCDIR)/JuliaSyntax.mk diff --git a/deps/blastrampoline.version b/deps/blastrampoline.version index 7e6dc61d1cbe7..1e4a75305a4dd 100644 --- a/deps/blastrampoline.version +++ b/deps/blastrampoline.version @@ -1,7 +1,9 @@ +# -*- makefile -*- + ## jll artifact BLASTRAMPOLINE_JLL_NAME := libblastrampoline ## source build -BLASTRAMPOLINE_VER := 5.11.2 -BLASTRAMPOLINE_BRANCH=v5.11.2 -BLASTRAMPOLINE_SHA1=c48da8a1225c2537ff311c28ef395152fb879eae +BLASTRAMPOLINE_VER := 5.12.0 +BLASTRAMPOLINE_BRANCH=v5.12.0 +BLASTRAMPOLINE_SHA1=b127bc8dd4758ffc064340fff2aef4ead552f386 diff --git a/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/md5 b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/md5 new file mode 100644 index 0000000000000..e172379604478 --- /dev/null +++ b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/md5 @@ -0,0 +1 @@ +d3209f45b8ea01a22ac7e9b265e3b84f diff --git a/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/sha512 b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/sha512 new file mode 100644 index 0000000000000..991a457654113 --- /dev/null +++ b/deps/checksums/ArgTools-1314758ad02ff5e9e5ca718920c6c633b467a84a.tar.gz/sha512 @@ -0,0 +1 @@ +314981eee11356f14b6dc9e07389c51432e7862d6c767d87d6679385f5a36faef34902954a5dfa6b37d8f3f25eaa4f23ba9431cc78acd3513377955e7d73f210 diff --git a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/md5 b/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/md5 deleted file mode 100644 index 3e85638390011..0000000000000 --- a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -44175a2843f243a8f2e01cd1e781ecc9 diff --git a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/sha512 b/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/sha512 deleted file mode 100644 index f5690055f63f4..0000000000000 --- a/deps/checksums/ArgTools-997089b9cd56404b40ff766759662e16dc1aab4b.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -8a9d0f20cd8fa0ed072966debc691597bb09b34836465f52595b9b2525e80b194c7176781495573dd2f9a02b142e832e59f0dccef15afa184543775d58dc7987 diff --git a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/md5 b/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/md5 deleted file mode 100644 index 9904464c82b3b..0000000000000 --- a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -390521058a478a131ca49d349c9b9383 diff --git a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/sha512 b/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/sha512 deleted file mode 100644 index a7fbe055c2251..0000000000000 --- a/deps/checksums/Distributed-6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -7f0f414d94739a25b7d713c46887e26cd349329828d42297f44928204b36d15ba9163ad6f670aba72ed9229557bb0f35ab4686429975d1f349fe12b1ba2b189f diff --git a/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/md5 b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/md5 new file mode 100644 index 0000000000000..e1c0f9e87b7c7 --- /dev/null +++ b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/md5 @@ -0,0 +1 @@ +98b8b8bc0ea4bf24c4b2986a5b7ae3e9 diff --git a/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/sha512 b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/sha512 new file mode 100644 index 0000000000000..ed816ebc21e97 --- /dev/null +++ b/deps/checksums/Distributed-c6136853451677f1957bec20ecce13419cde3a12.tar.gz/sha512 @@ -0,0 +1 @@ +4043933825bf716f2733f8e90632de34a95a437f3b31cda92edd510ffee208f8e374ec3c5922c8142342ae21b4ec4cbd1ecd4036b9057056a12c86169632ac7b diff --git a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/md5 b/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/md5 deleted file mode 100644 index 611f3dd448d98..0000000000000 --- a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -2472bd6434d21c4b3e3199437e6fdcf7 diff --git a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/sha512 b/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/sha512 deleted file mode 100644 index 6937982e838f3..0000000000000 --- a/deps/checksums/Downloads-89d3c7dded535a77551e763a437a6d31e4d9bf84.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -0a3fa9a09de81aa9676dbc7448408c7503f45e42519a2667540ad890316c7da089c95de5464a2032171f963c6f3cba73d6b3c246f1c7ac6ede283fc8132d5209 diff --git a/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/md5 b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/md5 new file mode 100644 index 0000000000000..221a62b1cf231 --- /dev/null +++ b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/md5 @@ -0,0 +1 @@ +cdaea923f7fa855409e8456159251f54 diff --git a/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/sha512 b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/sha512 new file mode 100644 index 0000000000000..b537ef2e9e1f6 --- /dev/null +++ b/deps/checksums/Downloads-e692e77fb5427bf3c6e81514b323c39a88217eec.tar.gz/sha512 @@ -0,0 +1 @@ +e893fbe079a433c3038b79c4c2998d1ae9abaf92ff74152820a67e97ffee6f7f052085a7108410cbb1a3bd8cc6670736b0827c8b0608cc31941251dd6500d36a diff --git a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/md5 b/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/md5 deleted file mode 100644 index c2663955ec773..0000000000000 --- a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -8c9d9579eeab1ba40f978a32c9db9900 diff --git a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/sha512 b/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/sha512 deleted file mode 100644 index 46647cb3e432b..0000000000000 --- a/deps/checksums/JuliaSyntax-4f1731d6ce7c2465fc21ea245110b7a39f34658a.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -1bdad624f61482b55deba8727fea1c087bfaea9e1f8afa3b44b984441fb7e663dac067baa4a96ae2d4cbd4a46ae8c87e9d20d2dfcd17046ad194711304184e57 diff --git a/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/md5 b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/md5 new file mode 100644 index 0000000000000..51b30461d3905 --- /dev/null +++ b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/md5 @@ -0,0 +1 @@ +e58559668aabb0fa96d598970c4d648e diff --git a/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/sha512 b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/sha512 new file mode 100644 index 0000000000000..63a513ec9ae63 --- /dev/null +++ b/deps/checksums/JuliaSyntax-dfd1d69b153eb119873035e62993a109b27192f0.tar.gz/sha512 @@ -0,0 +1 @@ +59e22f7db63a383beadf96a68d4db6ae173d61be6d766ea1792b3a3bd70125f73dd4df9e55bad4c66363aa0b6ff6ea5259d3c91abf42f5fe34446e3fa076cc87 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/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/md5 b/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/md5 deleted file mode 100644 index 4d14c85460418..0000000000000 --- a/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -8355c253fadfc3f9222e05cb67845dd6 diff --git a/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/sha512 b/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/sha512 deleted file mode 100644 index d44f215e67673..0000000000000 --- a/deps/checksums/LazyArtifacts-e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -6d965199ed02446e694789a38f05249ff60ac00f8295fe32bf91a79cca34649829e38eaf46cc0b0b72ff2df7e184c2eaeb610600ebb5158251b331c61e9dfc5d diff --git a/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/md5 b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/md5 new file mode 100644 index 0000000000000..5bd44506fd874 --- /dev/null +++ b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/md5 @@ -0,0 +1 @@ +eb4df255412ad9a05b807010f626afc8 diff --git a/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/sha512 b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/sha512 new file mode 100644 index 0000000000000..23617698dd26e --- /dev/null +++ b/deps/checksums/LinearAlgebra-1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8.tar.gz/sha512 @@ -0,0 +1 @@ +3b4bf7b761d9585fb2d5c5b8418770be4d1d4399a5f25dd5b2e08785506f0732c8e140ada6f82f6d8a7a77a2c2f79e2feecd6eb0e19eda0c3ee519ba554c19ec diff --git a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/md5 b/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/md5 deleted file mode 100644 index e240a1083833c..0000000000000 --- a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -00198e6d92d033fb33e75cf4eac34dca diff --git a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/sha512 b/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/sha512 deleted file mode 100644 index 5eeceaf1dbed3..0000000000000 --- a/deps/checksums/LinearAlgebra-56d561c22e1ab8e0421160edbdd42f3f194ecfa8.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -ba4b390d99644c31d64594352da888e9ef18021cc9b7700c37a6cdb0c1ff2532eb208ecaccf93217e3183e1db8e6c089456fa5d93633b8ff037e8796199934e7 diff --git a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/md5 b/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/md5 deleted file mode 100644 index 7f391aac1e64d..0000000000000 --- a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -d2ccb9b91b0700bfb5ac7c01a03b4322 diff --git a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/sha512 b/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/sha512 deleted file mode 100644 index b7db226225d75..0000000000000 --- a/deps/checksums/NetworkOptions-8eec5cb0acec4591e6db3c017f7499426cd8e352.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -051223ab45dce692c0bbea0755cc0057bb3322a40659c092007799932a10cc23e80ee6b88fa0d86f28af5e7fe5a455cc9fb8267c76af0cd2b425cf2718629e91 diff --git a/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/md5 b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/md5 new file mode 100644 index 0000000000000..87111ac121562 --- /dev/null +++ b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/md5 @@ -0,0 +1 @@ +b851cab503506c37af6e4c861d81b8ce diff --git a/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/sha512 b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/sha512 new file mode 100644 index 0000000000000..79f9e269ff599 --- /dev/null +++ b/deps/checksums/NetworkOptions-c090626d3feee6d6a5c476346d22d6147c9c6d2d.tar.gz/sha512 @@ -0,0 +1 @@ +4cba5c531e5e7205bb6d7f0179da8b29ca7c4dcf42f27de5f70be7674efc1fa92ea22e134e6584743e2905edbd754838d8a02f6ba7811c7a5b99ab9db3bde596 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/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 deleted file mode 100644 index f5f87b3f2fa9e..0000000000000 --- a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -1a5c995237815e0d7d5ee1ec50006c1c diff --git a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 b/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 deleted file mode 100644 index 839cd4704a135..0000000000000 --- a/deps/checksums/Pkg-d84a1a38b6466fa7400e9ad2874a0ef963a10456.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -2e0b984c8272fe4468e0b527698a58d5010ef3f18d38d862665902e5a0e0b7ba65d3085b3d9de367a7b48a216e71d1611687804254503b3905b7b4d217a00f2f 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-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 b/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 deleted file mode 100644 index 3b51189e187a3..0000000000000 --- a/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -dec1d21e890c88e57a0d4eb085633d57 diff --git a/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 b/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 deleted file mode 100644 index cbe1ff2eea29e..0000000000000 --- a/deps/checksums/SHA-aaf2df61ff8c3898196587a375d3cf213bd40b41.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -fb611794a539c6725000ff6eda13e0af5dd3f82e22466bdff650ffa0e4edbba5ac4707195035531645a4161ecbb5f873f4f6b1040ce33e9b1adf9c1d34187718 diff --git a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/md5 b/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/md5 deleted file mode 100644 index 41d78a15f2ddb..0000000000000 --- a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -a643f01ee101a274d86d6469dd6a9d48 diff --git a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/sha512 b/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/sha512 deleted file mode 100644 index 1868f9a865af5..0000000000000 --- a/deps/checksums/SparseArrays-1b4933ccc7b1f97427ff88bd7ba58950021f2c60.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -09a86606b28b17f1066d608374f4f8b2fcdcd17d08a8fa37b08edea7b27a9e6becadc8e8e93b1dcc1477dc247255d6a8ded4f8e678f46d80c9fd0ad72a7f3973 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/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/md5 b/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/md5 deleted file mode 100644 index 9ba42f555d535..0000000000000 --- a/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -01b84d67052d1558e51619d5159e7a8b diff --git a/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/sha512 b/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/sha512 deleted file mode 100644 index 31c9c6ca42cec..0000000000000 --- a/deps/checksums/Statistics-68869af06e8cdeb7aba1d5259de602da7328057f.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -6ab55ba6f93d2e8b34b19f53cb51a4bfc97b336d451b98f7b95ff81f04fee4fb90a2e4d04aa4bbf3ccffc99c36d9c82c9d00dbae283474308de4a27a91c2e0b7 diff --git a/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/md5 b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/md5 new file mode 100644 index 0000000000000..3956c67f7fd47 --- /dev/null +++ b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/md5 @@ -0,0 +1 @@ +acf2bb0ea30132602e172e2f5f6274b4 diff --git a/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/sha512 b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/sha512 new file mode 100644 index 0000000000000..051f2d0a862c3 --- /dev/null +++ b/deps/checksums/Statistics-d49c2bf4f81e1efb4980a35fe39c815ef8396297.tar.gz/sha512 @@ -0,0 +1 @@ +5e879fe79bae19b62f81659a102602271c73a424faf4be069ab31fb50e30b536a8c7b3692127763000cc1dbab69c93ac3da7bace5f093d05dce2d652fb221d52 diff --git a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/md5 b/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/md5 deleted file mode 100644 index 8d78dd7b0a11b..0000000000000 --- a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -f053c84279a8920f355f202e605842af diff --git a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/sha512 b/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/sha512 deleted file mode 100644 index 5a8ca888c38f8..0000000000000 --- a/deps/checksums/StyledStrings-056e843b2d428bb9735b03af0cff97e738ac7e14.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -b6f4c1d6c0dc73a520472746c96adff506e5405154e4b93d419e07b577b01804d2fc87d4a6cac48a136777579bebf8388c2c1e54f849b51e233138d482146b4f diff --git a/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/md5 b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/md5 new file mode 100644 index 0000000000000..0fd8e8966e068 --- /dev/null +++ b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/md5 @@ -0,0 +1 @@ +411277f3701cc3e286ec8a84ccdf6f11 diff --git a/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/sha512 b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/sha512 new file mode 100644 index 0000000000000..0b495aefef55d --- /dev/null +++ b/deps/checksums/StyledStrings-8985a37ac054c37d084a03ad2837208244824877.tar.gz/sha512 @@ -0,0 +1 @@ +95a7e92389f6fd02d3bec17ec0201ba41316aa2d7c321b14af88ccce8246fd0000ed2c0cc818f87cb81f7134304233db897f656426a00caac1bc7635056260c2 diff --git a/deps/checksums/blastrampoline b/deps/checksums/blastrampoline index 987d4662e6cc7..9e007f6055cf9 100644 --- a/deps/checksums/blastrampoline +++ b/deps/checksums/blastrampoline @@ -1,36 +1,38 @@ -blastrampoline-c48da8a1225c2537ff311c28ef395152fb879eae.tar.gz/md5/0747a7c65427a5e6ff4820ea1079f095 -blastrampoline-c48da8a1225c2537ff311c28ef395152fb879eae.tar.gz/sha512/8d5c60ce84ae42e529506821b051e043c0d8861cd7e39780ebc858c2b8638d6628b2f9ceffd67c9ee18983c9c7e5a454f65cf14fb414907c28c90eb67e7de8fe -libblastrampoline.v5.11.2+0.aarch64-apple-darwin.tar.gz/md5/c0f71f80654d6025e29e763f7bf2de92 -libblastrampoline.v5.11.2+0.aarch64-apple-darwin.tar.gz/sha512/49a7f8f2aac286763d7ce2c086b60b84e9ed7eb9dbbd8ba00c5956840ea6c642f4b1d80cb69888045dfdce55dcde1ee2843df9fa63947d3ce8615faf1523a902 -libblastrampoline.v5.11.2+0.aarch64-linux-gnu.tar.gz/md5/7e9b45c623aa527d65f85edff7d056dd -libblastrampoline.v5.11.2+0.aarch64-linux-gnu.tar.gz/sha512/f41378f63a6513ca9b25febb8c01257711cd34e86303a081865696adadc41db5e39c1fd1fdf50ff1ea5d3224fe22ea7f8e571dc7001ee8708be2a27d41410eb5 -libblastrampoline.v5.11.2+0.aarch64-linux-musl.tar.gz/md5/1a2b0eafdaedc1870508948f4a8fd6d8 -libblastrampoline.v5.11.2+0.aarch64-linux-musl.tar.gz/sha512/5d9c8cce5a0abfa10b2907d9b44ad62e62cd9cd7c4c94c14b0ae93f83adff7c1c9f386c1b82dbc2f8f1f959c86c724663ae5dfdbcdd081cebcbf8a91be87da7b -libblastrampoline.v5.11.2+0.aarch64-unknown-freebsd.tar.gz/md5/3c518305add0202d56798c30cbd04345 -libblastrampoline.v5.11.2+0.aarch64-unknown-freebsd.tar.gz/sha512/ac292d999cd258052a95dd641bd06d22db3e6c0574077e9aecb63dca70c1810395921d9bc939a629cf38ece16de42d541dd03aef84d53cc6bd7b7d65bb743b66 -libblastrampoline.v5.11.2+0.armv6l-linux-gnueabihf.tar.gz/md5/fd47f376283002dc6821c4dac0127198 -libblastrampoline.v5.11.2+0.armv6l-linux-gnueabihf.tar.gz/sha512/e56b3e5b5f0bf2b3138484a49a922cb82608152de7dd972c52294eb8611cb76b95b06f33a1dc38f00dd02702ca1ef9b6f69572349b185695a55b269b91cf231f -libblastrampoline.v5.11.2+0.armv6l-linux-musleabihf.tar.gz/md5/70222a8dd72f03888401a2d0cf5a206c -libblastrampoline.v5.11.2+0.armv6l-linux-musleabihf.tar.gz/sha512/609894123a512831c9159312ea5f496de9361c60a838f9428ea5dc6aa9aa6bbb2b33856bf08868765e9af2548d8d386389747254d87d7ed403e492259d61ce32 -libblastrampoline.v5.11.2+0.armv7l-linux-gnueabihf.tar.gz/md5/966dfbf17d7eac1ff046b935e8202e7a -libblastrampoline.v5.11.2+0.armv7l-linux-gnueabihf.tar.gz/sha512/de173d9c17970bff612e1759dbcd9188f0bca0dffd21e0a98d2ed5b72a5ba60cc0097cec1e42cb2bc42f14c1c0bed3987b5bd4a04c7991c9e8d908f2aed231cd -libblastrampoline.v5.11.2+0.armv7l-linux-musleabihf.tar.gz/md5/90b43518c75e0071e4b2efe3aef344ec -libblastrampoline.v5.11.2+0.armv7l-linux-musleabihf.tar.gz/sha512/2bbb2676b381e588e6315576ed9a1d4cad4612aa6c1b5ec95fdd8434f0f0fcb07cc0b61162c0a1dac72217a008f01702f5bf63566a007622d7a3ab35461b6645 -libblastrampoline.v5.11.2+0.i686-linux-gnu.tar.gz/md5/ecf7b2fcdf8feb2114525290d09b99c7 -libblastrampoline.v5.11.2+0.i686-linux-gnu.tar.gz/sha512/10922aa2e567f1534340ec9422516ccf0ea625ae73a433ed864dc72926235fe1dc6c52c2ca716aca5eeac80544a99e76892a0f19fccd2c2b9103332fd2289980 -libblastrampoline.v5.11.2+0.i686-linux-musl.tar.gz/md5/6cf17a410bf50b3a87b9f2af0c6955e9 -libblastrampoline.v5.11.2+0.i686-linux-musl.tar.gz/sha512/30f78dd4948b26b14d04cf5e1821a381e9d8aa67c6b3547cf45a0d53a469829a98d7d47722c542699e65e1ae3411a86da094d8b354821ece1562288fa523b1f1 -libblastrampoline.v5.11.2+0.i686-w64-mingw32.tar.gz/md5/9c4c1fa7410f9e53687dbde1479deb3a -libblastrampoline.v5.11.2+0.i686-w64-mingw32.tar.gz/sha512/511eed07956b16555ab236905fe91c584d870e45d1a6b736b3b564f84ec66e8c12d9561efabad259ddc65b8965eb4cdc29b079d0a9a6a465b424b503399eae7b -libblastrampoline.v5.11.2+0.powerpc64le-linux-gnu.tar.gz/md5/816ee59bf7cc937399c273709882369b -libblastrampoline.v5.11.2+0.powerpc64le-linux-gnu.tar.gz/sha512/4e1095288ff02a9e0714f982be16782271643c1844100b38d5fcf02c2e2f62d0635457d52dd120792a59a62b905c60aa7e253a89c2f759d98c33d617c89e897f -libblastrampoline.v5.11.2+0.x86_64-apple-darwin.tar.gz/md5/9a4a86a441aa232e12e85bbf6e62f589 -libblastrampoline.v5.11.2+0.x86_64-apple-darwin.tar.gz/sha512/2d80b4c9149b8d62ae89fa3be32ccb297e815c9cd56b3481482c5f6ee253fc845d410807e099f4c1814a77e397c04511ebabc9d82352fc43ebe81a3306819ccc -libblastrampoline.v5.11.2+0.x86_64-linux-gnu.tar.gz/md5/45fbfd0422131044fff9ed44d12f13e1 -libblastrampoline.v5.11.2+0.x86_64-linux-gnu.tar.gz/sha512/c7e4f87aa0ab403be46b81967d40ebd4bd4b32af93a325cb16f64593c2261a365be3f338195cdfeada0cb6ecab8e33e4be1b380596ff0bb1c4a7b5e6aac3dccc -libblastrampoline.v5.11.2+0.x86_64-linux-musl.tar.gz/md5/161816fa857775d78bc671c444846844 -libblastrampoline.v5.11.2+0.x86_64-linux-musl.tar.gz/sha512/ba0ab54a9ccfb451b7b8fe46b2bd8e8a8135d2e1f2a896bfdf4bcc6e82812f56d93ef1e7b85671e58d388afe2876d79affdf59bfe7b1db5b76412008303a121e -libblastrampoline.v5.11.2+0.x86_64-unknown-freebsd.tar.gz/md5/aeaab847455f5a43c434155b09107cde -libblastrampoline.v5.11.2+0.x86_64-unknown-freebsd.tar.gz/sha512/24425c8bdc861404156bb5a8e950654904fb22ff6a5ebe52c873629e4dd1cfaccafaae74b779c2cb02370f012cf18c2142a105dd614938b2685db2cd7527c73d -libblastrampoline.v5.11.2+0.x86_64-w64-mingw32.tar.gz/md5/450afb701cc2899c7c083bd3f3e580a0 -libblastrampoline.v5.11.2+0.x86_64-w64-mingw32.tar.gz/sha512/e4d1785a06b051a4f16edd7343021eed61ac45cf45d26b4e3ef1e54cfaadb44da2e74b7d854e31b05a733dbb3004f3e85644967316c4f41d1ad64400fed126f2 +blastrampoline-b127bc8dd4758ffc064340fff2aef4ead552f386.tar.gz/md5/395f2035bcb52e886b55ac926a7bf183 +blastrampoline-b127bc8dd4758ffc064340fff2aef4ead552f386.tar.gz/sha512/9ae0fe2ca75dc0b2c784d5b7248caca29ed6d44258743ee2b32827032734757e9078dd6bcdf80a02b042deb5c7ca7b4e5be392be6700efde91427091fb53a03f +libblastrampoline.v5.12.0+0.aarch64-apple-darwin.tar.gz/md5/9a18b39bb575d0112834992043d302c0 +libblastrampoline.v5.12.0+0.aarch64-apple-darwin.tar.gz/sha512/4e406b155149414d3e4fd5db49ab56a87ed13577ebb399eaf8a251692c0b84e639c6e1a4eb20863e2638c31add0241ca916e57f91bb5a4aed07e2c56cc580870 +libblastrampoline.v5.12.0+0.aarch64-linux-gnu.tar.gz/md5/e100e93f0d6a104fc66c9f78a67150c5 +libblastrampoline.v5.12.0+0.aarch64-linux-gnu.tar.gz/sha512/f7e0c379e32d8163dbb4919b77e9637e1b16cf26618b9260222cf985bfab9ca3f36bebccd0e8360af68db925035c82127ba85d46b4a6578961dde6a049c7cf93 +libblastrampoline.v5.12.0+0.aarch64-linux-musl.tar.gz/md5/814a79e8cfe8744ca5a2a722f007fcaa +libblastrampoline.v5.12.0+0.aarch64-linux-musl.tar.gz/sha512/bc886b199500fc4245a95446d4c862fc636711e0875a9d5cf9aef661d819d00324adfd3e037d9c03e274be26034353d033fb041e7608ecef222e1d154f38337d +libblastrampoline.v5.12.0+0.aarch64-unknown-freebsd.tar.gz/md5/9b9a7fe0e45a73009bb9f8044f4a27a2 +libblastrampoline.v5.12.0+0.aarch64-unknown-freebsd.tar.gz/sha512/51d52afb13e326ef4750bdcad800aaf3db2c9e068b4c38bd148e312c63358b2228b81d23626d18b8983534a8a6f24df1b64b4e7121779d2535574ea907bd18ba +libblastrampoline.v5.12.0+0.armv6l-linux-gnueabihf.tar.gz/md5/1b6fd062d133b13e8efc63f08528fb51 +libblastrampoline.v5.12.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/78d525f425ee27068b94b94f89ef44a51ffac9f642ffe66e177434804e59b4ac3ba875190aceee386a8d740f7903e979e5b91f0973138d0fc7753061c6f5f26d +libblastrampoline.v5.12.0+0.armv6l-linux-musleabihf.tar.gz/md5/506be2b7669aa171efcc541388cb5444 +libblastrampoline.v5.12.0+0.armv6l-linux-musleabihf.tar.gz/sha512/2975136376c3f61b8f227676c4e1368d1847d85ff469dddbc0a330635eac77c00072c7544ae4aa9981d16a4ab04d494be54fc951b434a56fbf14003c42626579 +libblastrampoline.v5.12.0+0.armv7l-linux-gnueabihf.tar.gz/md5/99403eae880f52aa97884143e2ca7215 +libblastrampoline.v5.12.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/986dfcf5fe3ac731df3c71eb6b0bf3d7525511952d22cc9128ff35e6fcb330acf69e897aeb97920ebabd1ccccd1dd6ce9b6c16d0dbf661d39a103ce5b477462f +libblastrampoline.v5.12.0+0.armv7l-linux-musleabihf.tar.gz/md5/20adf8d2ef348f5362cb03e1a2780476 +libblastrampoline.v5.12.0+0.armv7l-linux-musleabihf.tar.gz/sha512/95068a3b5bcf17bd5f13373a2730a6508d3992f0aa83a91629527821cf038b9607327843cc44fb72730b63c01d3d70e2eb488eca8f48ed9444d7736f67745d02 +libblastrampoline.v5.12.0+0.i686-linux-gnu.tar.gz/md5/a56f833ad986fc3e9e64e5abdb16915f +libblastrampoline.v5.12.0+0.i686-linux-gnu.tar.gz/sha512/d478b4981dc17afb8aa8625fdbb23139f1c3edaa9aaa179e70d274984a056147b2e65e9f473b007733d094369f448823c33aa95fadd228016ecf9dfbf17f06bb +libblastrampoline.v5.12.0+0.i686-linux-musl.tar.gz/md5/8578119b3b3e84393e6324996e9506aa +libblastrampoline.v5.12.0+0.i686-linux-musl.tar.gz/sha512/b546de6687755ce43680f312008a23a8f9df422603098807f33e2ae969c9e9de0ca32a3319067d4f8fa1f782f21b6465638cd59e4c86fc6261fb4180f0ed116f +libblastrampoline.v5.12.0+0.i686-w64-mingw32.tar.gz/md5/b9e2800b8758d3fa0ac0597f738c399c +libblastrampoline.v5.12.0+0.i686-w64-mingw32.tar.gz/sha512/e0aa0ee2a750cfe702e0bd5861e352f97f433f67444dbc6e5814055fb32f571de318f640ac670c91bad233f8af85f0421daef71b7768a710de5b15febee28b27 +libblastrampoline.v5.12.0+0.powerpc64le-linux-gnu.tar.gz/md5/bab2048857c7c1ba4a6c3d540b9275c6 +libblastrampoline.v5.12.0+0.powerpc64le-linux-gnu.tar.gz/sha512/576026c970b19cc00480d7bb9439933c5bb432eec17def66b22f5c0dfd418bcf75bb10ccfc1b01fef48e8d504ebf953c5f6c63d504713315c43d9579ab5fa2e4 +libblastrampoline.v5.12.0+0.riscv64-linux-gnu.tar.gz/md5/f37e2849a948a8c8c8bfa6055e30909c +libblastrampoline.v5.12.0+0.riscv64-linux-gnu.tar.gz/sha512/89f30d52f1a1dcc0aa38b4b343534b7fadcff12d788f455172c043ea2511c03b2735fdacf8f794a6f62156cb5d82fb0e9e0edd04bb9c57a1ca3e680410456b17 +libblastrampoline.v5.12.0+0.x86_64-apple-darwin.tar.gz/md5/b07c42b602b91bf2229b1a5cfd8e37b3 +libblastrampoline.v5.12.0+0.x86_64-apple-darwin.tar.gz/sha512/ab064dff373826776f9b64a4a77e3418461d53d5119798a5e702967e4ac4f68c58cd8c3c0cc01bda3edeb613cf50b9d3171d9141c91ff9ef3a2c88a8e8f00a37 +libblastrampoline.v5.12.0+0.x86_64-linux-gnu.tar.gz/md5/c37b01242012e51e124711d5ad10cf97 +libblastrampoline.v5.12.0+0.x86_64-linux-gnu.tar.gz/sha512/3f9015bec4aaddc677cb3f3aebd432db8bad89b3f6e563634a37569afeb9fb0efa4f214166c984c2c1926831d5cd79fcd4d605d40675e0d1a7e494a76c066f02 +libblastrampoline.v5.12.0+0.x86_64-linux-musl.tar.gz/md5/c24e440a1757a45f087a2e1ac649fb45 +libblastrampoline.v5.12.0+0.x86_64-linux-musl.tar.gz/sha512/824b930d50df929fd22ead6dffad06593d2aad9fcb149f07f1c2f6d4b7b34911e89c2be5a1e9b8ad5ad8292ac29f9e5dbe6d7bb205d2b207432ade61ae5f8b68 +libblastrampoline.v5.12.0+0.x86_64-unknown-freebsd.tar.gz/md5/5721328a24473cefbb3e77ba85e46922 +libblastrampoline.v5.12.0+0.x86_64-unknown-freebsd.tar.gz/sha512/3537ea491828492f1cb68fa961dc5574b63a88b49abf19eb86f9d1a4544e1398fcd84d6338c6dcb9550ee3abcdcab0654f5cc2b85699c5ed5b3b31a1c35a199d +libblastrampoline.v5.12.0+0.x86_64-w64-mingw32.tar.gz/md5/450afb701cc2899c7c083bd3f3e580a0 +libblastrampoline.v5.12.0+0.x86_64-w64-mingw32.tar.gz/sha512/e4d1785a06b051a4f16edd7343021eed61ac45cf45d26b4e3ef1e54cfaadb44da2e74b7d854e31b05a733dbb3004f3e85644967316c4f41d1ad64400fed126f2 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/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/checksums/curl b/deps/checksums/curl index e6f7989db33d7..b0a223f42c5e2 100644 --- a/deps/checksums/curl +++ b/deps/checksums/curl @@ -1,36 +1,40 @@ LibCURL-a65b64f6eabc932f63c2c0a4a5fb5d75f3e688d0.tar.gz/md5/e8c53aa3fb963c80921787d5d565eb2c LibCURL-a65b64f6eabc932f63c2c0a4a5fb5d75f3e688d0.tar.gz/sha512/8e442ea834299df9c02acb87226c121395ad8e550025ac5ee1103df09c6ff43817e9e48dd1bcbc92c80331ef3ddff531962430269115179acbec2bab2de5b011 -LibCURL.v8.6.0+0.aarch64-apple-darwin.tar.gz/md5/83854e8cdd078ec1fc5f92da2816e379 -LibCURL.v8.6.0+0.aarch64-apple-darwin.tar.gz/sha512/f3b3cc5804d9a7986ed9ea7c3186caa8dba0f4d6bbcb9b5d2070b4e6412234f2ed7908446dbe217323510c6d3b042540e18ec7839093c2c3c66f3195937a6a3b -LibCURL.v8.6.0+0.aarch64-linux-gnu.tar.gz/md5/880014fface52bddaa1a0240e0668dde -LibCURL.v8.6.0+0.aarch64-linux-gnu.tar.gz/sha512/a29b923e14425ad729484648ce15577e717a97acf6138e0ec3d35a8000aeef17f27ce01d1fdc1642c6eda72d8d8b46642d79844ef9a50f30a0148e29452565c1 -LibCURL.v8.6.0+0.aarch64-linux-musl.tar.gz/md5/b84fcb98f1305803d941f7a5accbfdb1 -LibCURL.v8.6.0+0.aarch64-linux-musl.tar.gz/sha512/0880dc91109aedd9b108f2e28a25bf7091ac976a6f94e65000f647802c57a01e8111d421b91a91244c3cfb56990155af2c47b3499997be2af8ab93d344b8331d -LibCURL.v8.6.0+0.armv6l-linux-gnueabihf.tar.gz/md5/24249f42db0bc99c2dde4cf61d61f11f -LibCURL.v8.6.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/350443c86f7b6733fb6a28f8a2fe7a6c0e91462b9e4078fed3475059ec7e12fef5014e22d0d0babe44f172ace7258292de577a0ab90f90c65d825d74940c9c47 -LibCURL.v8.6.0+0.armv6l-linux-musleabihf.tar.gz/md5/375c01cef98204c4f63ac218b08c4c7b -LibCURL.v8.6.0+0.armv6l-linux-musleabihf.tar.gz/sha512/ed0981d458c6ddc9f380b90f1ec25cbaa6be910f0dab5d5485e4d1e9a33f8a918d210722a5e6685b4d3b917e0800194856f826164ee2e90b8a886ada7498a52b -LibCURL.v8.6.0+0.armv7l-linux-gnueabihf.tar.gz/md5/4c81aa99065cf797d6e09ce172dd2fa7 -LibCURL.v8.6.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/08bbb1bc80411a5fd65699a0d721fc70a9bba1005194f2937accc2e98f7f803bac4a704c88aa1fc1d72e54e7c327a113963f8a4c52ebb1e5921778d1dd549143 -LibCURL.v8.6.0+0.armv7l-linux-musleabihf.tar.gz/md5/6865b2f2d93754b5206d618048c32b57 -LibCURL.v8.6.0+0.armv7l-linux-musleabihf.tar.gz/sha512/c1a5891f4c487d5f7cf91db7cd2d85394d9686cda01c89cddaf7afba09782aa9f00713592d72ed8a0dd20439884dd75c1e001a9ecb16dd8ce5f08f79c194c7c8 -LibCURL.v8.6.0+0.i686-linux-gnu.tar.gz/md5/3f35cc6a2dc7e9dba5e3b4aeaf130160 -LibCURL.v8.6.0+0.i686-linux-gnu.tar.gz/sha512/b34c5ba2fee272e6ca848c42335ffa0c4d0c06337608504a3a2cfeb111e228da3f82d91c0c4387c76fc347babbf50b368992b5b8d5fda1a60ed5c0ce5d9242db -LibCURL.v8.6.0+0.i686-linux-musl.tar.gz/md5/0072b83eaf91d9da4a8d25ef65fd8ca8 -LibCURL.v8.6.0+0.i686-linux-musl.tar.gz/sha512/029552e3dac29857726988352a01a3b57859bfe5e327e7b759bd9968ed5af5498fd27ab490810d2d3ef05b1003c1a950fd092d1dbce7732a911f7cb6e5714303 -LibCURL.v8.6.0+0.i686-w64-mingw32.tar.gz/md5/d58ef948bc9a04a8c934a88b7ab5599d -LibCURL.v8.6.0+0.i686-w64-mingw32.tar.gz/sha512/1e1742ea39f2fe1f13b0aff5907f96401276e3fc469a8f09f2bc31fffc72367a92856973db66eb9b05d20fd708764ad9429e385913f6236ce8067ec4e11dbb33 -LibCURL.v8.6.0+0.powerpc64le-linux-gnu.tar.gz/md5/60ec16b6dfd3e30eb0655cf177b026c7 -LibCURL.v8.6.0+0.powerpc64le-linux-gnu.tar.gz/sha512/f591897972c8b01edf64701885f636fc1d5c04cce8fc63577d06108e14e5480bad74306d6ee31515911bd8ba3db10d1f2c733a6149aceae32aa4b77e263087c3 -LibCURL.v8.6.0+0.x86_64-apple-darwin.tar.gz/md5/c6bc0d9cd0a9f9c35ed2aac058ae332f -LibCURL.v8.6.0+0.x86_64-apple-darwin.tar.gz/sha512/038f55bfb06dce877540ea7d50f5a0b8fdc070539c505774139a7c23df276a5fc75b5cecabecbc2826417e091028382d79298a51ed73c3d776249b4ff35f9f26 -LibCURL.v8.6.0+0.x86_64-linux-gnu.tar.gz/md5/18bf9d909dd5eebc0554d23bf4a4ee0f -LibCURL.v8.6.0+0.x86_64-linux-gnu.tar.gz/sha512/35e60faa1ee072003fdd5cd510295bc310aa99375aee6ef94eee3ee2d5e0b7844145866a74927c588c14131939c1d9865d6f5128ac4f6b93606a68042a94f39f -LibCURL.v8.6.0+0.x86_64-linux-musl.tar.gz/md5/213190e1d79c9c291ff460e1648a61d3 -LibCURL.v8.6.0+0.x86_64-linux-musl.tar.gz/sha512/4ea063982520400c02dcdf44ed3f018dec19607ad20762231316eb745cdb1cd054b18677fee1b5c5fb0bd55eb845121a2113704c5301be1d76edfc8a4a09d93f -LibCURL.v8.6.0+0.x86_64-unknown-freebsd.tar.gz/md5/30dda5aaeb7977eb3563c603af08cd6c -LibCURL.v8.6.0+0.x86_64-unknown-freebsd.tar.gz/sha512/edf603a6c013d3f6e01fc4fd6f12caf93ff99df9baf14bc73b610638a5b5ff90ec3118b112d9a39221294f5f419f3bf12232c16eaf91b07a68d92342a5c56912 -LibCURL.v8.6.0+0.x86_64-w64-mingw32.tar.gz/md5/9a2c980db329393f5274d42f87c2aec6 -LibCURL.v8.6.0+0.x86_64-w64-mingw32.tar.gz/sha512/6b926a87a3470796eb111e448c459a8ff1267533513f14d58f6e08cbebfb3e838c114827fcf39298bcefe8d76b8578bb4d3903c848bfafb0590022e6a49b2a00 -curl-8.6.0.tar.bz2/md5/4418e0d94f29d352afafdab445e37a3d -curl-8.6.0.tar.bz2/sha512/726fe7e21f8a2a925ab4ab6fe4e4ad099105f00656bfdc702beec12e1549ba2cb63d908d1d19f43b90feeb1d950ae5a6ac9a72a27447f5acf1907df396d1823c +LibCURL.v8.11.1+1.aarch64-apple-darwin.tar.gz/md5/890c65523227b4352344b78575cd4c5c +LibCURL.v8.11.1+1.aarch64-apple-darwin.tar.gz/sha512/fae539243adc805d8da0ac88cf67901ff1f12ae94e40293dc6a7e17072f8c0cb9f0a54b7e324bd52ad9361b764c8bc88728ff4495e0cd6dbf1eb93d2bae8994b +LibCURL.v8.11.1+1.aarch64-linux-gnu.tar.gz/md5/bf937fb6a8ea8a82b732821f3652641c +LibCURL.v8.11.1+1.aarch64-linux-gnu.tar.gz/sha512/230c9983e4c7810d3eee1a5eff7e8b8c44f76db7af8a8312a608609f87bc8a56031c337c06af00a536c10ed33725200aa137c3153ef6dcf6575cc7c350b3b461 +LibCURL.v8.11.1+1.aarch64-linux-musl.tar.gz/md5/b40ea4266dc48a1fbfa016fb8d0ca987 +LibCURL.v8.11.1+1.aarch64-linux-musl.tar.gz/sha512/032d6208ebe226da90d0ef1f1f2d20580fd4e37db68146d1e836a9be4c1fc5f7890f1b808337ca41f46a07a833b55f06f09a4a164f26d0824a649ea40b30233f +LibCURL.v8.11.1+1.aarch64-unknown-freebsd.tar.gz/md5/69097390c0bd3a32969e47608f24363f +LibCURL.v8.11.1+1.aarch64-unknown-freebsd.tar.gz/sha512/391019370a9c122e6425a3097edafe0980dc2077be015919e7914aa781ba10060e3af9ee1fa881d8536d0ca57783d0616a1b5735e2ae7e06ea4edfaee2994120 +LibCURL.v8.11.1+1.armv6l-linux-gnueabihf.tar.gz/md5/bc4ab567f8cc4cd88b2239123d103113 +LibCURL.v8.11.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/0ecbf2380852744815a8f7e99e7c276c342f847907eb7b0d256905ba854ee59d37f83456fcdc8931dc39dbaed58f0949205b80d23e43e2b59195d18a539d4047 +LibCURL.v8.11.1+1.armv6l-linux-musleabihf.tar.gz/md5/18c896c544f02f7f2b976c03fc3772f1 +LibCURL.v8.11.1+1.armv6l-linux-musleabihf.tar.gz/sha512/e9a73670f1c3638c3a886055b32df5baadc41aad9829cfa0d4e05acd46d2d012464114ed6fd1e3d182a4adc266c1da97e9a683c7ba69e93f61592acf8567e336 +LibCURL.v8.11.1+1.armv7l-linux-gnueabihf.tar.gz/md5/4672f9d67ff357a2eda6f77d8f470659 +LibCURL.v8.11.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/a2f2dc8d8e10c652a324a4da3d2337d2886626e1c417c68efbcfcefa443cb3ec81b52f2a212c4a7dbd6a5ae920e54d1bfdc02b68c2607d09784206cd4d11ffb0 +LibCURL.v8.11.1+1.armv7l-linux-musleabihf.tar.gz/md5/49d297563fd44a03f88f67bb7ea2a0be +LibCURL.v8.11.1+1.armv7l-linux-musleabihf.tar.gz/sha512/5cc3902571f04c96be38de53b5320876a3e7e54934090ff2a80304a7ca59a361ed9f3f328c3e3c06ef33550d221a8243e924b7ea49792753f839c12aceb1e979 +LibCURL.v8.11.1+1.i686-linux-gnu.tar.gz/md5/f05a86574278ecf7802edeffe1fee9ac +LibCURL.v8.11.1+1.i686-linux-gnu.tar.gz/sha512/e493b5836022a6280f21237fef423034a9701097cb271683e81d4b4e487a6289080d00016fbaaa8bddeb004d44626a0076fa7832835fe7f58b60af6798223f89 +LibCURL.v8.11.1+1.i686-linux-musl.tar.gz/md5/03340412ba27f231dbf2de58a1af871f +LibCURL.v8.11.1+1.i686-linux-musl.tar.gz/sha512/541fbdd5570432832d3835038b41df73aac8e0e7bc03f41c696dc12a57bd4784b4da1f485264fd1fba263fe9e520a7dbb0ef9a365275efc30dfc361ceab252f3 +LibCURL.v8.11.1+1.i686-w64-mingw32.tar.gz/md5/5f2071282d572bbb53dfcfb16d0d9608 +LibCURL.v8.11.1+1.i686-w64-mingw32.tar.gz/sha512/e4d6fbd518055e8f2a71b89ee9a33728e6e076729adeafc358fc40f47d032b739363c9b57df5bfb3c43244f7b833afc76ae255e70bcf43b81262d74278532a22 +LibCURL.v8.11.1+1.powerpc64le-linux-gnu.tar.gz/md5/806ee9b51c2bffd798c1682867a7a2a0 +LibCURL.v8.11.1+1.powerpc64le-linux-gnu.tar.gz/sha512/20ae5f47ad24e1fba8ecdc3a81aa81acb5c3c224041f12f8be48f9a0abd5ce44117b096a59fc8f861b6f8c6ad9e4177e3a3ba3e2dbecb2078d4bab19bdd4d239 +LibCURL.v8.11.1+1.riscv64-linux-gnu.tar.gz/md5/2e029213e81955f39423733608c4ffa8 +LibCURL.v8.11.1+1.riscv64-linux-gnu.tar.gz/sha512/a634ae9de047bd8a93cbfaa3cd5375d895baf9917b5062653f15472527836b51eeb15006b5e1888251e3f09d8177b489ea9975580fe6d95bc759708fc9654fd1 +LibCURL.v8.11.1+1.x86_64-apple-darwin.tar.gz/md5/56cf7cf4ea22123e516843a5751eea17 +LibCURL.v8.11.1+1.x86_64-apple-darwin.tar.gz/sha512/5ae5569ade42cdf0a1aa8acfda7d1dd3df30d498637f83e93bd9f8be883ae777e789b417be24df83e42ebe32fb67cc328bedac3dc231d3569f585641175ed257 +LibCURL.v8.11.1+1.x86_64-linux-gnu.tar.gz/md5/a4a733fe879693e83e1f05b6ef742ea6 +LibCURL.v8.11.1+1.x86_64-linux-gnu.tar.gz/sha512/2767f49d4a528080a5c7fcdecd8374dd5498c5b1e0d65f58d027f6a9138cd00203732e5da1806b689efbaacb1ee905a6839a09eab35f0174279af314a34fca81 +LibCURL.v8.11.1+1.x86_64-linux-musl.tar.gz/md5/837a64073c3d8fd115cadf4af1b19235 +LibCURL.v8.11.1+1.x86_64-linux-musl.tar.gz/sha512/cf0559b65c213889ab0bad388ca6dc1699891e5cd2c5c34faf80cd60404b5f363eaa624d425fd463407d35c5cfd814c1a9964a2b3b638fa7e7a0a2919980ba8c +LibCURL.v8.11.1+1.x86_64-unknown-freebsd.tar.gz/md5/22726eb8caed9b279e6cddbfa328f2c6 +LibCURL.v8.11.1+1.x86_64-unknown-freebsd.tar.gz/sha512/b9e304575bb0e3241f938c545a91cc5b722e8dfc53d6ad270ea75b8fb05655ae8a03e5f844f5b8a75a84133d0883369bc6c46f0805be37ee840f2f1168994c37 +LibCURL.v8.11.1+1.x86_64-w64-mingw32.tar.gz/md5/aa5ce49a63d216776ef9fc11b6b3b012 +LibCURL.v8.11.1+1.x86_64-w64-mingw32.tar.gz/sha512/4e7fe5ff82ca9bafbaca476aa51273ee9590058350c889a6dd8a0eecaa024d19f0a26dd7078808d08dfdf2f5751daec51e88dc88253a4638274edb63ae93fd3c +curl-8.11.1.tar.bz2/md5/31dc730e6fff880a6ba92bdacead9d38 +curl-8.11.1.tar.bz2/sha512/30041e15b919684c46b6b3853950cba22e6fbc21157b1f682097277d2b20066ba71e51eb5d2c34bbd81b8bf4c2791255d6492ee21d49f606d71f66e211a6adde diff --git a/deps/checksums/dsfmt b/deps/checksums/dsfmt index 99ba378adcd4c..9d5fa782663ec 100644 --- a/deps/checksums/dsfmt +++ b/deps/checksums/dsfmt @@ -1,36 +1,38 @@ -dSFMT.v2.2.5+1.aarch64-apple-darwin.tar.gz/md5/1ac287cb891e0bb758e5ae1195e661b7 -dSFMT.v2.2.5+1.aarch64-apple-darwin.tar.gz/sha512/c604d55fb955e9d707e26b654670f07f18ddd0dc93c1a2b678b9cea9b84a24e21c88eb49d39e3e74c930cdffa35e45f5a63e96ecb0a098e8ea538438dc7281bd -dSFMT.v2.2.5+1.aarch64-linux-gnu.tar.gz/md5/260e14855dbc7773a2ca906d58cc57f2 -dSFMT.v2.2.5+1.aarch64-linux-gnu.tar.gz/sha512/820ca4c6afde931e855b74015150f4ffbb513276c3fa7dbcc1ec8d34c02d4989fb7424a6e4f81f93d054811b5f54f8633d955b05acdb088387ee90f1c3b00915 -dSFMT.v2.2.5+1.aarch64-linux-musl.tar.gz/md5/7ddccbad6b5c9de4be187fe76637a0d8 -dSFMT.v2.2.5+1.aarch64-linux-musl.tar.gz/sha512/e3c225da00927096e3a6cd4abc681fba8f469cb74828e7054d4f5684d71dcb8e75c9a81f14fa10bfbb78f62f9567a31a92edcca8d797e5810a2a44a3fc17bc84 -dSFMT.v2.2.5+1.aarch64-unknown-freebsd.tar.gz/md5/84f560104ab5eac8f214559645235350 -dSFMT.v2.2.5+1.aarch64-unknown-freebsd.tar.gz/sha512/3668a37d2516c304b296e2dd7b93a45decb37774088b03438b6d7dec71766d98b2ca1d61c1b317f86ca118d078f53817b6bc86f0ed487185e18b5cc786060592 -dSFMT.v2.2.5+1.armv6l-linux-gnueabihf.tar.gz/md5/a70329e0a6c57009c6b6950fd34089f6 -dSFMT.v2.2.5+1.armv6l-linux-gnueabihf.tar.gz/sha512/4418c42165660adc050e872ef834f920c89ed6a0d2b816821672b1e862e947aad7efd023289da9bf05bb2eb9ec4b9d2561c403e2d5384d5314a4ba016b1f9cfc -dSFMT.v2.2.5+1.armv6l-linux-musleabihf.tar.gz/md5/6ffc798b8a0c847fa5cb93640bd66ab3 -dSFMT.v2.2.5+1.armv6l-linux-musleabihf.tar.gz/sha512/94e5ae07d0b1420abd7290519bce6f77deae634bbb4df31e3f02416bf509e555a9b1c9d19dd77ca76a308c2b86d5c9d4718b9ef83c13167b88a8181d8ca7e73a -dSFMT.v2.2.5+1.armv7l-linux-gnueabihf.tar.gz/md5/660d95aa08580ca1716a89c4d8b1eb24 -dSFMT.v2.2.5+1.armv7l-linux-gnueabihf.tar.gz/sha512/bc757a9f805047be5375f92c10a3f3eab69345a4ec5cc997f763e66be36144a74d414ff926df8e17b9d5a2394189269c3188c55e0b7c75a72495394d65510cef -dSFMT.v2.2.5+1.armv7l-linux-musleabihf.tar.gz/md5/78c487049092fe61949d506637c713bb -dSFMT.v2.2.5+1.armv7l-linux-musleabihf.tar.gz/sha512/03ddada4478f05eab7d2971b2deaf2cba91f084d7ce66fc8219bcb3cf5c308ea13959fed95568ca80f4ce11794e197092984919265716de8f2558e2cb30d94ce -dSFMT.v2.2.5+1.i686-linux-gnu.tar.gz/md5/11463fd3981a8c143d7aed691d18d4e0 -dSFMT.v2.2.5+1.i686-linux-gnu.tar.gz/sha512/db946a4fbd8a3163b8b1c25e02bfc4a841da7d2532892a99037bd48ac98e1840691e8cc0127d9457a82667a0131e4826cb4e9d0a13f127afc62da4eb68af5a3e -dSFMT.v2.2.5+1.i686-linux-musl.tar.gz/md5/a61405f72c9a3bba5718f078c68e61a5 -dSFMT.v2.2.5+1.i686-linux-musl.tar.gz/sha512/726f130bbbfd0dece4185b89a25a73f3b5b950ebfb7f86aea6e9cbcf9ae932e591d20b854de0b4985103dbf8b4b7cb3560661c5070af971cd2c1f3ec3e1ea7d2 -dSFMT.v2.2.5+1.i686-w64-mingw32.tar.gz/md5/3bc27ef8f26c7a26f096cf1d558d408d -dSFMT.v2.2.5+1.i686-w64-mingw32.tar.gz/sha512/ea3608d3ae3874ea57a1a08f69abe2a1638bc340db71c6fe3c4fd5637d8c54943bf16b099a46817387c1ed4cb5f3cd1c0ff19ae8a4ed85dd555555821af06374 -dSFMT.v2.2.5+1.powerpc64le-linux-gnu.tar.gz/md5/fd8c73961ef7c82201e6d86e8bf4324c -dSFMT.v2.2.5+1.powerpc64le-linux-gnu.tar.gz/sha512/1bd0ebd019cfc6f25f7ba007547c5ee297854655b93c55e90d8ead420875de5a087e38956693d5e901ff2abf667c72aa66fb34f587b82adf4b91b3d5d666b5c7 -dSFMT.v2.2.5+1.x86_64-apple-darwin.tar.gz/md5/c8c0cd02cb1aa5e363b0c28a3fc4cf65 -dSFMT.v2.2.5+1.x86_64-apple-darwin.tar.gz/sha512/ac29d4b8aae51349474c9191822f92f69105e19521afe2bd9fc6b16385256610ae31e34cd70d894ed03299f1fd155f0a1db79969d1ed35eea44d11521e2030ab -dSFMT.v2.2.5+1.x86_64-linux-gnu.tar.gz/md5/fa671f4ca14b171d53c8866d03f9162a -dSFMT.v2.2.5+1.x86_64-linux-gnu.tar.gz/sha512/2e242a1448da0508ea88cc1a106f1e74f8d7e7562cd82b80d86abf9a8b454653ad7612e25c30ce00c23757e8a5b7b5736253b00a52f9473af6c5d4df768138f2 -dSFMT.v2.2.5+1.x86_64-linux-musl.tar.gz/md5/c648294163882ec539ab646542c74880 -dSFMT.v2.2.5+1.x86_64-linux-musl.tar.gz/sha512/9e96a47d660854b6517364f0db40a2f4e0e3b814499a0349f7cf550b1c8d04589fca5eb4a75bf34f36d1b5d1b2277b3e9a961c887092abedd08f438e025329e7 -dSFMT.v2.2.5+1.x86_64-unknown-freebsd.tar.gz/md5/4960e4ab2ecb6ae1025f9e7bf4c9a7b8 -dSFMT.v2.2.5+1.x86_64-unknown-freebsd.tar.gz/sha512/a2e8bbe382a0ebdd7b69fafdc901f33767f53b9f8b37a89104f2ef897bb5ec27bc8d3bc21f5cff52ca4f29b3a6a10535f7e5f16ef917a9323858c75f1569ea60 -dSFMT.v2.2.5+1.x86_64-w64-mingw32.tar.gz/md5/386adb3b7593c222dc7a1060a1356b21 -dSFMT.v2.2.5+1.x86_64-w64-mingw32.tar.gz/sha512/fe2ab5021126807b37042e89a22ef9a869c6a0a028680df445773b2affd11c2b02148be07d53504ea3842bb38bb62fe039529688266c1cba3545a892bd4dc185 +dSFMT.v2.2.5+2.aarch64-apple-darwin.tar.gz/md5/4d9e6a1ed07d1fe1557845b763224eeb +dSFMT.v2.2.5+2.aarch64-apple-darwin.tar.gz/sha512/930e12a9b6ac82888f4122515a8a7cc3aa5d5363e500455b33c57efb7656041fe3f0fa68b02dd048b2a9f00abb56449415f1edf600ef09703aaed991e1d6f23d +dSFMT.v2.2.5+2.aarch64-linux-gnu.tar.gz/md5/260e14855dbc7773a2ca906d58cc57f2 +dSFMT.v2.2.5+2.aarch64-linux-gnu.tar.gz/sha512/820ca4c6afde931e855b74015150f4ffbb513276c3fa7dbcc1ec8d34c02d4989fb7424a6e4f81f93d054811b5f54f8633d955b05acdb088387ee90f1c3b00915 +dSFMT.v2.2.5+2.aarch64-linux-musl.tar.gz/md5/7ddccbad6b5c9de4be187fe76637a0d8 +dSFMT.v2.2.5+2.aarch64-linux-musl.tar.gz/sha512/e3c225da00927096e3a6cd4abc681fba8f469cb74828e7054d4f5684d71dcb8e75c9a81f14fa10bfbb78f62f9567a31a92edcca8d797e5810a2a44a3fc17bc84 +dSFMT.v2.2.5+2.aarch64-unknown-freebsd.tar.gz/md5/d592c490259f45acef2308fd61046404 +dSFMT.v2.2.5+2.aarch64-unknown-freebsd.tar.gz/sha512/4f4e100b4cd5301e815f29f911b3ddba845a90247f1d641ea11153f5845c700e6f94ccd4a1d46fbb9e64a0c5698c5419c52560f0629629ffd665cf9ddec24e17 +dSFMT.v2.2.5+2.armv6l-linux-gnueabihf.tar.gz/md5/a70329e0a6c57009c6b6950fd34089f6 +dSFMT.v2.2.5+2.armv6l-linux-gnueabihf.tar.gz/sha512/4418c42165660adc050e872ef834f920c89ed6a0d2b816821672b1e862e947aad7efd023289da9bf05bb2eb9ec4b9d2561c403e2d5384d5314a4ba016b1f9cfc +dSFMT.v2.2.5+2.armv6l-linux-musleabihf.tar.gz/md5/6ffc798b8a0c847fa5cb93640bd66ab3 +dSFMT.v2.2.5+2.armv6l-linux-musleabihf.tar.gz/sha512/94e5ae07d0b1420abd7290519bce6f77deae634bbb4df31e3f02416bf509e555a9b1c9d19dd77ca76a308c2b86d5c9d4718b9ef83c13167b88a8181d8ca7e73a +dSFMT.v2.2.5+2.armv7l-linux-gnueabihf.tar.gz/md5/660d95aa08580ca1716a89c4d8b1eb24 +dSFMT.v2.2.5+2.armv7l-linux-gnueabihf.tar.gz/sha512/bc757a9f805047be5375f92c10a3f3eab69345a4ec5cc997f763e66be36144a74d414ff926df8e17b9d5a2394189269c3188c55e0b7c75a72495394d65510cef +dSFMT.v2.2.5+2.armv7l-linux-musleabihf.tar.gz/md5/78c487049092fe61949d506637c713bb +dSFMT.v2.2.5+2.armv7l-linux-musleabihf.tar.gz/sha512/03ddada4478f05eab7d2971b2deaf2cba91f084d7ce66fc8219bcb3cf5c308ea13959fed95568ca80f4ce11794e197092984919265716de8f2558e2cb30d94ce +dSFMT.v2.2.5+2.i686-linux-gnu.tar.gz/md5/11463fd3981a8c143d7aed691d18d4e0 +dSFMT.v2.2.5+2.i686-linux-gnu.tar.gz/sha512/db946a4fbd8a3163b8b1c25e02bfc4a841da7d2532892a99037bd48ac98e1840691e8cc0127d9457a82667a0131e4826cb4e9d0a13f127afc62da4eb68af5a3e +dSFMT.v2.2.5+2.i686-linux-musl.tar.gz/md5/a61405f72c9a3bba5718f078c68e61a5 +dSFMT.v2.2.5+2.i686-linux-musl.tar.gz/sha512/726f130bbbfd0dece4185b89a25a73f3b5b950ebfb7f86aea6e9cbcf9ae932e591d20b854de0b4985103dbf8b4b7cb3560661c5070af971cd2c1f3ec3e1ea7d2 +dSFMT.v2.2.5+2.i686-w64-mingw32.tar.gz/md5/3bc27ef8f26c7a26f096cf1d558d408d +dSFMT.v2.2.5+2.i686-w64-mingw32.tar.gz/sha512/ea3608d3ae3874ea57a1a08f69abe2a1638bc340db71c6fe3c4fd5637d8c54943bf16b099a46817387c1ed4cb5f3cd1c0ff19ae8a4ed85dd555555821af06374 +dSFMT.v2.2.5+2.powerpc64le-linux-gnu.tar.gz/md5/fd8c73961ef7c82201e6d86e8bf4324c +dSFMT.v2.2.5+2.powerpc64le-linux-gnu.tar.gz/sha512/1bd0ebd019cfc6f25f7ba007547c5ee297854655b93c55e90d8ead420875de5a087e38956693d5e901ff2abf667c72aa66fb34f587b82adf4b91b3d5d666b5c7 +dSFMT.v2.2.5+2.riscv64-linux-gnu.tar.gz/md5/5c4981c2c016436faf6f33fa8df4204b +dSFMT.v2.2.5+2.riscv64-linux-gnu.tar.gz/sha512/9b56f0abbfb2731d23b99b5286b69c31bfc21eb14f49d88953680d5596c20c6b4d59520828f0a398915d56c82e169a36316f8e319dfe4e25a8e3f44f2aca4938 +dSFMT.v2.2.5+2.x86_64-apple-darwin.tar.gz/md5/e21e30097f1f02c5cc14cca3f73ce92f +dSFMT.v2.2.5+2.x86_64-apple-darwin.tar.gz/sha512/48b19706189eabcab2c823e6143ae22f4a330abb239c7a952913fe9973c5f750d72b113af32a82a1f6124c534495b26d1f81ccab407d8d15ee459dc83fb8d3cd +dSFMT.v2.2.5+2.x86_64-linux-gnu.tar.gz/md5/fa671f4ca14b171d53c8866d03f9162a +dSFMT.v2.2.5+2.x86_64-linux-gnu.tar.gz/sha512/2e242a1448da0508ea88cc1a106f1e74f8d7e7562cd82b80d86abf9a8b454653ad7612e25c30ce00c23757e8a5b7b5736253b00a52f9473af6c5d4df768138f2 +dSFMT.v2.2.5+2.x86_64-linux-musl.tar.gz/md5/c648294163882ec539ab646542c74880 +dSFMT.v2.2.5+2.x86_64-linux-musl.tar.gz/sha512/9e96a47d660854b6517364f0db40a2f4e0e3b814499a0349f7cf550b1c8d04589fca5eb4a75bf34f36d1b5d1b2277b3e9a961c887092abedd08f438e025329e7 +dSFMT.v2.2.5+2.x86_64-unknown-freebsd.tar.gz/md5/5a9b811be74f02202c57588f35582cb6 +dSFMT.v2.2.5+2.x86_64-unknown-freebsd.tar.gz/sha512/8dc6cae5cdf038fd5647cf86b85a15ac082d35b4532340e145b7e091839079ff47371aef6c3012a67692e492622b4f84db8f0ccf46049cc94926aed5c9cd9fb4 +dSFMT.v2.2.5+2.x86_64-w64-mingw32.tar.gz/md5/386adb3b7593c222dc7a1060a1356b21 +dSFMT.v2.2.5+2.x86_64-w64-mingw32.tar.gz/sha512/fe2ab5021126807b37042e89a22ef9a869c6a0a028680df445773b2affd11c2b02148be07d53504ea3842bb38bb62fe039529688266c1cba3545a892bd4dc185 dsfmt-2.2.5.tar.gz/md5/d22e476b52cdee7d5b90d2f289570073 dsfmt-2.2.5.tar.gz/sha512/951e8669350f750b8915a819e704eae0a9b9c9518b3e3b9a1905f9ca0d25cc4c2486cb479e258a4a114e9c26ceb73a6c4e9f1cc02ed19173aeb8f20189754f6b diff --git a/deps/checksums/gmp b/deps/checksums/gmp index c786fddafef5e..949e4d738a472 100644 --- a/deps/checksums/gmp +++ b/deps/checksums/gmp @@ -1,62 +1,66 @@ -GMP.v6.3.0+1.aarch64-apple-darwin.tar.gz/md5/70a730ecf64eefb5a13f4524e29a6388 -GMP.v6.3.0+1.aarch64-apple-darwin.tar.gz/sha512/51791b4ae0ede1db4c6e7759072d125ca56f6a3a3e43fd5970981a3b2d651f28fe0abefce4b3ad0589d3a46c143054d20fee801bbd423bd2a4c12ba97314c39c -GMP.v6.3.0+1.aarch64-linux-gnu-cxx03.tar.gz/md5/e2b0bf1317259972cdc4f0e6fc3c2bc8 -GMP.v6.3.0+1.aarch64-linux-gnu-cxx03.tar.gz/sha512/8de1dd5d6971c76693c67222725c9eb0a1d276a55a28cd49d94115123100bfe45144652421d4cde468dce67a5630736f4174c9491c8a6e2543aadcb44f1f2d12 -GMP.v6.3.0+1.aarch64-linux-gnu-cxx11.tar.gz/md5/2017b6215ed99c3aed8b04abe75cb3e9 -GMP.v6.3.0+1.aarch64-linux-gnu-cxx11.tar.gz/sha512/78b22106f96348f0d9222279fdf8d1e3f5bd400f771fb0c54dd4045985ee05b896e3097f788739eefab9a9ab09a885aad65c4adb31ae5ba59b7ab22ca10bb574 -GMP.v6.3.0+1.aarch64-linux-musl-cxx03.tar.gz/md5/6477f35f92203db871f56f047b99a1fe -GMP.v6.3.0+1.aarch64-linux-musl-cxx03.tar.gz/sha512/66a6d18979c1ee9a5d06323a717d0a5dd73efc196087349408e739d7aa0444e8ee1af4bd634f85dfd4cfa4c97c24dda4ba472b490f50409581aff967c81b0750 -GMP.v6.3.0+1.aarch64-linux-musl-cxx11.tar.gz/md5/4648558f1e42b8e679f5be494a910402 -GMP.v6.3.0+1.aarch64-linux-musl-cxx11.tar.gz/sha512/9b7ff68a412bccd423b3cffefbc6350db6db8f3f7657713767187c2c2ea3b09d835e1c80d34ab4407f79fccbec82594e024787def27b9ad2ee7ea01ef1607b53 -GMP.v6.3.0+1.aarch64-unknown-freebsd.tar.gz/md5/362bc3fdbcd6d74b9fddb8a4d640d99a -GMP.v6.3.0+1.aarch64-unknown-freebsd.tar.gz/sha512/8e560b4d1014382d784ccf7c9dc6365526566301ec6a28d115170c0be92b8e6033b6c08f922104e405cf978204579754f0740aae97d0a334e47ed6f684aa4af4 -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/6cabb238d148b3e2e76e8527e65893cd -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/07b5673b4680781b7d42399213ecd491ede8883bbf1825689ad6678986a76581f6c4e53f17353f63bec8db8df5ed3fbddc228694eecc54ae7fc949f106bb8f14 -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/0257216ad4e96b404d456f07fcc30b09 -GMP.v6.3.0+1.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/ae8bbbbe3992f78186fe7535e450330e94e6630540eefbdfb51bb5014afd90feac0b1583e3fd2bbf226e61523647b3ec6324188bd6267c353a2a98594566c02b -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/md5/48b949c062ea27dc0dbcc07ea5387821 -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/03699c20b5c50dbd44f45a0f5f115c6b10b4e8de68d747bceba605c3090469c819b82ad7e57fe7702c1700c25aae6ab9394a22ded319bc58c80e9d20692b610e -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/md5/847ba3116072a523e1ff4ce83e5a18a8 -GMP.v6.3.0+1.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/402548acd57f4112bf2435803f35ea93fd8d07f3df0e2f053b0bec6b08aa3dff4052990a724e2547ce35a29ee376b17d34b7e7e2ab45ecb4981ffc99c56f1a9f -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/5cc75b66059c3b8b5fbf9b8fcb781b10 -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/1ef583d014c825e1d4e6d5f7e2d84c3ba183ba9490410f5d424760e275b7032e98f8377d87ed349d4969c6ef8f9b961a1e8df6f40efb406d41983446a9510303 -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/c0295c143bcb6b53d6184e2852ce35c5 -GMP.v6.3.0+1.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/3c74edb123a6f4147b416e5f7f25903bc859ac5f58f141bd463d3dff8cc2928fedf176f20869a1018a2731c1d7170444b3b3405c8f89c3fc22dc2edf9c036c24 -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/md5/a67696b02a7f67405dd84252c908e071 -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/73ba1809cfc68199401974f73e7a37b1fe00d4c0cf3e58ed85d161a8fbac4390aeb28591c3108fc503ef8fb5b131d027cb76dcf5d7731698997c2f377d929dce -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/md5/484f00cd5b0beec20f63cd6734d02611 -GMP.v6.3.0+1.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/46fc56f945647f5c8577ad45f540a034f747604e5a89230d9d419b10d5f0571c7580e18e1138ea920efc08b25798c0c7110e15359de17dce3b6db7f07b8ceb3a -GMP.v6.3.0+1.i686-linux-gnu-cxx03.tar.gz/md5/d36d84638e2e5f927d15f07c55919f5f -GMP.v6.3.0+1.i686-linux-gnu-cxx03.tar.gz/sha512/61c62084ab90d25f7168281c7fb672f5bcafdf909afbf66847cfaa1077dd5474b2c27464eb76cac45f5e319aca0c4f7367fc238b83d2dde46ba90a7c1f396dfb -GMP.v6.3.0+1.i686-linux-gnu-cxx11.tar.gz/md5/d87627470bdcac981f7b004c27ac9a89 -GMP.v6.3.0+1.i686-linux-gnu-cxx11.tar.gz/sha512/2a34028687f75422b43f5365b0a8c9530b29473d41bfec4fb9822f074f813b8c6c1fc9efbfbb17a7e4d3d66f2549b5589b3fdbd08711a365330deb72be4958d0 -GMP.v6.3.0+1.i686-linux-musl-cxx03.tar.gz/md5/a2f2fc663bcacfc3e7d6aff29a52de23 -GMP.v6.3.0+1.i686-linux-musl-cxx03.tar.gz/sha512/a30a5d0ee78e747f074b3a5f0a26b9ba99b7553b3c83411a3cb9298814e605509194e9f0d8934caaa1cb7b78eef521805bbc86a297aebd06473ba80a20ffc443 -GMP.v6.3.0+1.i686-linux-musl-cxx11.tar.gz/md5/246b24935442815ff75a13b3dcf24756 -GMP.v6.3.0+1.i686-linux-musl-cxx11.tar.gz/sha512/ca351c4b93adf3f3e40f93c7b0cd61b33ec10049d39e8d33975f46d509efcded67600e6b19d8018a29ee893027d7a28edef0b19c1d70451d072a7a0989e9317d -GMP.v6.3.0+1.i686-w64-mingw32-cxx03.tar.gz/md5/c3b321ae48db0cb8dac4e09e2722e56c -GMP.v6.3.0+1.i686-w64-mingw32-cxx03.tar.gz/sha512/6a6feeb8baf6d499409a9010295b474a8c6de461fa0e34562d53e58190b66c50e278fae7560495cd85ea6f5b41f9e8c6e950ff4f451d26d0757e1d1696e8bca5 -GMP.v6.3.0+1.i686-w64-mingw32-cxx11.tar.gz/md5/3f633b0ff74c2a44350855fc6ce310b8 -GMP.v6.3.0+1.i686-w64-mingw32-cxx11.tar.gz/sha512/eecb17dec70fe84d90f47e1958672d273c865da9607ba3056c9c923a6ff9a3cab5b30414389d8f0c7f5ae5d87c05999964ed0900c80ae5afb525eaec00f401e2 -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/md5/8b5f113ad7fd4a312229cfe8c2d1abca -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/36525ffc0ac5c363810c47945c34c81daabf88cf1f9c60d236447249d06332d3f5a130b431ab2d1c0148eb5413a4fa66bdd50671f2e7fcb77858d9fcdf83a94c -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/md5/7f1237e9668136b00dd719a5cad3b6aa -GMP.v6.3.0+1.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/46a6efe23173a12299da371121847d16d7950ffe5c87d1221b54c5e95dafbf723c4a327b1c2e832d4742a91254aa40fd5d8152d6d0801769b2efd4f83a042afd -GMP.v6.3.0+1.x86_64-apple-darwin.tar.gz/md5/cd2d1b309aea2c781a9c28470fd2f0eb -GMP.v6.3.0+1.x86_64-apple-darwin.tar.gz/sha512/d7f94d80f1ba170c9553601d1af323bef7bbb98575b80b58b3d7b37d69d81cdee0e132fb4fa20393a0e8719984c785d0c7e5c8ae2c29c62ffbd82b00375993d4 -GMP.v6.3.0+1.x86_64-linux-gnu-cxx03.tar.gz/md5/5be8efef65dafe52e5726ef24238ae36 -GMP.v6.3.0+1.x86_64-linux-gnu-cxx03.tar.gz/sha512/f4c303fe915c89fecdb5a333a30412e0cfb04e07b4f1bc2f726179243dbc61d60ae5b0773a6bd5da8a10cb8764e448bc88035a639ea88d2e06f04e55074d8551 -GMP.v6.3.0+1.x86_64-linux-gnu-cxx11.tar.gz/md5/66f9a3858d07591227f2bc057c3c988b -GMP.v6.3.0+1.x86_64-linux-gnu-cxx11.tar.gz/sha512/5611b9bfd24efac0a189bbd85533e1cd2bee7f833f5ae0a06343f2c1d92925e0d0f0758b99c43520293348ad61f98e1b470829514c35d208697988d8b469fc41 -GMP.v6.3.0+1.x86_64-linux-musl-cxx03.tar.gz/md5/edaa83f6432ff7e75e106d8bfd03d509 -GMP.v6.3.0+1.x86_64-linux-musl-cxx03.tar.gz/sha512/1587e7b91e387da9c23559826c161fa4d447250bd7b6565f0b9fedc36e7502dc2b59caa8157abcb7e7862d24d696470289bd650511b07e8711ecf5a462330b6d -GMP.v6.3.0+1.x86_64-linux-musl-cxx11.tar.gz/md5/e668c4f0c1246aa1510c36f246b1b483 -GMP.v6.3.0+1.x86_64-linux-musl-cxx11.tar.gz/sha512/cf4bd47a5ddb067a57e852855fbd637a93f3652c3327af256f74e9e265c9e0de7c5be78b3e7bcbf08a03916876ecdc05cc294149e2c3d472a30fedc2e6dded47 -GMP.v6.3.0+1.x86_64-unknown-freebsd.tar.gz/md5/4cbf56d2884aa357291321b182d07cb8 -GMP.v6.3.0+1.x86_64-unknown-freebsd.tar.gz/sha512/0c723b8e0f5fabf9e43945d3fb355c3d7b036662a8d6542629aaff27164f12d13b2a19f5c4964f165466705b231884b7f7193d7a01a0e9d3644da1d79af79631 -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx03.tar.gz/md5/02e8f5d66c15731117cf805e0a4c4976 -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx03.tar.gz/sha512/1f94805fe9f34f4e77c54e92625615d91ade617468483409037d0693c3bf106187916d9d21e92681673faae158b376133c0ede643f31bfc9f73ac29c9fd13bcc -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx11.tar.gz/md5/10752137fccc73175872db07749d6f49 -GMP.v6.3.0+1.x86_64-w64-mingw32-cxx11.tar.gz/sha512/3a5d7e8125f3b538a2e59e9c6919db36c974575e6b1950451cb60307da68dc092c4ce21b8f49c40871aadf3bd07681b43eea9c7bf37ba383da9a0e80c30b176e +GMP.v6.3.0+2.aarch64-apple-darwin.tar.gz/md5/3fb601fcf70024fcc40889cf1b958441 +GMP.v6.3.0+2.aarch64-apple-darwin.tar.gz/sha512/7ecc97c1f22287e9d7f3e8073e1cc3c6b3c75aa4a350a55a0b6f92c5bf60339b52f8866994f5973077e1026b9d3b10a7bcd71ec2abf25c3cc1bf6ca1041c3e73 +GMP.v6.3.0+2.aarch64-linux-gnu-cxx03.tar.gz/md5/10581945c01bac319c9c2d76f1f7052c +GMP.v6.3.0+2.aarch64-linux-gnu-cxx03.tar.gz/sha512/3aa2799ef7783a4edb767a695bd2797776def8ce1b2dc471b2cc733371db9981d6c3f395fee2fb50b13c7ef74c1521d2787c29dc60a75e1b92652b94819b5364 +GMP.v6.3.0+2.aarch64-linux-gnu-cxx11.tar.gz/md5/c1f9765fccec8ec131faa5e31b7ac28f +GMP.v6.3.0+2.aarch64-linux-gnu-cxx11.tar.gz/sha512/aebde82400544dc7a2aef0a4531cee78f9abcac9352dfd5d86472a70d704b281de03325cc609583169ecbe4cb64623ab04a3d7fff9cf24c70991530fe530aa05 +GMP.v6.3.0+2.aarch64-linux-musl-cxx03.tar.gz/md5/b1f771c79f3b380555c1c96232074523 +GMP.v6.3.0+2.aarch64-linux-musl-cxx03.tar.gz/sha512/daca9d3b4179e99da8e61f4010f5965718c79d02627e0b3272e4d20c34dac0d933408dc7d760a6d6fa09546e436c800ad5da4a1d34283eac9558f3d2f97bebce +GMP.v6.3.0+2.aarch64-linux-musl-cxx11.tar.gz/md5/523c386457e9d48430b83f2db85ac10f +GMP.v6.3.0+2.aarch64-linux-musl-cxx11.tar.gz/sha512/18155dd92641bf6240606d23b0d3cab16bb9b63b6034a7c7c61f3728fb48a6b710fdc21c6477145c015c648557e97003b0cc6087b4b36a691daecb87272cd51a +GMP.v6.3.0+2.aarch64-unknown-freebsd.tar.gz/md5/7dd3f2813fd7e9e620a8123ae2340ab2 +GMP.v6.3.0+2.aarch64-unknown-freebsd.tar.gz/sha512/375b12dee41285b65b5cdd55f6b000a90fd431c3eeb788a928396a102594fb6fad257f2c4e707f11ce7d0e4d45bc82a77ac85d8a48fa0a42f969b48b8b2c1c23 +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx03.tar.gz/md5/7d23f84102362ec3974ca2d84da33c4a +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx03.tar.gz/sha512/51e419159fad75ca0ab12c31db29259be6fa280e66e2b980df4c99a0558615297741f633322978a409fbc071ec71834214b12d27d04ced0c043c569438dabd12 +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx11.tar.gz/md5/5f809ffa56ec07cc04e3c4cb155faad0 +GMP.v6.3.0+2.armv6l-linux-gnueabihf-cxx11.tar.gz/sha512/e394afb93a2c0aebe0ac7887bb2610720cb926256f0f5e7b05f3b1a805d3f7967fb97f4227ccec049df554c6cd1c4d4e9414fc4fea33f201204dd87e207e33ff +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx03.tar.gz/md5/494564a56197edc5b8772c15eca7b117 +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx03.tar.gz/sha512/a7bd8bc19a030c56edd4d91e3cff16d78d4a9c1c1bec99897e55cfaca7e14cb99cee32e220473e207b78f0b5e0c0bf188c679d1748c010380485fad4d89758c5 +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx11.tar.gz/md5/751c36d4975d6ff88eb968123afc1845 +GMP.v6.3.0+2.armv6l-linux-musleabihf-cxx11.tar.gz/sha512/af471834ba32a970b4f358a263434b03e169dc48445aa5af412ec51e70668a41699f9c408d90f64b06dc9233360f70a03df859428fdc0d759e5696a3ae32f3f4 +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx03.tar.gz/md5/ea9c867ae191a29647e8ccfb67947bc6 +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx03.tar.gz/sha512/d6c44c945d1ef869155be087320d7750be549399b186aad8c92bba32ff5312bf09cbb2fb57be91be237be7d50f8f6ef0aea67070f50c024e6f5302485f405d5e +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx11.tar.gz/md5/ee5becfac9fe3c448a5de322ddee66d7 +GMP.v6.3.0+2.armv7l-linux-gnueabihf-cxx11.tar.gz/sha512/bc9bb2ad83644cf0b9f2bb0bfce28938ee6e82dbc0de74d1f411a8eb5ab96c5ec00c648019384ec07f34a469bd984d6c62eac1bcb803eaa013b6c85547ec3277 +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx03.tar.gz/md5/23962e487398f02c8d660724d88bf7f6 +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx03.tar.gz/sha512/4c561053f79ed976a698c7382c5c94ebcbcd25ed27c939016bbb4af59948fd6bfb82e494e18fc7b4969941a7756c33afd2f177b3158f1b3d659215c25c958d2c +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx11.tar.gz/md5/4734feb61dd3f2a4e6e395f9ac7ccf57 +GMP.v6.3.0+2.armv7l-linux-musleabihf-cxx11.tar.gz/sha512/088a52c372681b4853fe7c4c70eb8625b58df6d79eea2a8982bd781458188930aa31dd9a121ff7a6d00cd8165f5d126155d7f931100aeff256b55a2281d44a90 +GMP.v6.3.0+2.i686-linux-gnu-cxx03.tar.gz/md5/e229a7a09d6c843f03028b036a54b786 +GMP.v6.3.0+2.i686-linux-gnu-cxx03.tar.gz/sha512/d92cccfdd7abe3ca5c6ee1eecfe3f7aebe875ca6b9f6257bf1181dc5ee9c873a930ebb2accc825596ee26dc45bd290a482f0405cfd7a3a1b0eb606f5ca897b70 +GMP.v6.3.0+2.i686-linux-gnu-cxx11.tar.gz/md5/01dbe43b15197cd39351dce91b3a62c9 +GMP.v6.3.0+2.i686-linux-gnu-cxx11.tar.gz/sha512/d6e7ea99f76e10b4f7733d8c7f4af3fb2fc09618510c222da1fb95e8b4c83b0aa7c5d2f896bb620546bf39041d6dc1b32ca74ddf5024ef1beb5526b374ba885c +GMP.v6.3.0+2.i686-linux-musl-cxx03.tar.gz/md5/ce2f8d8b59228888cb7f03da0c1aca70 +GMP.v6.3.0+2.i686-linux-musl-cxx03.tar.gz/sha512/cc024a2ca4b4f042c19f667c4c3c08e3041d9b9ea0279cc668a3c0212103e86444abbdb323304e05c506b44b3c1b32a55f90c04cc32e9d26ac013336821c9ac1 +GMP.v6.3.0+2.i686-linux-musl-cxx11.tar.gz/md5/c37741b3a03ef2e705d45124eae25afa +GMP.v6.3.0+2.i686-linux-musl-cxx11.tar.gz/sha512/c343ad2ea47d5775e6e4c50fd8d46745d39f3632f4ad479199f7583fd02b08a0126048625d3999b23a0534e4f5c2bf19d021436229689da7c794427102c7780b +GMP.v6.3.0+2.i686-w64-mingw32-cxx03.tar.gz/md5/52a773a2111f7b1f938e78263c4608b0 +GMP.v6.3.0+2.i686-w64-mingw32-cxx03.tar.gz/sha512/6ef89b7eda8f0709315c1080e4d57810f976939c755f160e34b04e4c199409c8c707036fae5a73fca3a16813cb4ceff8daca38d1ead73e36d7ff23506e5bb4b1 +GMP.v6.3.0+2.i686-w64-mingw32-cxx11.tar.gz/md5/88b1ff47d913fa301c95e9e2aecf42ce +GMP.v6.3.0+2.i686-w64-mingw32-cxx11.tar.gz/sha512/3d631ee81906627a8bd9194fa8f18b634467565c10e5e08db7d1a4b0943bae9391ae15a1c39533c9796edf24e1f0210d082e44dc7c1fbd9f93855f37e207da07 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx03.tar.gz/md5/0b2c73cf7936500ce0f07577c4c76ba5 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx03.tar.gz/sha512/30e099bd6384e801fb28b4741810122f82ab0760a4e09d6ab28559b72feff278a48150579907cb2920a624fc85287a197743331bc1808353d0855c198341bfa1 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx11.tar.gz/md5/f496279b474948435f836ba39291c708 +GMP.v6.3.0+2.powerpc64le-linux-gnu-cxx11.tar.gz/sha512/c37d4fbba284af87fc16a24bf1fdfe80b42c84bd44f1859d1c9ee97fdbb489817b58db80a078729e19c8a5b8448f9234408a8e477fd15acf15521f3129e86acd +GMP.v6.3.0+2.riscv64-linux-gnu-cxx03.tar.gz/md5/f07fc6751104a407ea2515fda3f26880 +GMP.v6.3.0+2.riscv64-linux-gnu-cxx03.tar.gz/sha512/435b375da747d2dfba06a303b55118471c6ef705cc65afeabb5a59477cc98aa9a956b31c5e8b571126f63d922498b9a66510f8f6810a60f6a4fabba5ec368cdf +GMP.v6.3.0+2.riscv64-linux-gnu-cxx11.tar.gz/md5/493c24a7a7370f308f0da2955f40b5d5 +GMP.v6.3.0+2.riscv64-linux-gnu-cxx11.tar.gz/sha512/2e1a7562b759219d1a4283372e66fa1e907279c5b5feb8a858f6bd8de8b9c2ef3ddd09d5e812d93813fa781090574fd26d0cec85b211274db628681301a206f9 +GMP.v6.3.0+2.x86_64-apple-darwin.tar.gz/md5/c3bb785e10fe19cf1c47db6bc5e98fdd +GMP.v6.3.0+2.x86_64-apple-darwin.tar.gz/sha512/5280896654e1c7864d770ecbfc853a1c7837c2b1dd369047432d10f831762a26fdaeac4201ca419d8bf7c545c107800b892660f4484b5eb87bfaf42c919fb640 +GMP.v6.3.0+2.x86_64-linux-gnu-cxx03.tar.gz/md5/0fd62bb914554c3cb6b5dc0f5ec0d330 +GMP.v6.3.0+2.x86_64-linux-gnu-cxx03.tar.gz/sha512/78cdf0cdcdca4a0ddc87755f4afdb8f290fa946b3c5541a3e31145f8bd905884d59f38e9f5ee4fe96ceaedaf90881af795f4e3ecf1be922103b838964da101cf +GMP.v6.3.0+2.x86_64-linux-gnu-cxx11.tar.gz/md5/02f54f8895bae0d7a824374888300744 +GMP.v6.3.0+2.x86_64-linux-gnu-cxx11.tar.gz/sha512/83c865f6164400e56c28949c680cf92457daa270b745d89034e1bcc46af1eb93c96bce708561dee03b58162191f6448e4325e921daec11083bbc42dcf3a1ffda +GMP.v6.3.0+2.x86_64-linux-musl-cxx03.tar.gz/md5/8f3f26422f8bd0889b5c2ecd22d97101 +GMP.v6.3.0+2.x86_64-linux-musl-cxx03.tar.gz/sha512/680beb99936433bc1c3367e85f3a4129c5a99d4c4031a1da919293819f6d3f1b85be801a2f48af352c47d7cb6f394534333f1a0d0404ff41899952d55c4b1f75 +GMP.v6.3.0+2.x86_64-linux-musl-cxx11.tar.gz/md5/7ec0e3e9125c14a20d6d0044036f0996 +GMP.v6.3.0+2.x86_64-linux-musl-cxx11.tar.gz/sha512/c22e6a25ec854f9c199d5e76bc1dbcbe57c4cc219eb2b5f24418729252eee1a5c1d3e8bbf5b62d148cb408595e96f448f68a29a9425a902952bee666b6f051f6 +GMP.v6.3.0+2.x86_64-unknown-freebsd.tar.gz/md5/6782d7fd0bd15c189c4a1753ee0fb0eb +GMP.v6.3.0+2.x86_64-unknown-freebsd.tar.gz/sha512/04d7a95337e832f7ec228f160a09b74ed7908ef9cef1bd392555392a24ff63ce4a88b616b5426cd710dcb581e164bb94c04fe17f0b599adf3c3bc33106bcd886 +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx03.tar.gz/md5/b4cb31e93c85cd453b7d8d392a365088 +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx03.tar.gz/sha512/3bd84fa8f580b272eecb06077ef710ae8df661126e86afa2c901b298a2598975a07f840b922da0066dbf555f03376cba1b7e4915cd37617341fd420b6707276d +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx11.tar.gz/md5/2342842254e7b47b26836366d29d6802 +GMP.v6.3.0+2.x86_64-w64-mingw32-cxx11.tar.gz/sha512/fb12be14433763d9de689a5df222802cd79d5c990da9a53855fd2f6f8e663a9838b444a310318c059cdb4962eb87d0d4cc2b54d163cf82b09377339c8e45510f gmp-6.3.0.tar.bz2/md5/c1cd6ef33085e9cb818b9b08371f9000 gmp-6.3.0.tar.bz2/sha512/3b684c9bcb9ede2b7e54d0ba4c9764bfa17c20d4f3000017c553b6f1e135b536949580ff37341680c25dc236cfe0ba1db8cfdfe619ce013656189ef0871b89f8 diff --git a/deps/checksums/libgit2 b/deps/checksums/libgit2 index 629a5f0601fcd..c1906c995cc73 100644 --- a/deps/checksums/libgit2 +++ b/deps/checksums/libgit2 @@ -1,34 +1,38 @@ -LibGit2.v1.8.0+0.aarch64-apple-darwin.tar.gz/md5/c19f3a4f6567b7504f607fc6f328312f -LibGit2.v1.8.0+0.aarch64-apple-darwin.tar.gz/sha512/0a776ab3eb4593abe0f2198a7371cbcf653ac5cf71ab7af9d5520c2bbbbbc981cf07ba3afa70f1ef6ea56f81e2d4b33b1be1482f9e215e61178b3dd1149ecb80 -LibGit2.v1.8.0+0.aarch64-linux-gnu.tar.gz/md5/8137d530bea16d41a614983068c1909d -LibGit2.v1.8.0+0.aarch64-linux-gnu.tar.gz/sha512/bdcb6249acd8df887a8af7c084d409132694a39f5e9f90bd70bba0f3eba2bad3eab6958cce9f060b2a4392d99352ccda8be92000f24ed4498c85ba55e0cbf13f -LibGit2.v1.8.0+0.aarch64-linux-musl.tar.gz/md5/4b9508ea58d4b1bd99f8471bd7c9a839 -LibGit2.v1.8.0+0.aarch64-linux-musl.tar.gz/sha512/e0996627a3d3ab9b3b1d103bbdd3e1179ede5479816f6b1be54471f120f76fe0495d3c7587c382985173c0614b634903b58c67ac3badbead82b4d797cc5915d7 -LibGit2.v1.8.0+0.armv6l-linux-gnueabihf.tar.gz/md5/02d6fae1745562cf724190929383688e -LibGit2.v1.8.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/11c14c5f395252143218a495c7dd2817c8f18f73320200a521f5ccd5f0c3c87403dee2c3b9e8166022fde1a67e83cbb83e6f222aac38b41efa43a6c0254548a9 -LibGit2.v1.8.0+0.armv6l-linux-musleabihf.tar.gz/md5/afa7b90751565b865f443b5a0a870d8b -LibGit2.v1.8.0+0.armv6l-linux-musleabihf.tar.gz/sha512/3594c223883a7da3bc0c78ae656fb15e47cc9dd196cf08f0abc0a1fb5f799842261e125440c07e92ba82896ad7427814bb43b63ba64d9b72ba38e9149132c26b -LibGit2.v1.8.0+0.armv7l-linux-gnueabihf.tar.gz/md5/ead27583a1cc5748c84d58a07fa6fc7e -LibGit2.v1.8.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/c81c3582fda7b299aaed72de07e9d0bd06c0c231aed73bb980c12c89b2b7593b2fb7990421bc2e45173f3d107ab50660842289675efa31f24ff752f0ebc63875 -LibGit2.v1.8.0+0.armv7l-linux-musleabihf.tar.gz/md5/71e38f112e8629682cc383c510f1f13f -LibGit2.v1.8.0+0.armv7l-linux-musleabihf.tar.gz/sha512/0b4b2677bdfc4f8e2a5ef3b9adf8fa2c0c1e76bd240b2173c268835b59cda29cbffc4241319fe36dcd63d1507ecf0e0e843f48fca80e3fbe4d3df53601ad7dec -LibGit2.v1.8.0+0.i686-linux-gnu.tar.gz/md5/b54cdd02201c1481746ab81db6f39aac -LibGit2.v1.8.0+0.i686-linux-gnu.tar.gz/sha512/0496a607b0d6841fc0c87477274b61eb95afa24d48d2624f8aaf230028a24d0248336902b01a326010fdbc45d8d73eecedb14c82313e1b1a94b3b6a4296e2607 -LibGit2.v1.8.0+0.i686-linux-musl.tar.gz/md5/b8946f9c1b83a7c22b2a8ca6da05b23b -LibGit2.v1.8.0+0.i686-linux-musl.tar.gz/sha512/931ff27da4e35749a5c020af72b750dce0b1d672cd98c04ad5a340f4f33ddb61c4df6711c36c6601063262fb733d45a3bb24eb1141e9d2fd2e0ab7b9bfbf54c8 -LibGit2.v1.8.0+0.i686-w64-mingw32.tar.gz/md5/cb9db0b590efe0c60f6e2f9558de4e5b -LibGit2.v1.8.0+0.i686-w64-mingw32.tar.gz/sha512/b9f637ec10cd751dfb2156e154a68809af400cdecbf0d25910792937c63ea56e60b703c7b78e3038ab34b1100bb20df79dce6346f40f1d24e5188fefe9517ccc -LibGit2.v1.8.0+0.powerpc64le-linux-gnu.tar.gz/md5/4ac1fa6b1ca43d3f6e97d590d1d27127 -LibGit2.v1.8.0+0.powerpc64le-linux-gnu.tar.gz/sha512/5cc3b9b9d85068bb3c6711c63ccb2672be765888a114147f70cae0eebf96f5bde00a40f163202c20e18a4cf4af2488fd1c304060daa3dd35748b30ab5a1fdb1d -LibGit2.v1.8.0+0.x86_64-apple-darwin.tar.gz/md5/26c2d1dcf68bc7b9919dfd24eb2fabc7 -LibGit2.v1.8.0+0.x86_64-apple-darwin.tar.gz/sha512/9c3ba94c438682f321cb2130f71028587a4a21b960f94f8c3f633dbe007210ff1b7b5e0b0bc4972e818458843a47a9e8d50d88f1bd3fb03a8fe129fa66332a38 -LibGit2.v1.8.0+0.x86_64-linux-gnu.tar.gz/md5/8d48ad388cca20d6338095cf8a36c3c9 -LibGit2.v1.8.0+0.x86_64-linux-gnu.tar.gz/sha512/9ddf4dc7420a9129ff8c34eb07ee94d9213c1a1c22700521199032a773353ab2413fd70d002b273a06dd951558128cd5577b7e917de6575d379911831d737bed -LibGit2.v1.8.0+0.x86_64-linux-musl.tar.gz/md5/5d9fd50bdf38ec99311e9627f254b95d -LibGit2.v1.8.0+0.x86_64-linux-musl.tar.gz/sha512/eae36cc70cb414e15924c22c9b03a98949b89fd8ca429fbe23fa215253266ed4cd11530adb2feccc9a19299ebf2048f1f5929c1faffba463b593b6c3e1808bee -LibGit2.v1.8.0+0.x86_64-unknown-freebsd.tar.gz/md5/af9e9d4bbe0df291f07f41416809a6f2 -LibGit2.v1.8.0+0.x86_64-unknown-freebsd.tar.gz/sha512/859786f13ba1fb5cd448dd5f22ebdf3381f5290d4875d65840fb31567ccd012f283a1849a82f2b2f58c3d73eda4c748d3da07d84a99665e0f50aeb39c37a4fb2 -LibGit2.v1.8.0+0.x86_64-w64-mingw32.tar.gz/md5/b51e3e238d776d52e396dd749f895e4f -LibGit2.v1.8.0+0.x86_64-w64-mingw32.tar.gz/sha512/2581d4b1d6fd4d0f15b406f050bd8a2a41e13dc2a1699a9b956e56426778beb994e6552988bf50ddad682349209a8694eace9450dab0570434cdfbed9c9f0b24 -libgit2-d74d491481831ddcd23575d376e56d2197e95910.tar.gz/md5/2420def04a290dd7ad0e67f93789f106 -libgit2-d74d491481831ddcd23575d376e56d2197e95910.tar.gz/sha512/496c6640d2453c58b66bc53c6e4e9e84f48d89eb8f240aefc1eea7e2d19b6c601614764590f2d2ca9e51e7e1de8fcdd5bf67f27f32bab628eae40d26ed382048 +LibGit2.v1.9.0+0.aarch64-apple-darwin.tar.gz/md5/1e22c2cf3e6003addd9bf16026ac4a06 +LibGit2.v1.9.0+0.aarch64-apple-darwin.tar.gz/sha512/78d5e5d246534164e1d70cf69dea273bbb8386df24c13fc3c3571762df15f2714307e7ff4cae6f977eee9def121c94cfe33cfcd44a60905a8161d65d17565e90 +LibGit2.v1.9.0+0.aarch64-linux-gnu.tar.gz/md5/70bfe9da256442ea2c295a016a89d3b9 +LibGit2.v1.9.0+0.aarch64-linux-gnu.tar.gz/sha512/14916a5521aa1281b443e61beee2573bc55b76d88810a3bec8bdea677d95763da82f1a527975cdabcdaa213e69aa1640201a03656bdb505b886906795aad0c74 +LibGit2.v1.9.0+0.aarch64-linux-musl.tar.gz/md5/62f6e885de29a345cc5ee3e773c74471 +LibGit2.v1.9.0+0.aarch64-linux-musl.tar.gz/sha512/09e793209505ea954e608c609138b8865d8a1630340fa8ff032a55234bfb8277d2c3c31f26048ae4993bf8c3d8f165abd0b4ccd80526c61efca0807f634572df +LibGit2.v1.9.0+0.aarch64-unknown-freebsd.tar.gz/md5/6fcba6e43265aa7a1ea5bba85977d622 +LibGit2.v1.9.0+0.aarch64-unknown-freebsd.tar.gz/sha512/34b836d3c22436e74963141dbe1f9372cb7ee695ebb2054ee0af1353d4401e1dfb855e91341a1d06a24ce18d57caaa3aa1e2bc7063000fa4f9be40130eb6ff95 +LibGit2.v1.9.0+0.armv6l-linux-gnueabihf.tar.gz/md5/75ede2c2c7312adf06a2a9859cd6310f +LibGit2.v1.9.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/9de567bee3aad33eebac51ad5b57b4fefaa4b778ce8510b2524a55cd223bfaf3051fd48c8713741e799d1464b308469580716dcb847a6eb97fd632727ca22a7d +LibGit2.v1.9.0+0.armv6l-linux-musleabihf.tar.gz/md5/e5341f0c76c89273c465cb43cbf0f284 +LibGit2.v1.9.0+0.armv6l-linux-musleabihf.tar.gz/sha512/1029d47c82ce20223b1c108da77a1a32ef0b91b9645040c1d941e7abdd161011736a81f4ad25006b32d83d4c07c548fcf1c8a3326cf3cb91d56fd443e2e9ced7 +LibGit2.v1.9.0+0.armv7l-linux-gnueabihf.tar.gz/md5/03191a1c4ff1c1ae764092b26c941783 +LibGit2.v1.9.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/6bb113c722b550fb28fc84033a3a38565ed5305a7fa193eeb4949b979fcf4599b84c748f50dad2ad47481827138a6e405eaf727f719d219984a809088bbb2948 +LibGit2.v1.9.0+0.armv7l-linux-musleabihf.tar.gz/md5/1678d6e57aa887963b27917c884cbf36 +LibGit2.v1.9.0+0.armv7l-linux-musleabihf.tar.gz/sha512/52590e9ca4118e0dec70191353b2c76155363df77df6c0bb5741dfb3f333539a8ad75339796748a744c342b51c15869726cfe9bbf6ca78d524e7d2ccce4a4622 +LibGit2.v1.9.0+0.i686-linux-gnu.tar.gz/md5/3fc50746cb80e0455f8e7c7622cd433a +LibGit2.v1.9.0+0.i686-linux-gnu.tar.gz/sha512/20c97e1a816456267a16759378a5e968e6bca122d1e0dc7cc282cad2bf2a8e3929e90373752065d91dfb6688e39ac6db660d9bdbb3277f1b9cb04b5d3f46fd8c +LibGit2.v1.9.0+0.i686-linux-musl.tar.gz/md5/fadb5e051e3b21e68a61b2a3049f65c7 +LibGit2.v1.9.0+0.i686-linux-musl.tar.gz/sha512/369c8c64df89149e9ed600028c1ac96db24e7b2c1977146667b8aeba93aa7a3b4787a49734411448680654188ece33e740fa475108b80b876a5082edad722925 +LibGit2.v1.9.0+0.i686-w64-mingw32.tar.gz/md5/610da247e41070b73e71df7e41267846 +LibGit2.v1.9.0+0.i686-w64-mingw32.tar.gz/sha512/d5b61c885133e3002e48e0fc37ceed0bfeef070e8fc6b2d78ec5f3069ad80966ea5b3a2b3aeae1ca478e9a2f839309fd67c3a186ecf751f4642ff4cb4ca3cb38 +LibGit2.v1.9.0+0.powerpc64le-linux-gnu.tar.gz/md5/f05f5f07de55fd297c564b6cd4e54747 +LibGit2.v1.9.0+0.powerpc64le-linux-gnu.tar.gz/sha512/57b740ca3ef6b18994386d74f1cf39c97c1f58f5a63e749c1a0dcef8c43a915f13cc093a8e1d06cef1d1c60cf484ba0e38d20a96344df69dfc997daa63ee1137 +LibGit2.v1.9.0+0.riscv64-linux-gnu.tar.gz/md5/b043226b10e5cbbe4914be3392f5bf72 +LibGit2.v1.9.0+0.riscv64-linux-gnu.tar.gz/sha512/a580795dd9a7ee237cd1d51d55f5079588686b1adfe391a017de743946e1bd4e7d5e4f8b79a6f84f0ce165733ca1b67ea740d06fa18547c29616df2f73e3f289 +LibGit2.v1.9.0+0.x86_64-apple-darwin.tar.gz/md5/bad8607d4997ef82cd43edfc7579d0fb +LibGit2.v1.9.0+0.x86_64-apple-darwin.tar.gz/sha512/c7359d79949a6727973b1df2264b672bfcd1617b6d4c74d281ef70ac93bcadfe47f99f7a5d031eed36b65077668ba12f2b31bbe6d491542b6938816659070317 +LibGit2.v1.9.0+0.x86_64-linux-gnu.tar.gz/md5/21e5fd214a6358f643477973c22ec70c +LibGit2.v1.9.0+0.x86_64-linux-gnu.tar.gz/sha512/9e68cb6d25d85ad272fcb0d77deedce2daa9c62d7ce2fd7e9221647d021aa00e372f490ad29211d7ca2b5ddefb4addcc4733e25e3df038aaf26fe3cb269d8f56 +LibGit2.v1.9.0+0.x86_64-linux-musl.tar.gz/md5/e9ad320825b22ee378b33856ca266b12 +LibGit2.v1.9.0+0.x86_64-linux-musl.tar.gz/sha512/bd33b4d31a7622a0440bd0979ecc7bbdef7ba7a52bfc911f880c9430d57d2b9ea1c6c4e57697b5a2b63c2e00e07673b3dad6feac056a4f345ed6e3b0ef7aef77 +LibGit2.v1.9.0+0.x86_64-unknown-freebsd.tar.gz/md5/501c63c8810616e6764ff80c23fff0b5 +LibGit2.v1.9.0+0.x86_64-unknown-freebsd.tar.gz/sha512/109e5676899ba6992a68fcff6d7503f49cc3b748b4b0faffcf951f318f9730e242914b57a7848111e229642070fdbce29bc181cbc79ac2e794c6ef489bb27293 +LibGit2.v1.9.0+0.x86_64-w64-mingw32.tar.gz/md5/4e76fa8356407a7065b50298817ad462 +LibGit2.v1.9.0+0.x86_64-w64-mingw32.tar.gz/sha512/01204b29ff2f90a9204d2e91fb7d48a3b6bea008a77984e3e67423a04f630690073d648a7200168809999aa5885fa6035c5b099256724b0379229c257ef19b9f +libgit2-338e6fb681369ff0537719095e22ce9dc602dbf0.tar.gz/md5/0ce4a212921ef1752ea057a3be45e384 +libgit2-338e6fb681369ff0537719095e22ce9dc602dbf0.tar.gz/sha512/4eb018a85a59c6ac0514f09f19a40813d8a4bc5ea230bf54897aa2ef5f584796e8c680a27ac68985a3457e1ea1f554ba4af803b430d67a9065cf51ff317d7a89 diff --git a/deps/checksums/libssh2 b/deps/checksums/libssh2 index 697601a037132..056d373656d98 100644 --- a/deps/checksums/libssh2 +++ b/deps/checksums/libssh2 @@ -1,34 +1,38 @@ -LibSSH2.v1.11.0+1.aarch64-apple-darwin.tar.gz/md5/462442a50f5dd719d251f65e7170dbf6 -LibSSH2.v1.11.0+1.aarch64-apple-darwin.tar.gz/sha512/8f0d9916c1e1abb8ba2d4baef0f850f9f5aa8d24f5eeefd7c7d30697b15d33180b32588f50328f4999e1d4136a2951c4e3319c5a5dca6f34a84fba30ac90518f -LibSSH2.v1.11.0+1.aarch64-linux-gnu.tar.gz/md5/63d8a681bcce23e76650719cf3c6999b -LibSSH2.v1.11.0+1.aarch64-linux-gnu.tar.gz/sha512/9dc722d866d27f378481e4787a5bb932facc0c7b828e75e812c9c875ac10e7194d090d94e01a46bb2b3c5624e18d013f0226c5f574269df96f1de0ed16897571 -LibSSH2.v1.11.0+1.aarch64-linux-musl.tar.gz/md5/e85cfee900145726857d3609b541f7b5 -LibSSH2.v1.11.0+1.aarch64-linux-musl.tar.gz/sha512/ad42ddf4674f6359e61fb23ef6fb5942e716c6f0cd50378e93b8c3af799b9b21cc9cefc471d27e19bc31686c7aa469a5ed81918ea9926d5d432c3c5f70e83fcb -LibSSH2.v1.11.0+1.armv6l-linux-gnueabihf.tar.gz/md5/acb3b46ec386e9d41dd73cb3c9b60d1e -LibSSH2.v1.11.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/bddc50ab698c280256d819cd7ea1a39a33366f2eb6004df6b66f6a45ce4b5bdb1525f724aee35f3b9796809f9e68db4a6dab01ab035c8a88bec291b59fd55854 -LibSSH2.v1.11.0+1.armv6l-linux-musleabihf.tar.gz/md5/d4efa89a3b4e1d3be80f6790e183ad07 -LibSSH2.v1.11.0+1.armv6l-linux-musleabihf.tar.gz/sha512/8da36af6514189b7bf3422ccbbbf69d271208e7d9b0af469cbbd476ddd3d62f2f9a0d25f38f22123a603e448c285936f0692a31d91d6d79dfc66baacb8af4522 -LibSSH2.v1.11.0+1.armv7l-linux-gnueabihf.tar.gz/md5/d4eeaf06f64997a4f46737798c15ccb0 -LibSSH2.v1.11.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/4cb24ec2b13c9f56220a6cd3bb0ea1dda687a7ebbf062caa8fad9d17c903a2982f12340b93e82b42567e29b4326acda373f81c0ebb4f4d968a12ff7807f5d066 -LibSSH2.v1.11.0+1.armv7l-linux-musleabihf.tar.gz/md5/319db985d453fc32a69eaad85bdbeac4 -LibSSH2.v1.11.0+1.armv7l-linux-musleabihf.tar.gz/sha512/5f7f35e3cb1362ecda3236c1686a211409937e90fdb29dd9e4032d541b8fe45c28f24067cd012edef879d668d7b1040e887ea594eac03ffe5412d5f2c49cc294 -LibSSH2.v1.11.0+1.i686-linux-gnu.tar.gz/md5/e7cb7d9d6db13b46250da30969f8504d -LibSSH2.v1.11.0+1.i686-linux-gnu.tar.gz/sha512/fe8983aa012787361cadb5a78df8eec6ac5640a514c3fe4b4ab23d584b018ba4fa7d3514f0951d2b687cf56bf9ee17e247049d99a4e9360aec4ecbb636d2a6f1 -LibSSH2.v1.11.0+1.i686-linux-musl.tar.gz/md5/d7c5d3e8ecd86e216d97d4912457a66c -LibSSH2.v1.11.0+1.i686-linux-musl.tar.gz/sha512/4d64996d837cfec15b42ca7f850cda32ee3b3a8f93001d24f95ff6f8c94b76517e5dfc7e525e8335fc8788ecf7e196bdb7cc64c8c53f536c592afb337d98ee82 -LibSSH2.v1.11.0+1.i686-w64-mingw32.tar.gz/md5/9562e41b5dda94c23150668559e9b123 -LibSSH2.v1.11.0+1.i686-w64-mingw32.tar.gz/sha512/d13d022ec9eb82f8afa3954c730bd1840a8d1bb16cdbd07a89fff6ce07b1c0c2ba6a9e934b2585abf7dddcb0522e1ba0f38df4385447c66986d5fcb6dddc2d15 -LibSSH2.v1.11.0+1.powerpc64le-linux-gnu.tar.gz/md5/4e2463eb11a5dde8c3e0d3fab6c58169 -LibSSH2.v1.11.0+1.powerpc64le-linux-gnu.tar.gz/sha512/d8794571d051cf206da87a4f7f0f71c8b41be061691b08333df7678c4e40fb9abbe63812a5ff5243fabca9eb2e599d81a69520cd854afbddbc16b44678fbe1b7 -LibSSH2.v1.11.0+1.x86_64-apple-darwin.tar.gz/md5/5729492b3a91e0d8e3fcc459de784157 -LibSSH2.v1.11.0+1.x86_64-apple-darwin.tar.gz/sha512/8e49b2ff1c9b5ae499f14be238776d7da2b64231592f1d46a6f769f200681342ff157d76102fa7c16b2972c7fe603919f7d2ce7c8a30b46c98ecaf2ef809fe3c -LibSSH2.v1.11.0+1.x86_64-linux-gnu.tar.gz/md5/0f7f2214d453f562107fe22af5004e8a -LibSSH2.v1.11.0+1.x86_64-linux-gnu.tar.gz/sha512/bd510f25dc26c05362ff204adcc356521bfdacd665411a99e07071ea0c4638274a2e78f009644cdf5e472a1d81c80e353f4673071d90411e6122b55160140f3e -LibSSH2.v1.11.0+1.x86_64-linux-musl.tar.gz/md5/ee98538d67b8b091c4ddcf632e72e7d1 -LibSSH2.v1.11.0+1.x86_64-linux-musl.tar.gz/sha512/38cbb59ffa420e4299db848b6ae95098e8e3e6e1334e05369089d17b04fcd0787ad22ba69465611f3e335a1efab228990db776916f40a937b21b18ca511a4484 -LibSSH2.v1.11.0+1.x86_64-unknown-freebsd.tar.gz/md5/0abe5a971abe63c3db4353e7e9b181e9 -LibSSH2.v1.11.0+1.x86_64-unknown-freebsd.tar.gz/sha512/8e8199bc0634a8ec51460cb8628c3b33d765b7060ca79aac3e80a0b29d55de5562cdbb36945b4a9feab5392f7f16d2dc48684e43d54c62a9fdb1f07f36b71810 -LibSSH2.v1.11.0+1.x86_64-w64-mingw32.tar.gz/md5/d30fc8e9b74388a1c642cb15ed33dba3 -LibSSH2.v1.11.0+1.x86_64-w64-mingw32.tar.gz/sha512/e278b87d081fbbe15f88bafa8870f0f294cea3ff8c8c1fc9a6c10228da91717aa3caa268cdb10f78c8e55651a90243962f85101eeb4433f85c1dfacc1461d96d -libssh2-1c3f1b7da588f2652260285529ec3c1f1125eb4e.tar.gz/md5/7b52de6ff70e16aa78cd699fee3e997a -libssh2-1c3f1b7da588f2652260285529ec3c1f1125eb4e.tar.gz/sha512/7c99d33e60862e2d89bbcc4a09ffff3fbfb921ed674e0d3166a255c72a8e0622a9c6be64f0eb2f8c12ddd80da0307b05d761615b876194bd854aa2c62e26f4ad +LibSSH2.v1.11.3+1.aarch64-apple-darwin.tar.gz/md5/87ba86e78421d6195aa6a46129ff61d4 +LibSSH2.v1.11.3+1.aarch64-apple-darwin.tar.gz/sha512/2b7129be9e9518337f59857474882a6a3448f358c931c66ab9f9ec67506c68d2356df591bd45925154844ca0d6f6e1f071d4c54d62039c5078b468fcb356187b +LibSSH2.v1.11.3+1.aarch64-linux-gnu.tar.gz/md5/84c6eb68e7797038d0863513fa4e292f +LibSSH2.v1.11.3+1.aarch64-linux-gnu.tar.gz/sha512/3012beb35fdf94136907037e8f5261a5cc94d102f461172321d4ed8f328da3789d521513dd03cb344c6fcb73675cd1d3ede606bf9a904fb811d40c43fd09d8aa +LibSSH2.v1.11.3+1.aarch64-linux-musl.tar.gz/md5/5a49057201e779f3427b794b72bf07a2 +LibSSH2.v1.11.3+1.aarch64-linux-musl.tar.gz/sha512/62a812efb4ad7b24bfeeb3bb89756004215c09a1cc01e0530f14ce4b8546f1dcbbac18155ac2ce08311c1790d659b14674e3bb3549ff68d1209d52b5e5986fff +LibSSH2.v1.11.3+1.aarch64-unknown-freebsd.tar.gz/md5/a5129167b7be7ac8ba2c873e164afb1b +LibSSH2.v1.11.3+1.aarch64-unknown-freebsd.tar.gz/sha512/f8d9cc5098a3b401fbbe98a24efaca0ea46f533ecaf11dbfe8f7e7e3853363af19914de62bd1cb5a573e55e90d5c6074532ddc6d64723c9e235b277f438ce6ef +LibSSH2.v1.11.3+1.armv6l-linux-gnueabihf.tar.gz/md5/5c59c95612bf9aa172e5d487002db509 +LibSSH2.v1.11.3+1.armv6l-linux-gnueabihf.tar.gz/sha512/5ba41e49365c2018d55c92e4a23d806ca9ab960a448593b08380527da21eec03f76cab89c34befbc56f4104002aa189d5cae6f655797f1447f395b51a14d40e2 +LibSSH2.v1.11.3+1.armv6l-linux-musleabihf.tar.gz/md5/4bc27411f0eddf82a787d1ede17ce2c3 +LibSSH2.v1.11.3+1.armv6l-linux-musleabihf.tar.gz/sha512/d6024b6949ac6867c56c66defbb99300a5661e0c73da6c330165bceba78d64063986c8851601ca74554b27944d5b02e3f602b1e71781097bbb8b12effc0cbbdb +LibSSH2.v1.11.3+1.armv7l-linux-gnueabihf.tar.gz/md5/40e1a0d323969b96ab121eb5a3ecc874 +LibSSH2.v1.11.3+1.armv7l-linux-gnueabihf.tar.gz/sha512/67ce15a5b1c1fe0fd1096ed5d2d9f44d83983de11c1bc651f5914d70d387a99ee6bde31716031b758f48981e2a9383599f077f02d61a5c783ee6d09a7bf445db +LibSSH2.v1.11.3+1.armv7l-linux-musleabihf.tar.gz/md5/9453c52394b1b06bd36c43e461a3b48f +LibSSH2.v1.11.3+1.armv7l-linux-musleabihf.tar.gz/sha512/c62068ecb1b88dbd08a2474e0b93cd313bdc4e1407a22cd9164a73b2d897564f12a3c34f6fc492b264af579b00e9335a0fe1fa853fbe0fbb18d8335b77d409b2 +LibSSH2.v1.11.3+1.i686-linux-gnu.tar.gz/md5/992453b1c59033aefa8d98b89f491ff6 +LibSSH2.v1.11.3+1.i686-linux-gnu.tar.gz/sha512/ebf14565d614086c4401e1a997a3aacc83f8e499ed836c429f87c4f95f1c8409713fad47f1c34a2b1cd23f90de3daf14caafba3c82b15642018592213607c874 +LibSSH2.v1.11.3+1.i686-linux-musl.tar.gz/md5/e0cb0566c724c107f4f04619080d4c0c +LibSSH2.v1.11.3+1.i686-linux-musl.tar.gz/sha512/af7d08dba5bb06eaf7ce8aeb12b69701d3c2829996a1c8e68510c106402a1166ad060687987df49365c26d30e8d6511c66f2a50ec810a493d2c090931ccf05a5 +LibSSH2.v1.11.3+1.i686-w64-mingw32.tar.gz/md5/c5e8d3145deb56d6df008522a5d3ea6f +LibSSH2.v1.11.3+1.i686-w64-mingw32.tar.gz/sha512/47f3c36747d2e42a4c0669ef468d395078328235d30056b7d67d76bd737b5118c1bbc720aef455c4d9017e7b9350e8cc043ed28264ea8a9ecb6833ca517f82aa +LibSSH2.v1.11.3+1.powerpc64le-linux-gnu.tar.gz/md5/12eba4aec5e320a4d0cf09225bca3f7c +LibSSH2.v1.11.3+1.powerpc64le-linux-gnu.tar.gz/sha512/d6b8413d77d8af3d29b867692f6c02b63e793f5e8f17c4777756d247c8e602b3ab87380031aefa60f2c3ddae5a3c7a1f1c739439f149db34a32c79f32e08048b +LibSSH2.v1.11.3+1.riscv64-linux-gnu.tar.gz/md5/cc11dd403ecaa373241b3c30cd16bd24 +LibSSH2.v1.11.3+1.riscv64-linux-gnu.tar.gz/sha512/d195ad62cde58dfa1e3546efd70a5f6b8a0762a2a933c637120aa71eda45dc6dc4213e87f9f401e2e148bbd5fb10638e429ae514bcda5bada0940c70cb7ff15e +LibSSH2.v1.11.3+1.x86_64-apple-darwin.tar.gz/md5/f6e7cd35e16290b198c80c61a0fca5e5 +LibSSH2.v1.11.3+1.x86_64-apple-darwin.tar.gz/sha512/2c83814ef6ae78ec94a43f2997151dd7195c0a0f9cf456fcd3f780268bd1cbdd7ea55182fc5a1f8e1413c26889e54fccb01964b0b91dd4b925ecaa16b7df8d07 +LibSSH2.v1.11.3+1.x86_64-linux-gnu.tar.gz/md5/95aa96befc9f9007e6a000a95c1b7572 +LibSSH2.v1.11.3+1.x86_64-linux-gnu.tar.gz/sha512/6058dca6d933afb7fe5fc3374937b4432f202a5dfe3ebcc2f91f65777230c18d76801c38071f84f8362527ee08656a97f79da234ab5481265a7ccf29e94c20c5 +LibSSH2.v1.11.3+1.x86_64-linux-musl.tar.gz/md5/88b69d889d602bc3df420535dba30f9e +LibSSH2.v1.11.3+1.x86_64-linux-musl.tar.gz/sha512/7335954124074e7df786989db86e86e3bcf41f503b8e3b27d6ac18032c8025bec26180bd2c537b23349bcf5673eb67245531479b939670e620faf5aa13c8c4ab +LibSSH2.v1.11.3+1.x86_64-unknown-freebsd.tar.gz/md5/6d5f6e9455c35c5f6655cb4d46797db0 +LibSSH2.v1.11.3+1.x86_64-unknown-freebsd.tar.gz/sha512/9515d11bb5686e29eb5a37bbcb7ab07574da0869c82e5b3f0cf282bbc56792af31e6174521d58133968b997caa6db75ac9b195024144fd2c95fd1bbf689ebbf6 +LibSSH2.v1.11.3+1.x86_64-w64-mingw32.tar.gz/md5/e66cdac0c2d5ce2d160e482d780ad0c3 +LibSSH2.v1.11.3+1.x86_64-w64-mingw32.tar.gz/sha512/2dabb1e8da5ea496898751d5517ca37178e1a44c78c26fe33f87487a0b4acf7185f686ce8d6ea0e65e38a8fd56e5ff09fd70becda402a942b5e459707eb2a44e +libssh2-a312b43325e3383c865a87bb1d26cb52e3292641.tar.gz/md5/06d5e2881ac023583c7fd6665d628a87 +libssh2-a312b43325e3383c865a87bb1d26cb52e3292641.tar.gz/sha512/5dee8cce91853eb8c9968d7453b1ad0c3cd1411901d288f1731b7c7e4adf380313f61c2a66eee0d3b89eba79e420e13269bb3738bcf2c59f0b88276aa785fa8c diff --git a/deps/checksums/libuv b/deps/checksums/libuv index 49869af795d45..fb2904b308a90 100644 --- a/deps/checksums/libuv +++ b/deps/checksums/libuv @@ -1,36 +1,38 @@ -LibUV.v2.0.1+19.aarch64-apple-darwin.tar.gz/md5/f176c76e5e2096dea8443302cf9550b8 -LibUV.v2.0.1+19.aarch64-apple-darwin.tar.gz/sha512/4301b13953a08a758b86e30af3261fd9a291ce3829b4d98e71e2a2c040e322e284c5a6eb4bc7189cc352f4b1cf7041e2cfd3380d511d88c151df3101ad74594e -LibUV.v2.0.1+19.aarch64-linux-gnu.tar.gz/md5/c81515783363702a1bd4b65fd6d7f36b -LibUV.v2.0.1+19.aarch64-linux-gnu.tar.gz/sha512/011429365337f5a45e56ca7a42709866bb994c747a1170d870f5f3ddfff2d36138866ee9278ac01172bc71bde8dee404bcb9cae9c7b44222bf1cc883659df269 -LibUV.v2.0.1+19.aarch64-linux-musl.tar.gz/md5/e74d5ea4912dd326b2705638faa7b805 -LibUV.v2.0.1+19.aarch64-linux-musl.tar.gz/sha512/a26a9f2c9051816230324071c502321f7af3885d581a400615858a93a4cd457226048d15b0e7f6a73d12659763c705b5ab519e9f5b35c6d886b9fd5babbfe352 -LibUV.v2.0.1+19.aarch64-unknown-freebsd.tar.gz/md5/f2fe50ada3b6935af4f6b28fbc3940b2 -LibUV.v2.0.1+19.aarch64-unknown-freebsd.tar.gz/sha512/c4ba0190d21c6edb561062b2615792e9b4c2474dfc200d9dba12a3add44e1fbc0b74989748d85576f0a6e42d8e0bc02f6cb13b5963f3a56b00edffe6348a9f26 -LibUV.v2.0.1+19.armv6l-linux-gnueabihf.tar.gz/md5/6df38bcf5d0a61dee63d16b73d0c9a24 -LibUV.v2.0.1+19.armv6l-linux-gnueabihf.tar.gz/sha512/d5354a6532061de0a58965ce0e427bde52f9ae0ee39a98e1a33de4c414fddcba9ba139ddf91be7321a4ccc97bbf7a8a8357ff10cf60f83c0a6bff7d839d6d7a8 -LibUV.v2.0.1+19.armv6l-linux-musleabihf.tar.gz/md5/6f02a24cfbfae3032fadceaea1faed39 -LibUV.v2.0.1+19.armv6l-linux-musleabihf.tar.gz/sha512/7fd107eb9a5ea84b488ea02e4fbedc9fe13bb11be859986a47af38f40ad775dd9f738c790878a3503437bcac1eb26ad9fe26f4aa0d3cb45c980b4c5abc9aec99 -LibUV.v2.0.1+19.armv7l-linux-gnueabihf.tar.gz/md5/96b09dec72f7e9b7409fa2920e67c866 -LibUV.v2.0.1+19.armv7l-linux-gnueabihf.tar.gz/sha512/6a0f79fc15c944fabba5c65180b665bc9769c6ff25863e330049f48b3a4394b448492f5a9a76bb7f8dbd3ce44dfc6f9ccdc2c71c42e1c749e88070fe99b1db69 -LibUV.v2.0.1+19.armv7l-linux-musleabihf.tar.gz/md5/f44e4b2521a813181f943895bdb0dd3c -LibUV.v2.0.1+19.armv7l-linux-musleabihf.tar.gz/sha512/cda1413dca817f772e8b343db0c6de0ef6b8f269e9a6a2ef3403c2582aeab554f46281bbb1eb4659c259198ef47fe26aab648a281e66f80aaf2f2cda0a23ac05 -LibUV.v2.0.1+19.i686-linux-gnu.tar.gz/md5/1f231d89cf9c04515d2d107a5d786cc8 -LibUV.v2.0.1+19.i686-linux-gnu.tar.gz/sha512/089cb8a372cdee0cbc0e78fc201611bb9bafd99af9a78e09d6097a6b70e7c4aa001ebd86f944b0a885c072093c529bf86bcaa32bde4fc1934407a858c1a5a764 -LibUV.v2.0.1+19.i686-linux-musl.tar.gz/md5/01cfc2a9e2536dbd330267917abb19ce -LibUV.v2.0.1+19.i686-linux-musl.tar.gz/sha512/72f3588cb464a60e61f8998242aaa2abdf93df920a2feba5e1d66ef0f2498488df0ec415cbb499d7f75c47bdfc7e3a2fdda6a94383492e0ad13e464eb1314ff8 -LibUV.v2.0.1+19.i686-w64-mingw32.tar.gz/md5/8c6599aab9ed4c46e52f03683aac664e -LibUV.v2.0.1+19.i686-w64-mingw32.tar.gz/sha512/13f0565f7244a8bcf1ab43fac91a856dc86d214877033a3cefee8c2179c1a275dfd7dda32e9017763acac2ba42ab6799934a58f5feaa38fb6cf2253dd713f57a -LibUV.v2.0.1+19.powerpc64le-linux-gnu.tar.gz/md5/af0e43d9d0aa91dd82b63220d96991ef -LibUV.v2.0.1+19.powerpc64le-linux-gnu.tar.gz/sha512/9fabe3089e4fc60e910770c32d36300ce8ef36c28e8cc9c72fbecba6eb80285ee8174e84e4452fb4ce90ee7c7f94e99b03fce47d8c579bd614bfffd553f93666 -LibUV.v2.0.1+19.x86_64-apple-darwin.tar.gz/md5/871040e874eedae54553d8f1c91b9133 -LibUV.v2.0.1+19.x86_64-apple-darwin.tar.gz/sha512/d5eee08b65e4bb8b444c61ac277bec9ef944b9279dd7f0732b3cd91d47788c77938e5db71e019e01bbe7785a75df95faf14368764f700c6b7a6b9e4d96d6b4c2 -LibUV.v2.0.1+19.x86_64-linux-gnu.tar.gz/md5/d2d186952c6d017fe33f6a6bea63a3ea -LibUV.v2.0.1+19.x86_64-linux-gnu.tar.gz/sha512/15501534bf5721e6bb668aabe6dc6375349f7a284e28df0609d00982e7e456908bd6868722391afa7f44a5c82faedc8cf544f69a0e4fb9fb0d529b3ae3d44d78 -LibUV.v2.0.1+19.x86_64-linux-musl.tar.gz/md5/271d4d40a1ae53ed5b2376e5936cfcf9 -LibUV.v2.0.1+19.x86_64-linux-musl.tar.gz/sha512/1956f059ed01f66b72349d6561b04e6a89b7257c0f838d7fbdd2cee79bd126bb46b93bf944a042b5a6a235762a7a0cdd117207342dd55a0c58653a70b4a38d48 -LibUV.v2.0.1+19.x86_64-unknown-freebsd.tar.gz/md5/62fe8523948914fbe7e28bf0b8d73594 -LibUV.v2.0.1+19.x86_64-unknown-freebsd.tar.gz/sha512/e6486888028c96975f74bc9313cba9706f6bf2be085aa776c44cbb2886753b2eee62469a0be92eb0542df1d0f51db3b34c7ba5e46842e16c6ff1d20e11b75322 -LibUV.v2.0.1+19.x86_64-w64-mingw32.tar.gz/md5/ae103f24b6e1830cdbe02143826fe551 -LibUV.v2.0.1+19.x86_64-w64-mingw32.tar.gz/sha512/f814085c135815947f342ff24fa0e1015e283ccece84a5b8dd5ccec0f5928a129e5fd79100a33b131376ad696f70b5acadcc5a02a7e6544635ecf7e18003ba1c +LibUV.v2.0.1+20.aarch64-apple-darwin.tar.gz/md5/7b889e32bcb01afc19f9f3801b28a0fd +LibUV.v2.0.1+20.aarch64-apple-darwin.tar.gz/sha512/cfa58e835512957171c7f2dcc9171bd9ea1717f71ed6920b6cac2560da3c5b13440df0d14c5aee210df3346743d3605dec22d78891e8237f5c3867d5cb6d4f56 +LibUV.v2.0.1+20.aarch64-linux-gnu.tar.gz/md5/696ae3e79f9b838a98dae8152d980ff4 +LibUV.v2.0.1+20.aarch64-linux-gnu.tar.gz/sha512/74ac009cebfa3ec67209921296f5d395c2f888d825b0f3d3f3bad5432819deaf5ee758f88030e620530e94f4861734d7984b8ef981ae4eebc356d96e274d678d +LibUV.v2.0.1+20.aarch64-linux-musl.tar.gz/md5/d23a45e4d9cefad93e3e83cf990c095a +LibUV.v2.0.1+20.aarch64-linux-musl.tar.gz/sha512/80d06afae0b5ab657c5c743beeaff112c3cddabd2a2604f8fc16a50cab5db878b4ea8941496a11004c9464bcada13844528cc4fee209bdd8ba374d9b13351991 +LibUV.v2.0.1+20.aarch64-unknown-freebsd.tar.gz/md5/7957f7740cfe6dd5ccb4ff4cd2811b45 +LibUV.v2.0.1+20.aarch64-unknown-freebsd.tar.gz/sha512/923fc895d3fe41005e47d6af422ba450b32e94210c393065a891b44f83f016104d3073a9faa609cd7979bfeca9d0ed0c7164b37de5da92deeb4e8676311cc57f +LibUV.v2.0.1+20.armv6l-linux-gnueabihf.tar.gz/md5/c2ec51470a4d66e3bd23bed67c109cc9 +LibUV.v2.0.1+20.armv6l-linux-gnueabihf.tar.gz/sha512/d139d5a6a141933a83f0d10f8da9366d709013bd2ef005d2b783716fb13d165b87640b7d9f51dc2772a69fc6f63e8545901c96da2343506a2f940edf36332164 +LibUV.v2.0.1+20.armv6l-linux-musleabihf.tar.gz/md5/a1a432902cd687f692c5619e72de241b +LibUV.v2.0.1+20.armv6l-linux-musleabihf.tar.gz/sha512/209207dde41fa699adb72af9a6211d74366d393d335c9b0d4c9c9509c832123707bca27e8410c7b1c63f89fbae77dc15eba55031701e307f88d5c183b929d9f3 +LibUV.v2.0.1+20.armv7l-linux-gnueabihf.tar.gz/md5/bdb8124a2b3c9e42b1b9dc8ce813e664 +LibUV.v2.0.1+20.armv7l-linux-gnueabihf.tar.gz/sha512/2f8879b4f41aa6cab3b195a76dd02376bf5d47f51ac157541b0c8453d03cd2f51fac83f59b2cd2fa49a2395262d18d636251715f1a4912750aa3de56eab4d6f3 +LibUV.v2.0.1+20.armv7l-linux-musleabihf.tar.gz/md5/91ddead3be8fa8b06b37983cba074615 +LibUV.v2.0.1+20.armv7l-linux-musleabihf.tar.gz/sha512/3be790d1c580e2a69d76171b82cfd2f594135920e68f7f4ff7a6fdc42918130e628458492fa2a157947c25effd2de0a71d434fcc1c6fb1d741985bbbfcfac3c5 +LibUV.v2.0.1+20.i686-linux-gnu.tar.gz/md5/c906674ba1bffffb685f0f00189187c1 +LibUV.v2.0.1+20.i686-linux-gnu.tar.gz/sha512/c3e5b394959dc76e2abd51fe59f7e8bbb1755b3a008f019ad05c41ffe8fd9f42d0bf262a506b36f26a2f8f4b14c937eff70a9e1ba2c55f19fbc57e5ba9c2dacf +LibUV.v2.0.1+20.i686-linux-musl.tar.gz/md5/977204bc42355bbdb908693b3baa8e10 +LibUV.v2.0.1+20.i686-linux-musl.tar.gz/sha512/5fb2717575ee97545026b79c2acc0660eaa04827637138896aabbe69bffa0c11732de4f9aad9dd78ba68db265ccf5ff3aef244d7da0008cafc4a417423db361e +LibUV.v2.0.1+20.i686-w64-mingw32.tar.gz/md5/ae698bbab57855ad41bd850ef2ccc695 +LibUV.v2.0.1+20.i686-w64-mingw32.tar.gz/sha512/9c6530404babe8383c6a1db7fa1e81b40b08de0dc2d2be3507a6466c150acc842cca277e39680b21a6c7f5a6dbae618bd3f5c3ac8f11882898cc116d5e13e7d9 +LibUV.v2.0.1+20.powerpc64le-linux-gnu.tar.gz/md5/e68314bb638f210d2ec9326c617752ca +LibUV.v2.0.1+20.powerpc64le-linux-gnu.tar.gz/sha512/f74ce6b21cd2776cdf49b4c6c2ad551c0bf55951f8bd9090020e71d2b233f72907a3e145b9a95715c391b82ad36ab1a069bb9f87d54c219179021cc26902dd22 +LibUV.v2.0.1+20.riscv64-linux-gnu.tar.gz/md5/d8e1ffb730c784df14faff06027b724d +LibUV.v2.0.1+20.riscv64-linux-gnu.tar.gz/sha512/60e7699ac4dc353d0b9fbd34952bd68185ab301a449354b7e805b6759d3866ffa5906041cd9e6ff299cb9fe3f5a92f4c5bfd9c441210125d52f06d614afc84a5 +LibUV.v2.0.1+20.x86_64-apple-darwin.tar.gz/md5/15d8197dea20880edb96a8bf643fe95e +LibUV.v2.0.1+20.x86_64-apple-darwin.tar.gz/sha512/7d65d4d2e0720f997c164234b78a729f4d4239fbb0b01634f23081e2209ab010ef27deca1cc3824fd8e17630370efa86f1567aae035a246ab9f60a6c14ea6d3b +LibUV.v2.0.1+20.x86_64-linux-gnu.tar.gz/md5/013be6d2673a59cd00b2ea62d4e34e21 +LibUV.v2.0.1+20.x86_64-linux-gnu.tar.gz/sha512/f466af2a1f9ff83d887ecaa200d3042bd5685d6cd487af00bdf8c92bf1d4256017f2757084de3b7331071c473b254df43b03f580de09db3bb9268af759a5b0c7 +LibUV.v2.0.1+20.x86_64-linux-musl.tar.gz/md5/21099b0c3ad76c3d67fb24260ec39836 +LibUV.v2.0.1+20.x86_64-linux-musl.tar.gz/sha512/03279a4d29072246dd806d800b80d9db14b637235e211294d5840104056cd206b370a987a2b771216e762549d13b13432f1e1893510e4fba6c4b111bb3330a05 +LibUV.v2.0.1+20.x86_64-unknown-freebsd.tar.gz/md5/dfcce3d6c2c42f419987f8289b1ace02 +LibUV.v2.0.1+20.x86_64-unknown-freebsd.tar.gz/sha512/8ad3c51f43124b7ad43cbdfe92685ce448d3195eeff5838387ef3145f1bec89851106293eca501ab6f986c0714f9bf9ecbb5a7ef44935a76a95bbdecd4fd2fba +LibUV.v2.0.1+20.x86_64-w64-mingw32.tar.gz/md5/7c37d147586c06f00f6dea947d7e912d +LibUV.v2.0.1+20.x86_64-w64-mingw32.tar.gz/sha512/58762e5a7a8cfd4ee8f0c7ba2c2919fc3b922f673e9b6138ee3714062d8088cac8e3cd5bd244d262426260ac55cef609abb30c25b1a5e38123fb61476a522a53 libuv-af4172ec713ee986ba1a989b9e33993a07c60c9e.tar.gz/md5/c1a7d3c74ef3999052f3bfe426264353 libuv-af4172ec713ee986ba1a989b9e33993a07c60c9e.tar.gz/sha512/a3f16863b711ddeeb5ab8d135d7df7a4be19cc2b9821fc78c8cd3ba421231d39b7d8bd9965321455094fda01584842a58f60612d93082b4fe32210b8aa44d999 diff --git a/deps/checksums/mbedtls b/deps/checksums/mbedtls deleted file mode 100644 index e52066b6f4bac..0000000000000 --- a/deps/checksums/mbedtls +++ /dev/null @@ -1,36 +0,0 @@ -MbedTLS.v2.28.6+1.aarch64-apple-darwin.tar.gz/md5/c97705b08c6bf695fa7a11a42167df94 -MbedTLS.v2.28.6+1.aarch64-apple-darwin.tar.gz/sha512/91825c3a495045ca74ceb5a23e3d7e9387701e401911b147d905a49892b1a5a9f22662a4f16a7f4468c5a807f2980b66e3409ea1ff7e04c6fdac0b105472e200 -MbedTLS.v2.28.6+1.aarch64-linux-gnu.tar.gz/md5/8ebaaeefd75c805227229086c262d0e7 -MbedTLS.v2.28.6+1.aarch64-linux-gnu.tar.gz/sha512/89983c1f9f9d7b901619522afcd12c6bc1996757edeb9f3012954992f82f3b36ae50f49dcf7731623fca197946e4281eecffdc29a5819f04e7f6203afd4eb93a -MbedTLS.v2.28.6+1.aarch64-linux-musl.tar.gz/md5/b40b2ba247f4ff755e15daad13c5a255 -MbedTLS.v2.28.6+1.aarch64-linux-musl.tar.gz/sha512/4cb4f2213b631dda0caa8baafa8effc9c8592c72a6a5b826fce060cd81f8f77c188c9ddc76595b47078db3c35b3043d9bf0cb891d822a940df87982de56dec44 -MbedTLS.v2.28.6+1.aarch64-unknown-freebsd.tar.gz/md5/51774d7907dc1a72d7c6e1b6cff02347 -MbedTLS.v2.28.6+1.aarch64-unknown-freebsd.tar.gz/sha512/b85292a75d4ba6fc3996ed497f0951f0dc0a3846e1df83f36b7d3ed3fc30687efdc1742848f6fb5a06e204fa9eb66837c8fbef16e6329f50763086bafef14fb7 -MbedTLS.v2.28.6+1.armv6l-linux-gnueabihf.tar.gz/md5/c6dd1cb1aba1075c73c41719a03c5ab5 -MbedTLS.v2.28.6+1.armv6l-linux-gnueabihf.tar.gz/sha512/981a8925dd90418150625e9467cc791e4a9d5223e7df6ead113ec41a279a5dd7e8ebcecb5b87611ef451fc6483fd6eb5bf984cf528037ad742e68b4be94e5c07 -MbedTLS.v2.28.6+1.armv6l-linux-musleabihf.tar.gz/md5/c30ed777bd74d269656f7e9bc8163765 -MbedTLS.v2.28.6+1.armv6l-linux-musleabihf.tar.gz/sha512/f04014181082561195caa4d3b178480bb5cce7f459d76aca8cdaa2f615d105b24871656ce4cbf8d9ec33f0424de35a16f12d4964a1f0fab9a416e5d18a468c94 -MbedTLS.v2.28.6+1.armv7l-linux-gnueabihf.tar.gz/md5/256f8327773ea2d0d6b4649541c34e84 -MbedTLS.v2.28.6+1.armv7l-linux-gnueabihf.tar.gz/sha512/ab4c9e82752386a0fd642a709bc90b712d6aaff78309968f1fdbf1121a790a9c0227ddd8e79373359cea9c75b21e762f600abea42036609571ba999531b50852 -MbedTLS.v2.28.6+1.armv7l-linux-musleabihf.tar.gz/md5/249ada3e9a7ad4eba08270e575ae68ec -MbedTLS.v2.28.6+1.armv7l-linux-musleabihf.tar.gz/sha512/0682e65f4257c3d237ba8cfc643be4430341888ec4cd17c2dc3018350aa7ff176e834a69ebc9d240b383a7aed439b34e45c237310ad66043956700b782323793 -MbedTLS.v2.28.6+1.i686-linux-gnu.tar.gz/md5/d0a176d2843ac780884395c90971bf68 -MbedTLS.v2.28.6+1.i686-linux-gnu.tar.gz/sha512/c2f96f314d0e5d9bffe46dc7d0adceb038db81e8c9d9a3c0fb0a237849d0d568d249e2df6c275d27a74a9122d0a53b38e5d8521807669a9c82bd67befbea169c -MbedTLS.v2.28.6+1.i686-linux-musl.tar.gz/md5/9c7501c6b04df53f8d56cd59dd42ae4c -MbedTLS.v2.28.6+1.i686-linux-musl.tar.gz/sha512/6fd35f9c2e1c5822920bc1d9315dc68b10694ee5507cc512868615c3d35dc389fa67038b9ab79fa86ea7ff6bf5f6f1eed053fafcc519080559057dcaff813ec5 -MbedTLS.v2.28.6+1.i686-w64-mingw32.tar.gz/md5/1eef46b3c89a81973778817a8856673c -MbedTLS.v2.28.6+1.i686-w64-mingw32.tar.gz/sha512/f202595cf971825601d5e12263eef0dd101e9be971d15592a12187f1d170fafaab358f02db89458f495ddc8922f66fbd662123b0d6df527fffa514e9f410784a -MbedTLS.v2.28.6+1.powerpc64le-linux-gnu.tar.gz/md5/fec1779ff02d71d5e94b3f1455453fc0 -MbedTLS.v2.28.6+1.powerpc64le-linux-gnu.tar.gz/sha512/e97ae38c555f6b45e33c023c7e07c982d36501f6c2dc36121bb73f2fb08db3fa3ab7f4ab0d9ecb622d25bfe1816eab3a6190d2034a05a66b7425c36a637623e0 -MbedTLS.v2.28.6+1.x86_64-apple-darwin.tar.gz/md5/6d44a0c126affaedad544460da9415ab -MbedTLS.v2.28.6+1.x86_64-apple-darwin.tar.gz/sha512/bf074429f32f51d954bc0c242fb4455ec6ead0e8337a3e5ab9e5b0df47d8a195947a488169f743db63d70b245be80084cd0d78f2211b6cd4b9524010b2c893cc -MbedTLS.v2.28.6+1.x86_64-linux-gnu.tar.gz/md5/95641af7a92c8c83d82264dd2275692c -MbedTLS.v2.28.6+1.x86_64-linux-gnu.tar.gz/sha512/3606ecd5a566e643cc03959a3eac9a45cb4c644006ee5820b852dfc22d40b85d75f5c018c46776954d92001986ecb49238058ca3d99340f9a689875b690aa6e7 -MbedTLS.v2.28.6+1.x86_64-linux-musl.tar.gz/md5/aee58ac107ca0d9e1eb5d7de8146ec8d -MbedTLS.v2.28.6+1.x86_64-linux-musl.tar.gz/sha512/86219aa5ba3280da39e91beded7455160c1ebc274c3158b9f0703a2c034756a9a9e51e5354d22ce983fcd026157d81f471446e6ee2743cae2663384e3e796176 -MbedTLS.v2.28.6+1.x86_64-unknown-freebsd.tar.gz/md5/67857ac031b10fb6a0620b453477653b -MbedTLS.v2.28.6+1.x86_64-unknown-freebsd.tar.gz/sha512/118f3c662580c88d092610be08b60236939c7fd7feab4cd524c7c1e2e2e1b557bddbd603902b697142695889ea6c0a8087982020cd5e7267c9c7c82b49622460 -MbedTLS.v2.28.6+1.x86_64-w64-mingw32.tar.gz/md5/1ca2c982712620941c4b0d731251dfff -MbedTLS.v2.28.6+1.x86_64-w64-mingw32.tar.gz/sha512/cef70c00c79e421ce92424bbfda259b4e233d7be3489db1b8cbac7e926d9429be6c88fb806664db60210427748810ea08117066480e8e17c60cb61485b639669 -mbedtls-2.28.6.tar.gz/md5/768932cee6c42f7f4751362091ac56d4 -mbedtls-2.28.6.tar.gz/sha512/a5c876489bf89908f34626c879f68e8f962d84b50756df17b6b75dfb93e08fe163ed3f32bf70e89bce9080d15257a4cbd2679b743bf8f2e2d7a04606c5811c05 diff --git a/deps/checksums/mmtk_julia b/deps/checksums/mmtk_julia new file mode 100644 index 0000000000000..979ab79e52207 --- /dev/null +++ b/deps/checksums/mmtk_julia @@ -0,0 +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 +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/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/nghttp2 b/deps/checksums/nghttp2 index e552dfe9329b0..4520109441588 100644 --- a/deps/checksums/nghttp2 +++ b/deps/checksums/nghttp2 @@ -1,36 +1,38 @@ -nghttp2-1.63.0.tar.bz2/md5/c29228929c3c323ecd0eae172f1eb9d5 -nghttp2-1.63.0.tar.bz2/sha512/a328b4642c6ca4395adfcaaf4e6eb6dbd39fa7bd86f872a76260af59a5a830e0ff5ad015865d6bc00e0baa8e4d0d9a67b4b97e9d78e5e05d1c53522364e5e235 -nghttp2.v1.63.0+1.aarch64-apple-darwin.tar.gz/md5/d11717d2fa4d04a374c55b86c790366a -nghttp2.v1.63.0+1.aarch64-apple-darwin.tar.gz/sha512/10dd24435818b66c92399941d3ea3280451f039e59112a866f973cdfe5602136e366f2bdb4638a1264f48fde737be4e50a49e44934971b4c69284377f4d9cf53 -nghttp2.v1.63.0+1.aarch64-linux-gnu.tar.gz/md5/5ebe2395d0d31b6481a4218468ec82a4 -nghttp2.v1.63.0+1.aarch64-linux-gnu.tar.gz/sha512/e7aff0eaa99be3b5e8539f160e1e5cf53bf1efa6b5f07d625796353a36ef12473946562731cedd570205229d263f81fd692b222a01297b09c89ce0e49edeff7a -nghttp2.v1.63.0+1.aarch64-linux-musl.tar.gz/md5/95c492eeca62b92baf8f8fa11a1da41f -nghttp2.v1.63.0+1.aarch64-linux-musl.tar.gz/sha512/10c0b3f560b1ff7ca9fe5cbc3340ec7789ecdeddf5d857d5c1245d1519074bd105f68c29714f36c8c9b688c5bf42133b30cbabed450410b79bb4f1f1d1474ef6 -nghttp2.v1.63.0+1.aarch64-unknown-freebsd.tar.gz/md5/c6fe5cea3d1386532f75f512e3641a7c -nghttp2.v1.63.0+1.aarch64-unknown-freebsd.tar.gz/sha512/20437e066e13b770f014e30b57830237bf38c3ecc56e716208c5103a7c242fec6cedcf78e641004891afa40ce945bfe1319d11aab4810a76ceeb6ff10373984c -nghttp2.v1.63.0+1.armv6l-linux-gnueabihf.tar.gz/md5/995dbd522109b882eaf7bedec84e8372 -nghttp2.v1.63.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/faf7ca13cd1d3050a5c693c61a5e92b560e1c0c2e30833162cc7aeefcd31c018b2015dbdbf543f38ddec2aefe78927af5f30f3938dc6a67b3b84fc399513c8cf -nghttp2.v1.63.0+1.armv6l-linux-musleabihf.tar.gz/md5/7bf7063ee64eb9b41212a6c39111de4f -nghttp2.v1.63.0+1.armv6l-linux-musleabihf.tar.gz/sha512/3091a4373508e1913e69d76688fd31d57d8e01e15c39c8859b025ac19ff23a0d396dc771fb0a2860ee1913866c0b0dbc4432fbcd0283b5cbecfb02235c738762 -nghttp2.v1.63.0+1.armv7l-linux-gnueabihf.tar.gz/md5/645de11170289308ce00ed089853271c -nghttp2.v1.63.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/bd974e629cd2626fc67a20b175e82e3a0dc742ee0c1b82b505395ebb7ce282def7d123b9bd8c4f7e3386db6c2c3d38d94475a00d96efb504a06fc2371db5a9e2 -nghttp2.v1.63.0+1.armv7l-linux-musleabihf.tar.gz/md5/8b5776769ec5577fde617814ccf57a7c -nghttp2.v1.63.0+1.armv7l-linux-musleabihf.tar.gz/sha512/7d463687abdfb600fcc11fd62b4973cdabdcfc076c5ace554af126ba6b0d925b9ff3eb3a9f730af6e4ef39d6ca1930084833a159d205a4230c88bbc82da7a3b6 -nghttp2.v1.63.0+1.i686-linux-gnu.tar.gz/md5/beb06b6d634fce5c15453c216c50d6b7 -nghttp2.v1.63.0+1.i686-linux-gnu.tar.gz/sha512/0616ffb2a98aa4cfdfbcaa408a6b33815a8e52af60417081854afb7b500e433f9fd63dff633df40507829217e96058f8b27184e50f442c175480e975f2387e13 -nghttp2.v1.63.0+1.i686-linux-musl.tar.gz/md5/ab15ac7ffaaeb7e69f7cad24ed3a6c4e -nghttp2.v1.63.0+1.i686-linux-musl.tar.gz/sha512/c9c18a6e255f4e3f81a9ee27b8ac58149507bce3dc9e79acbba8573ed66908c6cf3dcd29d9b989e47788977e6dec474c291f764fc1cfd718f20557001ca363c7 -nghttp2.v1.63.0+1.i686-w64-mingw32.tar.gz/md5/415858a5c10d7f2473174224e44ef3f6 -nghttp2.v1.63.0+1.i686-w64-mingw32.tar.gz/sha512/575c425df04c084980e8b9149579b787bf7ff38eecd958f38164db0bb0b4c331d4f9d6534f2c2cf1a105fc922ecba1d654a6a48a9a390f53bbcb4e8c2edbb0c7 -nghttp2.v1.63.0+1.powerpc64le-linux-gnu.tar.gz/md5/b2b8216a50aa7dd670e14ad47de31c3f -nghttp2.v1.63.0+1.powerpc64le-linux-gnu.tar.gz/sha512/c41570c8aa245fc2dce2a824cd73c4132ae2a65f9347d097462624917d637da34652c7f693e595a1f1ff1376171be4e2d48633d00dd6cafb00cd6cc974d9fa9e -nghttp2.v1.63.0+1.x86_64-apple-darwin.tar.gz/md5/878b3344f3656d663e33d7afc2fefb21 -nghttp2.v1.63.0+1.x86_64-apple-darwin.tar.gz/sha512/3f9cd4b20b149f8166f8411dc922c80a483113722f9a54c6274b3d4527dfd54bd5723fbd60535d8e90196f1d4e6e5c415f839b34cc4dc8c98eceee5466666471 -nghttp2.v1.63.0+1.x86_64-linux-gnu.tar.gz/md5/96fbea72cc42fa050fb0c9cb065588c8 -nghttp2.v1.63.0+1.x86_64-linux-gnu.tar.gz/sha512/47dd191ec2eb91b34ac9acd1802515778b2cea930c7c5876db3812566d3959e8a0e47bcee9601866180e40c9fd382d1599ca205a6229aaebdfa47e689f6ebd23 -nghttp2.v1.63.0+1.x86_64-linux-musl.tar.gz/md5/d68d6aac8629d95b2cd1b218152cc529 -nghttp2.v1.63.0+1.x86_64-linux-musl.tar.gz/sha512/fdac9dacd1392322cdc308997d7205b7194f897e21ff15fe4eda7c9c8a3b0b2b777cbc54723d884c341ef46467fc4fa056054ebff0f849090464ced031ff98f7 -nghttp2.v1.63.0+1.x86_64-unknown-freebsd.tar.gz/md5/61ecaf1d84e6b203ca7e601a91dc68e3 -nghttp2.v1.63.0+1.x86_64-unknown-freebsd.tar.gz/sha512/c25a017148ff7f01299a9a7cead87251f1a31fd404f4b1f5413fe9b09823ae471173f8d0828b096bb0ac7411e23d354f2c9e2596668d38d9a509831c6b4f5624 -nghttp2.v1.63.0+1.x86_64-w64-mingw32.tar.gz/md5/60ceb3ff3f5287b2782dfd98db4f1816 -nghttp2.v1.63.0+1.x86_64-w64-mingw32.tar.gz/sha512/971fd9e24c393fc594ae813caa7b14052320d924309bea0bd77c847ce0e86803cb803be051812ea029baf632deff6f9f8200dbc41f9bc143eba098adc294e757 +nghttp2-1.64.0.tar.bz2/md5/103421866471b6d5fc828189552d98a5 +nghttp2-1.64.0.tar.bz2/sha512/3b3d16168f6ea5a3e8a7b30b6545b86ff6be874771a1a8d502cbdc7c46f80195c1b8190b5279030aa2edea54fec40962cf245ce4fe89cdf89f06e3f091a34cda +nghttp2.v1.64.0+1.aarch64-apple-darwin.tar.gz/md5/67a5c302c3d1089682e2d6c251273f7b +nghttp2.v1.64.0+1.aarch64-apple-darwin.tar.gz/sha512/88abd96e47d85072abb74d65c0f4872134768b7703a9bb5e5e3f1fb8bdf4d0f6a9f07fbe76089c6746b22787774f362246092c3b2155e94345216aef9f67f2ac +nghttp2.v1.64.0+1.aarch64-linux-gnu.tar.gz/md5/f45a84bd28f598305002f154fb02e3da +nghttp2.v1.64.0+1.aarch64-linux-gnu.tar.gz/sha512/95e1034e1fcd5d96a5ed01e9870af27ee160cdcd624a196dbde31ad400768a55fae39ba11c22a868a5ec79e36e98dcf6a4f37c706e91e466fd01d9b8da868d78 +nghttp2.v1.64.0+1.aarch64-linux-musl.tar.gz/md5/a2680c3d4d94433c787fc1b75f4ab096 +nghttp2.v1.64.0+1.aarch64-linux-musl.tar.gz/sha512/8c02e4e3dfdefecc8c01b397ba8ece94be8f478aa63752d5310517728715b105101f371c281575de7e7c0678b31a7c7cfd021383d000b6f747992bbe47242047 +nghttp2.v1.64.0+1.aarch64-unknown-freebsd.tar.gz/md5/4d69a91c94fabf6af9f5197607639a58 +nghttp2.v1.64.0+1.aarch64-unknown-freebsd.tar.gz/sha512/8d679a0a9ee8a2136da71102eeaf511209c217c771a113fe2fa1736ac232a5637aeafa41ea53fb8ea2514857198cb907a4a8ea5667a325257f527cea4f2c5464 +nghttp2.v1.64.0+1.armv6l-linux-gnueabihf.tar.gz/md5/f44f3dde6ce2f4e34241a336c6f71934 +nghttp2.v1.64.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/02bda6e05712de74805a6895a2f8f29b5930af2c62fed2b3e8a8fcd210c3542484131a5442c8ff707a7ac20c16eae93752609aeb6123b2296346c6399a0369b6 +nghttp2.v1.64.0+1.armv6l-linux-musleabihf.tar.gz/md5/a4dd8ed38b411d4b7c2a3411e6d59b6e +nghttp2.v1.64.0+1.armv6l-linux-musleabihf.tar.gz/sha512/a0552be25160d1878bfb10b30da23381d9d7f9ee7c749b0fb18a0a98ea1e9dcd53b103512b3fe2c98752063385b51551efff0dd0d9190db0105550595cd61d5e +nghttp2.v1.64.0+1.armv7l-linux-gnueabihf.tar.gz/md5/f0f309affb5726efdd93cc4ed0ef25c3 +nghttp2.v1.64.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/55974dc62616e50d1cb1efda380edec6b69dfa175773abc48045ae34b545a19cc50b7a53b12b67dfd9bed9200fbba543875bb821d80e7c3dfcc2aaa3442a5a66 +nghttp2.v1.64.0+1.armv7l-linux-musleabihf.tar.gz/md5/ca090db026ea470523b8cb2c93eed8ac +nghttp2.v1.64.0+1.armv7l-linux-musleabihf.tar.gz/sha512/d2dccf74baa66abd5ecbb187efbd79bf8a43e0b920d7f4c94b6569dd71b74aa4eb6dfcd8d090bd8841496e3f4aa184028b907faf5a0ea3f91df3bb8e286a27c2 +nghttp2.v1.64.0+1.i686-linux-gnu.tar.gz/md5/aebffa8c32cc829f9fb7089ff972b215 +nghttp2.v1.64.0+1.i686-linux-gnu.tar.gz/sha512/f43e4d90f4ca755ea2b4fc90f10944562e9a7b9666b8469bb0fbe12df38c9db9625bfd6f4f4ec16d7da3cb5e3e9e3d85b1bffb56be18d746ae7be2c3dae9a306 +nghttp2.v1.64.0+1.i686-linux-musl.tar.gz/md5/64cc8696b37eeb2a225a02412d73e86d +nghttp2.v1.64.0+1.i686-linux-musl.tar.gz/sha512/2995ab7123630c2c7c606422b25a0a7761642d72177f26046b781209b13d7e90678923dacad35637df7cd171608d44f5d7d3c586768a1d4eaef0751a1f108c04 +nghttp2.v1.64.0+1.i686-w64-mingw32.tar.gz/md5/2ed9ff15d05f6cef7bf85bb19621a2fe +nghttp2.v1.64.0+1.i686-w64-mingw32.tar.gz/sha512/45f38653664cc7343b66561a9b5bfec341593504714afbcb35a856343e583d2e75cab8062b2ff23ebdf4625607748f5c70b1ae79cc047a4073eb8d01f8252338 +nghttp2.v1.64.0+1.powerpc64le-linux-gnu.tar.gz/md5/4622f699a44d02570298daf5864cf60b +nghttp2.v1.64.0+1.powerpc64le-linux-gnu.tar.gz/sha512/f2cc88fd537503ac138518b7f72a67c18508307c0dddca41d44c8496ca4dd8f15aa133e08f13e03b2fbb3c83272ea433456c9ebb929f648a7b2af13fcd048d71 +nghttp2.v1.64.0+1.riscv64-linux-gnu.tar.gz/md5/5ec27224b6a780e989479ae4b38e5b26 +nghttp2.v1.64.0+1.riscv64-linux-gnu.tar.gz/sha512/57cfc7297f1cd2b33578ccc5f0ae847ef4771c087fe1235edd541f6f07a9feb692c554c159a40118c619f16ec0bc3cc313af19a9e845240cc50427583505a9f0 +nghttp2.v1.64.0+1.x86_64-apple-darwin.tar.gz/md5/c6e5d0a179f065f4aab2b8661e6fc2d4 +nghttp2.v1.64.0+1.x86_64-apple-darwin.tar.gz/sha512/77073fecbdac780dea34c9cb42b019b7cfe8a125a1356cd7de2ffd3aebeb29aa6251008574efa8d0a017e86023248fdd93e50c4ed2952d8a23cb67e0cf557a74 +nghttp2.v1.64.0+1.x86_64-linux-gnu.tar.gz/md5/805f31fffc112ea45716b8a661911696 +nghttp2.v1.64.0+1.x86_64-linux-gnu.tar.gz/sha512/73ba29b4f65eeab2ea5c195cb17279d8234b6a650a1b58d0494a564725cd9c76c89321cd455280dd2627d6ba48e91a68be8bdcb5472eae9c3cfc3c2623892963 +nghttp2.v1.64.0+1.x86_64-linux-musl.tar.gz/md5/fbd3da6f5b100767ab7cb77ca6e6074b +nghttp2.v1.64.0+1.x86_64-linux-musl.tar.gz/sha512/493f632d1ba08a0e8114c883d7fef12e364b0b2556e57ed8fd8d8716c43251675f3f60808e32ec430949c4480d5eb052a7837abda2f3e7423ffc658b45805e41 +nghttp2.v1.64.0+1.x86_64-unknown-freebsd.tar.gz/md5/1dba5e39ebfa6c6aac668d5488fb0a41 +nghttp2.v1.64.0+1.x86_64-unknown-freebsd.tar.gz/sha512/259c7cac2cc45a5ebf0c9f90277d6aee68332fe37e8269f93a7d72fae40d41899e6ee63c211dcee81d6bcf056d81e89624e1d09f960039a950b8709b5966ee49 +nghttp2.v1.64.0+1.x86_64-w64-mingw32.tar.gz/md5/228fd64b1581ca3a8a45646b434bbf2a +nghttp2.v1.64.0+1.x86_64-w64-mingw32.tar.gz/sha512/c9ac17a35cd89e71c3a29165f29bb86bc589635bfafc70e64f7437200a886db8a74291ab40b255d977fa0b4bf8d88b12f75cf3ba75163dd906e08c30ec200b8f 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/checksums/openlibm b/deps/checksums/openlibm index e8c17e1efd26e..cad61fd42cf94 100644 --- a/deps/checksums/openlibm +++ b/deps/checksums/openlibm @@ -1,36 +1,38 @@ -OpenLibm.v0.8.1+3.aarch64-apple-darwin.tar.gz/md5/9ce53048e8944f6edff44f75b731229c -OpenLibm.v0.8.1+3.aarch64-apple-darwin.tar.gz/sha512/3a14e28db0656b47a473e19ca0afae1f8b72dd01e108d6b6cb52dc24fc03e4a43db867616b375369e82177bb274fbcfeb8f24b488ee68871e8da8463e9090adf -OpenLibm.v0.8.1+3.aarch64-linux-gnu.tar.gz/md5/8b284fe2905c3e5315291f5e5f27ca8b -OpenLibm.v0.8.1+3.aarch64-linux-gnu.tar.gz/sha512/d326181349ee7f74b73611cd71f933e93c38c11d6db9a1cd4fee49d1ac06c7f244f4cfc6ab373dd52909064117405b3d4fa39e5c626464c066ab53f1cd26dc4a -OpenLibm.v0.8.1+3.aarch64-linux-musl.tar.gz/md5/dc40ad1f2e53a3b914dcca364b6ead77 -OpenLibm.v0.8.1+3.aarch64-linux-musl.tar.gz/sha512/3779d8cd23c5987a15666e2160e40f5a6fc5e7d350c9e3c86d8af8c99515a8cb1f3b5e8438dae0f3cf0b5e1cb2c0cb74c5dd5a06c65e0c2a2382d86dacfaf9fb -OpenLibm.v0.8.1+3.aarch64-unknown-freebsd.tar.gz/md5/f5e9441d81626b958396e585083e0bdb -OpenLibm.v0.8.1+3.aarch64-unknown-freebsd.tar.gz/sha512/1078823b0f5f48cd9f6dc753213b6b3f8112476c9df70192b042fd9bbb597fff34da009f376b6e67034681fcb07810a1a22b0dc83112fbbbaa60dac189164a41 -OpenLibm.v0.8.1+3.armv6l-linux-gnueabihf.tar.gz/md5/7c9e56f6124b85e7dee74601f8c16abd -OpenLibm.v0.8.1+3.armv6l-linux-gnueabihf.tar.gz/sha512/a78e15177992025462d334a9d5b10b9c7f6710d77ac36056fe7a1cc3bc3fada87f16696366578cfa5f325d5f746639c41c5d80b4885814014d29556d63bd4c7c -OpenLibm.v0.8.1+3.armv6l-linux-musleabihf.tar.gz/md5/78d9e3178fdf93a35f7d2b0b00753dc6 -OpenLibm.v0.8.1+3.armv6l-linux-musleabihf.tar.gz/sha512/ff7b78786f7035eaa08770ddf7d4eb2984595a318c3ac4dfbe4091ca398e00638df2e77bc2ab5fd159defd0927d4fe46b7e824cf055fbae4860bfa12347e8c5b -OpenLibm.v0.8.1+3.armv7l-linux-gnueabihf.tar.gz/md5/7c9e56f6124b85e7dee74601f8c16abd -OpenLibm.v0.8.1+3.armv7l-linux-gnueabihf.tar.gz/sha512/a78e15177992025462d334a9d5b10b9c7f6710d77ac36056fe7a1cc3bc3fada87f16696366578cfa5f325d5f746639c41c5d80b4885814014d29556d63bd4c7c -OpenLibm.v0.8.1+3.armv7l-linux-musleabihf.tar.gz/md5/78d9e3178fdf93a35f7d2b0b00753dc6 -OpenLibm.v0.8.1+3.armv7l-linux-musleabihf.tar.gz/sha512/ff7b78786f7035eaa08770ddf7d4eb2984595a318c3ac4dfbe4091ca398e00638df2e77bc2ab5fd159defd0927d4fe46b7e824cf055fbae4860bfa12347e8c5b -OpenLibm.v0.8.1+3.i686-linux-gnu.tar.gz/md5/69b0c561e8f70e12f78a47bbcc28d43f -OpenLibm.v0.8.1+3.i686-linux-gnu.tar.gz/sha512/916bedde7b75aaa10a7517aa6a24da924e896aa46159447722010aa60a8c0974da8c2aa847d0a5853d391e7f3b792371304aa18a6d72d998f38f2a00b7179c30 -OpenLibm.v0.8.1+3.i686-linux-musl.tar.gz/md5/0037f2e2113282d49967eba72f215c4b -OpenLibm.v0.8.1+3.i686-linux-musl.tar.gz/sha512/96666332a814232084340791384505acf964064dba4f7b62db51a7ae4416237decb40318dc07b9a041547fd4ff77f204f42bc5c7f029e590af1ee1dd6196d843 -OpenLibm.v0.8.1+3.i686-w64-mingw32.tar.gz/md5/a2a5ba90531660f1e758df91bb11c2f9 -OpenLibm.v0.8.1+3.i686-w64-mingw32.tar.gz/sha512/b177c124dbe2dd491b49bf01b58b639629e2039c60dbd8ef1acf42985a7bd5ac1c5950a803b19e3ed5436ebd0a83f1e7af505d5f90b270467600ecab3e8a5cda -OpenLibm.v0.8.1+3.powerpc64le-linux-gnu.tar.gz/md5/01997fb48464f94f59f4708bd26eabc3 -OpenLibm.v0.8.1+3.powerpc64le-linux-gnu.tar.gz/sha512/1e1d8901fd3aab0948be5c387b8d5bd0db12766fe00bf800ee3100aa0d5973c7aa03ef9c9b4e34942e5e2b46b64035d7f8d7b070113db031d4611f2a7dd02ca3 -OpenLibm.v0.8.1+3.x86_64-apple-darwin.tar.gz/md5/6cb5a472d6c1446acfca11bb8f7283d6 -OpenLibm.v0.8.1+3.x86_64-apple-darwin.tar.gz/sha512/e52f399002544d94536c3bda742d3cc5b0995929d656eeb0e808954fb800fd8e5cfc0ab57279fbccab44fc33a1207ab345d78e685d519ff7f02cca8f554b9c06 -OpenLibm.v0.8.1+3.x86_64-linux-gnu.tar.gz/md5/e1c7dc61e98d5b8aa68de3462a2620a4 -OpenLibm.v0.8.1+3.x86_64-linux-gnu.tar.gz/sha512/fe6d74a2522d75374b87ac9746d444d75a768e069f24f3fbfc6a140aa9d073fa54e8899861f839e647b9261e660c5f2b5555f52fab39ef84a74685b632e89df9 -OpenLibm.v0.8.1+3.x86_64-linux-musl.tar.gz/md5/5fe8eb59d21732a80f432720419324b3 -OpenLibm.v0.8.1+3.x86_64-linux-musl.tar.gz/sha512/0d1b22ca01eda89caa1832b63b1d7ddafe0fedf5906680e817100e2176cbbae95f576409706a9ea1834bc692b72009f4fd244586df30228d18e626bf25fc040a -OpenLibm.v0.8.1+3.x86_64-unknown-freebsd.tar.gz/md5/2bcdf32fdef91433763e32be029814d9 -OpenLibm.v0.8.1+3.x86_64-unknown-freebsd.tar.gz/sha512/97854736fc8c797abd5a5c331e5795dfa9124ac108a76fc2bcac518f5750a08884717d611bb98222b13387bcd27e1c3f4ec841547859e87fafbbe8c7dcd7381a -OpenLibm.v0.8.1+3.x86_64-w64-mingw32.tar.gz/md5/31a75f828f782130bf6a463521a11f04 -OpenLibm.v0.8.1+3.x86_64-w64-mingw32.tar.gz/sha512/d54f688940229a5fc3db958460556d362c81e2e0a7bac010537123e5ff102b17d84123ee2e164151d51fb8ee7524e0888531e14d2c5ebfb3d6847b03af0086ad -openlibm-ae2d91698508701c83cab83714d42a1146dccf85.tar.gz/md5/19408d70bf042a109e1c267a53740089 -openlibm-ae2d91698508701c83cab83714d42a1146dccf85.tar.gz/sha512/9597fdcbc4af8369e6eecc3f8e86f251661cc64d236578f3ee8a6b39e77a47951446e1a0fe1151513da153e7ed17bf39aa5a36c32153d0d0400232bed2839e22 +OpenLibm.v0.8.5+0.aarch64-apple-darwin.tar.gz/md5/5fcbd746e90712e396e76dc4e76724d0 +OpenLibm.v0.8.5+0.aarch64-apple-darwin.tar.gz/sha512/f4ac2bc38bdc723384b67119daa2974fb43da34b2e45cea2029ea48f92c84c4cad6dfb43521b09a1e89ddf8c5b8cc22a38fa4b78ba39ac7524fd6bd1ba897aa9 +OpenLibm.v0.8.5+0.aarch64-linux-gnu.tar.gz/md5/4d1b4cd566805b5179c5ecdd060da473 +OpenLibm.v0.8.5+0.aarch64-linux-gnu.tar.gz/sha512/a9fe1a3d2e3898c017eb8615b2f3dbb514995ff041ac964c931c99c60d8cfe4eab7563a9cd65058f42f83c812f33d998573a7c5cc56a2e3960a4657e459ed321 +OpenLibm.v0.8.5+0.aarch64-linux-musl.tar.gz/md5/413be59af62b3ce0ebafeca093e3179e +OpenLibm.v0.8.5+0.aarch64-linux-musl.tar.gz/sha512/7bd76373e047ba854066af61f1c56b2e3a4d28c266228d7b30f596eadbaec52b070548ae60d41840c425ad5d0829c6c0cdaf326f2f160ed7508877ab5ec1a4b1 +OpenLibm.v0.8.5+0.aarch64-unknown-freebsd.tar.gz/md5/80736f9022c695eb1198e0b591a8fa63 +OpenLibm.v0.8.5+0.aarch64-unknown-freebsd.tar.gz/sha512/c633644578265e7ccc259ceb0442457b8c09290b4861b66c86dd6be7b30c4e394e70728142798097d6fe3afcfb4d9d1bd7ef58513fe8eed5684a4fba51bf185a +OpenLibm.v0.8.5+0.armv6l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 +OpenLibm.v0.8.5+0.armv6l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 +OpenLibm.v0.8.5+0.armv6l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 +OpenLibm.v0.8.5+0.armv6l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 +OpenLibm.v0.8.5+0.armv7l-linux-gnueabihf.tar.gz/md5/8fe0900a318393a290907f016bc654c3 +OpenLibm.v0.8.5+0.armv7l-linux-gnueabihf.tar.gz/sha512/167100a2d46e68462ef9a66915ced881d6358f05337bd38f2f77176f41cfd5be37e3c5226dd5d7d59147bd3e1aa7fb0893c1c81e9516134d3ab663b5752c4969 +OpenLibm.v0.8.5+0.armv7l-linux-musleabihf.tar.gz/md5/e8566719387984604f19dc5f9354a783 +OpenLibm.v0.8.5+0.armv7l-linux-musleabihf.tar.gz/sha512/532dd2b764fa15f7a838fb14cccafd2d4fe8fa4a132ea8394479a719c7aee11442f1b8a18e5d4a26ca820fa696d9d2afc7f5ec63dd96fa3b6763cea72b7026c3 +OpenLibm.v0.8.5+0.i686-linux-gnu.tar.gz/md5/9580d34e69d6067427b9c33db631cfd3 +OpenLibm.v0.8.5+0.i686-linux-gnu.tar.gz/sha512/46934f82791f69ac5f5da0dab7dcc6e3e9a4577c3bb529e9c0519c38f140c7b54517c55ff3579cd4ed4df68f0863e006aa98e51873f1dab452ce9f853996429a +OpenLibm.v0.8.5+0.i686-linux-musl.tar.gz/md5/66bfc9611d04c5d609e7824cb076d24b +OpenLibm.v0.8.5+0.i686-linux-musl.tar.gz/sha512/1bda2395d44c22aba3d1aab2b08ae06f763d3755037d454aa73f8e8134289a1ab5d65862bbc5a17a7a6b9f2918eb87e926b21527ddc4471e2ea20d605ba14e2d +OpenLibm.v0.8.5+0.i686-w64-mingw32.tar.gz/md5/0e97311b2f08b57d79085635f01ccced +OpenLibm.v0.8.5+0.i686-w64-mingw32.tar.gz/sha512/ae061ea406c06969332af58ed6fdfce2825326d771d30274d90775a1709b0361b7ca1dc7e6b0b76b93e4dd7a81d1842510a2c835251ee0a0978d6c839d96070e +OpenLibm.v0.8.5+0.powerpc64le-linux-gnu.tar.gz/md5/8ecfff7db76eee29591a654871e88855 +OpenLibm.v0.8.5+0.powerpc64le-linux-gnu.tar.gz/sha512/af03993b162316dd581f6ba5d1c23bca4c26cb22356ab229f326c42e111acbdf7ef45c9ad05894fe2d68794a63670cf89888653f788192a38b9255ce4bc72e28 +OpenLibm.v0.8.5+0.riscv64-linux-gnu.tar.gz/md5/69e06de135940666791c984941e9c4ad +OpenLibm.v0.8.5+0.riscv64-linux-gnu.tar.gz/sha512/2ac84deb7eb80a6a6237eff6fe861fd2907b3c95d1a76366dea062f3f35228dbc67aa40bd982e646508b4ff7cb6ef029111e2c0325039e60679800d6c6886be5 +OpenLibm.v0.8.5+0.x86_64-apple-darwin.tar.gz/md5/bd671ab9fe01835cab3e42e7cfa790fb +OpenLibm.v0.8.5+0.x86_64-apple-darwin.tar.gz/sha512/8bf2e66df17effc1e8778453904ffc20127f785bf096873289e8fdd8b17069ca844faffbd9f7621b87a7cb0a0051037eb9402360f2a03cf8794fbac8f7719777 +OpenLibm.v0.8.5+0.x86_64-linux-gnu.tar.gz/md5/df7fab134fbce3b625e9a82376f23e79 +OpenLibm.v0.8.5+0.x86_64-linux-gnu.tar.gz/sha512/64d07434e0db79833f84a2225838456eb9532617d377a776b3a534a908b1673bc4f890903f95350e4045e05c29539d993a18ecadeb879761e279ec3947f74390 +OpenLibm.v0.8.5+0.x86_64-linux-musl.tar.gz/md5/ebef6bb7651d116b397e035f39adfb1b +OpenLibm.v0.8.5+0.x86_64-linux-musl.tar.gz/sha512/de9036073e5dba2721b4119ecbbd21a0c9f75b65aff9392b7e88e464da35b97135d62404477441d0dadd3a2f8d49f1082291b35bf4b626fb1096d36d401980bf +OpenLibm.v0.8.5+0.x86_64-unknown-freebsd.tar.gz/md5/1115497539f00a37af18aa6516d52268 +OpenLibm.v0.8.5+0.x86_64-unknown-freebsd.tar.gz/sha512/71a2c06d141b3671fd220f2d88d72e845848b6d2b08a7b3a6c4bb1d5cc27cc450e1e681647bb583e7ed6375d5a70748401e95e61dc95d7808f33a9aa06755337 +OpenLibm.v0.8.5+0.x86_64-w64-mingw32.tar.gz/md5/b6b5335f4c83f7ebf0f74cf753358f00 +OpenLibm.v0.8.5+0.x86_64-w64-mingw32.tar.gz/sha512/e8351ddda305b757f337bb7ea26c441968843b23861676f0bdd7bcf83bb3969af790d4112307d3204eb87fac044dda9be305f349700ebe9ba2bfe3d6df24fde8 +openlibm-db24332879c320606c37f77fea165e6ecb49153c.tar.gz/md5/2375dd448e77e59152442a4b33abda01 +openlibm-db24332879c320606c37f77fea165e6ecb49153c.tar.gz/sha512/36054e7051990d04913f054a0542e2e104273f61308e9a442c2dab3dd392d40c03f264fbeca93c4296218eed85dad71028989a225088254013d752f4407d57ef diff --git a/deps/checksums/openssl b/deps/checksums/openssl new file mode 100644 index 0000000000000..c973f592861f3 --- /dev/null +++ b/deps/checksums/openssl @@ -0,0 +1,38 @@ +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/deps/checksums/p7zip b/deps/checksums/p7zip index 2fe4fb874bec4..6850967ace1b5 100644 --- a/deps/checksums/p7zip +++ b/deps/checksums/p7zip @@ -1,36 +1,38 @@ p7zip-17.05.tar.gz/md5/de921a08f37242a8eed8e4a758fbcb58 p7zip-17.05.tar.gz/sha512/97a7cfd15287998eb049c320548477be496c4ddf6b45c833c42adca4ab88719b07a442ae2e71cf2dc3b30a0777a3acab0a1a30f01fd85bacffa3fa9bd22c3f7d -p7zip.v17.5.0+1.aarch64-apple-darwin.tar.gz/md5/2a254e251901b3d1ddfd7aff23a6e5eb -p7zip.v17.5.0+1.aarch64-apple-darwin.tar.gz/sha512/8efb9a2c9bcab388e523adba3dc0b876e8ae34e2440c3eee01fd780eb87c8619c7a7bbdc46d703ccefff6aa6ad64c4e4b45b723136ab1f6fd6de4f52e75ebbbf -p7zip.v17.5.0+1.aarch64-linux-gnu.tar.gz/md5/bb1f3773fd409dbb91a10f7d9d2e99b5 -p7zip.v17.5.0+1.aarch64-linux-gnu.tar.gz/sha512/e95ccc342be644570d218d25403b91a7db9ee983fbf8cce3deff453355d68d426f9301eaac865a98691025b596b8cd77ebebf6184c0eaf8b2f294bc6763b9a4b -p7zip.v17.5.0+1.aarch64-linux-musl.tar.gz/md5/3fac518a6a70412294d71ca510958cf2 -p7zip.v17.5.0+1.aarch64-linux-musl.tar.gz/sha512/fc127790739bf8a8b918b2e83753d86f5e79ee8706bde4cc79d74d9f7d846aae99a109da4b2b3cc92ccedc1eef4d52a555a65a95f588e173e0fecc11f2ca21e6 -p7zip.v17.5.0+1.aarch64-unknown-freebsd.tar.gz/md5/4190f8d7d42572b3fdab0fa382417d43 -p7zip.v17.5.0+1.aarch64-unknown-freebsd.tar.gz/sha512/5b0cb08374b8561873f76cb2b8bcbb8de1ff4c91bde23222cc1b650c6ea2fff265e48b6190551ed136324a47d25e1d357a754295b674e74b4628b20223ad067d -p7zip.v17.5.0+1.armv6l-linux-gnueabihf.tar.gz/md5/355410848192de3b02d12fd663867f4b -p7zip.v17.5.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/8f103b41e755d157d70dacca89a0ef4610bea109686b4005e8edd5f79ed2e6419c00c2625d0ab90e6e33fa389e670490d8de263c0bdae952cc34cbbf440e275f -p7zip.v17.5.0+1.armv6l-linux-musleabihf.tar.gz/md5/34363b227306fce34a728af54b71064f -p7zip.v17.5.0+1.armv6l-linux-musleabihf.tar.gz/sha512/8dd7b37ce6223c9fedcaa999eb806eb6dec8c4a3133d3c07e2456cb8543b8e4f5b881c1bff2d2e25f19b1312b18673e9013aeff87d6a274eec6c451b1ba0d6b9 -p7zip.v17.5.0+1.armv7l-linux-gnueabihf.tar.gz/md5/dbb1fc0cf3bea674442ff8cc932a94cd -p7zip.v17.5.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/c4d71d905fa420391417786ed206a0c334475dd0df8baa1fc3f6560ce548db11805003d0d0b35bb622fe818c761f2b0abe0796d1cbfce2a922da69e697f056a2 -p7zip.v17.5.0+1.armv7l-linux-musleabihf.tar.gz/md5/d188b5dd453faedb616ba9c48fdeab6b -p7zip.v17.5.0+1.armv7l-linux-musleabihf.tar.gz/sha512/ea30a775370502ca9e271b87cbda528d0c51d63ce0df41883d4dbc1527a32f251d797f3692fcf9b883b5fbaaad80515b971a8f8fe09ba102978b19a0ecb58528 -p7zip.v17.5.0+1.i686-linux-gnu.tar.gz/md5/dc02bdde045a0b6b22cf14d6960e63ed -p7zip.v17.5.0+1.i686-linux-gnu.tar.gz/sha512/d2d0dd14a5fc1163fea2276e0925bfa8d075d5dba1d8018e4e3160977d3b09642b2e521d8e57d049abaf0e2ea391a846f0b0136b3c59e8b476c8c52ac5210447 -p7zip.v17.5.0+1.i686-linux-musl.tar.gz/md5/0b8658147938a8ec109ee2b3b0a0665f -p7zip.v17.5.0+1.i686-linux-musl.tar.gz/sha512/411b2950f5928c537b87ba0651c09c08e57afed765db9fee89eda8b12939ef0da94c8ba38c0a24ba46b4513a0e4cca798eb09f2b20a011099ed3cf14455dd19e -p7zip.v17.5.0+1.i686-w64-mingw32.tar.gz/md5/98bdd8767c77a35f71303ff490a3d363 -p7zip.v17.5.0+1.i686-w64-mingw32.tar.gz/sha512/14f08071af74297df8bfe1d9f7efa3c0212e62ace573848f17b729e4c36dc3861110f3c5cc9315364c318e5b040736443a24492e86d76161993653a309996eb3 -p7zip.v17.5.0+1.powerpc64le-linux-gnu.tar.gz/md5/b18c917b9852898a9b9d6d24bcc6863e -p7zip.v17.5.0+1.powerpc64le-linux-gnu.tar.gz/sha512/0148dc8a0bc9c95212d7f8e2f92ee24e968eb7290fe72c7ae02e286bf5c05dd6b1f10b32350a7ff37777ed5a8cc21f3303f464620f3394c7a4690ae98bf77299 -p7zip.v17.5.0+1.x86_64-apple-darwin.tar.gz/md5/da31752a2556644d39e48649bb0111de -p7zip.v17.5.0+1.x86_64-apple-darwin.tar.gz/sha512/0695ad111263d2fadfdf9a46ce7ee80def0bf60db7d1c2585ed2af6fc945fb169311a9f1ffc6f95fb43b0b03694d2d1be9136d3d78ba2ef2b19228987883a385 -p7zip.v17.5.0+1.x86_64-linux-gnu.tar.gz/md5/2fb55d86e4eaccb0488bd637d088b996 -p7zip.v17.5.0+1.x86_64-linux-gnu.tar.gz/sha512/38ac355157d59c09f308fc29964d0e9c1466c9633efd8d3c6ff3c738abce2af45ebc6b92a29f56d5e7baa4871f9f39b14ecfcbedd4e2f4ca7c0fe6627c6b13e7 -p7zip.v17.5.0+1.x86_64-linux-musl.tar.gz/md5/f0bd567a851d2dd9d306552ffafbca3a -p7zip.v17.5.0+1.x86_64-linux-musl.tar.gz/sha512/e60047a6e7e3496cb6658f87c8c88676f399cd9f3d0d7daa880b6be09cd5525f7f22776896f1375722b47555514ff8c018f02ce800ec3fd0ed922e16e8a6d657 -p7zip.v17.5.0+1.x86_64-unknown-freebsd.tar.gz/md5/d37bd26e39a3ec84f262636f70624341 -p7zip.v17.5.0+1.x86_64-unknown-freebsd.tar.gz/sha512/0604a880c19f9d72d5828edd75be641625c29f230b3a5e7d70ec3812c014c96b76ee7b45e0e80f49be63f109a48700e75d1e5be01b5ae7b46d42dafda9885e8c -p7zip.v17.5.0+1.x86_64-w64-mingw32.tar.gz/md5/f02c7b2481dee880b096340a8735350f -p7zip.v17.5.0+1.x86_64-w64-mingw32.tar.gz/sha512/08b717c1b072d1309f6af8973eb09b1a482abb7ae7d01fba79873d4310a7c11292e2e8779029f99cc60627ed0d064224bc87782e587c520f970b840b7b838052 +p7zip.v17.5.0+2.aarch64-apple-darwin.tar.gz/md5/2a254e251901b3d1ddfd7aff23a6e5eb +p7zip.v17.5.0+2.aarch64-apple-darwin.tar.gz/sha512/8efb9a2c9bcab388e523adba3dc0b876e8ae34e2440c3eee01fd780eb87c8619c7a7bbdc46d703ccefff6aa6ad64c4e4b45b723136ab1f6fd6de4f52e75ebbbf +p7zip.v17.5.0+2.aarch64-linux-gnu.tar.gz/md5/bb1f3773fd409dbb91a10f7d9d2e99b5 +p7zip.v17.5.0+2.aarch64-linux-gnu.tar.gz/sha512/e95ccc342be644570d218d25403b91a7db9ee983fbf8cce3deff453355d68d426f9301eaac865a98691025b596b8cd77ebebf6184c0eaf8b2f294bc6763b9a4b +p7zip.v17.5.0+2.aarch64-linux-musl.tar.gz/md5/3fac518a6a70412294d71ca510958cf2 +p7zip.v17.5.0+2.aarch64-linux-musl.tar.gz/sha512/fc127790739bf8a8b918b2e83753d86f5e79ee8706bde4cc79d74d9f7d846aae99a109da4b2b3cc92ccedc1eef4d52a555a65a95f588e173e0fecc11f2ca21e6 +p7zip.v17.5.0+2.aarch64-unknown-freebsd.tar.gz/md5/4190f8d7d42572b3fdab0fa382417d43 +p7zip.v17.5.0+2.aarch64-unknown-freebsd.tar.gz/sha512/5b0cb08374b8561873f76cb2b8bcbb8de1ff4c91bde23222cc1b650c6ea2fff265e48b6190551ed136324a47d25e1d357a754295b674e74b4628b20223ad067d +p7zip.v17.5.0+2.armv6l-linux-gnueabihf.tar.gz/md5/355410848192de3b02d12fd663867f4b +p7zip.v17.5.0+2.armv6l-linux-gnueabihf.tar.gz/sha512/8f103b41e755d157d70dacca89a0ef4610bea109686b4005e8edd5f79ed2e6419c00c2625d0ab90e6e33fa389e670490d8de263c0bdae952cc34cbbf440e275f +p7zip.v17.5.0+2.armv6l-linux-musleabihf.tar.gz/md5/34363b227306fce34a728af54b71064f +p7zip.v17.5.0+2.armv6l-linux-musleabihf.tar.gz/sha512/8dd7b37ce6223c9fedcaa999eb806eb6dec8c4a3133d3c07e2456cb8543b8e4f5b881c1bff2d2e25f19b1312b18673e9013aeff87d6a274eec6c451b1ba0d6b9 +p7zip.v17.5.0+2.armv7l-linux-gnueabihf.tar.gz/md5/dbb1fc0cf3bea674442ff8cc932a94cd +p7zip.v17.5.0+2.armv7l-linux-gnueabihf.tar.gz/sha512/c4d71d905fa420391417786ed206a0c334475dd0df8baa1fc3f6560ce548db11805003d0d0b35bb622fe818c761f2b0abe0796d1cbfce2a922da69e697f056a2 +p7zip.v17.5.0+2.armv7l-linux-musleabihf.tar.gz/md5/d188b5dd453faedb616ba9c48fdeab6b +p7zip.v17.5.0+2.armv7l-linux-musleabihf.tar.gz/sha512/ea30a775370502ca9e271b87cbda528d0c51d63ce0df41883d4dbc1527a32f251d797f3692fcf9b883b5fbaaad80515b971a8f8fe09ba102978b19a0ecb58528 +p7zip.v17.5.0+2.i686-linux-gnu.tar.gz/md5/dc02bdde045a0b6b22cf14d6960e63ed +p7zip.v17.5.0+2.i686-linux-gnu.tar.gz/sha512/d2d0dd14a5fc1163fea2276e0925bfa8d075d5dba1d8018e4e3160977d3b09642b2e521d8e57d049abaf0e2ea391a846f0b0136b3c59e8b476c8c52ac5210447 +p7zip.v17.5.0+2.i686-linux-musl.tar.gz/md5/0b8658147938a8ec109ee2b3b0a0665f +p7zip.v17.5.0+2.i686-linux-musl.tar.gz/sha512/411b2950f5928c537b87ba0651c09c08e57afed765db9fee89eda8b12939ef0da94c8ba38c0a24ba46b4513a0e4cca798eb09f2b20a011099ed3cf14455dd19e +p7zip.v17.5.0+2.i686-w64-mingw32.tar.gz/md5/98bdd8767c77a35f71303ff490a3d363 +p7zip.v17.5.0+2.i686-w64-mingw32.tar.gz/sha512/14f08071af74297df8bfe1d9f7efa3c0212e62ace573848f17b729e4c36dc3861110f3c5cc9315364c318e5b040736443a24492e86d76161993653a309996eb3 +p7zip.v17.5.0+2.powerpc64le-linux-gnu.tar.gz/md5/b18c917b9852898a9b9d6d24bcc6863e +p7zip.v17.5.0+2.powerpc64le-linux-gnu.tar.gz/sha512/0148dc8a0bc9c95212d7f8e2f92ee24e968eb7290fe72c7ae02e286bf5c05dd6b1f10b32350a7ff37777ed5a8cc21f3303f464620f3394c7a4690ae98bf77299 +p7zip.v17.5.0+2.riscv64-linux-gnu.tar.gz/md5/8d5f804091c2d21b2c35121d40d1024f +p7zip.v17.5.0+2.riscv64-linux-gnu.tar.gz/sha512/68042f32b8b9f8d422dc0390efa2502d4a1a816daf4adf1133128f9366ec93ee1c1dda699844c0c3c3649a6b55a16312bd6b8fe4aedd6780e6faf11509932a9a +p7zip.v17.5.0+2.x86_64-apple-darwin.tar.gz/md5/da31752a2556644d39e48649bb0111de +p7zip.v17.5.0+2.x86_64-apple-darwin.tar.gz/sha512/0695ad111263d2fadfdf9a46ce7ee80def0bf60db7d1c2585ed2af6fc945fb169311a9f1ffc6f95fb43b0b03694d2d1be9136d3d78ba2ef2b19228987883a385 +p7zip.v17.5.0+2.x86_64-linux-gnu.tar.gz/md5/2fb55d86e4eaccb0488bd637d088b996 +p7zip.v17.5.0+2.x86_64-linux-gnu.tar.gz/sha512/38ac355157d59c09f308fc29964d0e9c1466c9633efd8d3c6ff3c738abce2af45ebc6b92a29f56d5e7baa4871f9f39b14ecfcbedd4e2f4ca7c0fe6627c6b13e7 +p7zip.v17.5.0+2.x86_64-linux-musl.tar.gz/md5/f0bd567a851d2dd9d306552ffafbca3a +p7zip.v17.5.0+2.x86_64-linux-musl.tar.gz/sha512/e60047a6e7e3496cb6658f87c8c88676f399cd9f3d0d7daa880b6be09cd5525f7f22776896f1375722b47555514ff8c018f02ce800ec3fd0ed922e16e8a6d657 +p7zip.v17.5.0+2.x86_64-unknown-freebsd.tar.gz/md5/d37bd26e39a3ec84f262636f70624341 +p7zip.v17.5.0+2.x86_64-unknown-freebsd.tar.gz/sha512/0604a880c19f9d72d5828edd75be641625c29f230b3a5e7d70ec3812c014c96b76ee7b45e0e80f49be63f109a48700e75d1e5be01b5ae7b46d42dafda9885e8c +p7zip.v17.5.0+2.x86_64-w64-mingw32.tar.gz/md5/f02c7b2481dee880b096340a8735350f +p7zip.v17.5.0+2.x86_64-w64-mingw32.tar.gz/sha512/08b717c1b072d1309f6af8973eb09b1a482abb7ae7d01fba79873d4310a7c11292e2e8779029f99cc60627ed0d064224bc87782e587c520f970b840b7b838052 diff --git a/deps/checksums/pcre b/deps/checksums/pcre index 0c2732f8cc2b5..9e290c914baec 100644 --- a/deps/checksums/pcre +++ b/deps/checksums/pcre @@ -1,36 +1,38 @@ -PCRE2.v10.44.0+0.aarch64-apple-darwin.tar.gz/md5/14de26cfc0f6ff7635fac39e81e81a27 -PCRE2.v10.44.0+0.aarch64-apple-darwin.tar.gz/sha512/45079ecca5f4966a32895fcc63585f1dd60f306dc1cb5c098d42452fcff67f7f6b405c200a15747af4680151bb6a6374832a0119b8ddd743d2ed13d0beaef7c9 -PCRE2.v10.44.0+0.aarch64-linux-gnu.tar.gz/md5/3cf179ed36d37bff698ab81cf3d5797b -PCRE2.v10.44.0+0.aarch64-linux-gnu.tar.gz/sha512/db93e5a5c0c46b5536ed49515682d9bfe1d23f6ba8ae2468289ec8f2160140f39f5606a3c7095f45251f3663d8ccf2d6d7e5e8b1efb21c39bbf9a13b6ec60ef9 -PCRE2.v10.44.0+0.aarch64-linux-musl.tar.gz/md5/02baa415218f581a5ceeb7bf7fc0a090 -PCRE2.v10.44.0+0.aarch64-linux-musl.tar.gz/sha512/1685f37ed8f465ecc2f738fdf65d20bb1806934ff2c50194882282fb6c3900121c61c39210e4c0b89847493bfc3e15bb7b9136b0d968103b47c8662a78b412fe -PCRE2.v10.44.0+0.aarch64-unknown-freebsd.tar.gz/md5/4de065ea59ab4f622b46079df1d9d941 -PCRE2.v10.44.0+0.aarch64-unknown-freebsd.tar.gz/sha512/aa6df9edfb690d155a8b5a9390db7ca11622ac0020174cf070a33a075801bfe43bd4c80b8e28017989a8b7374d39897cdcf72ab0e1962e3e234239975f7ac0b4 -PCRE2.v10.44.0+0.armv6l-linux-gnueabihf.tar.gz/md5/f8a0907fbb20a06507fce849db098c4f -PCRE2.v10.44.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/3f5bcc1742380a31683a81740d55e198d7ec8d8ea5a13d6d0556d6603e4fadbf0dc648093c44e36dd6d3793c52a5e3dae6f2f459c73e3d3b5a005f3395d26772 -PCRE2.v10.44.0+0.armv6l-linux-musleabihf.tar.gz/md5/8854c24183441aa6fd21989c00888904 -PCRE2.v10.44.0+0.armv6l-linux-musleabihf.tar.gz/sha512/a74d9378f071dc4cb021e5171d66cd4ac5de3b348e993fc90d824ce5d2f554f7c8af7af55ec31d874d302aaba7d542b6505cc5963e53656c28026a06a53ed48b -PCRE2.v10.44.0+0.armv7l-linux-gnueabihf.tar.gz/md5/04960309ee7cf69a53e280878d5880ef -PCRE2.v10.44.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/a1644daf036daa3799368598427c87c23bcfdddac55a0d06adca08a2e9d617c893285855af562101b05129d0ed0d84d22f5a8a1703316ecd09aa1752b8330eef -PCRE2.v10.44.0+0.armv7l-linux-musleabihf.tar.gz/md5/1335defc6090be76c509840633f7cdfb -PCRE2.v10.44.0+0.armv7l-linux-musleabihf.tar.gz/sha512/9595052eeae4da413b930b14d7e89359a29220cd9e908325e0b7788c8f4a2feb2134e78a0d8f56007787f0fefadc9de31750db6104bbdd048fa50e1d785c2a8c -PCRE2.v10.44.0+0.i686-linux-gnu.tar.gz/md5/e2d6be1d19566c965c2afeb995aba52f -PCRE2.v10.44.0+0.i686-linux-gnu.tar.gz/sha512/4a9d981bb6aa9150b670db7c5d4d188c8391fcb2a16bc710ede7a84bf7ec546fc5fd9096a339720579d25b6dcb5674b2b5b28e9664e5ef589b1a5044ce38b6a7 -PCRE2.v10.44.0+0.i686-linux-musl.tar.gz/md5/23cf857bd3daea4f094fcec48a7712dc -PCRE2.v10.44.0+0.i686-linux-musl.tar.gz/sha512/534f0cfab0cd60db9498eff387f7280a8baaf893a98dd2e7a737e68ba6473ed8236e9da85116eefb9812ec5323c705a00fcaff010b1900f752de8bdff65ef3ad -PCRE2.v10.44.0+0.i686-w64-mingw32.tar.gz/md5/3d05764df2305f16e4ffab60031ad40c -PCRE2.v10.44.0+0.i686-w64-mingw32.tar.gz/sha512/3e21cc6b71849c1a361373de30567990dba13dfd8812e7a7b5e2734b572bf1d45aeb730289d329975e76932c4c40e476824be2ab8e80a40fb7a7e2f46159235a -PCRE2.v10.44.0+0.powerpc64le-linux-gnu.tar.gz/md5/596d7c29d1417ed8959ea3ae3b4df453 -PCRE2.v10.44.0+0.powerpc64le-linux-gnu.tar.gz/sha512/89e03bfd6890150e2c8dddc4e7d024f2e09421c25a3d0fef3b5cd7f6bab7d6402ec1e82b02ecb5d26d01dfa2fb6068d050513894c374b7f2244c8fcbf00d69e2 -PCRE2.v10.44.0+0.x86_64-apple-darwin.tar.gz/md5/18f13c78ff6388c601bd36788e526b31 -PCRE2.v10.44.0+0.x86_64-apple-darwin.tar.gz/sha512/7b43a289f54064fc3c292de98173ec91cde2e49402c99c7848cbdc0e6d90a23a86d41f521e3986fcc8d941ee070d09e29ddc89a4e23009b8e9333e577ae4a09c -PCRE2.v10.44.0+0.x86_64-linux-gnu.tar.gz/md5/9f45feca0955f81ceb898208b9c74e15 -PCRE2.v10.44.0+0.x86_64-linux-gnu.tar.gz/sha512/eac215838306f7b5adb2166c3f620a69ed52fbd752ef3673a887507963a826c305d9b078dbb5236dc9a45eaca0d34f77325aab41703745701a077c84822ec0d0 -PCRE2.v10.44.0+0.x86_64-linux-musl.tar.gz/md5/79f092c6e8e971027ac6c1f0987376fb -PCRE2.v10.44.0+0.x86_64-linux-musl.tar.gz/sha512/2c5655b0f719a7d442c89f1040f2973b03f8becd855a0cfd6c0a985a07b25de351a84e3b9daaebd952b62628db0d937de08a8d05ee4bcace7e72d6b5ce6b8435 -PCRE2.v10.44.0+0.x86_64-unknown-freebsd.tar.gz/md5/a0bc32a099a584d453458a76c892fe47 -PCRE2.v10.44.0+0.x86_64-unknown-freebsd.tar.gz/sha512/6649c1b9e9569a9decccf6ebaa61d44acdb9069208ec796777d8e70a908210f775be2142053f6a5762ebaa321e297f6d8b51db99629766bc702c498b5f772492 -PCRE2.v10.44.0+0.x86_64-w64-mingw32.tar.gz/md5/eeffb6164fba08b0d5c7f50afa081475 -PCRE2.v10.44.0+0.x86_64-w64-mingw32.tar.gz/sha512/f06db992a2070a88559c15224972aeb098d4291a4325970fc0fbbb7cdd539f4a2fd4f90c0de90a34fe454da6c38290f9e0c7fdf2fe8c441f687fe4491d652adc +PCRE2.v10.44.0+1.aarch64-apple-darwin.tar.gz/md5/14de26cfc0f6ff7635fac39e81e81a27 +PCRE2.v10.44.0+1.aarch64-apple-darwin.tar.gz/sha512/45079ecca5f4966a32895fcc63585f1dd60f306dc1cb5c098d42452fcff67f7f6b405c200a15747af4680151bb6a6374832a0119b8ddd743d2ed13d0beaef7c9 +PCRE2.v10.44.0+1.aarch64-linux-gnu.tar.gz/md5/3cf179ed36d37bff698ab81cf3d5797b +PCRE2.v10.44.0+1.aarch64-linux-gnu.tar.gz/sha512/db93e5a5c0c46b5536ed49515682d9bfe1d23f6ba8ae2468289ec8f2160140f39f5606a3c7095f45251f3663d8ccf2d6d7e5e8b1efb21c39bbf9a13b6ec60ef9 +PCRE2.v10.44.0+1.aarch64-linux-musl.tar.gz/md5/02baa415218f581a5ceeb7bf7fc0a090 +PCRE2.v10.44.0+1.aarch64-linux-musl.tar.gz/sha512/1685f37ed8f465ecc2f738fdf65d20bb1806934ff2c50194882282fb6c3900121c61c39210e4c0b89847493bfc3e15bb7b9136b0d968103b47c8662a78b412fe +PCRE2.v10.44.0+1.aarch64-unknown-freebsd.tar.gz/md5/4de065ea59ab4f622b46079df1d9d941 +PCRE2.v10.44.0+1.aarch64-unknown-freebsd.tar.gz/sha512/aa6df9edfb690d155a8b5a9390db7ca11622ac0020174cf070a33a075801bfe43bd4c80b8e28017989a8b7374d39897cdcf72ab0e1962e3e234239975f7ac0b4 +PCRE2.v10.44.0+1.armv6l-linux-gnueabihf.tar.gz/md5/f8a0907fbb20a06507fce849db098c4f +PCRE2.v10.44.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/3f5bcc1742380a31683a81740d55e198d7ec8d8ea5a13d6d0556d6603e4fadbf0dc648093c44e36dd6d3793c52a5e3dae6f2f459c73e3d3b5a005f3395d26772 +PCRE2.v10.44.0+1.armv6l-linux-musleabihf.tar.gz/md5/8854c24183441aa6fd21989c00888904 +PCRE2.v10.44.0+1.armv6l-linux-musleabihf.tar.gz/sha512/a74d9378f071dc4cb021e5171d66cd4ac5de3b348e993fc90d824ce5d2f554f7c8af7af55ec31d874d302aaba7d542b6505cc5963e53656c28026a06a53ed48b +PCRE2.v10.44.0+1.armv7l-linux-gnueabihf.tar.gz/md5/04960309ee7cf69a53e280878d5880ef +PCRE2.v10.44.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/a1644daf036daa3799368598427c87c23bcfdddac55a0d06adca08a2e9d617c893285855af562101b05129d0ed0d84d22f5a8a1703316ecd09aa1752b8330eef +PCRE2.v10.44.0+1.armv7l-linux-musleabihf.tar.gz/md5/1335defc6090be76c509840633f7cdfb +PCRE2.v10.44.0+1.armv7l-linux-musleabihf.tar.gz/sha512/9595052eeae4da413b930b14d7e89359a29220cd9e908325e0b7788c8f4a2feb2134e78a0d8f56007787f0fefadc9de31750db6104bbdd048fa50e1d785c2a8c +PCRE2.v10.44.0+1.i686-linux-gnu.tar.gz/md5/e2d6be1d19566c965c2afeb995aba52f +PCRE2.v10.44.0+1.i686-linux-gnu.tar.gz/sha512/4a9d981bb6aa9150b670db7c5d4d188c8391fcb2a16bc710ede7a84bf7ec546fc5fd9096a339720579d25b6dcb5674b2b5b28e9664e5ef589b1a5044ce38b6a7 +PCRE2.v10.44.0+1.i686-linux-musl.tar.gz/md5/23cf857bd3daea4f094fcec48a7712dc +PCRE2.v10.44.0+1.i686-linux-musl.tar.gz/sha512/534f0cfab0cd60db9498eff387f7280a8baaf893a98dd2e7a737e68ba6473ed8236e9da85116eefb9812ec5323c705a00fcaff010b1900f752de8bdff65ef3ad +PCRE2.v10.44.0+1.i686-w64-mingw32.tar.gz/md5/3d05764df2305f16e4ffab60031ad40c +PCRE2.v10.44.0+1.i686-w64-mingw32.tar.gz/sha512/3e21cc6b71849c1a361373de30567990dba13dfd8812e7a7b5e2734b572bf1d45aeb730289d329975e76932c4c40e476824be2ab8e80a40fb7a7e2f46159235a +PCRE2.v10.44.0+1.powerpc64le-linux-gnu.tar.gz/md5/596d7c29d1417ed8959ea3ae3b4df453 +PCRE2.v10.44.0+1.powerpc64le-linux-gnu.tar.gz/sha512/89e03bfd6890150e2c8dddc4e7d024f2e09421c25a3d0fef3b5cd7f6bab7d6402ec1e82b02ecb5d26d01dfa2fb6068d050513894c374b7f2244c8fcbf00d69e2 +PCRE2.v10.44.0+1.riscv64-linux-gnu.tar.gz/md5/8330a431f4da1d20cffdb64d2c270dfb +PCRE2.v10.44.0+1.riscv64-linux-gnu.tar.gz/sha512/a836d0b9feefd9ffd50cf29db72ab704e6ae442939322526e2a5613973eabc8e543c5546ce507b0c5f9e6f1ce324978aeb6e99f8833eb60fc90e74139e47c6d2 +PCRE2.v10.44.0+1.x86_64-apple-darwin.tar.gz/md5/18f13c78ff6388c601bd36788e526b31 +PCRE2.v10.44.0+1.x86_64-apple-darwin.tar.gz/sha512/7b43a289f54064fc3c292de98173ec91cde2e49402c99c7848cbdc0e6d90a23a86d41f521e3986fcc8d941ee070d09e29ddc89a4e23009b8e9333e577ae4a09c +PCRE2.v10.44.0+1.x86_64-linux-gnu.tar.gz/md5/9f45feca0955f81ceb898208b9c74e15 +PCRE2.v10.44.0+1.x86_64-linux-gnu.tar.gz/sha512/eac215838306f7b5adb2166c3f620a69ed52fbd752ef3673a887507963a826c305d9b078dbb5236dc9a45eaca0d34f77325aab41703745701a077c84822ec0d0 +PCRE2.v10.44.0+1.x86_64-linux-musl.tar.gz/md5/79f092c6e8e971027ac6c1f0987376fb +PCRE2.v10.44.0+1.x86_64-linux-musl.tar.gz/sha512/2c5655b0f719a7d442c89f1040f2973b03f8becd855a0cfd6c0a985a07b25de351a84e3b9daaebd952b62628db0d937de08a8d05ee4bcace7e72d6b5ce6b8435 +PCRE2.v10.44.0+1.x86_64-unknown-freebsd.tar.gz/md5/a0bc32a099a584d453458a76c892fe47 +PCRE2.v10.44.0+1.x86_64-unknown-freebsd.tar.gz/sha512/6649c1b9e9569a9decccf6ebaa61d44acdb9069208ec796777d8e70a908210f775be2142053f6a5762ebaa321e297f6d8b51db99629766bc702c498b5f772492 +PCRE2.v10.44.0+1.x86_64-w64-mingw32.tar.gz/md5/eeffb6164fba08b0d5c7f50afa081475 +PCRE2.v10.44.0+1.x86_64-w64-mingw32.tar.gz/sha512/f06db992a2070a88559c15224972aeb098d4291a4325970fc0fbbb7cdd539f4a2fd4f90c0de90a34fe454da6c38290f9e0c7fdf2fe8c441f687fe4491d652adc pcre2-10.44.tar.bz2/md5/9d1fe11e2e919c7b395e3e8f0a5c3eec pcre2-10.44.tar.bz2/sha512/ee91cc10a2962bc7818b03d368df3dd31f42ea9a7260ae51483ea8cd331b7431e36e63256b0adc213cc6d6741e7c90414fd420622308c0ae3fcb5dd878591be2 diff --git a/deps/checksums/suitesparse b/deps/checksums/suitesparse index bac143325196f..f4e47961d8cc3 100644 --- a/deps/checksums/suitesparse +++ b/deps/checksums/suitesparse @@ -1,36 +1,40 @@ -SuiteSparse-7.8.0.tar.gz/md5/ad42a80d28bb56a1fce15f6e7332e04e -SuiteSparse-7.8.0.tar.gz/sha512/91aff0aee26e938ba88a8f92db15b0db0ecc6ada3b60153bb299f53a45ccda131db4bc66f890c220034c900180d0bb3a5fb3e2686fec7d6174f5900a3ee64424 -SuiteSparse.v7.8.0+1.aarch64-apple-darwin.tar.gz/md5/38379e14a53663a9c23f32ed56801676 -SuiteSparse.v7.8.0+1.aarch64-apple-darwin.tar.gz/sha512/3f2a7aa7778a22d150bad9ecb8d03edfa75707a07545e65660c8ccc4b0a9fb058ccab29e21e4728741d40d390d28922d521d3841e16258cf8e26acacadfc1fbd -SuiteSparse.v7.8.0+1.aarch64-linux-gnu.tar.gz/md5/bc52c7df0a442c0fb9aafb83d60878f4 -SuiteSparse.v7.8.0+1.aarch64-linux-gnu.tar.gz/sha512/436e79ea0774d6ffb571b513e385ef48d9cc70b72010cffdc23d606ad6c8984c8b49e2422ce8881def0722f3f608e4ecb87e6752dd80cf7988addd330c5ded13 -SuiteSparse.v7.8.0+1.aarch64-linux-musl.tar.gz/md5/87e4c2588efc39723621ac5010ddf2e5 -SuiteSparse.v7.8.0+1.aarch64-linux-musl.tar.gz/sha512/17115826716bb48f16e4593941be275d47012d112e54d8826c75fde119ffc9f66accd02353b309365b59779d7af3ac220f31ab7cf7eea165b209a93ecdc4102f -SuiteSparse.v7.8.0+1.aarch64-unknown-freebsd.tar.gz/md5/108a78ec5d21c910b1f0d3cd58b2b18e -SuiteSparse.v7.8.0+1.aarch64-unknown-freebsd.tar.gz/sha512/730f93e317305073acda619044296eb1844bc1380719a9c2f2f255bebd7c0c827317ff99ce06a081521f9441c3ca7fbcb2362a310ef3c5d289f485b2628c3d80 -SuiteSparse.v7.8.0+1.armv6l-linux-gnueabihf.tar.gz/md5/b1490603aa129942d8e4c9581853cd0a -SuiteSparse.v7.8.0+1.armv6l-linux-gnueabihf.tar.gz/sha512/e23c3532784e295ae72b811d285c3729c3f8ac1b5ee1621e831b6b2824a5b357e4bfa49e09174de7763fc3ebcab6b84ef16536bc1cf6f4bc0543b1b229209178 -SuiteSparse.v7.8.0+1.armv6l-linux-musleabihf.tar.gz/md5/f8199358882f76dd30bcce741b837de1 -SuiteSparse.v7.8.0+1.armv6l-linux-musleabihf.tar.gz/sha512/2c8d4ec21bfe253d3d32a5f5f09601b9b2864149f63f53067b157f5f7315fb04236bf5b19a1e5b4569e2c73127dcbb1703d56c7d06fc3ab9ae155902b7a1c2a9 -SuiteSparse.v7.8.0+1.armv7l-linux-gnueabihf.tar.gz/md5/cc3aa1a013cc91e7076dddf20fba9f60 -SuiteSparse.v7.8.0+1.armv7l-linux-gnueabihf.tar.gz/sha512/a6b8cfbc345a089f12e55d8d44061dcce30f94c2d79fc520d6c5dfe433ac2e362d049fac72278cb59d4b3760ca08d5e350b7e2658fa5e8c77ce8608f67c2c4c4 -SuiteSparse.v7.8.0+1.armv7l-linux-musleabihf.tar.gz/md5/0d7797d31c30c53bf219cdc0a48e64dc -SuiteSparse.v7.8.0+1.armv7l-linux-musleabihf.tar.gz/sha512/a7df8938ee6a04f62169bedd29c8408951cf33a43e0f529fb4d1e360bdad6462a50b2af297adb5f51fd726e1ced1fc8fcda7feeeafbeb44000bfe02a8e29c29e -SuiteSparse.v7.8.0+1.i686-linux-gnu.tar.gz/md5/e48fa3d2e00f210e964c21e4ff27efae -SuiteSparse.v7.8.0+1.i686-linux-gnu.tar.gz/sha512/3088c2af476285eb8549cf6aa56381156d49513a274348f86fbf01aa9ce0712961471f83fa50b261f3f365a302b88eb20ef0bb35b58c07a2cfb5dc337fdb72c1 -SuiteSparse.v7.8.0+1.i686-linux-musl.tar.gz/md5/e55202dbeca107a0c25a4f09d5d68915 -SuiteSparse.v7.8.0+1.i686-linux-musl.tar.gz/sha512/0f4de2e62016914b4d1bcb9b13bd8cb2bebefc5f0a532e103948b9aae79a20462ac7b74a3e968d4f99076c37dbbafb747699cd151e831ff89d297f78478fb84f -SuiteSparse.v7.8.0+1.i686-w64-mingw32.tar.gz/md5/e8f4de53ec4ae74554e76bd52702d7a4 -SuiteSparse.v7.8.0+1.i686-w64-mingw32.tar.gz/sha512/f944f14e62408f04a9966cd927cbbbe26b00a4beccc85ab8923dc4028875b0395c6b5e56efba1fd2f29fb954543ca83e800685ffafcdfdd97351a7d4926349a8 -SuiteSparse.v7.8.0+1.powerpc64le-linux-gnu.tar.gz/md5/12058f122b548a37070770d1847f3ce9 -SuiteSparse.v7.8.0+1.powerpc64le-linux-gnu.tar.gz/sha512/f375feeb8448ea90ce8d9f31c7e1230f6868316f06094ba0155069dded4f8da2e1b54d462ef9cfc77abd76147740d4066236dcf1fcea91f8a7141819962ad0ae -SuiteSparse.v7.8.0+1.x86_64-apple-darwin.tar.gz/md5/1bd473f2a25f1ebcea8acc858e2594b4 -SuiteSparse.v7.8.0+1.x86_64-apple-darwin.tar.gz/sha512/034af137deee5bf0ebf3746745d09ad50ce135cd4768a2049bb9811478ff90e6ed8e2c990e277b4c3b38a3a5e9eaa856938eb86239ca445fa64b6dab6af7e996 -SuiteSparse.v7.8.0+1.x86_64-linux-gnu.tar.gz/md5/c58a86d9f25e6705941105d9e41f084c -SuiteSparse.v7.8.0+1.x86_64-linux-gnu.tar.gz/sha512/56447062802f01815ffb014624423c6fd3ab6e16b642b2fe37972a151b02865965c95ca3d1a455c6d51cd31633aea8a732b235b55d68e6779c17b293c488fa43 -SuiteSparse.v7.8.0+1.x86_64-linux-musl.tar.gz/md5/ba6e10ba61c209df94f18ab51fe2dd90 -SuiteSparse.v7.8.0+1.x86_64-linux-musl.tar.gz/sha512/3b8fc504cfb4a3b628d5b955a482bad08c85e09e529f833855a84b847721247aaa469f96adef6b218a1ba5896cde91664cc819ba33115e3cc309e72140841ca3 -SuiteSparse.v7.8.0+1.x86_64-unknown-freebsd.tar.gz/md5/a50c69142a42c14edac4ce94b86b138a -SuiteSparse.v7.8.0+1.x86_64-unknown-freebsd.tar.gz/sha512/963be0dccd1a594df08fe5135ef4ac13e1d707841c3e97d31ba5477d0d6ec26bad9be1c52d9fd78f199740a53950353adbdd767469f3bf01ea1e3ee843eb6c1a -SuiteSparse.v7.8.0+1.x86_64-w64-mingw32.tar.gz/md5/7ca11ba89bd09183cc5a9320d6e8a4a7 -SuiteSparse.v7.8.0+1.x86_64-w64-mingw32.tar.gz/sha512/e1d5def1103bbf0bb29c08cdd3bf21ba60456353694985c66f8e55a31d54a32c5b891e56e1ffe30f9e1223c49283d267e483e2f1b999f566099c239b3eed1d78 +SuiteSparse-7.8.3.tar.gz/md5/242e38ecfc8a3e3aa6b7d8d44849c5cf +SuiteSparse-7.8.3.tar.gz/sha512/fc0fd0aaf55a6712a3b8ca23bf7536a31d52033e090370ebbf291f05d0e073c7dcfd991a80b037f54663f524804582b87af86522c2e4435091527f0d3c189244 +SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/md5/46541001073d1c3c85e18d910f8308f3 +SuiteSparse-e8285dd13a6d5b5cf52d8124793fc4d622d07554.tar.gz/sha512/f7470a447b934ca9315e216a07b97e363f11bc93186f9aa057b20b2d05092c58ae4f1b733de362de4a0730861c00be4ca5588d0b3ba65f018c1798b9122b9672 +SuiteSparse.v7.8.3+2.aarch64-apple-darwin.tar.gz/md5/e97424dc7b9e44cb18ca50b99d71a0a8 +SuiteSparse.v7.8.3+2.aarch64-apple-darwin.tar.gz/sha512/2d077c785fe1109ad83e001516394c027f0ba1d77186e73df3d89ee03aea7817f09e15c0b1302711aebd168e06675cc865e2936c4c654c9f65932434f974e9c6 +SuiteSparse.v7.8.3+2.aarch64-linux-gnu.tar.gz/md5/7b14b0fe44156b117ebee60811f666e6 +SuiteSparse.v7.8.3+2.aarch64-linux-gnu.tar.gz/sha512/dc726895c6f4c3e7a8d87507946cc0fd15e8d6c6d6d22698976df8c53aeec0532abb0c34bcb98767a6ee3b3146f60189a575a8e523be75b951d33535b6de5359 +SuiteSparse.v7.8.3+2.aarch64-linux-musl.tar.gz/md5/5a4e485cb6a7025196548e8bab4228c6 +SuiteSparse.v7.8.3+2.aarch64-linux-musl.tar.gz/sha512/9c091cd13b61a4d291751c294a080b95c9068b13bd805089c962e06fafdb12da08087709759d5310ceb2c115255b14c1a99c4ed45f660f8680dcc30f55ac6f49 +SuiteSparse.v7.8.3+2.aarch64-unknown-freebsd.tar.gz/md5/895f1b9b79455c3c26a9e3c64c335dc5 +SuiteSparse.v7.8.3+2.aarch64-unknown-freebsd.tar.gz/sha512/9876a711d79314dcf68bacf0460267f69474c736346bf9f098ed56c3430fca67d9b73d7d30fa6d3c5ac1cacb017f57be2d83b2310f695d51b73e3ce98234a10e +SuiteSparse.v7.8.3+2.armv6l-linux-gnueabihf.tar.gz/md5/9784404d2ff45a94a9ce9e671badcdf0 +SuiteSparse.v7.8.3+2.armv6l-linux-gnueabihf.tar.gz/sha512/8f49fc05c80f6b869810e5f128c04a5816ebc2ae24313ba699723be9550407a634486d0c95089325350381cd534d3e991cc07a80f509a612f6da27da32b1d6d0 +SuiteSparse.v7.8.3+2.armv6l-linux-musleabihf.tar.gz/md5/b26cdada5bd08e3284dd74e7bb14a770 +SuiteSparse.v7.8.3+2.armv6l-linux-musleabihf.tar.gz/sha512/78695ebab8c73bed06723e3052c471888e84e90681561e32469bac49784b8973af355a19db5ad3663373fde97b92ade112e48a0ece4209b9933c05faa9a7b83d +SuiteSparse.v7.8.3+2.armv7l-linux-gnueabihf.tar.gz/md5/4ae051735ae0c34ab2d5e1f0bec3f26c +SuiteSparse.v7.8.3+2.armv7l-linux-gnueabihf.tar.gz/sha512/efdd084c9bfac1cd9a4128aa7d6a4f0d682cd6c791dbcf1ed2f53b77f6e9c4ab9ed13f54ff6dc54603b5426bc09f7833defaca3d135cd1995d92a177d1d97eb0 +SuiteSparse.v7.8.3+2.armv7l-linux-musleabihf.tar.gz/md5/2e55d69017c5ec6fca694aabf1470dc1 +SuiteSparse.v7.8.3+2.armv7l-linux-musleabihf.tar.gz/sha512/1c75fa1536f5db13e1d613d61959dc1004570a5df45f75820f9554c7395f7492ad5edd5865d5b5c3f6aee65ffa33aa68dab1616547aeb7614da6bf708a748dc1 +SuiteSparse.v7.8.3+2.i686-linux-gnu.tar.gz/md5/817e2479c223e9c023ec431aea4b2361 +SuiteSparse.v7.8.3+2.i686-linux-gnu.tar.gz/sha512/c0e4482570bed4366f68df9635a6229289008c0754c3d636d26a44004e5c80ae04c6ab434b0dbf57baa05e4afc847716d9e059904faf9d10be7abdade2890803 +SuiteSparse.v7.8.3+2.i686-linux-musl.tar.gz/md5/e7a6c8f58a81e0ac511d44e878b9128d +SuiteSparse.v7.8.3+2.i686-linux-musl.tar.gz/sha512/54c00ba5bd8bb514e8cc29ce0ed596c642678ea1fe27571cbbb3210b9ad8940ecac2100e05b29d5db51804daab714c48d18dbf65650924b90c076078681990a3 +SuiteSparse.v7.8.3+2.i686-w64-mingw32.tar.gz/md5/3db74decc8363735a0a9f71f2558c2c9 +SuiteSparse.v7.8.3+2.i686-w64-mingw32.tar.gz/sha512/d5dc5e263a9705d2510f541ffe9c5a543a4a0ba7c104ad03142ef04de5a25cdb7da59eed3218cdf540b7b2167235206d438db283da682ba31568d99076fccece +SuiteSparse.v7.8.3+2.powerpc64le-linux-gnu.tar.gz/md5/78f008e14dfb2580da95ac58466d9d16 +SuiteSparse.v7.8.3+2.powerpc64le-linux-gnu.tar.gz/sha512/ea7370f5071c1e5bb2980f76f16ec88eded7fab6d7773c99fff9087adee446b5f4cefd16ff483aa92197fabea35cb3e486742a58fefa6fee0997a358ada14c8a +SuiteSparse.v7.8.3+2.riscv64-linux-gnu.tar.gz/md5/966c2093ab4d0652084652f54e58c5f7 +SuiteSparse.v7.8.3+2.riscv64-linux-gnu.tar.gz/sha512/febff4241ff15471a7a3bcb544a7e34ab71da1c516b3fcff89cd726d392c2fcea0bb970c8a2ee7a4461c341c7be02f47fcdc47f4a7f88307cceeb3f75327c625 +SuiteSparse.v7.8.3+2.x86_64-apple-darwin.tar.gz/md5/7a8b5ab88a83081545a411202caf5a1f +SuiteSparse.v7.8.3+2.x86_64-apple-darwin.tar.gz/sha512/186f5fb8a7117d8cf77b311ea0c137b270eca895aecd31dc616b86425c62ae3d0218938cf1cf54d5009b7ff8247f40ae21b6c452fdd339fead5622e710c03418 +SuiteSparse.v7.8.3+2.x86_64-linux-gnu.tar.gz/md5/001cb5ce58344f1186a51d6018a9c337 +SuiteSparse.v7.8.3+2.x86_64-linux-gnu.tar.gz/sha512/8cd407ff3e857cb49d26adde68746c0a73742c4556ab624b34eb5caa95a7c438d1aa6a7fb3b9d54341f0469ae7b19f78e09f2a2642f15f4795d9583162cf12e1 +SuiteSparse.v7.8.3+2.x86_64-linux-musl.tar.gz/md5/305e268c36927a94037419153d37fe91 +SuiteSparse.v7.8.3+2.x86_64-linux-musl.tar.gz/sha512/aebd921b721f8f71bbdc94aa60ae2f2c3bc5de21acbda0ae1e96e19dbc86c13cbe1921cd5938bbb4f9f83c84a2a6b4f980e743684e8236e7a979ead0042e9dec +SuiteSparse.v7.8.3+2.x86_64-unknown-freebsd.tar.gz/md5/81f85e3374a9b7bbe0a25b8cb88d3438 +SuiteSparse.v7.8.3+2.x86_64-unknown-freebsd.tar.gz/sha512/fb0b1c219d1ce35f79d945fccb5c5a2e1e8d9f32a2401dc3071781740c6c16e729746ffb02c76680e681f8978d19948b28612c97136f1396d030e69c3eb336d9 +SuiteSparse.v7.8.3+2.x86_64-w64-mingw32.tar.gz/md5/a3a68bafb213ea68006cdfdbb15e1457 +SuiteSparse.v7.8.3+2.x86_64-w64-mingw32.tar.gz/sha512/6db131bb8b0efbcbaf4ee9f2688dc1083a570da5fc9ddb044ffc9308fd5d6949241cd780e5246484ae6417b261bfd61683b6122c7dba7d1598d5e89be6d73acc diff --git a/deps/checksums/utf8proc b/deps/checksums/utf8proc index 543c1805afbd8..2055d3323b7e1 100644 --- a/deps/checksums/utf8proc +++ b/deps/checksums/utf8proc @@ -1,2 +1,2 @@ -utf8proc-34db3f7954e9298e89f42641ac78e0450f80a70d.tar.gz/md5/e70e4fd2c914b4d4c0e3f0e2ca6c96d4 -utf8proc-34db3f7954e9298e89f42641ac78e0450f80a70d.tar.gz/sha512/0037f144e1150abd1b330d8a0c3a46c8352903acc9f4c8aad6bddd1370b19cc34551f8def58752cdff4eaace3efe54180bc11439a0e35c5ccad2fec4678c017e +utf8proc-a1b99daa2a3393884220264c927a48ba1251a9c6.tar.gz/md5/2c404870fdc19982ec5313ee78e478d7 +utf8proc-a1b99daa2a3393884220264c927a48ba1251a9c6.tar.gz/sha512/a6652f5840439fe051d973d9467ca9805dcea8d0ac75a2d35e3f8041c513d6ccd5d205a3873f28d7cb5e33ce6471165850164997f188ca359111963b3aac9a16 diff --git a/deps/checksums/zlib b/deps/checksums/zlib index f5e7353f32e3e..bd651003399b9 100644 --- a/deps/checksums/zlib +++ b/deps/checksums/zlib @@ -1,36 +1,38 @@ -Zlib.v1.3.1+1.aarch64-apple-darwin.tar.gz/md5/50b48e14f0b3578e3f398d130749a25d -Zlib.v1.3.1+1.aarch64-apple-darwin.tar.gz/sha512/d970e183035b3615b410f7b0da2c7a1d516234744491d65ed1ebc3800b55732f20bf00fcbb0cf91289b8b4660915282873fb23788896713cf8dfae2984a8fd85 -Zlib.v1.3.1+1.aarch64-linux-gnu.tar.gz/md5/ee42c0bae86fc39968c8cd6a77a801bf -Zlib.v1.3.1+1.aarch64-linux-gnu.tar.gz/sha512/5d21cbeab03d44008c6cbad114d45c917ebee2fe98de6b19686f4f6ba1fc67eeedf968b94ed1c2d4efb89e93be9efa342bcc8a57cb8a505085d177abae14bc2d -Zlib.v1.3.1+1.aarch64-linux-musl.tar.gz/md5/9091d1288736b218f7b016791dc1a9c8 -Zlib.v1.3.1+1.aarch64-linux-musl.tar.gz/sha512/b49cbfe734beb2af9ef8e847542d006765345cbb08aee0854779e35e03c98df25c93539b046547c6b66029987c49499ddf6cb207824b1e376900bfceaa79691a -Zlib.v1.3.1+1.aarch64-unknown-freebsd.tar.gz/md5/c73793872e3a2259519276b3ab2899ce -Zlib.v1.3.1+1.aarch64-unknown-freebsd.tar.gz/sha512/ce1e3ed5dfb01653471ace4c0cb2d8b521ccd02bc2a2c537e433a0dc497906ad21008645c645f2e0f2bb1f39c40e9a68d8cca0aeddc74ade0e188dc80748c2e8 -Zlib.v1.3.1+1.armv6l-linux-gnueabihf.tar.gz/md5/b686c85047b7dad2c2f08d1d16e7978a -Zlib.v1.3.1+1.armv6l-linux-gnueabihf.tar.gz/sha512/511fda619519dccedb264988e3b59a0e0fbf8f73d3ae290f238346209ebc0202a22f945257cea19afef64246574285e0322901a46bb48d7b48364c1e2eacd801 -Zlib.v1.3.1+1.armv6l-linux-musleabihf.tar.gz/md5/374be5cb926876f3f0492cfe0e193220 -Zlib.v1.3.1+1.armv6l-linux-musleabihf.tar.gz/sha512/4d3a2cc0c7c48146e63ed098da5a5acad75517197adc965550c123f7f8bcee0811a27be76fa37b6b0515eee4b5ba1c1a85c854e7b23bea36b5e21671805bedce -Zlib.v1.3.1+1.armv7l-linux-gnueabihf.tar.gz/md5/9febbc6a3d492e34c9ed53c95f3b799f -Zlib.v1.3.1+1.armv7l-linux-gnueabihf.tar.gz/sha512/4cee0e2cf572eb91028a09ef356e1aa6360949e046ceec03bd37574295ddcc4a7cefca9276f7565f152697d55b35f62af2ab107cdbf402b42846818629fea9c7 -Zlib.v1.3.1+1.armv7l-linux-musleabihf.tar.gz/md5/5d0d59a6cbbd1e63193ba6f7dbb755f9 -Zlib.v1.3.1+1.armv7l-linux-musleabihf.tar.gz/sha512/ee3f48b354168342ef63509b19a26aca3301fb3e5f4f6898afe2d3b44ee3380515efd6ced5d4e06e69736d851d19352deb9595bad82c051caccaee8c55e629d8 -Zlib.v1.3.1+1.i686-linux-gnu.tar.gz/md5/834350a64b2302a9caf0250a8f6068e5 -Zlib.v1.3.1+1.i686-linux-gnu.tar.gz/sha512/63dc158c4dfc42db97875893fcdd9784d9487af855bd576dbe04d1b967ad64510222df74a4cfb1b7e67386329d2a5686d7931b81720883fc1924f0d706a0a711 -Zlib.v1.3.1+1.i686-linux-musl.tar.gz/md5/e4f96efdeafa3d74c7c348059a8dc46a -Zlib.v1.3.1+1.i686-linux-musl.tar.gz/sha512/b47a571d94887ddcab8d7b50c6dce3afed3f56513a9d1859feaefebfad4a271d428b440df1d19ef3c2ed01ca4c8fd121ffc1572f5e252f27d0930f616cb47f18 -Zlib.v1.3.1+1.i686-w64-mingw32.tar.gz/md5/aaa1500c06b280d142e2900dbedf2a8f -Zlib.v1.3.1+1.i686-w64-mingw32.tar.gz/sha512/bc6668baf33bc8e130ae6a72f6cd89d9f1ccc95d2f3a3bcef20cde03ed7602de511f7646feed918918a24d8a2221a0be39eb2c0884c1adb6fe0d67b91cceb683 -Zlib.v1.3.1+1.powerpc64le-linux-gnu.tar.gz/md5/27dcad8557994cfd89d6fa7072bb843c -Zlib.v1.3.1+1.powerpc64le-linux-gnu.tar.gz/sha512/3b388dd286b273881d4344cff61c7da316c2bd2bab93072bf47ce4cb1cf9662158351b8febb0d5b1f8dfd9bc73cd32f7cae37fdd19b0ca91531bd3375df104bb -Zlib.v1.3.1+1.x86_64-apple-darwin.tar.gz/md5/9187319377191ae8b34162b375baa5db -Zlib.v1.3.1+1.x86_64-apple-darwin.tar.gz/sha512/895203434f161926978be52a223dd49a99454651a79c1c5e0529fa064f3f7ac2d7a069fed47a577b32523df22afadd6eb97d564dbd59c5d67ed90083add13c00 -Zlib.v1.3.1+1.x86_64-linux-gnu.tar.gz/md5/55d4d982d60cb643aa8688eb031b07ee -Zlib.v1.3.1+1.x86_64-linux-gnu.tar.gz/sha512/d8f94d22ffc37df027de23b2408c2000014c8b7b6c8539feca669ac1f2dbbe1679ca534c3be4d32c90fe38bbba27c795689226962fb067346b5ca213e64b9c4b -Zlib.v1.3.1+1.x86_64-linux-musl.tar.gz/md5/95d735bba178da4b8bee23903419919c -Zlib.v1.3.1+1.x86_64-linux-musl.tar.gz/sha512/370370f08133a720e3fbedcc434f102dc95225fda3ec8a399e782851bd4be57fb2b64a3ed62dc0559fb0c58d2e28db9b9e960efafd940982e4cb6652be0e81f1 -Zlib.v1.3.1+1.x86_64-unknown-freebsd.tar.gz/md5/df158f50fdb8ac1179fe6dad3bc62713 -Zlib.v1.3.1+1.x86_64-unknown-freebsd.tar.gz/sha512/f4ba4ccfeaf3fd2e172a2d5b3b1ae083ee9854022e71e062e29423e4179cb1fc49b2b99df49b3f5f231e2a0c5becc59b89644e9dcaf0fda9c97e83af7ea1c25d -Zlib.v1.3.1+1.x86_64-w64-mingw32.tar.gz/md5/9cc735c54ddf5d1ea0db60e05d6631ea -Zlib.v1.3.1+1.x86_64-w64-mingw32.tar.gz/sha512/8a2fd20944866cb7f717517ea0b80a134466e063f85bec87ffba56ca844f983f91060dfdc65f8faee1981d7329348c827b723aaad4fea36041e710b9e35c43de +Zlib.v1.3.1+2.aarch64-apple-darwin.tar.gz/md5/938c376c7513fa48d4b8b78cea741260 +Zlib.v1.3.1+2.aarch64-apple-darwin.tar.gz/sha512/ccece3f5618efe3e3699eb521167e2ee768932ea6f4e411d36619a941af3e9e32394beb260171d557930382f412f9be70f4c69215d3f7e448d4446b1690111ee +Zlib.v1.3.1+2.aarch64-linux-gnu.tar.gz/md5/44a14273caeea9c5cb34ce3e0ba9d1fc +Zlib.v1.3.1+2.aarch64-linux-gnu.tar.gz/sha512/8977bdc225404a01746fc14885e4823b4e2781c73a75e0ee0c8d9ca58b706c6cf9f98647b4e22bb09e7e09640caf4643e5210054a4624e06c76fc3eb2c2a2728 +Zlib.v1.3.1+2.aarch64-linux-musl.tar.gz/md5/dcef6c714555de9b2181b8c5b0a2c668 +Zlib.v1.3.1+2.aarch64-linux-musl.tar.gz/sha512/499701cc0fd1e52f3952da1b3c4377662c54390db9ebd6f5be82ecc0ba8754d2ca42b2f572b3a78ccdef30e527b7bed22c15511944f1299398587c529f8f4619 +Zlib.v1.3.1+2.aarch64-unknown-freebsd.tar.gz/md5/166f8a076a01a6f0979c712d7cec44e8 +Zlib.v1.3.1+2.aarch64-unknown-freebsd.tar.gz/sha512/7a1546b614cb5e2c0566774247269740d881c0a6d22ef6dca8010d77829b4e64594f4e609bb83299fa239d66909a4eb046d6d078268006723747f86e6c733e6b +Zlib.v1.3.1+2.armv6l-linux-gnueabihf.tar.gz/md5/1f0bcb50b545badbc9de1569f51c4668 +Zlib.v1.3.1+2.armv6l-linux-gnueabihf.tar.gz/sha512/1e4bea6fa41300ec770822dcd9335d1393c087db45d128e2c60d9315db01a69c984c98304b83af0725a99ae3a5cac4a273f4eea8a4213454608edbe0e55c74ce +Zlib.v1.3.1+2.armv6l-linux-musleabihf.tar.gz/md5/3a78103181bf8a74dfc0c6f7681bd3de +Zlib.v1.3.1+2.armv6l-linux-musleabihf.tar.gz/sha512/2a7c70266fd5928e46c8d71d95884054eaff2432d9fbce37eef67eb62af2b087f5f9fa3752a5d14f50cd058519d39a1b81450b30786a4f66eafbd16d18ef7b6b +Zlib.v1.3.1+2.armv7l-linux-gnueabihf.tar.gz/md5/4e202f829e7f478451e93da7be2b6f98 +Zlib.v1.3.1+2.armv7l-linux-gnueabihf.tar.gz/sha512/0734bc8a84b039b971a15620adb9b5da77d1b1992fb4c6adf9031fa8c592512645d424d2ce752efdda1f300f871c3d4f3b159794c3725fd113e1acd5512aed59 +Zlib.v1.3.1+2.armv7l-linux-musleabihf.tar.gz/md5/5000d1941b7e32dec4a2d125bbd22fff +Zlib.v1.3.1+2.armv7l-linux-musleabihf.tar.gz/sha512/6abd69ef6878fa6cdcf7fe94e4d7aedaae58d961122e131a414f3aea43b401a3812d9d847ab4b1690e9faf89d577935d7f547484edb6cb2814cbc1156159e8ed +Zlib.v1.3.1+2.i686-linux-gnu.tar.gz/md5/7a5de529294b9d8dba4ac1eeb4cbcbdc +Zlib.v1.3.1+2.i686-linux-gnu.tar.gz/sha512/72d52c4e2f01fe1436b22c854efff83068f6a65a9280556018c77bb843f81902c0c96f30132123d4dd6a66041e9391a418ceec227b2b2411f99a26df76d21c74 +Zlib.v1.3.1+2.i686-linux-musl.tar.gz/md5/d18b442e4d108397482fd852deb4241e +Zlib.v1.3.1+2.i686-linux-musl.tar.gz/sha512/6c367f7c522167db510cf42a84dfcce75fc129bb49800c05b90dfdfa5fb31fa20ed020e165f1b283b81f4568c9bf79d4c41f7ad4e42a3513cb13149a50707114 +Zlib.v1.3.1+2.i686-w64-mingw32.tar.gz/md5/b2c8af112298ae9e635054e4ba22e5ae +Zlib.v1.3.1+2.i686-w64-mingw32.tar.gz/sha512/0a28076fc8cf8daa925f4be76dd0025d01d8ad6bc269f87164749da0c3bea6f4b404ef097a2907ce2c009211d9f8387f844fe5e5b1bd2f6d77c9b35b2b1c7548 +Zlib.v1.3.1+2.powerpc64le-linux-gnu.tar.gz/md5/9ae4feb621ae088c323ff12235bdf5db +Zlib.v1.3.1+2.powerpc64le-linux-gnu.tar.gz/sha512/912134f741fe96217d1b8465510ac82d238d3d8a21519534fb88c568092dcc9eb8e51ef66b7ca56a2a7a881474f04edb7a6f7bf1ebf06bfff7708b3edd3487c0 +Zlib.v1.3.1+2.riscv64-linux-gnu.tar.gz/md5/43b61473a02e492f932ce60f726966a8 +Zlib.v1.3.1+2.riscv64-linux-gnu.tar.gz/sha512/4742503831da6a6b7945c6e5efd96bd6b03b8a63b73e68181e961b6f326ac5d805350219c43f4537165d1af0ac2ed496d5a72edd0c1d11e012ef12385a8f2e5f +Zlib.v1.3.1+2.x86_64-apple-darwin.tar.gz/md5/347a92686d81ed7c022d2e7310babb77 +Zlib.v1.3.1+2.x86_64-apple-darwin.tar.gz/sha512/a59b9c4f63124c893a2a11b886bbe03bfc75846599eb21997652bd62a2f28afe754d16127e964683552423bf1c0da160e46c32d0b584ed07e28f4e91904b9c67 +Zlib.v1.3.1+2.x86_64-linux-gnu.tar.gz/md5/0630f603e35ab56efdef331e29db436b +Zlib.v1.3.1+2.x86_64-linux-gnu.tar.gz/sha512/b936c328fad685c22473ff4cbfcc8bc48772ed9927c5b29c5d0503b95888efd0ca8d891f53cca45da7b5768ed4a1f6994f9e211167f4704c15c688cced90cac5 +Zlib.v1.3.1+2.x86_64-linux-musl.tar.gz/md5/252d8542bb5a53c479f4ffc067847e27 +Zlib.v1.3.1+2.x86_64-linux-musl.tar.gz/sha512/449809acbbff1fcbd89b9689e803f69d1f9cb49860f0b508b69c560cfcb51232640fcff17ede6ea75d9906edb5a8f38139afd890f18a34260ef5dbb5d167af36 +Zlib.v1.3.1+2.x86_64-unknown-freebsd.tar.gz/md5/79fa906629dff81c38b93001a7798040 +Zlib.v1.3.1+2.x86_64-unknown-freebsd.tar.gz/sha512/53dbcce99b2d6ec82ef86d76f3f574db304ab90f1b131c49b2c06f89bd2426afa4a31bfa8455e2ecdad64d4da71fef1b2d79f471efd55a8bbdc29e95c952a289 +Zlib.v1.3.1+2.x86_64-w64-mingw32.tar.gz/md5/92b083205ca44db131b7cf6b9c09eb21 +Zlib.v1.3.1+2.x86_64-w64-mingw32.tar.gz/sha512/1c3b7b414f09b1896c5a08f156c5e55f07ee012cf3f6fe50d5ba116405dcd9a80e5004ee7c774f7cc981e4d1b099efee85e16b8417cef2734cb7c12ec440d09a zlib-51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf.tar.gz/md5/7ce1b2766499af7d948130113b649028 zlib-51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf.tar.gz/sha512/79d032b8c93260ce6b9806f2289cdccce67e9d80865b5bb39ac46dadffc8ee009da51c551eead59c56249c7adfa164c1d5ebcf2b10a8645e0b11b5650176cb24 diff --git a/deps/csl.mk b/deps/csl.mk index fefe71a5e871c..fef950aa41621 100644 --- a/deps/csl.mk +++ b/deps/csl.mk @@ -75,12 +75,24 @@ else $(eval $(call copy_csl,$(call versioned_libname,libgcc_s_seh,1))) endif else -ifeq ($(APPLE_ARCH),arm64) +ifeq ($(OS),Darwin) +# On macOS, libgcc_s has soversion 1.1 always on aarch64 and only for GCC 12+ +# (-> libgfortran 5) on x86_64 +ifeq ($(ARCH),aarch64) +$(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1.1))) +else +ifeq ($(LIBGFORTRAN_VERSION),5) $(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1.1))) else $(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1))) endif endif +else +# Other targets just use libgcc_s.1 +$(eval $(call copy_csl,$(call versioned_libname,libgcc_s,1))) +endif +endif + # winpthread is only Windows, pthread is only others ifeq ($(OS),WINNT) $(eval $(call copy_csl,$(call versioned_libname,libwinpthread,1))) @@ -105,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/deps/curl.mk b/deps/curl.mk index ae2830c3cd4f2..6232d56e5e333 100644 --- a/deps/curl.mk +++ b/deps/curl.mk @@ -1,6 +1,10 @@ ## CURL ## include $(SRCDIR)/curl.version +ifeq ($(USE_SYSTEM_OPENSSL), 0) +$(BUILDDIR)/curl-$(CURL_VER)/build-configured: | $(build_prefix)/manifest/openssl +endif + ifeq ($(USE_SYSTEM_LIBSSH2), 0) $(BUILDDIR)/curl-$(CURL_VER)/build-configured: | $(build_prefix)/manifest/libssh2 endif @@ -35,37 +39,33 @@ checksum-curl: $(SRCCACHE)/curl-$(CURL_VER).tar.bz2 ## xref: https://github.com/JuliaPackaging/Yggdrasil/blob/master/L/LibCURL/common.jl # Disable....almost everything -CURL_CONFIGURE_FLAGS := $(CONFIGURE_COMMON) \ - --without-gnutls --without-libidn2 --without-librtmp \ - --without-libpsl --without-libgsasl --without-fish-functions-dir \ - --disable-ares --disable-manual --disable-ldap --disable-ldaps --disable-static \ - --without-gssapi --without-brotli +CURL_CONFIGURE_FLAGS := $(CONFIGURE_COMMON) \ + --without-gnutls \ + --without-libidn2 --without-librtmp \ + --without-nss --without-libpsl \ + --disable-ares --disable-manual \ + --disable-ldap --disable-ldaps --without-zsh-functions-dir \ + --disable-static --without-libgsasl \ + --without-brotli # A few things we actually enable -CURL_CONFIGURE_FLAGS += --enable-versioned-symbols \ - --with-libssh2=${build_prefix} --with-zlib=${build_prefix} --with-nghttp2=${build_prefix} +CURL_CONFIGURE_FLAGS += \ + --with-libssh2=${build_prefix} --with-zlib=${build_prefix} --with-nghttp2=${build_prefix} \ + --enable-versioned-symbols # We use different TLS libraries on different platforms. # On Windows, we use schannel # On MacOS, we use SecureTransport -# On Linux, we use mbedTLS +# On Linux, we use OpenSSL ifeq ($(OS), WINNT) CURL_TLS_CONFIGURE_FLAGS := --with-schannel else ifeq ($(OS), Darwin) CURL_TLS_CONFIGURE_FLAGS := --with-secure-transport else -CURL_TLS_CONFIGURE_FLAGS := --with-mbedtls=$(build_prefix) +CURL_TLS_CONFIGURE_FLAGS := --with-openssl endif CURL_CONFIGURE_FLAGS += $(CURL_TLS_CONFIGURE_FLAGS) -$(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied: $(SRCCACHE)/curl-$(CURL_VER)/source-extracted - cd $(dir $@) && \ - patch -p1 -f < $(SRCDIR)/patches/curl-8.6.0-build.patch - echo 1 > $@ - -$(SRCCACHE)/curl-$(CURL_VER)/source-patched: $(SRCCACHE)/curl-$(CURL_VER)/curl-8.6.0-build.patch-applied - echo 1 > $@ - -$(BUILDDIR)/curl-$(CURL_VER)/build-configured: $(SRCCACHE)/curl-$(CURL_VER)/source-patched +$(BUILDDIR)/curl-$(CURL_VER)/build-configured: $(SRCCACHE)/curl-$(CURL_VER)/source-extracted mkdir -p $(dir $@) cd $(dir $@) && \ $(dir $<)/configure $(CURL_CONFIGURE_FLAGS) \ diff --git a/deps/curl.version b/deps/curl.version index 5ecfcc2b642a1..fbbb55ffb17ea 100644 --- a/deps/curl.version +++ b/deps/curl.version @@ -3,4 +3,4 @@ CURL_JLL_NAME := LibCURL ## source build -CURL_VER := 8.6.0 +CURL_VER := 8.11.1 diff --git a/deps/libgit2.mk b/deps/libgit2.mk index 022582d48c78e..8b17ae6d70424 100644 --- a/deps/libgit2.mk +++ b/deps/libgit2.mk @@ -9,8 +9,8 @@ ifeq ($(USE_SYSTEM_LIBSSH2), 0) $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/libssh2 endif -ifeq ($(USE_SYSTEM_MBEDTLS), 0) -$(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/mbedtls +ifeq ($(USE_SYSTEM_OPENSSL), 0) +$(BUILDDIR)/$(LIBGIT2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/openssl endif LIBGIT2_OPTS := $(CMAKE_COMMON) -DCMAKE_BUILD_TYPE=Release -DUSE_THREADS=ON -DUSE_BUNDLED_ZLIB=ON -DUSE_SSH=ON -DBUILD_CLI=OFF @@ -39,7 +39,7 @@ LIBGIT2_OPTS += -DCMAKE_C_FLAGS="-I/usr/local/include" endif ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD)) -LIBGIT2_OPTS += -DUSE_HTTPS="mbedTLS" -DUSE_SHA1="CollisionDetection" -DCMAKE_INSTALL_RPATH="\$$ORIGIN" +LIBGIT2_OPTS += -DUSE_HTTPS="OpenSSL" -DUSE_SHA1="CollisionDetection" -DCMAKE_INSTALL_RPATH="\$$ORIGIN" endif # use the bundled distribution of libpcre. we should consider linking against the diff --git a/deps/libgit2.version b/deps/libgit2.version index ae475f0b3644f..6bfb6106e67d2 100644 --- a/deps/libgit2.version +++ b/deps/libgit2.version @@ -3,12 +3,12 @@ LIBGIT2_JLL_NAME := LibGit2 ## source build -LIBGIT2_BRANCH=v1.8.0 -LIBGIT2_SHA1=d74d491481831ddcd23575d376e56d2197e95910 +LIBGIT2_BRANCH=v1.9.0 +LIBGIT2_SHA1=338e6fb681369ff0537719095e22ce9dc602dbf0 ## Other deps # Specify the version of the Mozilla CA Certificate Store to obtain. # 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/deps/libssh2.mk b/deps/libssh2.mk index c293d8309d2bc..3f802db15be6d 100644 --- a/deps/libssh2.mk +++ b/deps/libssh2.mk @@ -4,8 +4,8 @@ LIBSSH2_GIT_URL := https://github.com/libssh2/libssh2.git LIBSSH2_TAR_URL = https://api.github.com/repos/libssh2/libssh2/tarball/$1 $(eval $(call git-external,libssh2,LIBSSH2,CMakeLists.txt,,$(SRCCACHE))) -ifeq ($(USE_SYSTEM_MBEDTLS), 0) -$(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/mbedtls +ifeq ($(USE_SYSTEM_OPENSSL), 0) +$(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: | $(build_prefix)/manifest/openssl endif LIBSSH2_OPTS := $(CMAKE_COMMON) -DBUILD_SHARED_LIBS=ON -DBUILD_EXAMPLES=OFF \ @@ -21,7 +21,7 @@ ifeq ($(BUILD_OS),WINNT) LIBSSH2_OPTS += -G"MSYS Makefiles" endif else -LIBSSH2_OPTS += -DCRYPTO_BACKEND=mbedTLS -DENABLE_ZLIB_COMPRESSION=OFF +LIBSSH2_OPTS += -DCRYPTO_BACKEND=OpenSSL -DENABLE_ZLIB_COMPRESSION=OFF endif ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD)) @@ -34,14 +34,6 @@ endif LIBSSH2_SRC_PATH := $(SRCCACHE)/$(LIBSSH2_SRC_DIR) -$(LIBSSH2_SRC_PATH)/libssh2-mbedtls-size_t.patch-applied: $(LIBSSH2_SRC_PATH)/source-extracted - cd $(LIBSSH2_SRC_PATH) && \ - patch -p1 -f < $(SRCDIR)/patches/libssh2-mbedtls-size_t.patch - echo 1 > $@ - -$(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: \ - $(LIBSSH2_SRC_PATH)/libssh2-mbedtls-size_t.patch-applied - $(BUILDDIR)/$(LIBSSH2_SRC_DIR)/build-configured: $(LIBSSH2_SRC_PATH)/source-extracted mkdir -p $(dir $@) cd $(dir $@) && \ diff --git a/deps/libssh2.version b/deps/libssh2.version index 7fff90885f6a3..d6cc8a629c3bf 100644 --- a/deps/libssh2.version +++ b/deps/libssh2.version @@ -1,7 +1,8 @@ +# -*- makefile -*- ## jll artifact LIBSSH2_JLL_NAME := LibSSH2 ## source build -LIBSSH2_VER := 1.11.0 -LIBSSH2_BRANCH=libssh2-1.11.0 -LIBSSH2_SHA1=1c3f1b7da588f2652260285529ec3c1f1125eb4e +LIBSSH2_VER := 1.11.1 +LIBSSH2_BRANCH=libssh2-1.11.1 +LIBSSH2_SHA1=a312b43325e3383c865a87bb1d26cb52e3292641 diff --git a/deps/libsuitesparse.version b/deps/libsuitesparse.version index 6f841190cebc7..cc294f68c2d5a 100644 --- a/deps/libsuitesparse.version +++ b/deps/libsuitesparse.version @@ -4,5 +4,5 @@ LIBSUITESPARSE_JLL_NAME := SuiteSparse ## source build -LIBSUITESPARSE_VER := 7.8.0 -LIBSUITESPARSE_SHA1=58e6558408f6a51c08e35a5557d5e68cae32147e +LIBSUITESPARSE_VER := 7.8.3 +LIBSUITESPARSE_SHA1=d3c4926d2c47fd6ae558e898bfc072ade210a2a1 diff --git a/deps/mbedtls.mk b/deps/mbedtls.mk deleted file mode 100644 index 39cf817d70658..0000000000000 --- a/deps/mbedtls.mk +++ /dev/null @@ -1,97 +0,0 @@ -## mbedtls -include $(SRCDIR)/mbedtls.version - -ifneq ($(USE_BINARYBUILDER_MBEDTLS), 1) -MBEDTLS_SRC = mbedtls-$(MBEDTLS_VER) -MBEDTLS_URL = https://github.com/Mbed-TLS/mbedtls/archive/v$(MBEDTLS_VER).tar.gz - -MBEDTLS_OPTS := $(CMAKE_COMMON) -DUSE_SHARED_MBEDTLS_LIBRARY=ON \ - -DUSE_STATIC_MBEDTLS_LIBRARY=OFF -DENABLE_PROGRAMS=OFF -DCMAKE_BUILD_TYPE=Release - -MBEDTLS_OPTS += -DENABLE_ZLIB_SUPPORT=OFF -DMBEDTLS_FATAL_WARNINGS=OFF -ifeq ($(BUILD_OS),WINNT) -MBEDTLS_OPTS += -G"MSYS Makefiles" -endif - -ifneq (,$(findstring $(OS),Linux FreeBSD OpenBSD)) -MBEDTLS_OPTS += -DCMAKE_INSTALL_RPATH="\$$ORIGIN" -endif - -$(SRCCACHE)/$(MBEDTLS_SRC).tar.gz: | $(SRCCACHE) - $(JLDOWNLOAD) $@ $(MBEDTLS_URL) - -$(SRCCACHE)/$(MBEDTLS_SRC)/source-extracted: $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz - $(JLCHECKSUM) $< - mkdir -p $(dir $@) && \ - $(TAR) -C $(dir $@) --strip-components 1 -xf $< - # Force-enable MD4 - sed -i.org "s|//#define MBEDTLS_MD4_C|#define MBEDTLS_MD4_C|" $(SRCCACHE)/$(MBEDTLS_SRC)/include/mbedtls/config.h - touch -c $(SRCCACHE)/$(MBEDTLS_SRC)/CMakeLists.txt # old target - echo 1 > $@ - -checksum-mbedtls: $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz - $(JLCHECKSUM) $< - -$(BUILDDIR)/$(MBEDTLS_SRC)/build-configured: $(SRCCACHE)/$(MBEDTLS_SRC)/source-extracted - mkdir -p $(dir $@) - cd $(dir $@) && \ - $(CMAKE) $(dir $<) $(MBEDTLS_OPTS) - echo 1 > $@ - -$(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled: $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured - $(MAKE) -C $(dir $<) - echo 1 > $@ - -$(BUILDDIR)/$(MBEDTLS_SRC)/build-checked: $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled -ifeq ($(OS),$(BUILD_OS)) - $(MAKE) -C $(dir $@) test -endif - echo 1 > $@ - -ifeq ($(OS),WINNT) -define MBEDTLS_INSTALL - mkdir -p $2/$$(build_shlibdir) - cp $1/library/libmbedcrypto.$$(SHLIB_EXT) $2/$$(build_shlibdir) - cp $1/library/libmbedx509.$$(SHLIB_EXT) $2/$$(build_shlibdir) - cp $1/library/libmbedtls.$$(SHLIB_EXT) $2/$$(build_shlibdir) -endef -else -define MBEDTLS_INSTALL - $(call MAKE_INSTALL,$1,$2,) -endef -endif -$(eval $(call staged-install, \ - mbedtls,$(MBEDTLS_SRC), \ - MBEDTLS_INSTALL,,, \ - $$(INSTALL_NAME_CMD)libmbedx509.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedx509.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CMD)libmbedtls.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedtls.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CHANGE_CMD) libmbedx509.1.dylib @rpath/libmbedx509.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedtls.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CHANGE_CMD) libmbedcrypto.7.dylib @rpath/libmbedcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedtls.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CHANGE_CMD) libmbedcrypto.7.dylib @rpath/libmbedcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedx509.$$(SHLIB_EXT) && \ - $$(INSTALL_NAME_CMD)libmbedcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libmbedcrypto.$$(SHLIB_EXT))) - - -clean-mbedtls: - -rm -f $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured \ - $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled - -$(MAKE) -C $(BUILDDIR)/$(MBEDTLS_SRC) clean - -distclean-mbedtls: - rm -rf $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz \ - $(SRCCACHE)/$(MBEDTLS_SRC) \ - $(BUILDDIR)/$(MBEDTLS_SRC) - - -get-mbedtls: $(SRCCACHE)/$(MBEDTLS_SRC).tar.gz -extract-mbedtls: $(SRCCACHE)/$(MBEDTLS_SRC)/source-extracted -configure-mbedtls: $(BUILDDIR)/$(MBEDTLS_SRC)/build-configured -compile-mbedtls: $(BUILDDIR)/$(MBEDTLS_SRC)/build-compiled -# tests disabled since they are known to fail -fastcheck-mbedtls: #check-mbedtls -check-mbedtls: $(BUILDDIR)/$(MBEDTLS_SRC)/build-checked - -else # USE_BINARYBUILDER_MBEDTLS - -$(eval $(call bb-install,mbedtls,MBEDTLS,false)) - -endif diff --git a/deps/mmtk_julia.mk b/deps/mmtk_julia.mk new file mode 100644 index 0000000000000..424113fd4164c --- /dev/null +++ b/deps/mmtk_julia.mk @@ -0,0 +1,80 @@ +## MMTK ## + +# Both MMTK_MOVING and MMTK_PLAN should be specified in the Make.user file. +# At this point, since we only support non-moving this is always set to 0 +# FIXME: change it to `?:` when introducing moving plans +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) + +# Download the binding, build it from source +ifeq (${MMTK_JULIA_DIR},$(BUILDROOT)/usr/lib/mmtk_julia) + +MMTK_JULIA_DIR=$(BUILDROOT)/deps/$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR) +MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD) +PROJECT_DIRS := JULIA_PATH=$(JULIAHOME) JULIA_BUILDROOT=$(BUILDROOT) MMTK_JULIA_DIR=$(MMTK_JULIA_DIR) + +$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/build-compiled: $(BUILDROOT)/usr/lib/libmmtk_julia.so + @echo 1 > $@ + +# NB: use the absolute dir when creating the symlink +$(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so + @ln -sf $(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) + +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 +fastcheck-mmtk_julia: #none +check-mmtk_julia: compile-mmtk_julia + +$(eval $(call symlink_install,mmtk_julia,$$(MMTK_JULIA_SRC_DIR),$$(BUILDROOT)/usr/lib)) + +# In this case, there is a custom version of the binding in MMTK_JULIA_DIR +# Build it and symlink libmmtk_julia.so file into $(BUILDROOT)/usr/lib +else + +PROJECT_DIRS := JULIA_PATH=$(JULIAHOME) JULIA_BUILDROOT=$(BUILDROOT) MMTK_JULIA_DIR=$(MMTK_JULIA_DIR) +MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD) + +install-mmtk_julia: compile-mmtk_julia $(build_prefix)/manifest/mmtk_julia + +compile-mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so + +version-check-mmtk_julia: $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so + +# NB: This will NOT run `cargo build` if there are changes in the Rust source files +# inside the binding repo. However the target below should remake the symlink if there +# are changes in the libmmtk_julia.so from the custom MMTK_JULIA_DIR folder +$(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so + @ln -sf $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so $@ + +$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so: + @$(PROJECT_DIRS) $(MMTK_VARS) $(MAKE) -C $(MMTK_JULIA_DIR) $(MMTK_BUILD) + +MMTK_JULIA_VER := mmtk_julia_custom + +UNINSTALL_mmtk_julia := $(MMTK_JULIA_VER) manual_mmtk_julia + +define manual_mmtk_julia +uninstall-mmtk_julia: + -rm -f $(build_prefix)/manifest/mmtk_julia + -rm -f $(BUILDROOT)/usr/lib/libmmtk_julia.so +endef + +$(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 new file mode 100644 index 0000000000000..cb1e8064f9825 --- /dev/null +++ b/deps/mmtk_julia.version @@ -0,0 +1,6 @@ +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 diff --git a/deps/nghttp2.version b/deps/nghttp2.version index c9a39ea5ae757..a3cd46d457c2c 100644 --- a/deps/nghttp2.version +++ b/deps/nghttp2.version @@ -3,4 +3,4 @@ NGHTTP2_JLL_NAME := nghttp2 ## source build -NGHTTP2_VER := 1.63.0 +NGHTTP2_VER := 1.64.0 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/openlibm.version b/deps/openlibm.version index f35b291260380..788701a66301b 100644 --- a/deps/openlibm.version +++ b/deps/openlibm.version @@ -1,7 +1,9 @@ +# -*- makefile -*- + ## jll artifact OPENLIBM_JLL_NAME := OpenLibm ## source build -OPENLIBM_VER := 0.8.1 -OPENLIBM_BRANCH=v0.8.1 -OPENLIBM_SHA1=ae2d91698508701c83cab83714d42a1146dccf85 +OPENLIBM_VER := 0.8.5 +OPENLIBM_BRANCH=v0.8.5 +OPENLIBM_SHA1=db24332879c320606c37f77fea165e6ecb49153c diff --git a/deps/openssl.mk b/deps/openssl.mk new file mode 100644 index 0000000000000..6f96717b2fb74 --- /dev/null +++ b/deps/openssl.mk @@ -0,0 +1,104 @@ +## OpenSSL ## +include $(SRCDIR)/openssl.version + +ifneq ($(USE_BINARYBUILDER_OPENSSL),1) + +ifeq ($(OS),Darwin) +ifeq ($(APPLE_ARCH),arm64) +OPENSSL_TARGET := darwin64-arm64-cc +else +OPENSSL_TARGET := darwin64-x86_64-cc +endif +else ifeq ($(OS),WINNT) +ifeq ($(ARCH),x86_64) +OPENSSL_TARGET := mingw64 +else +OPENSSL_TARGET := mingw +endif +else ifeq ($(OS),FreeBSD) +ifeq ($(ARCH),aarch64) +OPENSSL_TARGET := BSD-aarch64 +else +OPENSSL_TARGET := BSD-x86_64 +endif +else ifeq ($(OS),Linux) +ifeq ($(ARCH),x86_64) +OPENSSL_TARGET := linux-x86_64 +else ifeq ($(ARCH),i686) +OPENSSL_TARGET := linux-x86 +else ifeq ($(ARCH),arm) +OPENSSL_TARGET := linux-armv4 +else ifeq ($(ARCH),aarch64) +OPENSSL_TARGET := linux-aarch64 +else ifeq ($(ARCH),ppc64le) +OPENSSL_TARGET := linux-ppc64le +else ifeq ($(ARCH),powerpc64le) +OPENSSL_TARGET := linux-ppc64le +else ifeq ($(ARCH),riscv64) +OPENSSL_TARGET := linux64-riscv64 +endif +else +OPENSSL_TARGET := unknown +endif + +$(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz: | $(SRCCACHE) + $(JLDOWNLOAD) $@ https://www.openssl.org/source/$(notdir $@) + +$(SRCCACHE)/openssl-$(OPENSSL_VER)/source-extracted: $(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz + $(JLCHECKSUM) $< + cd $(dir $<) && $(TAR) -zxf $< + touch -c $(SRCCACHE)/openssl-$(OPENSSL_VER)/configure # old target + echo 1 > $@ + +checksum-openssl: $(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz + $(JLCHECKSUM) $< + +# We cannot use $(CONFIGURE_COMMON) in this step, because openssl's Configure scripts is picky +# and does not like that we pass make variables as arguments, it wants them in the environment +$(BUILDDIR)/openssl-$(OPENSSL_VER)/build-configured: $(SRCCACHE)/openssl-$(OPENSSL_VER)/source-extracted + mkdir -p $(dir $@) + cd $(dir $@) && \ + CC="$(CC) $(SANITIZE_OPTS)" CXX="$(CXX) $(SANITIZE_OPTS)" LDFLAGS="$(LDFLAGS) $(RPATH_ESCAPED_ORIGIN) $(SANITIZE_LDFLAGS)" \ + $(dir $<)/Configure shared --prefix=$(abspath $(build_prefix)) $(OPENSSL_TARGET) + echo 1 > $@ + +$(BUILDDIR)/openssl-$(OPENSSL_VER)/build-compiled: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-configured + $(MAKE) -C $(dir $<) + echo 1 > $@ + +$(BUILDDIR)/openssl-$(OPENSSL_VER)/build-checked: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-compiled +ifeq ($(OS),$(BUILD_OS)) + $(MAKE) -C $(dir $@) test +endif + echo 1 > $@ + +$(eval $(call staged-install, \ + openssl,openssl-$(OPENSSL_VER), \ + MAKE_INSTALL,,, \ + $$(WIN_MAKE_HARD_LINK) $(build_bindir)/libcrypto-*.dll $(build_bindir)/libcrypto.dll && \ + $$(WIN_MAKE_HARD_LINK) $(build_bindir)/libssl-*.dll $(build_bindir)/libssl.dll && \ + $$(INSTALL_NAME_CMD)libcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libcrypto.$$(SHLIB_EXT) && \ + $$(INSTALL_NAME_CMD)libssl.$$(SHLIB_EXT) $$(build_shlibdir)/libssl.$$(SHLIB_EXT) && \ + $$(INSTALL_NAME_CHANGE_CMD) $$(build_shlibdir)/libcrypto.3.dylib @rpath/libcrypto.$$(SHLIB_EXT) $$(build_shlibdir)/libssl.$$(SHLIB_EXT))) + +clean-openssl: + -rm -f $(BUILDDIR)/-openssl-$(OPENSSL_VER)/build-configured $(BUILDDIR)/-openssl-$(OPENSSL_VER)/build-compiled + -$(MAKE) -C $(BUILDDIR)/-openssl-$(OPENSSL_VER) clean + +distclean-openssl: + rm -rf $(SRCCACHE)/-openssl-$(OPENSSL_VER).tar.gz \ + $(SRCCACHE)/-openssl-$(OPENSSL_VER) \ + $(BUILDDIR)/-openssl-$(OPENSSL_VER) + +get-openssl: $(SRCCACHE)/openssl-$(OPENSSL_VER).tar.gz +extract-openssl: $(SRCCACHE)/openssl-$(OPENSSL_VER)/source-extracted +configure-openssl: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-configured +compile-openssl: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-compiled +fastcheck-openssl: check-openssl +check-openssl: $(BUILDDIR)/openssl-$(OPENSSL_VER)/build-checked + +else # USE_BINARYBUILDER_OPENSSL + +$(eval $(call bb-install,openssl,OPENSSL,false)) + +endif diff --git a/deps/mbedtls.version b/deps/openssl.version similarity index 50% rename from deps/mbedtls.version rename to deps/openssl.version index ef88b8109f68c..7253e063167db 100644 --- a/deps/mbedtls.version +++ b/deps/openssl.version @@ -1,7 +1,6 @@ # -*- makefile -*- - ## jll artifact -MBEDTLS_JLL_NAME := MbedTLS +OPENSSL_JLL_NAME := OpenSSL ## source build -MBEDTLS_VER := 2.28.6 +OPENSSL_VER := 3.0.15 diff --git a/deps/patches/curl-8.6.0-build.patch b/deps/patches/curl-8.6.0-build.patch deleted file mode 100644 index 827b02808d505..0000000000000 --- a/deps/patches/curl-8.6.0-build.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 5cc2b016c36aaf5a08e2feb7c068fca5bb0a8052 Mon Sep 17 00:00:00 2001 -From: Daniel Stenberg -Date: Mon, 5 Feb 2024 15:22:08 +0100 -Subject: [PATCH] md4: include strdup.h for the memdup proto - -Reported-by: Erik Schnetter -Fixes #12849 -Closes #12863 ---- - lib/md4.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/lib/md4.c b/lib/md4.c -index 067c211e420afd..58dd1166cf924f 100644 ---- a/lib/md4.c -+++ b/lib/md4.c -@@ -28,6 +28,7 @@ - - #include - -+#include "strdup.h" - #include "curl_md4.h" - #include "warnless.h" diff --git a/deps/patches/libssh2-mbedtls-size_t.patch b/deps/patches/libssh2-mbedtls-size_t.patch deleted file mode 100644 index 502adf6bdf439..0000000000000 --- a/deps/patches/libssh2-mbedtls-size_t.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 6cad964056848d3d78ccc74600fbff6298baddcb Mon Sep 17 00:00:00 2001 -From: Viktor Szakats -Date: Tue, 30 May 2023 17:28:03 +0000 -Subject: [PATCH 1/1] mbedtls: use more size_t to sync up with crypto.h - -Ref: 5a96f494ee0b00282afb2db2e091246fc5e1774a #846 #879 - -Fixes #1053 -Closes #1054 ---- - src/mbedtls.c | 14 ++++++++------ - src/mbedtls.h | 13 ++++++------- - 2 files changed, 14 insertions(+), 13 deletions(-) - -diff --git a/src/mbedtls.c b/src/mbedtls.c -index e387cdb..cd14a4b 100644 ---- a/src/mbedtls.c -+++ b/src/mbedtls.c -@@ -186,7 +186,7 @@ _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx) - int - _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, - mbedtls_md_type_t mdtype, -- const unsigned char *key, unsigned long keylen) -+ const unsigned char *key, size_t keylen) - { - const mbedtls_md_info_t *md_info; - int ret, hmac; -@@ -221,7 +221,7 @@ _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) - } - - int --_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, -+_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen, - mbedtls_md_type_t mdtype, unsigned char *hash) - { - const mbedtls_md_info_t *md_info; -@@ -497,8 +497,9 @@ int - _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, - size_t hash_len, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, unsigned long m_len) -+ size_t sig_len, -+ const unsigned char *m, -+ size_t m_len) - { - int ret; - int md_type; -@@ -548,8 +549,9 @@ _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, - int - _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, unsigned long m_len) -+ size_t sig_len, -+ const unsigned char *m, -+ size_t m_len) - { - return _libssh2_mbedtls_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, - sig, sig_len, m, m_len); -diff --git a/src/mbedtls.h b/src/mbedtls.h -index d9592f7..03484da 100644 ---- a/src/mbedtls.h -+++ b/src/mbedtls.h -@@ -478,12 +478,12 @@ _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx); - int - _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, - mbedtls_md_type_t mdtype, -- const unsigned char *key, unsigned long keylen); -+ const unsigned char *key, size_t keylen); - - int - _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash); - int --_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, -+_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen, - mbedtls_md_type_t mdtype, unsigned char *hash); - - _libssh2_bn * -@@ -526,9 +526,8 @@ _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, - int - _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, -- unsigned long m_len); -+ size_t sig_len, -+ const unsigned char *m, size_t m_len); - int - _libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsa, -@@ -540,8 +539,8 @@ int - _libssh2_mbedtls_rsa_sha2_verify(libssh2_rsa_ctx * rsactx, - size_t hash_len, - const unsigned char *sig, -- unsigned long sig_len, -- const unsigned char *m, unsigned long m_len); -+ size_t sig_len, -+ const unsigned char *m, size_t m_len); - int - _libssh2_mbedtls_rsa_sha2_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsa, --- -2.31.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/deps/pcre.version b/deps/pcre.version index 681e97e197f51..78245a5777a0c 100644 --- a/deps/pcre.version +++ b/deps/pcre.version @@ -1,3 +1,4 @@ +# -*- makefile -*- ## jll artifact PCRE_JLL_NAME := PCRE2 diff --git a/deps/tools/common.mk b/deps/tools/common.mk index 3cefc253cec3d..01b57316f9d1a 100644 --- a/deps/tools/common.mk +++ b/deps/tools/common.mk @@ -36,8 +36,8 @@ CMAKE_COMMON += -DCMAKE_C_COMPILER_LAUNCHER=ccache CMAKE_COMMON += -DCMAKE_CXX_COMPILER_LAUNCHER=ccache CMAKE_CC := "$$(which $(shell echo $(CC_ARG) | cut -d' ' -f1))" CMAKE_CXX := "$$(which $(shell echo $(CXX_ARG) | cut -d' ' -f1))" -CMAKE_CC_ARG := $(shell echo $(CC_ARG) | cut -d' ' -f2-) -CMAKE_CXX_ARG := $(shell echo $(CXX_ARG) | cut -d' ' -f2-) +CMAKE_CC_ARG := $(shell echo $(CC_ARG) | cut -s -d' ' -f2-) +CMAKE_CXX_ARG := $(shell echo $(CXX_ARG) | cut -s -d' ' -f2-) else CMAKE_CC := "$$(which $(CC_BASE))" CMAKE_CXX := "$$(which $(CXX_BASE))" diff --git a/deps/utf8proc.version b/deps/utf8proc.version index a026ca858cfd3..c880d6561ce09 100644 --- a/deps/utf8proc.version +++ b/deps/utf8proc.version @@ -1,2 +1,2 @@ -UTF8PROC_BRANCH=v2.9.0 -UTF8PROC_SHA1=34db3f7954e9298e89f42641ac78e0450f80a70d +UTF8PROC_BRANCH=v2.10.0 +UTF8PROC_SHA1=a1b99daa2a3393884220264c927a48ba1251a9c6 diff --git a/doc/Manifest.toml b/doc/Manifest.toml index 490754c4c3068..e91958808828e 100644 --- a/doc/Manifest.toml +++ b/doc/Manifest.toml @@ -115,9 +115,9 @@ uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" +version = "8.9.1+0" [[deps.LibGit2]] deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -125,14 +125,14 @@ uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" version = "1.11.0" [[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.0+0" +version = "1.8.4+0" [[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" +version = "1.11.3+0" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" @@ -159,11 +159,6 @@ git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" version = "0.1.2" -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+1" - [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" version = "1.11.0" @@ -177,8 +172,7 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.OpenSSL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7493f61f55a6cce7325f197443aa80d32554ba10" +deps = ["Artifacts", "Libdl", "NetworkOptions"] uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" version = "3.0.15+1" 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", ] ] diff --git a/doc/src/base/base.md b/doc/src/base/base.md index 7181965d9aa81..e6c8ff554d494 100644 --- a/doc/src/base/base.md +++ b/doc/src/base/base.md @@ -166,6 +166,7 @@ Core.replacefield! Core.swapfield! Core.setfieldonce! Core.isdefined +Core.isdefinedglobal Base.@isdefined Base.convert Base.promote diff --git a/doc/src/base/sort.md b/doc/src/base/sort.md index b9d333ef2a939..cef080c5f8995 100644 --- a/doc/src/base/sort.md +++ b/doc/src/base/sort.md @@ -41,7 +41,7 @@ indices that puts the array into sorted order: ```julia-repl julia> v = randn(5) -5-element Array{Float64,1}: +5-element Vector{Float64}: 0.297288 0.382396 -0.597634 @@ -49,7 +49,7 @@ julia> v = randn(5) -0.839027 julia> p = sortperm(v) -5-element Array{Int64,1}: +5-element Vector{Int64}: 5 3 4 @@ -57,7 +57,7 @@ julia> p = sortperm(v) 2 julia> v[p] -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.839027 -0.597634 -0.0104452 @@ -69,7 +69,7 @@ Arrays can be sorted according to an arbitrary transformation of their values: ```julia-repl julia> sort(v, by=abs) -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.0104452 0.297288 0.382396 @@ -81,7 +81,7 @@ Or in reverse order by a transformation: ```julia-repl julia> sort(v, by=abs, rev=true) -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.839027 -0.597634 0.382396 @@ -93,7 +93,7 @@ If needed, the sorting algorithm can be chosen: ```julia-repl julia> sort(v, alg=InsertionSort) -5-element Array{Float64,1}: +5-element Vector{Float64}: -0.839027 -0.597634 -0.0104452 diff --git a/doc/src/devdocs/ast.md b/doc/src/devdocs/ast.md index d8db3ca677082..fe63dfe35edac 100644 --- a/doc/src/devdocs/ast.md +++ b/doc/src/devdocs/ast.md @@ -426,11 +426,8 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. * `isdefined` - `Expr(:isdefined, :x [, allow_import])` returns a Bool indicating whether `x` has - already been defined in the current scope. The optional second argument is a boolean - that specifies whether `x` should be considered defined by an import or if only constants - or globals in the current module count as being defined. If `x` is not a global, the argument - is ignored. + `Expr(:isdefined, :x)` returns a Bool indicating whether `x` has + already been defined in the current scope. * `the_exception` diff --git a/doc/src/devdocs/build/build.md b/doc/src/devdocs/build/build.md index 966ef3d102d1c..5fe038959edf0 100644 --- a/doc/src/devdocs/build/build.md +++ b/doc/src/devdocs/build/build.md @@ -195,7 +195,7 @@ uses are listed in [`deps/$(libname).version`](https://github.com/JuliaLang/juli - **[libgit2]** — Git linkable library, used by Julia's package manager. - **[curl]** — libcurl provides download and proxy support. - **[libssh2]** — library for SSH transport, used by libgit2 for packages with SSH remotes. -- **[mbedtls]** — library used for cryptography and transport layer security, used by libssh2 +- **[OpenSSL]** — library used for cryptography and transport layer security, used by libgit2 and libssh2. - **[utf8proc]** — a library for processing UTF-8 encoded Unicode strings. - **[LLVM libunwind]** — LLVM's fork of [libunwind], a library that determines the call-chain of a program. - **[ITTAPI]** — Intel's Instrumentation and Tracing Technology and Just-In-Time API. @@ -230,7 +230,7 @@ uses are listed in [`deps/$(libname).version`](https://github.com/JuliaLang/juli [utf8proc]: https://julialang.org/utf8proc/ [libunwind]: https://www.nongnu.org/libunwind [libssh2]: https://www.libssh2.org -[mbedtls]: https://tls.mbed.org/ +[OpenSSL]: https://www.openssl.org/ [pkg-config]: https://www.freedesktop.org/wiki/Software/pkg-config/ [powershell]: https://docs.microsoft.com/en-us/powershell/scripting/wmf/overview [which]: https://carlowood.github.io/which/ diff --git a/doc/src/manual/arrays.md b/doc/src/manual/arrays.md index 8a33d31a23cf8..02d71fcd9939e 100644 --- a/doc/src/manual/arrays.md +++ b/doc/src/manual/arrays.md @@ -355,7 +355,7 @@ julia> Int8[[1 2] [3 4]] Comprehensions provide a general and powerful way to construct arrays. Comprehension syntax is similar to set construction notation in mathematics: -``` +```julia A = [ F(x, y, ...) for x=rx, y=ry, ... ] ``` @@ -366,11 +366,11 @@ The result is an N-d dense array with dimensions that are the concatenation of t of the variable ranges `rx`, `ry`, etc. and each `F(x,y,...)` evaluation returns a scalar. The following example computes a weighted average of the current element and its left and right -neighbor along a 1-d grid. : +neighbor along a 1-d grid: ```julia-repl julia> x = rand(8) -8-element Array{Float64,1}: +8-element Vector{Float64}: 0.843025 0.869052 0.365105 @@ -381,7 +381,7 @@ julia> x = rand(8) 0.809411 julia> [ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ] -6-element Array{Float64,1}: +6-element Vector{Float64}: 0.736559 0.57468 0.685417 @@ -1040,7 +1040,7 @@ be to replicate the vector to the size of the matrix: julia> a = rand(2, 1); A = rand(2, 3); julia> repeat(a, 1, 3) + A -2×3 Array{Float64,2}: +2×3 Matrix{Float64}: 1.20813 1.82068 1.25387 1.56851 1.86401 1.67846 ``` @@ -1051,16 +1051,16 @@ without using extra memory, and applies the given function elementwise: ```julia-repl julia> broadcast(+, a, A) -2×3 Array{Float64,2}: +2×3 Matrix{Float64}: 1.20813 1.82068 1.25387 1.56851 1.86401 1.67846 julia> b = rand(1,2) -1×2 Array{Float64,2}: +1×2 Matrix{Float64}: 0.867535 0.00457906 julia> broadcast(+, a, b) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 1.71056 0.847604 1.73659 0.873631 ``` diff --git a/doc/src/manual/calling-c-and-fortran-code.md b/doc/src/manual/calling-c-and-fortran-code.md index f675ab5eb16e8..d198c796a2e0b 100644 --- a/doc/src/manual/calling-c-and-fortran-code.md +++ b/doc/src/manual/calling-c-and-fortran-code.md @@ -27,9 +27,9 @@ commonly passed in registers when using C or Julia calling conventions. The syntax for [`@ccall`](@ref) to generate a call to the library function is: ```julia - @ccall library.function_name(argvalue1::argtype1, ...)::returntype - @ccall function_name(argvalue1::argtype1, ...)::returntype - @ccall $function_pointer(argvalue1::argtype1, ...)::returntype +@ccall library.function_name(argvalue1::argtype1, ...)::returntype +@ccall function_name(argvalue1::argtype1, ...)::returntype +@ccall $function_pointer(argvalue1::argtype1, ...)::returntype ``` where `library` is a string constant or literal (but see [Non-constant Function @@ -825,7 +825,7 @@ Instead define a [`Base.cconvert`](@ref) method and pass the variables directly automatically arranges that all of its arguments will be preserved from garbage collection until the call returns. If a C API will store a reference to memory allocated by Julia, after the `@ccall` returns, you must ensure that the object remains visible to the garbage collector. The suggested -way to do this is to make a global variable of type `Array{Ref,1}` to hold these values until +way to do this is to make a global variable of type `Vector{Ref}` to hold these values until the C library notifies you that it is finished with them. Whenever you have created a pointer to Julia data, you must ensure the original data exists until 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: diff --git a/doc/src/manual/command-line-interface.md b/doc/src/manual/command-line-interface.md index 9b06deaf0ea8a..14dd60d89b384 100644 --- a/doc/src/manual/command-line-interface.md +++ b/doc/src/manual/command-line-interface.md @@ -216,12 +216,16 @@ The following is a complete list of command-line switches available when launchi |`--output-asm ` |Generate an assembly file (.s)| |`--output-incremental={yes\|no*}` |Generate an incremental output file (rather than complete)| |`--trace-compile={stderr\|name}` |Print precompile statements for methods compiled during execution or save to stderr or a path. Methods that were recompiled are printed in yellow or with a trailing comment if color is not supported| -|`--trace-compile-timing` |If --trace-compile is enabled show how long each took to compile in ms| +|`--trace-compile-timing` |If `--trace-compile` is enabled show how long each took to compile in ms| |`--trace-dispatch={stderr\|name}` |Print precompile statements for methods dispatched during execution or save to stderr or a path.| |`--image-codegen` |Force generate code in imaging mode| |`--permalloc-pkgimg={yes\|no*}` |Copy the data section of package images into memory| |`--trim={no*\|safe\|unsafe\|unsafe-warn}` |Build a sysimage including only code provably reachable from methods marked by calling `entrypoint`. The three non-default options differ in how they handle dynamic call sites. In safe mode, such sites result in compile-time errors. In unsafe mode, such sites are allowed but the resulting binary might be missing needed code and can throw runtime errors. With unsafe-warn, such sites will trigger warnings at compile-time and might error at runtime.| +Options that have the form `--option={...}` can be specified either as `--option=value` or as `--option value`. For example, `julia --banner=no` is equivalent to `julia --banner no`. This is especially relevant for options that take a filename for output, because forgetting to specifying the argument for (say) `--trace-compile` will cause the option following it to be interpreted as the filename, possibly unintentionally overwriting it. + +Note that options of the form `--option[=...]` can **not** be specified as `--option value`, but only as `--option=value` (or simply `--option`, when no argument is provided). + !!! compat "Julia 1.1" In Julia 1.0, the default `--project=@.` option did not search up from the root directory of a Git repository for the `Project.toml` file. From Julia 1.1 forward, it diff --git a/doc/src/manual/complex-and-rational-numbers.md b/doc/src/manual/complex-and-rational-numbers.md index 9cab2ed1e4f24..d1d6ffeca245f 100644 --- a/doc/src/manual/complex-and-rational-numbers.md +++ b/doc/src/manual/complex-and-rational-numbers.md @@ -254,13 +254,30 @@ julia> float(3//4) ``` Conversion from rational to floating-point respects the following identity for any integral values -of `a` and `b`, with the exception of the two cases `b == 0` and `a == 0 && b < 0`: +of `a` and `b`, except when `a==0 && b <= 0`: ```jldoctest julia> a = 1; b = 2; julia> isequal(float(a//b), a/b) true + +julia> a, b = 0, 0 +(0, 0) + +julia> float(a//b) +ERROR: ArgumentError: invalid rational: zero(Int64)//zero(Int64) +Stacktrace: +[...] + +julia> a/b +NaN + +julia> a, b = 0, -1 +(0, -1) + +julia> float(a//b), a/b +(0.0, -0.0) ``` Constructing infinite rational values is acceptable: diff --git a/doc/src/manual/distributed-computing.md b/doc/src/manual/distributed-computing.md index f60dfb7004ada..873a94ffb2181 100644 --- a/doc/src/manual/distributed-computing.md +++ b/doc/src/manual/distributed-computing.md @@ -48,7 +48,7 @@ Generally it makes sense for `n` to equal the number of CPU threads (logical cor argument implicitly loads module [`Distributed`](@ref man-distributed). -```julia +```julia-repl $ julia -p 2 julia> r = remotecall(rand, 2, 2, 2) @@ -58,7 +58,7 @@ julia> s = @spawnat 2 1 .+ fetch(r) Future(2, 1, 5, nothing) julia> fetch(s) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 1.18526 1.50912 1.16296 1.60607 ``` @@ -106,7 +106,7 @@ julia> s = @spawnat :any 1 .+ fetch(r) Future(3, 1, 5, nothing) julia> fetch(s) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 1.38854 1.9098 1.20939 1.57158 ``` @@ -153,7 +153,7 @@ julia> function rand2(dims...) end julia> rand2(2,2) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 0.153756 0.368514 1.15119 0.918912 @@ -262,7 +262,7 @@ as a programmatic means of adding, removing and querying the processes in a clus julia> using Distributed julia> addprocs(2) -2-element Array{Int64,1}: +2-element Vector{Int64}: 2 3 ``` @@ -734,7 +734,7 @@ serialization/deserialization of data. Consequently, the call refers to the same as passed - no copies are created. This behavior is highlighted below: ```julia-repl -julia> using Distributed; +julia> using Distributed julia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node @@ -748,7 +748,7 @@ julia> for i in 1:3 julia> result = [take!(rc) for _ in 1:3]; julia> println(result); -Array{Int64,1}[[3], [3], [3]] +[[3], [3], [3]] julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); Num Unique objects : 1 @@ -767,7 +767,7 @@ julia> for i in 1:3 julia> result = [take!(rc) for _ in 1:3]; julia> println(result); -Array{Int64,1}[[1], [2], [3]] +[[1], [2], [3]] julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); Num Unique objects : 3 @@ -855,7 +855,7 @@ Here's a brief example: julia> using Distributed julia> addprocs(3) -3-element Array{Int64,1}: +3-element Vector{Int64}: 2 3 4 @@ -863,7 +863,7 @@ julia> addprocs(3) julia> @everywhere using SharedArrays julia> S = SharedArray{Int,2}((3,4), init = S -> S[localindices(S)] = repeat([myid()], length(localindices(S)))) -3×4 SharedArray{Int64,2}: +3×4 SharedMatrix{Int64}: 2 2 3 4 2 3 3 4 2 3 4 4 @@ -872,7 +872,7 @@ julia> S[3,2] = 7 7 julia> S -3×4 SharedArray{Int64,2}: +3×4 SharedMatrix{Int64}: 2 2 3 4 2 3 3 4 2 7 4 4 @@ -884,7 +884,7 @@ you wish: ```julia-repl julia> S = SharedArray{Int,2}((3,4), init = S -> S[indexpids(S):length(procs(S)):length(S)] = repeat([myid()], length( indexpids(S):length(procs(S)):length(S)))) -3×4 SharedArray{Int64,2}: +3×4 SharedMatrix{Int64}: 2 2 2 2 3 3 3 3 4 4 4 4 @@ -1371,7 +1371,7 @@ julia> all(C .≈ 4*π) true julia> typeof(C) -Array{Float64,1} +Vector{Float64} (alias for Array{Float64, 1}) julia> dB = distribute(B); @@ -1383,7 +1383,7 @@ julia> all(dC .≈ 4*π) true julia> typeof(dC) -DistributedArrays.DArray{Float64,1,Array{Float64,1}} +DistributedArrays.DArray{Float64,1,Vector{Float64}} julia> cuB = CuArray(B); @@ -1419,7 +1419,7 @@ function declaration, let's see if it works with the aforementioned datatypes: julia> M = [2. 1; 1 1]; julia> v = rand(2) -2-element Array{Float64,1}: +2-element Vector{Float64}: 0.40395 0.445877 @@ -1442,7 +1442,7 @@ julia> dv = distribute(v); julia> dC = power_method(dM, dv); julia> typeof(dC) -Tuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64} +Tuple{DistributedArrays.DArray{Float64,1,Vector{Float64}},Float64} ``` To end this short exposure to external packages, we can consider `MPI.jl`, a Julia wrapper diff --git a/doc/src/manual/documentation.md b/doc/src/manual/documentation.md index d41249abe6af8..a11d41d441b73 100644 --- a/doc/src/manual/documentation.md +++ b/doc/src/manual/documentation.md @@ -142,7 +142,7 @@ As in the example above, we recommend following some simple conventions when wri # Examples ```jldoctest julia> a = [1 2; 3 4] - 2×2 Array{Int64,2}: + 2×2 Matrix{Int64}: 1 2 3 4 ``` diff --git a/doc/src/manual/functions.md b/doc/src/manual/functions.md index be81fe529ef7d..0fcfdeb80d7b9 100644 --- a/doc/src/manual/functions.md +++ b/doc/src/manual/functions.md @@ -616,9 +616,9 @@ julia> foo(A(3, 4)) For anonymous functions, destructuring a single argument requires an extra comma: -``` +```julia-repl julia> map(((x, y),) -> x + y, [(1, 2), (3, 4)]) -2-element Array{Int64,1}: +2-element Vector{Int64}: 3 7 ``` diff --git a/doc/src/manual/networking-and-streams.md b/doc/src/manual/networking-and-streams.md index 35ba7fdf16601..3ef41754c1e07 100644 --- a/doc/src/manual/networking-and-streams.md +++ b/doc/src/manual/networking-and-streams.md @@ -31,7 +31,7 @@ For example, to read a simple byte array, we could do: ```julia-repl julia> x = zeros(UInt8, 4) -4-element Array{UInt8,1}: +4-element Vector{UInt8}: 0x00 0x00 0x00 @@ -39,7 +39,7 @@ julia> x = zeros(UInt8, 4) julia> read!(stdin, x) abcd -4-element Array{UInt8,1}: +4-element Vector{UInt8}: 0x61 0x62 0x63 @@ -52,7 +52,7 @@ example, we could have written the above as: ```julia-repl julia> read(stdin, 4) abcd -4-element Array{UInt8,1}: +4-element Vector{UInt8}: 0x61 0x62 0x63 @@ -151,7 +151,7 @@ julia> f = open("hello.txt") IOStream() julia> readlines(f) -1-element Array{String,1}: +1-element Vector{String}: "Hello, World!" ``` @@ -367,7 +367,7 @@ julia> task = Threads.@spawn open("foo.txt", "w") do io julia> wait(task) julia> readlines("foo.txt") -1-element Array{String,1}: +1-element Vector{String}: "Hello, World!" ``` diff --git a/doc/src/manual/performance-tips.md b/doc/src/manual/performance-tips.md index 038000f55e761..d506ac9946ba6 100644 --- a/doc/src/manual/performance-tips.md +++ b/doc/src/manual/performance-tips.md @@ -3,6 +3,13 @@ In the following sections, we briefly go through a few techniques that can help make your Julia code run as fast as possible. +## [Table of contents](@id man-performance-tips-toc) + +```@contents +Pages = ["performance-tips.md"] +Depth = 3 +``` + ## General advice ### Performance critical code should be inside a function @@ -1058,12 +1065,12 @@ the output. As a trivial example, compare ```jldoctest prealloc julia> function xinc(x) - return [x, x+1, x+2] + return [x + i for i in 1:3000] end; julia> function loopinc() y = 0 - for i = 1:10^7 + for i = 1:10^5 ret = xinc(i) y += ret[2] end @@ -1075,16 +1082,16 @@ with ```jldoctest prealloc julia> function xinc!(ret::AbstractVector{T}, x::T) where T - ret[1] = x - ret[2] = x+1 - ret[3] = x+2 + for i in 1:3000 + ret[i] = x+i + end nothing end; julia> function loopinc_prealloc() - ret = Vector{Int}(undef, 3) + ret = Vector{Int}(undef, 3000) y = 0 - for i = 1:10^7 + for i = 1:10^5 xinc!(ret, i) y += ret[2] end @@ -1096,12 +1103,12 @@ Timing results: ```jldoctest prealloc; filter = r"[0-9\.]+ seconds \(.*?\)" julia> @time loopinc() - 0.529894 seconds (40.00 M allocations: 1.490 GiB, 12.14% gc time) -50000015000000 + 0.297454 seconds (200.00 k allocations: 2.239 GiB, 39.80% gc time) +5000250000 julia> @time loopinc_prealloc() - 0.030850 seconds (6 allocations: 288 bytes) -50000015000000 + 0.009410 seconds (2 allocations: 23.477 KiB) +5000250000 ``` Preallocation has other advantages, for example by allowing the caller to control the "output" diff --git a/doc/src/manual/types.md b/doc/src/manual/types.md index 0b1d380c2c601..f13e2e6865d0f 100644 --- a/doc/src/manual/types.md +++ b/doc/src/manual/types.md @@ -1595,7 +1595,7 @@ Most new types should only need to define `show` methods, if anything. * [`display(x)`](@ref) tells the current environment to display `x` in whatever way it thinks best. (This might even be a graphical display in something like a Jupyter or Pluto notebook.) By default (e.g. in scripts or in the text REPL), it calls `show(io, "text/plain", x)`, or equivalently `show(io, MIME"text/plain"(), x)`, for an appropriate `io` stream. (In the REPL, `io` is an [`IOContext`](@ref) wrapper around [`stdout`](@ref).) The REPL uses `display` to output the result of an evaluated expression. * The 3-argument [`show(io, ::MIME"text/plain", x)`](@ref) method performs verbose pretty-printing of `x`. By default (if no 3-argument method is defined for `typeof(x)`), it calls the 2-argument `show(io, x)`. It is called by the 2-argument `repr("text/plain", x)`. Other 3-argument `show` methods can be defined for additional MIME types as discussed above, to enable richer display of `x` in some interactive environments. * The 2-argument [`show(io, x)`](@ref) is the default simple text representation of `x`. It is called by the 1-argument [`repr(x)`](@ref), and is typically the format you might employ to input `x` into Julia. The 1-argument `show(x)` calls `show(stdout, x)`. -* [`print(io, x)`](@ref) by default calls `show(io, x)`, but a few types have a distinct `print` format — most notably, when `x` is a string, `print` outputs the raw text whereas `show` outputs an escaped string enclosed in quotation marks. The 1-argument `print(x)` calls `print(stdout, x)`. `print` is also called by [`string(x)`](@ref). +* [`print(io, x)`](@ref) by default calls `show(io, x)`, but a few types have a distinct `print` format — most notably, when `x` is a string, `print` outputs the raw text whereas `show` outputs an escaped string enclosed in quotation marks. The 1-argument `print(x)` calls `print(stdout, x)`. `print` is also called by [`string(x)`](@ref). See also [`println`](@ref) (to append a newline) and [`printstyled`](@ref) (to add colors etc.), both of which call `print`. * [`write(io, x)`](@ref), if it is defined (it generally has *no* default definition for new types), writes a "raw" binary representation of `x` to `io`, e.g. an `x::Int32` will be written as 4 bytes. It is also helpful to be familiar with the metadata that can be attached to an `io` stream by an [`IOContext`](@ref) wrapper. For example, the REPL sets the `:limit => true` flag from `display` for an evaluated expression, in order to limit the output to fit in the terminal; you can query this flag with `get(io, :limit, false)`. And when displaying an object contained within, for example, a multi-column matrix, the `:compact => true` flag could be set, which you can query with `get(io, :compact, false)`. diff --git a/doc/src/manual/variables-and-scoping.md b/doc/src/manual/variables-and-scoping.md index 64a12ea88c7dd..99f7ba088311d 100644 --- a/doc/src/manual/variables-and-scoping.md +++ b/doc/src/manual/variables-and-scoping.md @@ -64,7 +64,7 @@ The constructs introducing scope blocks are: | Construct | Scope Type Introduced | Scope Types Able to Contain Construct | |:----------|:----------------------|:--------------------------------------| | [`module`](@ref), [`baremodule`](@ref) | global | global | -| [`struct`](@ref) | local (soft) | global | +| [`struct`](@ref) | local (hard) | global | | [`macro`](@ref) | local (hard) | global | | [`for`](@ref), [`while`](@ref), [`try`](@ref try) | local (soft) | global, local | | [`function`](@ref), [`do`](@ref), [`let`](@ref), [comprehensions](@ref man-comprehensions), [generators](@ref man-generators) | local (hard) | global, local | @@ -169,10 +169,10 @@ that location: 1. **Existing local:** If `x` is *already a local variable*, then the existing local `x` is assigned; 2. **Hard scope:** If `x` is *not already a local variable* and assignment occurs inside of any - hard scope construct (i.e. within a `let` block, function or macro body, comprehension, or + hard scope construct (i.e. within a `let` block, function, struct or macro body, comprehension, or generator), a new local named `x` is created in the scope of the assignment; 3. **Soft scope:** If `x` is *not already a local variable* and all of the scope constructs - containing the assignment are soft scopes (loops, `try`/`catch` blocks, or `struct` blocks), the + containing the assignment are soft scopes (loops, `try`/`catch` blocks), the behavior depends on whether the global variable `x` is defined: * if global `x` is *undefined*, a new local named `x` is created in the scope of the assignment; diff --git a/julia.spdx.json b/julia.spdx.json index 0e0067f00efb1..0d7ab1df94688 100644 --- a/julia.spdx.json +++ b/julia.spdx.json @@ -231,16 +231,16 @@ "summary": "libssh2 is a library implementing the SSH2 protocol, available under the revised BSD license." }, { - "name": "mbedtls", - "SPDXID": "SPDXRef-mbedtls", - "downloadLocation": "git+https://github.com/ARMmbed/mbedtls.git", + "name": "OpenSSL", + "SPDXID": "SPDXRef-OpenSSL", + "downloadLocation": "git+https://github.com/openssl/openssl.git", "filesAnalyzed": false, - "homepage": "https://tls.mbed.org", - "sourceInfo": "The version in use can be found in the file deps/mbedtls.version", + "homepage": "https://www.openssl.org", + "sourceInfo": "The version in use can be found in the file deps/openssl.version", "licenseConcluded": "Apache-2.0", "licenseDeclared": "Apache-2.0", - "copyrightText": "NOASSERTION", - "summary": "An open source, portable, easy to use, readable and flexible SSL library." + "copyrightText": "Copyright (c) 1998-2024 The OpenSSL Project Authors. Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson.", + "summary": "OpenSSL is a robust, commercial-grade, full-featured Open Source Toolkit for the TLS (formerly SSL), DTLS and QUIC (currently client side only) protocols.", }, { "name": "mpfr", @@ -560,7 +560,7 @@ "relatedSpdxElement": "SPDXRef-JuliaMain" }, { - "spdxElementId": "SPDXRef-mbedtls", + "spdxElementId": "SPDXRef-OpenSSL", "relationshipType": "BUILD_DEPENDENCY_OF", "relatedSpdxElement": "SPDXRef-JuliaMain" }, diff --git a/src/Makefile b/src/Makefile index 9355ca2c4c675..b49d27e05ff28 100644 --- a/src/Makefile +++ b/src/Makefile @@ -29,6 +29,10 @@ ifeq ($(USECLANG),1) FLAGS += -Wno-return-type-c-linkage -Wno-atomic-alignment endif +ifneq (${MMTK_PLAN},None) +FLAGS += -I$(MMTK_API_INC) +endif + FLAGS += -DJL_BUILD_ARCH='"$(ARCH)"' ifeq ($(OS),WINNT) FLAGS += -DJL_BUILD_UNAME='"NT"' @@ -40,23 +44,41 @@ ifeq ($(OS),FreeBSD) FLAGS += -I$(LOCALBASE)/include endif +# GC source code. It depends on which GC implementation to use. +GC_SRCS := gc-common gc-stacks gc-alloc-profiler gc-heap-snapshot +ifneq (${MMTK_PLAN},None) +GC_SRCS += gc-mmtk +else +GC_SRCS += gc-stock gc-debug gc-pages gc-page-profiler +endif + SRCS := \ jltypes gf typemap smallintset ast builtins module interpreter symbol \ dlload sys init task array genericmemory staticdata toplevel jl_uv datatype \ simplevector runtime_intrinsics precompile jloptions mtarraylist \ - threading scheduler stackwalk gc-common gc-stock gc-debug gc-pages gc-stacks gc-alloc-profiler gc-page-profiler method \ - jlapi signal-handling safepoint timing subtype rtutils gc-heap-snapshot \ - crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall engine + threading scheduler stackwalk \ + method jlapi signal-handling safepoint timing subtype rtutils \ + crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall engine \ + $(GC_SRCS) RT_LLVMLINK := CG_LLVMLINK := ifeq ($(JULIACODEGEN),LLVM) +# Currently these files are used by both GCs. But we should make the list specific to stock, and MMTk should have its own implementation. +GC_CODEGEN_SRCS := llvm-final-gc-lowering llvm-late-gc-lowering llvm-gc-invariant-verifier +ifneq (${MMTK_PLAN},None) +FLAGS += -I$(MMTK_API_INC) +GC_CODEGEN_SRCS += llvm-late-gc-lowering-mmtk +else +GC_CODEGEN_SRCS += llvm-late-gc-lowering-stock +endif CODEGEN_SRCS := codegen jitlayers aotcompile debuginfo disasm llvm-simdloop \ - llvm-final-gc-lowering llvm-pass-helpers llvm-late-gc-lowering llvm-ptls \ - llvm-lower-handlers llvm-gc-invariant-verifier llvm-propagate-addrspaces \ + llvm-pass-helpers llvm-ptls \ + llvm-lower-handlers llvm-propagate-addrspaces \ llvm-multiversioning llvm-alloc-opt llvm-alloc-helpers cgmemmgr llvm-remove-addrspaces \ - llvm-remove-ni llvm-julia-licm llvm-demote-float16 llvm-cpufeatures pipeline llvm_api + llvm-remove-ni llvm-julia-licm llvm-demote-float16 llvm-cpufeatures pipeline llvm_api \ + $(GC_CODEGEN_SRCS) FLAGS += -I$(shell $(LLVM_CONFIG_HOST) --includedir) CG_LLVM_LIBS := all ifeq ($(USE_POLLY),1) @@ -99,7 +121,12 @@ ifeq ($(USE_SYSTEM_LIBUV),0) UV_HEADERS += uv.h UV_HEADERS += uv/*.h endif -PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-interface.h gc-tls.h gc-tls-common.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h) +PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-interface.h gc-tls-common.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h) +ifneq (${MMTK_PLAN},None) + PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,gc-tls-mmtk.h) +else + PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,gc-tls-stock.h) +endif ifeq ($(OS),WINNT) PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,win32_ucontext.h) endif @@ -164,8 +191,8 @@ LIBJULIA_PATH_REL := libjulia endif COMMON_LIBPATHS := -L$(build_libdir) -L$(build_shlibdir) -RT_LIBS := $(WHOLE_ARCHIVE) $(LIBUV) $(WHOLE_ARCHIVE) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LIBUNWIND) $(RT_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) -CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) +RT_LIBS := $(WHOLE_ARCHIVE) $(LIBUV) $(WHOLE_ARCHIVE) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LIBUNWIND) $(RT_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) $(MMTK_LIB) +CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) $(MMTK_LIB) RT_DEBUG_LIBS := $(COMMON_LIBPATHS) $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp-debug.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport-debug.a -ljulia-debug $(RT_LIBS) CG_DEBUG_LIBS := $(COMMON_LIBPATHS) $(CG_LIBS) -ljulia-debug -ljulia-internal-debug RT_RELEASE_LIBS := $(COMMON_LIBPATHS) $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport.a -ljulia $(RT_LIBS) @@ -314,6 +341,7 @@ $(BUILDDIR)/debuginfo.o $(BUILDDIR)/debuginfo.dbg.obj: $(addprefix $(SRCDIR)/,de $(BUILDDIR)/disasm.o $(BUILDDIR)/disasm.dbg.obj: $(SRCDIR)/debuginfo.h $(SRCDIR)/processor.h $(BUILDDIR)/gc-debug.o $(BUILDDIR)/gc-debug.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(BUILDDIR)/gc-pages.o $(BUILDDIR)/gc-pages.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h +$(BUILDDIR)/gc-mmtk.o $(BUILDDIR)/gc-mmtk.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h $(BUILDDIR)/gc-stacks.o $(BUILDDIR)/gc-stacks.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(BUILDDIR)/gc-stock.o $(BUILDDIR)/gc.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h $(SRCDIR)/gc-page-profiler.h $(BUILDDIR)/gc-heap-snapshot.o $(BUILDDIR)/gc-heap-snapshot.dbg.obj: $(SRCDIR)/gc-heap-snapshot.h diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index ba9a3c05e41ff..5524518da46fa 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -52,7 +52,6 @@ using namespace llvm; #define DEBUG_TYPE "julia_aotcompile" -STATISTIC(CICacheLookups, "Number of codeinst cache lookups"); STATISTIC(CreateNativeCalls, "Number of jl_create_native calls made"); STATISTIC(CreateNativeMethods, "Number of methods compiled for jl_create_native"); STATISTIC(CreateNativeMax, "Max number of methods compiled at once for jl_create_native"); @@ -105,7 +104,7 @@ jl_get_llvm_mis_impl(void *native_code, size_t *num_elements, jl_method_instance assert(*num_elements == map.size()); size_t i = 0; for (auto &ci : map) { - data[i++] = ci.first->def; + data[i++] = jl_get_ci_mi(ci.first); } } @@ -307,37 +306,6 @@ static void makeSafeName(GlobalObject &G) G.setName(StringRef(SafeName.data(), SafeName.size())); } -static jl_code_instance_t *jl_ci_cache_lookup(jl_method_instance_t *mi, size_t world, jl_codeinstance_lookup_t lookup) -{ - ++CICacheLookups; - jl_value_t *ci = lookup(mi, world, world); - JL_GC_PROMISE_ROOTED(ci); - jl_code_instance_t *codeinst = NULL; - if (ci != jl_nothing && jl_atomic_load_relaxed(&((jl_code_instance_t *)ci)->inferred) != jl_nothing) { - codeinst = (jl_code_instance_t*)ci; - } - else { - if (lookup != jl_rettype_inferred_addr) { - // XXX: This will corrupt and leak a lot of memory which may be very bad - jl_error("Refusing to automatically run type inference with custom cache lookup."); - } - else { - // XXX: SOURCE_MODE_ABI is wrong here (not sufficient) - codeinst = jl_type_infer(mi, world, SOURCE_MODE_ABI); - /* Even if this codeinst is ordinarily not cacheable, we need to force - * it into the cache here, since it was explicitly requested and is - * otherwise not reachable from anywhere in the system image. - */ - if (codeinst && !jl_mi_cache_has_ci(mi, codeinst)) { - JL_GC_PUSH1(&codeinst); - jl_mi_cache_insert(mi, codeinst); - JL_GC_POP(); - } - } - } - return codeinst; -} - namespace { // file-local namespace class egal_set { public: @@ -432,7 +400,7 @@ static void aot_optimize_roots(jl_codegen_params_t ¶ms, egal_set &method_roo } } -static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_roots, CompilationPolicy policy, jl_compiled_functions_t &compiled_functions) +static void resolve_workqueue(jl_codegen_params_t ¶ms, egal_set &method_roots, jl_compiled_functions_t &compiled_functions) { decltype(params.workqueue) workqueue; std::swap(params.workqueue, workqueue); @@ -449,24 +417,6 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root bool preal_specsig = false; { auto it = compiled_functions.find(codeinst); - if (it == compiled_functions.end()) { - // Reinfer the function. The JIT came along and removed the inferred - // method body. See #34993 - if ((policy != CompilationPolicy::Default || params.params->trim) && - jl_atomic_load_relaxed(&codeinst->inferred) == jl_nothing) { - // XXX: SOURCE_MODE_FORCE_SOURCE is wrong here (neither sufficient nor necessary) - codeinst = jl_type_infer(codeinst->def, jl_atomic_load_relaxed(&codeinst->max_world), SOURCE_MODE_FORCE_SOURCE); - } - if (codeinst) { - orc::ThreadSafeModule result_m = - jl_create_ts_module(name_from_method_instance(codeinst->def), - params.tsctx, params.DL, params.TargetTriple); - auto decls = jl_emit_codeinst(result_m, codeinst, NULL, params); - record_method_roots(method_roots, codeinst->def); - if (result_m) - it = compiled_functions.insert(std::make_pair(codeinst, std::make_pair(std::move(result_m), std::move(decls)))).first; - } - } if (it != compiled_functions.end()) { auto &decls = it->second.second; invokeName = decls.functionObject; @@ -478,6 +428,12 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root preal_specsig = true; } } + else if (params.params->trim) { + jl_safe_printf("warning: no code provided for function "); + jl_(codeinst->def); + if (params.params->trim) + abort(); + } } // patch up the prototype we emitted earlier Module *mod = proto.decl->getParent(); @@ -485,7 +441,7 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root Function *pinvoke = nullptr; if (preal_decl.empty()) { if (invokeName.empty() && params.params->trim) { - errs() << "Bailed out to invoke when compiling:"; + jl_safe_printf("warning: bailed out to invoke when compiling: "); jl_(codeinst->def); abort(); } @@ -501,11 +457,11 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root proto.decl->setLinkage(GlobalVariable::InternalLinkage); //protodecl->setAlwaysInline(); jl_init_function(proto.decl, params.TargetTriple); - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; // TODO: maybe this can be cached in codeinst->specfptr? - emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke, 0, 0); + emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke); preal_decl = ""; // no need to fixup the name } if (!preal_decl.empty()) { @@ -543,31 +499,109 @@ static void compile_workqueue(jl_codegen_params_t ¶ms, egal_set &method_root JL_GC_POP(); } + // takes the running content that has collected in the shadow module and dump it to disk -// this builds the object file portion of the sysimage files for fast startup, and can +// this builds the object file portion of the sysimage files for fast startup +// `_external_linkage` create linkages between pkgimages. +extern "C" JL_DLLEXPORT_CODEGEN +void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, int _trim, int _external_linkage, size_t world) +{ + JL_TIMING(INFERENCE, INFERENCE); + auto ct = jl_current_task; + bool timed = (ct->reentrant_timing & 1) == 0; + if (timed) + ct->reentrant_timing |= 1; + 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(); + + jl_cgparams_t cgparams = jl_default_cgparams; + cgparams.trim = _trim ? 1 : 0; + size_t compile_for[] = { jl_typeinf_world, world }; + int compiler_world = 1; + if (_trim || compile_for[0] == 0) + compiler_world = 0; + jl_value_t **fargs; + JL_GC_PUSHARGS(fargs, 4); + jl_array_t *codeinfos = NULL; + if (jl_typeinf_func) { + fargs[0] = (jl_value_t*)jl_typeinf_func; + fargs[1] = (jl_value_t*)methods; +#ifdef _P64 + jl_value_t *jl_array_ulong_type = jl_array_uint64_type; +#else + jl_value_t *jl_array_ulong_type = jl_array_uint32_type; +#endif + jl_array_t *worlds = jl_alloc_array_1d(jl_array_ulong_type, 1 + compiler_world); + fargs[2] = (jl_value_t*)worlds; + jl_array_data(worlds, size_t)[0] = jl_typeinf_world; + jl_array_data(worlds, size_t)[compiler_world] = world; // might overwrite previous + fargs[3] = _trim ? jl_true : jl_false; + size_t last_age = ct->world_age; + ct->world_age = jl_typeinf_world; + codeinfos = (jl_array_t*)jl_apply(fargs, 4); + ct->world_age = last_age; + JL_TYPECHK(create_native, array_any, (jl_value_t*)codeinfos); + } + else { + // we could put a very simple generator here, but there is no reason to do that right now + jl_error("inference not available for generating compiled output"); + } + fargs[0] = (jl_value_t*)codeinfos; + void *data = jl_emit_native(codeinfos, llvmmod, &cgparams, _external_linkage); + + // move everything inside, now that we've merged everything + // (before adding the exported headers) + ((jl_native_code_desc_t*)data)->M.withModuleDo([&](Module &M) { + auto TT = Triple(M.getTargetTriple()); + Function *juliapersonality_func = nullptr; + if (TT.isOSWindows() && TT.getArch() == Triple::x86_64) { + // setting the function personality enables stack unwinding and catching exceptions + // so make sure everything has something set + Type *T_int32 = Type::getInt32Ty(M.getContext()); + juliapersonality_func = Function::Create(FunctionType::get(T_int32, true), + Function::ExternalLinkage, "__julia_personality", M); + juliapersonality_func->setDLLStorageClass(GlobalValue::DLLImportStorageClass); + } + for (GlobalObject &G : M.global_objects()) { + if (!G.isDeclaration()) { + G.setLinkage(GlobalValue::InternalLinkage); + G.setDSOLocal(true); + makeSafeName(G); + if (Function *F = dyn_cast(&G)) { + if (juliapersonality_func) { + // Add unwind exception personalities to functions to handle async exceptions + F->setPersonalityFn(juliapersonality_func); + } + } + } + } + }); + + JL_GC_POP(); + if (timed) { + if (measure_compile_time_enabled) { + auto end = jl_hrtime(); + jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); + } + ct->reentrant_timing &= ~1ull; + } + return data; +} + // also be used be extern consumers like GPUCompiler.jl to obtain a module containing // all reachable & inferrrable functions. -// The `policy` flag switches between the default mode `0` and the extern mode `1` used by GPUCompiler. -// `_imaging_mode` controls if raw pointers can be embedded (e.g. the code will be loaded into the same session). -// `_external_linkage` create linkages between pkgimages. extern "C" JL_DLLEXPORT_CODEGEN -void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _policy, int _imaging_mode, int _external_linkage, size_t _world, jl_codeinstance_lookup_t lookup) +void *jl_emit_native_impl(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _external_linkage) { JL_TIMING(NATIVE_AOT, NATIVE_Create); ++CreateNativeCalls; - CreateNativeMax.updateMax(jl_array_nrows(methods)); + CreateNativeMax.updateMax(jl_array_nrows(codeinfos)); if (cgparams == NULL) cgparams = &jl_default_cgparams; - if (lookup == NULL) - lookup = &jl_rettype_inferred_native; jl_native_code_desc_t *data = new jl_native_code_desc_t; - CompilationPolicy policy = (CompilationPolicy) _policy; - bool imaging = imaging_default() || _imaging_mode == 1; jl_method_instance_t *mi = NULL; - auto ct = jl_current_task; - bool timed = (ct->reentrant_timing & 1) == 0; - if (timed) - ct->reentrant_timing |= 1; orc::ThreadSafeContext ctx; orc::ThreadSafeModule backing; if (!llvmmod) { @@ -577,13 +611,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm orc::ThreadSafeModule &clone = llvmmod ? *unwrap(llvmmod) : backing; auto ctxt = clone.getContext(); - 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(); - // compile all methods for the current world and type-inference world - auto target_info = clone.withModuleDo([&](Module &M) { return std::make_pair(M.getDataLayout(), Triple(M.getTargetTriple())); }); @@ -592,84 +620,57 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm if (!llvmmod) params.getContext().setDiscardValueNames(true); params.params = cgparams; - params.imaging_mode = imaging; + assert(params.imaging_mode); // `_imaging_mode` controls if broken features like code-coverage are disabled params.external_linkage = _external_linkage; params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); JL_GC_PUSH3(¶ms.temporary_roots, &method_roots.list, &method_roots.keyset); - size_t compile_for[] = { jl_typeinf_world, _world }; - int worlds = 0; - if (jl_options.trim != JL_TRIM_NO) - worlds = 1; jl_compiled_functions_t compiled_functions; - for (; worlds < 2; worlds++) { - JL_TIMING(NATIVE_AOT, NATIVE_Codegen); - size_t this_world = compile_for[worlds]; - if (!this_world) - continue; - // Don't emit methods for the typeinf_world with extern policy - if (policy != CompilationPolicy::Default && this_world == jl_typeinf_world) - continue; - size_t i, l; - for (i = 0, l = jl_array_nrows(methods); i < l; i++) { - // each item in this list is either a MethodInstance indicating something - // to compile, or an svec(rettype, sig) describing a C-callable alias to create. - jl_value_t *item = jl_array_ptr_ref(methods, i); - if (jl_is_simplevector(item)) { - if (worlds == 1) - jl_compile_extern_c(wrap(&clone), ¶ms, NULL, jl_svecref(item, 0), jl_svecref(item, 1)); - continue; - } - mi = (jl_method_instance_t*)item; - // if this method is generally visible to the current compilation world, - // and this is either the primary world, or not applicable in the primary world - // then we want to compile and emit this - if (jl_atomic_load_relaxed(&mi->def.method->primary_world) <= this_world && this_world <= jl_atomic_load_relaxed(&mi->def.method->deleted_world)) { - // find and prepare the source code to compile - jl_code_instance_t *codeinst = jl_ci_cache_lookup(mi, this_world, lookup); - JL_GC_PROMISE_ROOTED(codeinst); - if (jl_options.trim != JL_TRIM_NO && !codeinst) { - // If we're building a small image, we need to compile everything - // to ensure that we have all the information we need. - jl_safe_printf("Codegen decided not to compile code root"); - jl_(mi); - abort(); - } - if (codeinst && !compiled_functions.count(codeinst) && !data->jl_fvar_map.count(codeinst)) { - // now add it to our compilation results - // Const returns do not do codegen, but juliac inspects codegen results so make a dummy fvar entry to represent it - if (jl_options.trim != JL_TRIM_NO && jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr) { - data->jl_fvar_map[codeinst] = std::make_tuple((uint32_t)-3, (uint32_t)-3); - } - else { - orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(codeinst->def), - params.tsctx, clone.getModuleUnlocked()->getDataLayout(), - Triple(clone.getModuleUnlocked()->getTargetTriple())); - jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, NULL, params); - JL_GC_PROMISE_ROOTED(codeinst->def); // analyzer seems confused - record_method_roots(method_roots, codeinst->def); - if (result_m) - compiled_functions[codeinst] = {std::move(result_m), std::move(decls)}; - else if (jl_options.trim != JL_TRIM_NO) { - // if we're building a small image, we need to compile everything - // to ensure that we have all the information we need. - jl_safe_printf("codegen failed to compile code root"); - jl_(mi); - abort(); - } - } + size_t i, l; + for (i = 0, l = jl_array_nrows(codeinfos); i < l; i++) { + // each item in this list is either a CodeInstance followed by a CodeInfo indicating something + // to compile, or a rettype followed by a sig describing a C-callable alias to create. + jl_value_t *item = jl_array_ptr_ref(codeinfos, i); + if (jl_is_code_instance(item)) { + // now add it to our compilation results + jl_code_instance_t *codeinst = (jl_code_instance_t*)item; + jl_code_info_t *src = (jl_code_info_t*)jl_array_ptr_ref(codeinfos, ++i); + assert(jl_is_code_info(src)); + if (compiled_functions.count(codeinst)) + continue; // skip any duplicates that accidentally made there way in here (or make this an error?) + if (_external_linkage) { + uint8_t specsigflags; + jl_callptr_t invoke; + void *fptr; + jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); + if (invoke != NULL && (specsigflags & 0b100)) { + // this codeinst is already available externally + // TODO: for performance, avoid generating the src code when we know it would reach here anyways + continue; } } - else if (this_world != jl_typeinf_world) { - /* - jl_safe_printf("Codegen could not find requested codeinstance to be compiled\n"); + orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), + params.tsctx, clone.getModuleUnlocked()->getDataLayout(), + Triple(clone.getModuleUnlocked()->getTargetTriple())); + jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, src, params); + record_method_roots(method_roots, jl_get_ci_mi(codeinst)); + if (result_m) + compiled_functions[codeinst] = {std::move(result_m), std::move(decls)}; + else if (params.params->trim) { + // if we're building a small image, we need to compile everything + // to ensure that we have all the information we need. + jl_safe_printf("codegen failed to compile code root "); jl_(mi); abort(); - */ } } + else { + jl_value_t *sig = jl_array_ptr_ref(codeinfos, ++i); + assert(jl_is_type(item) && jl_is_type(sig)); + jl_compile_extern_c(wrap(&clone), ¶ms, NULL, item, sig); + } } - // finally, make sure all referenced methods also get compiled or fixed up - compile_workqueue(params, method_roots, policy, compiled_functions); + // finally, make sure all referenced methods get fixed up, particularly if the user declined to compile them + resolve_workqueue(params, method_roots, compiled_functions); aot_optimize_roots(params, method_roots, compiled_functions); params.temporary_roots = nullptr; JL_GC_POP(); @@ -712,7 +713,6 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm // clones the contents of the module `m` to the shadow_output collector // while examining and recording what kind of function pointer we have { - JL_TIMING(NATIVE_AOT, NATIVE_Merge); Linker L(*clone.getModuleUnlocked()); for (auto &def : compiled_functions) { jl_merge_module(clone, std::move(std::get<0>(def.second))); @@ -762,45 +762,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm } CreateNativeGlobals += gvars.size(); - //Safe b/c context is locked by params - auto TT = Triple(clone.getModuleUnlocked()->getTargetTriple()); - Function *juliapersonality_func = nullptr; - if (TT.isOSWindows() && TT.getArch() == Triple::x86_64) { - // setting the function personality enables stack unwinding and catching exceptions - // so make sure everything has something set - Type *T_int32 = Type::getInt32Ty(clone.getModuleUnlocked()->getContext()); - juliapersonality_func = Function::Create(FunctionType::get(T_int32, true), - Function::ExternalLinkage, "__julia_personality", clone.getModuleUnlocked()); - juliapersonality_func->setDLLStorageClass(GlobalValue::DLLImportStorageClass); - } - - // move everything inside, now that we've merged everything - // (before adding the exported headers) - if (policy == CompilationPolicy::Default) { - //Safe b/c context is locked by params - for (GlobalObject &G : clone.getModuleUnlocked()->global_objects()) { - if (!G.isDeclaration()) { - G.setLinkage(GlobalValue::InternalLinkage); - G.setDSOLocal(true); - makeSafeName(G); - if (Function *F = dyn_cast(&G)) { - if (TT.isOSWindows() && TT.getArch() == Triple::x86_64) { - // Add unwind exception personalities to functions to handle async exceptions - F->setPersonalityFn(juliapersonality_func); - } - } - } - } - } - data->M = std::move(clone); - if (timed) { - if (measure_compile_time_enabled) { - auto end = jl_hrtime(); - jl_atomic_fetch_add_relaxed(&jl_cumulative_compile_time, end - compiler_start_time); - } - ct->reentrant_timing &= ~1ull; - } return (void*)data; } @@ -1954,8 +1916,7 @@ void jl_dump_native_impl(void *native_code, sysimg_outputs = compile(sysimgM, "sysimg", 1, [](Module &) {}); } - bool imaging_mode = imaging_default() || jl_options.outputo; - + const bool imaging_mode = true; unsigned threads = 1; unsigned nfvars = 0; unsigned ngvars = 0; @@ -2062,8 +2023,7 @@ void jl_dump_native_impl(void *native_code, data_outputs = compile(*dataM, "text", threads, [data](Module &) { delete data; }); } - if (params->emit_metadata) - { + if (params->emit_metadata) { JL_TIMING(NATIVE_AOT, NATIVE_Metadata); LLVMContext Context; Context.setDiscardValueNames(true); @@ -2249,71 +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 = imaging_default(); - // This would be nice, but currently it causes some assembly regressions that make printed output - // differ very significantly from the actual non-imaging mode code. - // // Force imaging mode for names of pointers - // output.imaging = true; - // This would also be nice, but it seems to cause OOMs on the windows32 builder - // To get correct names in the IR this needs to be at least 2 - 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, 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, 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 + + 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/array.c b/src/array.c index f0051ec17565a..da9cb24b4d0e9 100644 --- a/src/array.c +++ b/src/array.c @@ -16,12 +16,6 @@ extern "C" { #endif -#if defined(_P64) && defined(UINT128MAX) -typedef __uint128_t wideint_t; -#else -typedef uint64_t wideint_t; -#endif - #define MAXINTVAL (((size_t)-1)>>1) JL_DLLEXPORT int jl_array_validate_dims(size_t *nel, uint32_t ndims, size_t *dims) @@ -30,10 +24,9 @@ JL_DLLEXPORT int jl_array_validate_dims(size_t *nel, uint32_t ndims, size_t *dim size_t _nel = 1; for (i = 0; i < ndims; i++) { size_t di = dims[i]; - wideint_t prod = (wideint_t)_nel * (wideint_t)di; - if (prod >= (wideint_t) MAXINTVAL || di >= MAXINTVAL) + int overflow = __builtin_mul_overflow(_nel, di, &_nel); + if (overflow || di >= MAXINTVAL) return 1; - _nel = prod; } *nel = _nel; return 0; @@ -204,7 +197,7 @@ JL_DLLEXPORT void jl_array_grow_end(jl_array_t *a, size_t inc) int isbitsunion = jl_genericmemory_isbitsunion(a->ref.mem); size_t newnrows = n + inc; if (!isbitsunion && elsz == 0) { - jl_genericmemory_t *newmem = jl_alloc_genericmemory(mtype, MAXINTVAL - 1); + jl_genericmemory_t *newmem = jl_alloc_genericmemory(mtype, MAXINTVAL - 2); a->ref.mem = newmem; jl_gc_wb(a, newmem); a->dimsize[0] = newnrows; diff --git a/src/ast.c b/src/ast.c index 959bac26c2c15..0f24d96393f2f 100644 --- a/src/ast.c +++ b/src/ast.c @@ -669,6 +669,8 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m if (iscvalue(e) && cv_class((cvalue_t*)ptr(e)) == jl_ast_ctx(fl_ctx)->jvtype) { return *(jl_value_t**)cv_data((cvalue_t*)ptr(e)); } + fl_print(fl_ctx, ios_stderr, e); + ios_putc('\n', ios_stderr); jl_error("malformed tree"); } diff --git a/src/builtin_proto.h b/src/builtin_proto.h index 7fbd555758675..77463ae4884cb 100644 --- a/src/builtin_proto.h +++ b/src/builtin_proto.h @@ -45,7 +45,9 @@ DECLARE_BUILTIN(invoke); DECLARE_BUILTIN(is); DECLARE_BUILTIN(isa); DECLARE_BUILTIN(isdefined); +DECLARE_BUILTIN(isdefinedglobal); DECLARE_BUILTIN(issubtype); +DECLARE_BUILTIN(memorynew); DECLARE_BUILTIN(memoryref); DECLARE_BUILTIN(memoryref_isassigned); DECLARE_BUILTIN(memoryrefget); diff --git a/src/builtins.c b/src/builtins.c index 4b9c1ad6043c2..90d8a0d453e20 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1352,6 +1352,33 @@ JL_CALLABLE(jl_f_getglobal) return v; } +JL_CALLABLE(jl_f_isdefinedglobal) +{ + jl_module_t *m = NULL; + jl_sym_t *s = NULL; + JL_NARGS(isdefined, 2, 3); + int allow_import = 1; + enum jl_memory_order order = jl_memory_order_unspecified; + JL_TYPECHK(isdefined, module, args[0]); + JL_TYPECHK(isdefined, symbol, args[1]); + if (nargs == 3) { + JL_TYPECHK(isdefined, bool, args[2]); + allow_import = jl_unbox_bool(args[2]); + } + if (nargs == 4) { + JL_TYPECHK(isdefined, symbol, args[3]); + order = jl_get_atomic_order_checked((jl_sym_t*)args[2], 1, 0); + } + m = (jl_module_t*)args[0]; + s = (jl_sym_t*)args[1]; + if (order == jl_memory_order_unspecified) + order = jl_memory_order_unordered; + if (order < jl_memory_order_unordered) + jl_atomic_error("isdefined: module binding cannot be accessed non-atomically"); + int bound = jl_boundp(m, s, allow_import); // seq_cst always + return bound ? jl_true : jl_false; +} + JL_CALLABLE(jl_f_setglobal) { enum jl_memory_order order = jl_memory_order_release; @@ -1589,11 +1616,19 @@ JL_CALLABLE(jl_f_invoke) return jl_gf_invoke_by_method(m, args[0], &args[2], nargs - 1); } else if (jl_is_code_instance(argtypes)) { jl_code_instance_t *codeinst = (jl_code_instance_t*)args[1]; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); jl_callptr_t invoke = jl_atomic_load_acquire(&codeinst->invoke); // N.B.: specTypes need not be a subtype of the method signature. We need to check both. - if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->specTypes) || - (jl_is_method(codeinst->def->def.value) && !jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->def.method->sig))) { - jl_type_error("invoke: argument type error", codeinst->def->specTypes, arg_tuple(args[0], &args[2], nargs - 1)); + if (jl_is_abioverride(codeinst->def)) { + jl_datatype_t *abi = (jl_datatype_t*)((jl_abi_override_t*)(codeinst->def))->abi; + if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, abi)) { + jl_type_error("invoke: argument type error (ABI overwrite)", (jl_value_t*)abi, arg_tuple(args[0], &args[2], nargs - 1)); + } + } else { + if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)mi->specTypes) || + (jl_is_method(mi->def.value) && !jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)mi->def.method->sig))) { + jl_type_error("invoke: argument type error", mi->specTypes, arg_tuple(args[0], &args[2], nargs - 1)); + } } if (jl_atomic_load_relaxed(&codeinst->min_world) > jl_current_task->world_age || jl_current_task->world_age > jl_atomic_load_relaxed(&codeinst->max_world)) { @@ -1609,7 +1644,7 @@ JL_CALLABLE(jl_f_invoke) if (codeinst->owner != jl_nothing) { jl_error("Failed to invoke or compile external codeinst"); } - return jl_invoke(args[0], &args[2], nargs - 1, codeinst->def); + return jl_invoke(args[0], &args[2], nargs - 1, mi); } } if (!jl_is_tuple_type(jl_unwrap_unionall(argtypes))) @@ -1675,6 +1710,15 @@ JL_CALLABLE(jl_f__typevar) } // genericmemory --------------------------------------------------------------------- +JL_CALLABLE(jl_f_memorynew) +{ + JL_NARGS(memorynew, 2, 2); + jl_datatype_t *jl_genericmemory_type_type = jl_datatype_type; + JL_TYPECHK(memorynew, genericmemory_type, args[0]); + JL_TYPECHK(memorynew, long, args[1]); + size_t nel = jl_unbox_long(args[1]); + return (jl_value_t*)jl_alloc_genericmemory(args[0], nel); +} JL_CALLABLE(jl_f_memoryref) { @@ -2434,6 +2478,7 @@ void jl_init_primitives(void) JL_GC_DISABLED // module bindings jl_builtin_getglobal = add_builtin_func("getglobal", jl_f_getglobal); jl_builtin_setglobal = add_builtin_func("setglobal!", jl_f_setglobal); + jl_builtin_isdefinedglobal = add_builtin_func("isdefinedglobal", jl_f_isdefinedglobal); add_builtin_func("get_binding_type", jl_f_get_binding_type); jl_builtin_swapglobal = add_builtin_func("swapglobal!", jl_f_swapglobal); jl_builtin_replaceglobal = add_builtin_func("replaceglobal!", jl_f_replaceglobal); @@ -2441,6 +2486,7 @@ void jl_init_primitives(void) JL_GC_DISABLED jl_builtin_setglobalonce = add_builtin_func("setglobalonce!", jl_f_setglobalonce); // memory primitives + jl_builtin_memorynew = add_builtin_func("memorynew", jl_f_memorynew); jl_builtin_memoryref = add_builtin_func("memoryrefnew", jl_f_memoryref); jl_builtin_memoryrefoffset = add_builtin_func("memoryrefoffset", jl_f_memoryrefoffset); jl_builtin_memoryrefget = add_builtin_func("memoryrefget", jl_f_memoryrefget); diff --git a/src/ccall.cpp b/src/ccall.cpp index 9aa1c56e2e78f..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))); @@ -697,14 +694,12 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg } else if (sym.fptr != NULL) { res = ConstantInt::get(lrt, (uint64_t)sym.fptr); - if (ctx.emission_context.imaging_mode) - jl_printf(JL_STDERR,"WARNING: literal address used in cglobal for %s; code cannot be statically compiled\n", sym.f_name); } else if (sym.f_name != NULL) { if (sym.lib_expr) { res = runtime_sym_lookup(ctx, getPointerTy(ctx.builder.getContext()), NULL, sym.lib_expr, sym.f_name, ctx.f); } - else /*if (ctx.emission_context.imaging) */{ + else { res = runtime_sym_lookup(ctx, getPointerTy(ctx.builder.getContext()), sym.f_lib, NULL, sym.f_name, ctx.f); } } else { @@ -1877,33 +1872,6 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) JL_GC_POP(); return mark_julia_type(ctx, obj, true, jl_any_type); } - else if (is_libjulia_func(jl_alloc_genericmemory)) { - ++CCALL_STAT(jl_alloc_genericmemory); - assert(lrt == ctx.types().T_prjlvalue); - assert(!isVa && !llvmcall && nccallargs == 2); - const jl_cgval_t &typ = argv[0]; - const jl_cgval_t &nel = argv[1]; - auto arg_typename = [&] JL_NOTSAFEPOINT { - auto istyp = argv[0].constant; - std::string type_str; - if (istyp && jl_is_datatype(istyp) && jl_is_genericmemory_type(istyp)){ - auto eltype = jl_tparam1(istyp); - if (jl_is_datatype(eltype)) - type_str = jl_symbol_name(((jl_datatype_t*)eltype)->name->name); - else if (jl_is_uniontype(eltype)) - type_str = "Union"; - else - type_str = ""; - } - else - type_str = ""; - return "Memory{" + type_str + "}[]"; - }; - auto alloc = ctx.builder.CreateCall(prepare_call(jl_allocgenericmemory), { boxed(ctx,typ), emit_unbox(ctx, ctx.types().T_size, nel, (jl_value_t*)jl_ulong_type)}); - setName(ctx.emission_context, alloc, arg_typename); - JL_GC_POP(); - return mark_julia_type(ctx, alloc, true, jl_any_type); - } else if (is_libjulia_func(memcpy) && (rt == (jl_value_t*)jl_nothing_type || jl_is_cpointer_type(rt))) { ++CCALL_STAT(memcpy); const jl_cgval_t &dst = argv[0]; @@ -2161,8 +2129,6 @@ jl_cgval_t function_sig_t::emit_a_ccall( Type *funcptype = functype->getPointerTo(0); llvmf = literal_static_pointer_val((void*)(uintptr_t)symarg.fptr, funcptype); setName(ctx.emission_context, llvmf, "ccall_fptr"); - if (ctx.emission_context.imaging_mode) - jl_printf(JL_STDERR,"WARNING: literal address used in ccall for %s; code cannot be statically compiled\n", symarg.f_name); } else if (!ctx.params->use_jlplt) { if ((symarg.f_lib && !((symarg.f_lib == JL_EXE_LIBNAME) || @@ -2179,7 +2145,7 @@ jl_cgval_t function_sig_t::emit_a_ccall( ++DeferredCCallLookups; llvmf = runtime_sym_lookup(ctx, funcptype, NULL, symarg.lib_expr, symarg.f_name, ctx.f); } - else /*if (ctx.emission_context.imaging) */{ + else { ++DeferredCCallLookups; // vararg requires musttail, // but musttail is incompatible with noreturn. diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 9e170555e6149..98c5627578b80 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1548,19 +1548,24 @@ static void emit_error(jl_codectx_t &ctx, const Twine &txt) } // DO NOT PASS IN A CONST CONDITION! -static void error_unless(jl_codectx_t &ctx, Value *cond, const Twine &msg) +static void error_unless(jl_codectx_t &ctx, Function *F, Value *cond, const Twine &msg) { ++EmittedConditionalErrors; BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(), "fail", ctx.f); BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "pass"); ctx.builder.CreateCondBr(cond, passBB, failBB); ctx.builder.SetInsertPoint(failBB); - just_emit_error(ctx, prepare_call(jlerror_func), msg); + just_emit_error(ctx, F, msg); ctx.builder.CreateUnreachable(); passBB->insertInto(ctx.f); ctx.builder.SetInsertPoint(passBB); } +static void error_unless(jl_codectx_t &ctx, Value *cond, const Twine &msg) +{ + error_unless(ctx, prepare_call(jlerror_func), cond, msg); +} + static void raise_exception(jl_codectx_t &ctx, Value *exc, BasicBlock *contBB=nullptr) { @@ -2279,7 +2284,7 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, const jl_cgval_t argv[3] = { cmp, lhs, rhs }; jl_cgval_t ret; if (modifyop) { - ret = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type); + ret = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type, nullptr); } else { if (trim_may_error(ctx.params->trim)) { @@ -3316,7 +3321,7 @@ static Value *emit_genericmemoryptr(jl_codectx_t &ctx, Value *mem, const jl_data LoadInst *LI = ctx.builder.CreateAlignedLoad(PPT, addr, Align(sizeof(char*))); LI->setOrdering(AtomicOrdering::NotAtomic); LI->setMetadata(LLVMContext::MD_nonnull, MDNode::get(ctx.builder.getContext(), None)); - jl_aliasinfo_t aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + jl_aliasinfo_t aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); aliasinfo.decorateInst(LI); Value *ptr = LI; if (AS) { @@ -3342,7 +3347,7 @@ static Value *emit_genericmemoryowner(jl_codectx_t &ctx, Value *t) return emit_guarded_test(ctx, foreign, t, [&] { addr = ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_jlgenericmemory, m, 1); LoadInst *owner = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, addr, Align(sizeof(void*))); - jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); ai.decorateInst(owner); return ctx.builder.CreateSelect(ctx.builder.CreateIsNull(owner), t, owner); }); @@ -4018,7 +4023,7 @@ static jl_cgval_t union_store(jl_codectx_t &ctx, emit_lockstate_value(ctx, needlock, false); const jl_cgval_t argv[3] = { cmp, oldval, rhs }; if (modifyop) { - rhs = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type); + rhs = emit_invoke(ctx, *modifyop, argv, 3, (jl_value_t*)jl_any_type, nullptr); } else { if (trim_may_error(ctx.params->trim)) { @@ -4427,6 +4432,174 @@ static int compare_cgparams(const jl_cgparams_t *a, const jl_cgparams_t *b) } #endif +static auto *emit_genericmemory_unchecked(jl_codectx_t &ctx, Value *cg_nbytes, Value *cg_typ) +{ + auto ptls = get_current_ptls(ctx); + auto call = prepare_call(jl_alloc_genericmemory_unchecked_func); + auto *alloc = ctx.builder.CreateCall(call, { ptls, cg_nbytes, cg_typ}); + alloc->setAttributes(call->getAttributes()); + alloc->addRetAttr(Attribute::getWithAlignment(alloc->getContext(), Align(JL_HEAP_ALIGNMENT))); + call->addRetAttr(Attribute::getWithDereferenceableBytes(call->getContext(), sizeof(jl_genericmemory_t))); + return alloc; +} + +static void emit_memory_zeroinit_and_stores(jl_codectx_t &ctx, jl_datatype_t *typ, Value* alloc, Value* nbytes, Value* nel, int zi) +{ + auto arg_typename = [&] JL_NOTSAFEPOINT { + std::string type_str; + auto eltype = jl_tparam1(typ); + if (jl_is_datatype(eltype)) + type_str = jl_symbol_name(((jl_datatype_t*)eltype)->name->name); + else if (jl_is_uniontype(eltype)) + type_str = "Union"; + else + type_str = ""; + return "Memory{" + type_str + "}[]"; + }; + setName(ctx.emission_context, alloc, arg_typename); + // set length (jl_alloc_genericmemory_unchecked_func doesn't have it) + Value *decay_alloc = decay_derived(ctx, alloc); + Value *len_field = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 0); + 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); + // zeroinit pointers and unions + if (zi) { + Value *memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); + auto *load = ctx.builder.CreateAlignedLoad(ctx.types().T_ptr, memory_ptr, Align(sizeof(void*))); + aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); + aliasinfo.decorateInst(load); + auto int8t = getInt8Ty(ctx.builder.getContext()); + ctx.builder.CreateMemSet(load, ConstantInt::get(int8t, 0), nbytes, Align(sizeof(void*))); + } + return; +} + + +static jl_cgval_t emit_const_len_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, size_t nel, jl_genericmemory_t *inst) +{ + if (nel == 0) { + Value *empty_alloc = track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)inst)); + return mark_julia_type(ctx, empty_alloc, true, typ); + } + const jl_datatype_layout_t *layout = ((jl_datatype_t*)typ)->layout; + assert(((jl_datatype_t*)typ)->has_concrete_subtype && layout != NULL); + size_t elsz = layout->size; + int isboxed = layout->flags.arrayelem_isboxed; + int isunion = layout->flags.arrayelem_isunion; + int zi = ((jl_datatype_t*)typ)->zeroinit; + if (isboxed) + elsz = sizeof(void*); + size_t nbytes; + bool overflow = __builtin_mul_overflow(nel, elsz, &nbytes); + if (isunion) { + // an extra byte for each isbits union memory element, stored at m->ptr + m->length + overflow |= __builtin_add_overflow(nbytes, nel, &nbytes); + } + // overflow if signed size is too big or nel is too big (the latter matters iff elsz==0) + ssize_t tmp=1; + overflow |= __builtin_add_overflow(nel, 1, &tmp) || __builtin_add_overflow(nbytes, 1, &tmp); + if (overflow) + emit_error(ctx, prepare_call(jlargumenterror_func), "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); + + auto T_size = ctx.types().T_size; + auto cg_typ = literal_pointer_val(ctx, (jl_value_t*) typ); + auto cg_nbytes = ConstantInt::get(T_size, nbytes); + auto cg_nel = ConstantInt::get(T_size, nel); + size_t tot = nbytes + LLT_ALIGN(sizeof(jl_genericmemory_t),JL_SMALL_BYTE_ALIGNMENT); + // if allocation fits within GC pools + int pooled = tot <= GC_MAX_SZCLASS; + Value *alloc, *decay_alloc, *memory_ptr; + jl_aliasinfo_t aliasinfo; + if (pooled) { + alloc = emit_allocobj(ctx, tot, cg_typ, false, JL_SMALL_BYTE_ALIGNMENT); + decay_alloc = decay_derived(ctx, alloc); + memory_ptr = ctx.builder.CreateStructGEP(ctx.types().T_jlgenericmemory, decay_alloc, 1); + setName(ctx.emission_context, memory_ptr, "memory_ptr"); + auto objref = emit_pointer_from_objref(ctx, alloc); + Value *memory_data = emit_ptrgep(ctx, objref, JL_SMALL_BYTE_ALIGNMENT); + auto *store = ctx.builder.CreateAlignedStore(memory_data, memory_ptr, Align(sizeof(void*))); + aliasinfo = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_memoryptr); + aliasinfo.decorateInst(store); + setName(ctx.emission_context, memory_data, "memory_data"); + } else { // just use the dynamic length version since the malloc will be slow anyway + alloc = emit_genericmemory_unchecked(ctx, cg_nbytes, cg_typ); + } + emit_memory_zeroinit_and_stores(ctx, typ, alloc, cg_nbytes, cg_nel, zi); + return mark_julia_type(ctx, alloc, true, typ); +} + +static jl_cgval_t emit_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, jl_cgval_t nel, jl_genericmemory_t *inst) +{ + emit_typecheck(ctx, nel, (jl_value_t*)jl_long_type, "memorynew"); + nel = update_julia_type(ctx, nel, (jl_value_t*)jl_long_type); + if (nel.typ == jl_bottom_type) + return jl_cgval_t(); + + const jl_datatype_layout_t *layout = ((jl_datatype_t*)typ)->layout; + assert(((jl_datatype_t*)typ)->has_concrete_subtype && layout != NULL); + size_t elsz = layout->size; + int isboxed = layout->flags.arrayelem_isboxed; + int isunion = layout->flags.arrayelem_isunion; + int zi = ((jl_datatype_t*)typ)->zeroinit; + if (isboxed) + elsz = sizeof(void*); + + auto T_size = ctx.types().T_size; + BasicBlock *emptymemBB, *nonemptymemBB, *retvalBB; + emptymemBB = BasicBlock::Create(ctx.builder.getContext(), "emptymem"); + nonemptymemBB = BasicBlock::Create(ctx.builder.getContext(), "nonemptymem"); + retvalBB = BasicBlock::Create(ctx.builder.getContext(), "retval"); + auto nel_unboxed = emit_unbox(ctx, ctx.types().T_size, nel, (jl_value_t*)jl_long_type); + Value *memorynew_empty = ctx.builder.CreateICmpEQ(nel_unboxed, ConstantInt::get(T_size, 0)); + setName(ctx.emission_context, memorynew_empty, "memorynew_empty"); + ctx.builder.CreateCondBr(memorynew_empty, emptymemBB, nonemptymemBB); + // if nel == 0 + emptymemBB->insertInto(ctx.f); + ctx.builder.SetInsertPoint(emptymemBB); + auto emptyalloc = track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)inst)); + ctx.builder.CreateBr(retvalBB); + nonemptymemBB->insertInto(ctx.f); + ctx.builder.SetInsertPoint(nonemptymemBB); + + auto cg_typ = literal_pointer_val(ctx, (jl_value_t*) typ); + auto cg_elsz = ConstantInt::get(T_size, elsz); + + FunctionCallee intr = Intrinsic::getDeclaration(jl_Module, Intrinsic::smul_with_overflow, ArrayRef(T_size)); + // compute nbytes with possible overflow + Value *prod_with_overflow = ctx.builder.CreateCall(intr, {nel_unboxed, cg_elsz}); + Value *nbytes = ctx.builder.CreateExtractValue(prod_with_overflow, 0); + Value *overflow = ctx.builder.CreateExtractValue(prod_with_overflow, 1); + if (isunion) { + // if isunion, we need to allocate the union selector bytes as well + intr = Intrinsic::getDeclaration(jl_Module, Intrinsic::sadd_with_overflow, ArrayRef(T_size)); + Value *add_with_overflow = ctx.builder.CreateCall(intr, {nel_unboxed, nbytes}); + nbytes = ctx.builder.CreateExtractValue(add_with_overflow, 0); + Value *overflow1 = ctx.builder.CreateExtractValue(add_with_overflow, 1); + overflow = ctx.builder.CreateOr(overflow, overflow1); + } + Value *negnel = ctx.builder.CreateICmpSLT(nel_unboxed, ConstantInt::get(T_size, 0)); + overflow = ctx.builder.CreateOr(overflow, negnel); + auto cg_typemax_int = ConstantInt::get(T_size, (((size_t)-1)>>1)-1); + Value *tobignel = ctx.builder.CreateICmpSLT(cg_typemax_int, elsz == 0 ? nel_unboxed: nbytes); + overflow = ctx.builder.CreateOr(overflow, tobignel); + Value *notoverflow = ctx.builder.CreateNot(overflow); + error_unless(ctx, prepare_call(jlargumenterror_func), notoverflow, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); + // actually allocate the memory + + Value *alloc = emit_genericmemory_unchecked(ctx, nbytes, cg_typ); + emit_memory_zeroinit_and_stores(ctx, typ, alloc, nbytes, nel_unboxed, zi); + ctx.builder.CreateBr(retvalBB); + nonemptymemBB = ctx.builder.GetInsertBlock(); + // phi node to choose which side of branch + retvalBB->insertInto(ctx.f); + ctx.builder.SetInsertPoint(retvalBB); + auto phi = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2); + phi->addIncoming(emptyalloc, emptymemBB); + phi->addIncoming(alloc, nonemptymemBB); + return mark_julia_type(ctx, phi, true, typ); +} + static jl_cgval_t _emit_memoryref(jl_codectx_t &ctx, Value *mem, Value *data, const jl_datatype_layout_t *layout, jl_value_t *typ) { //jl_cgval_t argv[] = { diff --git a/src/clangsa/GCChecker.cpp b/src/clangsa/GCChecker.cpp index 40093ca15859b..fdbe5ec9d9e29 100644 --- a/src/clangsa/GCChecker.cpp +++ b/src/clangsa/GCChecker.cpp @@ -847,6 +847,7 @@ bool GCChecker::isGCTrackedType(QualType QT) { Name.ends_with_insensitive("jl_vararg_t") || Name.ends_with_insensitive("jl_opaque_closure_t") || Name.ends_with_insensitive("jl_globalref_t") || + Name.ends_with_insensitive("jl_abi_override_t") || // Probably not technically true for these, but let's allow it as a root Name.ends_with_insensitive("jl_ircode_state") || Name.ends_with_insensitive("typemap_intersection_env") || diff --git a/src/codegen-stubs.c b/src/codegen-stubs.c index fe50af3f8e84d..5e243ddda28c9 100644 --- a/src/codegen-stubs.c +++ b/src/codegen-stubs.c @@ -46,11 +46,26 @@ JL_DLLEXPORT void jl_generate_fptr_for_unspecialized_fallback(jl_code_instance_t JL_DLLEXPORT int jl_compile_codeinst_fallback(jl_code_instance_t *unspec) { - // Do nothing. The caller will notice that we failed to provide a an ->invoke and trigger + // Do nothing. The caller will notice that we failed to provide an ->invoke and trigger // appropriate fallbacks. return 0; } +JL_DLLEXPORT void jl_emit_codeinst_to_jit_fallback(jl_code_instance_t *codeinst, jl_code_info_t *src) +{ + jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred); + if (jl_is_code_info(inferred)) + return; + if (jl_is_svec(src->edges)) { + jl_atomic_store_release(&codeinst->inferred, (jl_value_t*)src->edges); + jl_gc_wb(codeinst, src->edges); + } + jl_atomic_store_release(&codeinst->debuginfo, src->debuginfo); + jl_gc_wb(codeinst, src->debuginfo); + jl_atomic_store_release(&codeinst->inferred, (jl_value_t*)src); + jl_gc_wb(codeinst, src); +} + JL_DLLEXPORT uint32_t jl_get_LLVM_VERSION_fallback(void) { return 0; @@ -70,7 +85,8 @@ JL_DLLEXPORT size_t jl_jit_total_bytes_fallback(void) return 0; } -JL_DLLEXPORT void *jl_create_native_fallback(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _policy, int _imaging_mode, int _external_linkage, size_t _world, jl_codeinstance_lookup_t lookup) UNAVAILABLE +JL_DLLEXPORT void *jl_create_native_fallback(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, int _trim, int _external_linkage, size_t _world) UNAVAILABLE +JL_DLLEXPORT void *jl_emit_native_fallback(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _external_linkage) UNAVAILABLE JL_DLLEXPORT void jl_dump_compiles_fallback(void *s) { diff --git a/src/codegen.cpp b/src/codegen.cpp index b9d42b9b5af16..e047632923f68 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -408,9 +408,9 @@ struct jl_tbaacache_t { tbaa_arrayptr = tbaa_make_child(mbuilder, "jtbaa_arrayptr", tbaa_array_scalar).first; tbaa_arraysize = tbaa_make_child(mbuilder, "jtbaa_arraysize", tbaa_array_scalar).first; tbaa_arrayselbyte = tbaa_make_child(mbuilder, "jtbaa_arrayselbyte", tbaa_array_scalar).first; - tbaa_memoryptr = tbaa_make_child(mbuilder, "jtbaa_memoryptr", tbaa_array_scalar, true).first; - tbaa_memorylen = tbaa_make_child(mbuilder, "jtbaa_memorylen", tbaa_array_scalar, true).first; - tbaa_memoryown = tbaa_make_child(mbuilder, "jtbaa_memoryown", tbaa_array_scalar, true).first; + tbaa_memoryptr = tbaa_make_child(mbuilder, "jtbaa_memoryptr", tbaa_array_scalar).first; + tbaa_memorylen = tbaa_make_child(mbuilder, "jtbaa_memorylen", tbaa_array_scalar).first; + tbaa_memoryown = tbaa_make_child(mbuilder, "jtbaa_memoryown", tbaa_array_scalar).first; tbaa_const = tbaa_make_child(mbuilder, "jtbaa_const", nullptr, true).first; } }; @@ -801,6 +801,12 @@ static const auto jlerror_func = new JuliaFunction<>{ {getPointerTy(C)}, false); }, get_attrs_noreturn, }; +static const auto jlargumenterror_func = new JuliaFunction<>{ + XSTR(jl_argument_error), + [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), + {getPointerTy(C)}, false); }, + get_attrs_noreturn, +}; static const auto jlatomicerror_func = new JuliaFunction<>{ XSTR(jl_atomic_error), [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), @@ -990,6 +996,15 @@ static const auto jlinvoke_func = new JuliaFunction<>{ {AttributeSet(), Attributes(C, {Attribute::ReadOnly, Attribute::NoCapture})}); }, }; +static const auto jlinvokeoc_func = new JuliaFunction<>{ + XSTR(jl_invoke_oc), + get_func2_sig, + [](LLVMContext &C) { return AttributeList::get(C, + AttributeSet(), + Attributes(C, {Attribute::NonNull}), + {AttributeSet(), + Attributes(C, {Attribute::ReadOnly, Attribute::NoCapture})}); }, +}; static const auto jlopaque_closure_call_func = new JuliaFunction<>{ XSTR(jl_f_opaque_closure_call), get_func_sig, @@ -1153,6 +1168,30 @@ static const auto jl_alloc_obj_func = new JuliaFunction{ None); }, }; +static const auto jl_alloc_genericmemory_unchecked_func = new JuliaFunction{ + XSTR(jl_alloc_genericmemory_unchecked), + [](LLVMContext &C, Type *T_size) { + auto T_jlvalue = JuliaType::get_jlvalue_ty(C); + auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked); + auto T_pjlvalue = PointerType::get(T_jlvalue, 0); + return FunctionType::get(T_prjlvalue, + {T_pjlvalue, T_size, T_pjlvalue}, false); + }, + [](LLVMContext &C) { + auto FnAttrs = AttrBuilder(C); + FnAttrs.addAllocKindAttr(AllocFnKind::Alloc); + FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef)); + FnAttrs.addAttribute(Attribute::WillReturn); + FnAttrs.addAttribute(Attribute::NoUnwind); + auto RetAttrs = AttrBuilder(C); + RetAttrs.addAttribute(Attribute::NoAlias); + RetAttrs.addAttribute(Attribute::NonNull); + return AttributeList::get(C, + AttributeSet::get(C, FnAttrs), + AttributeSet::get(C, RetAttrs), + None); + }, +}; static const auto jl_newbits_func = new JuliaFunction<>{ XSTR(jl_new_bits), [](LLVMContext &C) { @@ -1224,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, @@ -1338,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) @@ -1351,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, @@ -1461,6 +1498,10 @@ static const auto pointer_from_objref_func = new JuliaFunction<>{ AttrBuilder FnAttrs(C); FnAttrs.addMemoryAttr(MemoryEffects::none()); FnAttrs.addAttribute(Attribute::NoUnwind); + FnAttrs.addAttribute(Attribute::Speculatable); + FnAttrs.addAttribute(Attribute::WillReturn); + FnAttrs.addAttribute(Attribute::NoRecurse); + FnAttrs.addAttribute(Attribute::NoSync); return AttributeList::get(C, AttributeSet::get(C, FnAttrs), Attributes(C, {Attribute::NonNull}), @@ -1574,6 +1615,7 @@ static const auto &builtin_func_map() { { jl_f_nfields_addr, new JuliaFunction<>{XSTR(jl_f_nfields), get_func_sig, get_func_attrs} }, { jl_f__expr_addr, new JuliaFunction<>{XSTR(jl_f__expr), get_func_sig, get_func_attrs} }, { jl_f__typevar_addr, new JuliaFunction<>{XSTR(jl_f__typevar), get_func_sig, get_func_attrs} }, + { jl_f_memorynew_addr, new JuliaFunction<>{XSTR(jl_f_memorynew), get_func_sig, get_func_attrs} }, { jl_f_memoryref_addr, new JuliaFunction<>{XSTR(jl_f_memoryref), get_func_sig, get_func_attrs} }, { jl_f_memoryrefoffset_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefoffset), get_func_sig, get_func_attrs} }, { jl_f_memoryrefset_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefset), get_func_sig, get_func_attrs} }, @@ -2074,7 +2116,7 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction<> *theFptr, Value static Value *emit_f_is(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgval_t &arg2, Value *nullcheck1 = nullptr, Value *nullcheck2 = nullptr); static jl_cgval_t emit_new_struct(jl_codectx_t &ctx, jl_value_t *ty, size_t nargs, ArrayRef argv, bool is_promotable=false); -static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt); +static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt, Value *age_ok); static Value *literal_pointer_val(jl_codectx_t &ctx, jl_value_t *p); static unsigned julia_alignment(jl_value_t *jt); @@ -2141,18 +2183,18 @@ static jl_value_t *StackFrame( return frame; } -static void push_frames(jl_codectx_t &ctx, jl_method_instance_t *caller, jl_method_instance_t *callee, int no_debug=false) +static void push_frames(jl_codectx_t &ctx, jl_method_instance_t *caller, jl_method_instance_t *callee) { CallFrames frames; auto it = ctx.emission_context.enqueuers.find(callee); if (it != ctx.emission_context.enqueuers.end()) return; - if (no_debug) { // Used in tojlinvoke + auto DL = ctx.builder.getCurrentDebugLocation(); + if (caller == nullptr || !DL) { // Used in various places frames.push_back({ctx.funcName, "", 0}); ctx.emission_context.enqueuers.insert({callee, {caller, std::move(frames)}}); return; } - auto DL = ctx.builder.getCurrentDebugLocation(); auto filename = std::string(DL->getFilename()); auto line = DL->getLine(); auto fname = std::string(DL->getScope()->getSubprogram()->getName()); @@ -2991,9 +3033,8 @@ static bool uses_specsig(jl_value_t *sig, bool needsparams, jl_value_t *rettype, return false; // jlcall sig won't require any box allocations } -static std::pair uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig) +static std::pair uses_specsig(jl_value_t *abi, jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig) { - jl_value_t *sig = lam->specTypes; bool needsparams = false; if (jl_is_method(lam->def.method)) { if ((size_t)jl_subtype_env_size(lam->def.method->sig) != jl_svec_len(lam->sparam_vals)) @@ -3003,7 +3044,7 @@ static std::pair uses_specsig(jl_method_instance_t *lam, jl_value_t needsparams = true; } } - return std::make_pair(uses_specsig(sig, needsparams, rettype, prefer_specsig), needsparams); + return std::make_pair(uses_specsig(abi, needsparams, rettype, prefer_specsig), needsparams); } @@ -3095,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)) @@ -3117,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; @@ -3140,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; } } @@ -3424,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) @@ -4130,6 +4181,34 @@ static bool emit_f_opfield(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return false; } +static jl_cgval_t emit_isdefinedglobal(jl_codectx_t &ctx, jl_module_t *modu, jl_sym_t *name, int allow_import, enum jl_memory_order order) +{ + Value *isnull = NULL; + jl_binding_t *bnd = allow_import ? jl_get_binding(modu, name) : jl_get_module_binding(modu, name, 0); + jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world); + jl_ptr_kind_union_t pku = bpart ? jl_atomic_load_relaxed(&bpart->restriction) : encode_restriction(NULL, BINDING_KIND_GUARD); + if (decode_restriction_kind(pku) == BINDING_KIND_GLOBAL || jl_bkind_is_some_constant(decode_restriction_kind(pku))) { + if (jl_get_binding_value_if_const(bnd)) + return mark_julia_const(ctx, jl_true); + Value *bp = julia_binding_gv(ctx, bnd); + bp = julia_binding_pvalue(ctx, bp); + LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))); + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_binding); + ai.decorateInst(v); + v->setOrdering(get_llvm_atomic_order(order)); + isnull = ctx.builder.CreateICmpNE(v, Constant::getNullValue(ctx.types().T_prjlvalue)); + } + else { + Value *v = ctx.builder.CreateCall(prepare_call(jlboundp_func), { + literal_pointer_val(ctx, (jl_value_t*)modu), + literal_pointer_val(ctx, (jl_value_t*)name), + ConstantInt::get(getInt32Ty(ctx.builder.getContext()), allow_import) + }); + isnull = ctx.builder.CreateICmpNE(v, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)); + } + return mark_julia_type(ctx, isnull, false, jl_bool_type); +} + static bool emit_f_opmemory(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, ArrayRef argv, size_t nargs, const jl_cgval_t *modifyop) { @@ -4311,7 +4390,8 @@ static jl_llvm_functions_t orc::ThreadSafeModule &TSM, jl_method_instance_t *lam, jl_code_info_t *src, - jl_value_t *rettype, + jl_value_t *abi, + 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); @@ -4421,6 +4501,30 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } + else if (f == jl_builtin_memorynew && (nargs == 2)) { + const jl_cgval_t &memty = argv[1]; + if (!memty.constant) + return false; + jl_datatype_t *typ = (jl_datatype_t*) memty.constant; + if (!jl_is_concrete_type((jl_value_t*)typ) || !jl_is_genericmemory_type(typ)) + return false; + jl_genericmemory_t *inst = (jl_genericmemory_t*)((jl_datatype_t*)typ)->instance; + if (inst == NULL) + return false; + if (argv[2].constant) { + if (!jl_is_long(argv[2].constant)) + return false; + size_t nel = jl_unbox_long(argv[2].constant); + if (nel < 0) + return false; + *ret = emit_const_len_memorynew(ctx, typ, nel, inst); + } + else { + *ret = emit_memorynew(ctx, typ, argv[2], inst); + } + return true; + } + else if (f == jl_builtin_memoryref && nargs == 1) { const jl_cgval_t &mem = argv[1]; jl_datatype_t *mty_dt = (jl_datatype_t*)jl_unwrap_unionall(mem.typ); @@ -5006,6 +5110,42 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } + else if (f == jl_builtin_isdefinedglobal && (nargs == 2 || nargs == 3 || nargs == 4)) { + const jl_cgval_t &mod = argv[1]; + const jl_cgval_t &sym = argv[2]; + bool allow_import = true; + enum jl_memory_order order = jl_memory_order_unspecified; + + if (nargs >= 3) { + const jl_cgval_t &arg3 = argv[3]; + if (arg3.constant && jl_is_bool(arg3.constant)) + allow_import = jl_unbox_bool(arg3.constant); + else + return false; + } + + if (nargs == 4) { + const jl_cgval_t &arg4 = argv[4]; + if (arg4.constant && jl_is_symbol(arg4.constant)) + order = jl_get_atomic_order((jl_sym_t*)arg4.constant, true, false); + else + return false; + } + else + order = jl_memory_order_unordered; + + if (order < jl_memory_order_unordered) { + return false; + } + + if (!mod.constant || !sym.constant || !jl_is_symbol(sym.constant) || !jl_is_module(mod.constant)) { + return false; + } + + *ret = emit_isdefinedglobal(ctx, (jl_module_t*)mod.constant, (jl_sym_t*)sym.constant, allow_import, order); + return true; + } + else if (f == jl_builtin_isdefined && (nargs == 2 || nargs == 3)) { const jl_cgval_t &obj = argv[1]; const jl_cgval_t &fld = argv[2]; @@ -5205,14 +5345,12 @@ static CallInst *emit_jlcall(jl_codectx_t &ctx, JuliaFunction<> *theFptr, Value return emit_jlcall(ctx, prepare_call(theFptr), theF, argv, nargs, trampoline); } -static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_closure, jl_value_t *specTypes, jl_value_t *jlretty, jl_returninfo_t &returninfo, jl_code_instance_t *fromexternal, - ArrayRef argv, size_t nargs) +static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_closure, jl_value_t *specTypes, jl_value_t *jlretty, jl_returninfo_t &returninfo, ArrayRef argv, size_t nargs) { ++EmittedSpecfunCalls; // emit specialized call site bool gcstack_arg = JL_FEAT_TEST(ctx, gcstack_arg); - FunctionType *cft = returninfo.decl.getFunctionType(); - size_t nfargs = cft->getNumParams(); + size_t nfargs = returninfo.decl.getFunctionType()->getNumParams(); SmallVector argvals(nfargs); unsigned idx = 0; AllocaInst *result = nullptr; @@ -5304,23 +5442,7 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_clos idx++; } assert(idx == nfargs); - Value *TheCallee = returninfo.decl.getCallee(); - if (fromexternal) { - std::string namep("p"); - namep += cast(returninfo.decl.getCallee())->getName(); - GlobalVariable *GV = cast_or_null(jl_Module->getNamedValue(namep)); - if (GV == nullptr) { - GV = new GlobalVariable(*jl_Module, TheCallee->getType(), false, - GlobalVariable::ExternalLinkage, - Constant::getNullValue(TheCallee->getType()), - namep); - ctx.emission_context.external_fns[std::make_tuple(fromexternal, true)] = GV; - } - jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); - TheCallee = ai.decorateInst(ctx.builder.CreateAlignedLoad(TheCallee->getType(), GV, Align(sizeof(void*)))); - setName(ctx.emission_context, TheCallee, namep); - } - CallInst *call = ctx.builder.CreateCall(cft, TheCallee, argvals); + CallInst *call = ctx.builder.CreateCall(returninfo.decl, argvals); call->setAttributes(returninfo.attrs); if (gcstack_arg && ctx.emission_context.use_swiftcc) call->setCallingConv(CallingConv::Swift); @@ -5362,7 +5484,7 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_clos } static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_closure, jl_value_t *specTypes, jl_value_t *jlretty, llvm::Value *callee, StringRef specFunctionObject, jl_code_instance_t *fromexternal, - ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *nreturn_roots, jl_value_t *inferred_retty) + ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *nreturn_roots, jl_value_t *inferred_retty, Value *age_ok) { ++EmittedSpecfunCalls; // emit specialized call site @@ -5370,21 +5492,68 @@ static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, bool is_opaque_clos jl_returninfo_t returninfo = get_specsig_function(ctx, jl_Module, callee, specFunctionObject, specTypes, jlretty, is_opaque_closure, gcstack_arg); *cc = returninfo.cc; *nreturn_roots = returninfo.return_roots; - jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, specTypes, jlretty, returninfo, fromexternal, argv, nargs); + if (fromexternal) { + std::string namep("p"); + Value *TheCallee = returninfo.decl.getCallee(); + namep += cast(TheCallee)->getName(); + GlobalVariable *GV = cast_or_null(jl_Module->getNamedValue(namep)); + if (GV == nullptr) { + GV = new GlobalVariable(*jl_Module, TheCallee->getType(), false, + GlobalVariable::ExternalLinkage, + Constant::getNullValue(TheCallee->getType()), + namep); + ctx.emission_context.external_fns[std::make_tuple(fromexternal, true)] = GV; + } + jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const); + TheCallee = ai.decorateInst(ctx.builder.CreateAlignedLoad(TheCallee->getType(), GV, Align(sizeof(void*)))); + setName(ctx.emission_context, TheCallee, namep); + returninfo.decl = FunctionCallee(returninfo.decl.getFunctionType(), TheCallee); + } + if (age_ok) { + std::string funcName(specFunctionObject); + funcName += "_gfthunk"; + Function *gf_thunk = Function::Create(returninfo.decl.getFunctionType(), + GlobalVariable::InternalLinkage, funcName, jl_Module); + jl_init_function(gf_thunk, ctx.emission_context.TargetTriple); + gf_thunk->setAttributes(AttributeList::get(gf_thunk->getContext(), {returninfo.attrs, gf_thunk->getAttributes()})); + // build a specsig -> jl_apply_generic converter thunk + // this builds a method that calls jl_apply_generic (as a closure over a singleton function pointer), + // but which has the signature of a specsig + emit_specsig_to_fptr1(gf_thunk, returninfo.cc, returninfo.return_roots, specTypes, jlretty, is_opaque_closure, nargs, ctx.emission_context, + prepare_call(jlapplygeneric_func)); + returninfo.decl = FunctionCallee(returninfo.decl.getFunctionType(), ctx.builder.CreateSelect(age_ok, returninfo.decl.getCallee(), gf_thunk)); + } + jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, specTypes, jlretty, returninfo, argv, nargs); // see if inference has a different / better type for the call than the lambda return update_julia_type(ctx, retval, inferred_retty); } static jl_cgval_t emit_call_specfun_other(jl_codectx_t &ctx, jl_method_instance_t *mi, jl_value_t *jlretty, 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) + ArrayRef argv, size_t nargs, jl_returninfo_t::CallingConv *cc, unsigned *return_roots, jl_value_t *inferred_retty, Value *age_ok) { 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, mi->specTypes, jlretty, NULL, - specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty); + specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty, age_ok); +} + +static jl_value_t *get_ci_abi(jl_code_instance_t *ci) +{ + if (jl_typeof(ci->def) == (jl_value_t*)jl_abioverride_type) + return ((jl_abi_override_t*)ci->def)->abi; + return jl_get_ci_mi(ci)->specTypes; +} + +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), ci->rettype, NULL, + specFunctionObject, fromexternal, argv, nargs, cc, return_roots, inferred_retty, age_ok); } static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty, StringRef specFunctionObject, jl_code_instance_t *fromexternal, - ArrayRef argv, size_t nargs, jl_value_t *inferred_retty) + ArrayRef argv, size_t nargs, jl_value_t *inferred_retty, Value *age_ok) { Value *theFptr; if (fromexternal) { @@ -5407,6 +5576,8 @@ static jl_cgval_t emit_call_specfun_boxed(jl_codectx_t &ctx, jl_value_t *jlretty theFptr = jl_Module->getOrInsertFunction(specFunctionObject, ctx.types().T_jlfunc).getCallee(); addRetAttr(cast(theFptr), Attribute::NonNull); } + if (age_ok) + theFptr = ctx.builder.CreateSelect(age_ok, theFptr, prepare_call(jlapplygeneric_func)); Value *ret = emit_jlcall(ctx, FunctionCallee(ctx.types().T_jlfunc, theFptr), nullptr, argv, nargs, julia_call); return update_julia_type(ctx, mark_julia_type(ctx, ret, true, jlretty), inferred_retty); } @@ -5425,10 +5596,10 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt) if (argv[i].typ == jl_bottom_type) return jl_cgval_t(); } - return emit_invoke(ctx, lival, argv, nargs, rt); + return emit_invoke(ctx, lival, argv, nargs, rt, nullptr); } -static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt) +static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef argv, size_t nargs, jl_value_t *rt, Value *age_ok) { ++EmittedInvokes; bool handled = false; @@ -5442,23 +5613,28 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR else { ci = lival.constant; assert(jl_is_code_instance(ci)); - mi = ((jl_code_instance_t*)ci)->def; + mi = jl_get_ci_mi((jl_code_instance_t*)ci); } 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); - 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) { + 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 if (ft != ctx.types().T_jlfuncparams) { + else { unsigned return_roots = 0; - result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, nullptr, argv, nargs, &cc, &return_roots, rt); - handled = true; + 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; } else { if (ci) { @@ -5467,66 +5643,73 @@ 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 if (invoke != jl_fptr_sparam_addr) { + else { bool specsig, needsparams; - std::tie(specsig, needsparams) = uses_specsig(mi, codeinst->rettype, ctx.params->prefer_specsig); - std::string name; - StringRef protoname; - bool need_to_emit = true; - bool cache_valid = ctx.use_cache || ctx.external_linkage; - bool external = false; - - // Check if we already queued this up - auto it = ctx.call_targets.find(codeinst); - if (need_to_emit && it != ctx.call_targets.end()) { - assert(it->second.specsig == specsig); - protoname = it->second.decl->getName(); - need_to_emit = cache_valid = false; + std::tie(specsig, needsparams) = uses_specsig(get_ci_abi(codeinst), mi, codeinst->rettype, ctx.params->prefer_specsig); + if (needsparams) { + if (trim_may_error(ctx.params->trim)) + 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); } + else { + std::string name; + StringRef protoname; + bool need_to_emit = true; + bool cache_valid = ctx.use_cache || ctx.external_linkage; + bool external = false; + + // Check if we already queued this up + auto it = ctx.call_targets.find(codeinst); + if (need_to_emit && it != ctx.call_targets.end()) { + assert(it->second.specsig == specsig); + protoname = it->second.decl->getName(); + need_to_emit = cache_valid = false; + } - // Check if it is already compiled (either JIT or externally) - if (need_to_emit && cache_valid) { - // optimization: emit the correct name immediately, if we know it - // TODO: use `emitted` map here too to try to consolidate names? - uint8_t specsigflags; - jl_callptr_t invoke; - void *fptr; - jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); - if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) { - protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); - if (ctx.external_linkage) { - // TODO: Add !specsig support to aotcompile.cpp - // Check that the codeinst is containing native code - if (specsig && (specsigflags & 0b100)) { - external = true; + // Check if it is already compiled (either JIT or externally) + if (need_to_emit && cache_valid) { + // optimization: emit the correct name immediately, if we know it + // TODO: use `emitted` map here too to try to consolidate names? + uint8_t specsigflags; + jl_callptr_t invoke; + void *fptr; + jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); + if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) { + protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); + if (ctx.external_linkage) { + // TODO: Add !specsig support to aotcompile.cpp + // Check that the codeinst is containing native code + if (specsig && (specsigflags & 0b100)) { + external = true; + need_to_emit = false; + } + } + else { // ctx.use_cache need_to_emit = false; } } - else { // ctx.use_cache - need_to_emit = false; - } } - } - if (need_to_emit) { - raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1); - protoname = StringRef(name); - } - jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; - unsigned return_roots = 0; - if (specsig) - result = emit_call_specfun_other(ctx, mi, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt); - else - result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt); - 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}; - if (trim_may_error(ctx.params->trim)) - push_frames(ctx, ctx.linfo, mi); + if (need_to_emit) { + raw_string_ostream(name) << (specsig ? "j_" : "j1_") << name_from_method_instance(mi) << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1); + protoname = StringRef(name); + } + jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed; + unsigned return_roots = 0; + if (specsig) + 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) { + Function *trampoline_decl = cast(jl_Module->getNamedValue(protoname)); + ctx.call_targets[codeinst] = {cc, return_roots, trampoline_decl, nullptr, specsig}; + if (trim_may_error(ctx.params->trim)) + push_frames(ctx, ctx.linfo, mi); + } } } + handled = true; } } } @@ -5542,8 +5725,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR print_stacktrace(ctx, ctx.params->trim); } } - Value *r = emit_jlcall(ctx, jlinvoke_func, boxed(ctx, lival), argv, nargs, julia_call2); - result = mark_julia_type(ctx, r, true, rt); + Value *r = age_ok ? emit_jlcall(ctx, jlapplygeneric_func, nullptr, argv, nargs, julia_call) : emit_jlcall(ctx, jlinvoke_func, boxed(ctx, lival), argv, nargs, julia_call2); + result = mark_julia_type(ctx, r, true, age_ok ? (jl_value_t*)jl_any_type : rt); } if (result.typ == jl_bottom_type) { #ifndef JL_NDEBUG @@ -5636,7 +5819,7 @@ static jl_cgval_t emit_specsig_oc_call(jl_codectx_t &ctx, jl_value_t *oc_type, j Value *specptr = emit_unbox(ctx, ctx.types().T_size, closure_specptr, (jl_value_t*)jl_long_type); JL_GC_PUSH1(&sigtype); jl_cgval_t r = emit_call_specfun_other(ctx, true, sigtype, oc_rett, specptr, "", NULL, argv, nargs, - &cc, &return_roots, oc_rett); + &cc, &return_roots, oc_rett, nullptr); JL_GC_POP(); return r; } @@ -5907,8 +6090,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"); @@ -5960,46 +6142,13 @@ 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)); } else { - jl_module_t *modu; - jl_sym_t *name; - if (jl_is_globalref(sym)) { - modu = jl_globalref_mod(sym); - name = jl_globalref_name(sym); - } - else { - assert(jl_is_symbol(sym) && "malformed isdefined expression"); - modu = ctx.module; - name = (jl_sym_t*)sym; - } - jl_binding_t *bnd = allow_import ? jl_get_binding(modu, name) : jl_get_module_binding(modu, name, 0); - jl_binding_partition_t *bpart = jl_get_binding_partition_all(bnd, ctx.min_world, ctx.max_world); - jl_ptr_kind_union_t pku = bpart ? jl_atomic_load_relaxed(&bpart->restriction) : encode_restriction(NULL, BINDING_KIND_GUARD); - if (decode_restriction_kind(pku) == BINDING_KIND_GLOBAL || jl_bkind_is_some_constant(decode_restriction_kind(pku))) { - if (jl_get_binding_value_if_const(bnd)) - return mark_julia_const(ctx, jl_true); - Value *bp = julia_binding_gv(ctx, bnd); - bp = julia_binding_pvalue(ctx, bp); - LoadInst *v = ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))); - jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_binding); - ai.decorateInst(v); - v->setOrdering(AtomicOrdering::Unordered); - isnull = ctx.builder.CreateICmpNE(v, Constant::getNullValue(ctx.types().T_prjlvalue)); - } - else { - Value *v = ctx.builder.CreateCall(prepare_call(jlboundp_func), { - literal_pointer_val(ctx, (jl_value_t*)modu), - literal_pointer_val(ctx, (jl_value_t*)name), - ConstantInt::get(getInt32Ty(ctx.builder.getContext()), allow_import) - }); - isnull = ctx.builder.CreateICmpNE(v, ConstantInt::get(getInt32Ty(ctx.builder.getContext()), 0)); - } + assert(false && "malformed expression"); } return mark_julia_type(ctx, isnull, false, jl_bool_type); } @@ -6679,7 +6828,7 @@ static void emit_latestworld(jl_codectx_t &ctx) (void)store_world; } -// `expr` is not clobbered in JL_TRY +// `expr` is not actually clobbered in JL_TRY JL_GCC_IGNORE_START("-Wclobbered") static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_0based) { @@ -7189,8 +7338,7 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M name, M); jl_init_function(f, params.TargetTriple); if (trim_may_error(params.params->trim)) { - // TODO: Debuginfo! - push_frames(ctx, ctx.linfo, codeinst->def, 1); + push_frames(ctx, ctx.linfo, jl_get_ci_mi(codeinst)); } jl_name_jlfunc_args(params, f); //f->setAlwaysInline(); @@ -7206,8 +7354,10 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst); } else { - theFunc = prepare_call(jlinvoke_func); - theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst->def); + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); + bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; + theFunc = prepare_call(is_opaque_closure ? jlinvokeoc_func : jlinvoke_func); + theFarg = literal_pointer_val(ctx, (jl_value_t*)mi); } theFarg = track_pjlvalue(ctx, theFarg); auto args = f->arg_begin(); @@ -7232,11 +7382,10 @@ void emit_specsig_to_fptr1( jl_value_t *calltype, jl_value_t *rettype, bool is_for_opaque_closure, size_t nargs, jl_codegen_params_t ¶ms, - Function *target, - size_t min_world, size_t max_world) + Function *target) { ++EmittedCFuncInvalidates; - jl_codectx_t ctx(gf_thunk->getParent()->getContext(), params, min_world, max_world); + jl_codectx_t ctx(gf_thunk->getParent()->getContext(), params, 0, 0); ctx.f = gf_thunk; BasicBlock *b0 = BasicBlock::Create(ctx.builder.getContext(), "top", gf_thunk); @@ -7353,12 +7502,11 @@ void emit_specsig_to_fptr1( } } -static Function* gen_cfun_wrapper( +static Function *gen_cfun_wrapper( Module *into, jl_codegen_params_t ¶ms, const function_sig_t &sig, jl_value_t *ff, const char *aliasname, jl_value_t *declrt, jl_method_instance_t *lam, - jl_unionall_t *unionall_env, jl_svec_t *sparam_vals, jl_array_t **closure_types, - size_t min_world, size_t max_world) + jl_unionall_t *unionall_env, jl_svec_t *sparam_vals, jl_array_t **closure_types) { ++GeneratedCFuncWrappers; // Generate a c-callable wrapper @@ -7366,37 +7514,19 @@ static Function* gen_cfun_wrapper( size_t nargs = sig.nccallargs; const char *name = "cfunction"; size_t world = jl_atomic_load_acquire(&jl_world_counter); - jl_code_instance_t *codeinst = NULL; bool nest = (!ff || unionall_env); jl_value_t *astrt = (jl_value_t*)jl_any_type; - void *callptr = NULL; - jl_callptr_t invoke = NULL; - int calltype = 0; if (aliasname) name = aliasname; else if (lam) name = jl_symbol_name(lam->def.method->name); - if (lam && params.cache) { - // TODO: this isn't ideal to be unconditionally calling type inference (and compile) from here - codeinst = jl_compile_method_internal(lam, world); - uint8_t specsigflags; - void *fptr; - jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); - assert(invoke); - if (invoke == jl_fptr_args_addr) { - callptr = fptr; - calltype = 1; - } - else if (invoke == jl_fptr_const_return_addr) { - // don't need the fptr - callptr = (void*)codeinst->rettype_const; - calltype = 2; - } - else if (specsigflags & 0b1) { - callptr = fptr; - calltype = 3; - } - astrt = codeinst->rettype; + + jl_code_instance_t *codeinst = NULL; + if (lam) { + // TODO: this isn't ideal to be unconditionally calling type inference from here + codeinst = jl_type_infer(lam, world, SOURCE_MODE_NOT_REQUIRED); + if (codeinst) + astrt = codeinst->rettype; if (astrt != (jl_value_t*)jl_bottom_type && jl_type_intersection(astrt, declrt) == jl_bottom_type) { // Do not warn if the function never returns since it is @@ -7471,7 +7601,7 @@ static Function* gen_cfun_wrapper( jl_init_function(cw, params.TargetTriple); cw->setAttributes(AttributeList::get(M->getContext(), {attributes, cw->getAttributes()})); - jl_codectx_t ctx(M->getContext(), params, min_world, max_world); + jl_codectx_t ctx(M->getContext(), params, 0, 0); ctx.f = cw; ctx.name = name; ctx.funcName = name; @@ -7490,8 +7620,8 @@ static Function* gen_cfun_wrapper( prepare_global_in(jl_Module, jlgetworld_global), ctx.types().alignof_ptr); cast(world_v)->setOrdering(AtomicOrdering::Acquire); - Value *age_ok = NULL; - if (calltype) { + Value *age_ok = nullptr; + if (codeinst) { LoadInst *lam_max = ctx.builder.CreateAlignedLoad( ctx.types().T_size, emit_ptrgep(ctx, literal_pointer_val(ctx, (jl_value_t*)codeinst), offsetof(jl_code_instance_t, max_world)), @@ -7655,79 +7785,9 @@ static Function* gen_cfun_wrapper( // Create the call bool jlfunc_sret; jl_cgval_t retval; - if (calltype == 2) { - nargs = 0; // arguments not needed -- TODO: not really true, should emit an age_ok test and jlcall - (void)nargs; // silence unused variable warning - jlfunc_sret = false; - retval = mark_julia_const(ctx, (jl_value_t*)callptr); - } - else if (calltype == 0 || calltype == 1) { - // emit a jlcall - jlfunc_sret = false; - Function *theFptr = NULL; - if (calltype == 1) { - StringRef fname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)callptr, invoke, codeinst); - theFptr = cast_or_null(jl_Module->getNamedValue(fname)); - if (!theFptr) { - theFptr = Function::Create(ctx.types().T_jlfunc, GlobalVariable::ExternalLinkage, - fname, jl_Module); - jl_init_function(theFptr, ctx.emission_context.TargetTriple); - jl_name_jlfunc_args(ctx.emission_context, theFptr); - addRetAttr(theFptr, Attribute::NonNull); - } - else { - assert(theFptr->getFunctionType() == ctx.types().T_jlfunc); - } - } - BasicBlock *b_generic, *b_jlcall, *b_after; - Value *ret_jlcall; - if (age_ok) { - assert(theFptr); - b_generic = BasicBlock::Create(ctx.builder.getContext(), "generic", cw); - b_jlcall = BasicBlock::Create(ctx.builder.getContext(), "apply", cw); - b_after = BasicBlock::Create(ctx.builder.getContext(), "after", cw); - ctx.builder.CreateCondBr(age_ok, b_jlcall, b_generic); - ctx.builder.SetInsertPoint(b_jlcall); - // for jlcall, we need to pass the function object even if it is a ghost. - Value *theF = boxed(ctx, inputargs[0]); - assert(theF); - ret_jlcall = emit_jlcall(ctx, theFptr, theF, ArrayRef(inputargs).drop_front(), nargs, julia_call); - ctx.builder.CreateBr(b_after); - ctx.builder.SetInsertPoint(b_generic); - } - Value *ret = emit_jlcall(ctx, jlapplygeneric_func, NULL, inputargs, nargs + 1, julia_call); - if (age_ok) { - ctx.builder.CreateBr(b_after); - ctx.builder.SetInsertPoint(b_after); - PHINode *retphi = ctx.builder.CreatePHI(ctx.types().T_prjlvalue, 2); - retphi->addIncoming(ret_jlcall, b_jlcall); - retphi->addIncoming(ret, b_generic); - ret = retphi; - } - retval = mark_julia_type(ctx, ret, true, astrt); - } - else { - bool is_opaque_closure = jl_is_method(lam->def.value) && lam->def.method->is_for_opaque_closure; - assert(calltype == 3); - // emit a specsig call - StringRef protoname = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)callptr, invoke, codeinst); - bool gcstack_arg = JL_FEAT_TEST(ctx, gcstack_arg); - jl_returninfo_t returninfo = get_specsig_function(ctx, M, NULL, protoname, lam->specTypes, astrt, is_opaque_closure, gcstack_arg); - if (age_ok) { - funcName += "_gfthunk"; - Function *gf_thunk = Function::Create(returninfo.decl.getFunctionType(), - GlobalVariable::InternalLinkage, funcName, M); - jl_init_function(gf_thunk, ctx.emission_context.TargetTriple); - gf_thunk->setAttributes(AttributeList::get(M->getContext(), {returninfo.attrs, gf_thunk->getAttributes()})); - // build a specsig -> jl_apply_generic converter thunk - // this builds a method that calls jl_apply_generic (as a closure over a singleton function pointer), - // but which has the signature of a specsig - emit_specsig_to_fptr1(gf_thunk, returninfo.cc, returninfo.return_roots, lam->specTypes, codeinst->rettype, is_opaque_closure, nargs + 1, ctx.emission_context, - prepare_call_in(gf_thunk->getParent(), jlapplygeneric_func), min_world, max_world); - returninfo.decl = FunctionCallee(returninfo.decl.getFunctionType(), ctx.builder.CreateSelect(age_ok, returninfo.decl.getCallee(), gf_thunk)); - } - retval = emit_call_specfun_other(ctx, is_opaque_closure, lam->specTypes, codeinst->rettype, returninfo, nullptr, inputargs, nargs + 1); - jlfunc_sret = (returninfo.cc == jl_returninfo_t::SRet); + if (codeinst) { + retval = emit_invoke(ctx, mark_julia_const(ctx, (jl_value_t*)codeinst), inputargs, nargs + 1, astrt, age_ok); + jlfunc_sret = retval.V && isa(retval.V) && !retval.TIndex && retval.inline_roots.empty(); if (jlfunc_sret && sig.sret) { // fuse the two sret together assert(retval.ispointer()); @@ -7737,6 +7797,12 @@ static Function* gen_cfun_wrapper( result->eraseFromParent(); } } + else { + // emit a dispatch + jlfunc_sret = false; + Value *ret = emit_jlcall(ctx, jlapplygeneric_func, NULL, inputargs, nargs + 1, julia_call); + retval = mark_julia_type(ctx, ret, true, astrt); + } // inline a call to typeassert here, if required emit_typecheck(ctx, retval, declrt, "cfunction"); @@ -7909,15 +7975,13 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con } } size_t world = jl_atomic_load_acquire(&jl_world_counter); - size_t min_valid = 0; - size_t max_valid = ~(size_t)0; // try to look up this function for direct invoking - jl_method_instance_t *lam = sigt ? jl_get_specialization1((jl_tupletype_t*)sigt, world, &min_valid, &max_valid, 0) : NULL; + jl_method_instance_t *lam = sigt ? jl_get_specialization1((jl_tupletype_t*)sigt, world, 0) : NULL; Value *F = gen_cfun_wrapper( jl_Module, ctx.emission_context, sig, fexpr_rt.constant, NULL, declrt, lam, - unionall_env, sparam_vals, &closure_types, min_valid, max_valid); + unionall_env, sparam_vals, &closure_types); bool outboxed; if (nest) { // F is actually an init_trampoline function that returns the real address @@ -7946,7 +8010,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; } @@ -7977,7 +8041,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con // do codegen to create a C-callable alias/wrapper, or if sysimg_handle is set, // restore one from a loaded system image. -const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms) +const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms) { ++GeneratedCCallables; jl_datatype_t *ft = (jl_datatype_t*)jl_tparam0(sigt); @@ -8006,8 +8070,6 @@ const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysi argtypes, NULL, false, CallingConv::C, false, ¶ms); if (sig.err_msg.empty()) { size_t world = jl_atomic_load_acquire(&jl_world_counter); - size_t min_valid = 0; - size_t max_valid = ~(size_t)0; if (sysimg_handle) { // restore a ccallable from the system image void *addr; @@ -8020,9 +8082,9 @@ const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysi } } else { - jl_method_instance_t *lam = jl_get_specialization1((jl_tupletype_t*)sigt, world, &min_valid, &max_valid, 0); + jl_method_instance_t *lam = jl_get_specialization1((jl_tupletype_t*)sigt, world, 0); //Safe b/c params holds context lock - gen_cfun_wrapper(unwrap(llvmmod)->getModuleUnlocked(), params, sig, ff, name, declrt, lam, NULL, NULL, NULL, min_valid, max_valid); + gen_cfun_wrapper(llvmmod, params, sig, ff, name, declrt, lam, NULL, NULL, NULL); } JL_GC_POP(); return name; @@ -8034,7 +8096,7 @@ const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysi // generate a julia-callable function that calls f (AKA lam) // if is_opaque_closure, then generate the OC invoke, rather than a real invoke -static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, jl_returninfo_t &f, unsigned nargs, int retarg, bool is_opaque_closure, StringRef funcName, +static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *abi, jl_value_t *jlretty, jl_returninfo_t &f, unsigned nargs, int retarg, bool is_opaque_closure, StringRef funcName, Module *M, jl_codegen_params_t ¶ms) { ++GeneratedInvokeWrappers; @@ -8070,7 +8132,7 @@ static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, j argv[i] = mark_julia_slot(funcArg, oc_type, NULL, ctx.tbaa().tbaa_const); continue; } - jl_value_t *ty = jl_nth_slot_type(lam->specTypes, i); + jl_value_t *ty = jl_nth_slot_type(abi, i); Value *theArg; if (i == 0) { theArg = funcArg; @@ -8084,7 +8146,7 @@ static void gen_invoke_wrapper(jl_method_instance_t *lam, jl_value_t *jlretty, j } argv[i] = mark_julia_type(ctx, theArg, true, ty); } - jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, lam->specTypes, jlretty, f, nullptr, argv, nargs); + jl_cgval_t retval = emit_call_specfun_other(ctx, is_opaque_closure, abi, jlretty, f, argv, nargs); if (retarg != -1) { Value *theArg; if (retarg == 0) @@ -8316,13 +8378,13 @@ get_specsig_di(jl_codectx_t &ctx, jl_debugcache_t &debuginfo, jl_value_t *rt, jl } /* aka Core.Compiler.tuple_tfunc */ -static jl_datatype_t *compute_va_type(jl_method_instance_t *lam, size_t nreq) +static jl_datatype_t *compute_va_type(jl_value_t *sig, size_t nreq) { - size_t nvargs = jl_nparams(lam->specTypes)-nreq; + size_t nvargs = jl_nparams(sig)-nreq; jl_svec_t *tupargs = jl_alloc_svec(nvargs); JL_GC_PUSH1(&tupargs); - for (size_t i = nreq; i < jl_nparams(lam->specTypes); ++i) { - jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); + for (size_t i = nreq; i < jl_nparams(sig); ++i) { + jl_value_t *argType = jl_nth_slot_type(sig, i); // n.b. specTypes is required to be a datatype by construction for specsig if (is_uniquerep_Type(argType)) argType = jl_typeof(jl_tparam0(argType)); @@ -8362,6 +8424,7 @@ static jl_llvm_functions_t orc::ThreadSafeModule &TSM, jl_method_instance_t *lam, jl_code_info_t *src, + jl_value_t *abi, jl_value_t *jlrettype, jl_codegen_params_t ¶ms) { @@ -8440,7 +8503,7 @@ static jl_llvm_functions_t 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); ctx.slots.resize(vinfoslen, jl_varinfo_t(ctx.builder.getContext())); - assert(lam->specTypes); // the specTypes field should always be assigned + assert(abi); // the specTypes field should always be assigned // create SAvalue locations for SSAValue objects @@ -8449,7 +8512,7 @@ static jl_llvm_functions_t ctx.ssavalue_usecount.assign(n_ssavalues, 0); bool specsig, needsparams; - std::tie(specsig, needsparams) = uses_specsig(lam, jlrettype, params.params->prefer_specsig); + std::tie(specsig, needsparams) = uses_specsig(abi, lam, jlrettype, params.params->prefer_specsig); // step 3. some variable analysis size_t i; @@ -8459,7 +8522,7 @@ static jl_llvm_functions_t jl_sym_t *argname = slot_symbol(ctx, i); if (argname == jl_unused_sym) continue; - jl_value_t *ty = jl_nth_slot_type(lam->specTypes, i); + jl_value_t *ty = jl_nth_slot_type(abi, i); // TODO: jl_nth_slot_type should call jl_rewrap_unionall // specTypes is required to be a datatype by construction for specsig, but maybe not otherwise // OpaqueClosure implicitly loads the env @@ -8477,7 +8540,7 @@ static jl_llvm_functions_t if (va && ctx.vaSlot != -1) { jl_varinfo_t &varinfo = ctx.slots[ctx.vaSlot]; varinfo.isArgument = true; - vatyp = specsig ? compute_va_type(lam, nreq) : (jl_tuple_type); + vatyp = specsig ? compute_va_type(abi, nreq) : (jl_tuple_type); varinfo.value = mark_julia_type(ctx, (Value*)NULL, false, vatyp); } @@ -8528,7 +8591,7 @@ static jl_llvm_functions_t ArgNames[i] = name; } } - returninfo = get_specsig_function(ctx, M, NULL, declarations.specFunctionObject, lam->specTypes, + returninfo = get_specsig_function(ctx, M, NULL, declarations.specFunctionObject, abi, jlrettype, ctx.is_opaque_closure, JL_FEAT_TEST(ctx,gcstack_arg), ArgNames, nreq); f = cast(returninfo.decl.getCallee()); @@ -8562,8 +8625,8 @@ static jl_llvm_functions_t std::string wrapName; raw_string_ostream(wrapName) << "jfptr_" << ctx.name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1); declarations.functionObject = wrapName; - size_t nparams = jl_nparams(lam->specTypes); - gen_invoke_wrapper(lam, jlrettype, returninfo, nparams, retarg, ctx.is_opaque_closure, declarations.functionObject, M, ctx.emission_context); + size_t nparams = jl_nparams(abi); + gen_invoke_wrapper(lam, abi, jlrettype, returninfo, nparams, retarg, ctx.is_opaque_closure, declarations.functionObject, M, ctx.emission_context); // TODO: add attributes: maybe_mark_argument_dereferenceable(Arg, argType) // TODO: add attributes: dereferenceable // TODO: (if needsparams) add attributes: dereferenceable, readonly, nocapture @@ -8585,7 +8648,7 @@ static jl_llvm_functions_t if (!params.getContext().shouldDiscardValueNames() && ctx.emission_context.params->debug_info_level >= 2 && lam->def.method && jl_is_method(lam->def.method) && lam->specTypes != (jl_value_t*)jl_emptytuple_type) { ios_t sigbuf; ios_mem(&sigbuf, 0); - jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)lam->specTypes); + jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)abi); f->addFnAttr("julia.fsig", StringRef(sigbuf.buf, sigbuf.size)); ios_close(&sigbuf); } @@ -8642,7 +8705,7 @@ static jl_llvm_functions_t else if (!specsig) subrty = debugcache.jl_di_func_sig; else - subrty = get_specsig_di(ctx, debugcache, jlrettype, lam->specTypes, dbuilder); + subrty = get_specsig_di(ctx, debugcache, jlrettype, abi, dbuilder); SP = dbuilder.createFunction(nullptr ,dbgFuncName // Name ,f->getName() // LinkageName @@ -8922,6 +8985,8 @@ static jl_llvm_functions_t Type *RT = Arg->getParamStructRetType(); TypeSize sz = DL.getTypeAllocSize(RT); Align al = DL.getPrefTypeAlign(RT); + if (al > MAX_ALIGN) + al = Align(MAX_ALIGN); param.addAttribute(Attribute::NonNull); // The `dereferenceable` below does not imply `nonnull` for non addrspace(0) pointers. param.addDereferenceableAttr(sz); @@ -8974,7 +9039,7 @@ static jl_llvm_functions_t nullptr, nullptr, /*isboxed*/true, AtomicOrdering::NotAtomic, false, sizeof(void*)); } else { - jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); + jl_value_t *argType = jl_nth_slot_type(abi, i); // TODO: jl_nth_slot_type should call jl_rewrap_unionall? // specTypes is required to be a datatype by construction for specsig, but maybe not otherwise bool isboxed = deserves_argbox(argType); @@ -9048,10 +9113,10 @@ static jl_llvm_functions_t assert(vi.boxroot == NULL); } else if (specsig) { - ctx.nvargs = jl_nparams(lam->specTypes) - nreq; + ctx.nvargs = jl_nparams(abi) - nreq; SmallVector vargs(ctx.nvargs); - for (size_t i = nreq; i < jl_nparams(lam->specTypes); ++i) { - jl_value_t *argType = jl_nth_slot_type(lam->specTypes, i); + for (size_t i = nreq; i < jl_nparams(abi); ++i) { + jl_value_t *argType = jl_nth_slot_type(abi, i); // n.b. specTypes is required to be a datatype by construction for specsig bool isboxed = deserves_argbox(argType); Type *llvmArgType = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, argType); @@ -9970,13 +10035,12 @@ static jl_llvm_functions_t // --- entry point --- -void jl_add_code_in_flight(StringRef name, jl_code_instance_t *codeinst, const DataLayout &DL); - -JL_GCC_IGNORE_START("-Wclobbered") jl_llvm_functions_t jl_emit_code( orc::ThreadSafeModule &m, jl_method_instance_t *li, jl_code_info_t *src, + jl_value_t *abi_at, + jl_value_t *abi_rt, jl_codegen_params_t ¶ms) { JL_TIMING(CODEGEN, CODEGEN_LLVM); @@ -9986,7 +10050,7 @@ jl_llvm_functions_t jl_emit_code( compare_cgparams(params.params, &jl_default_cgparams)) && "functions compiled with custom codegen params must not be cached"); JL_TRY { - decls = emit_function(m, li, src, 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()); @@ -10015,15 +10079,6 @@ jl_llvm_functions_t jl_emit_code( return decls; } -static int effects_foldable(uint32_t effects) -{ - // N.B.: This needs to be kept in sync with Core.Compiler.is_foldable(effects, true) - return ((effects & 0x7) == 0) && // is_consistent(effects) - (((effects >> 10) & 0x03) == 0) && // is_noub(effects) - (((effects >> 3) & 0x03) == 0) && // is_effect_free(effects) - ((effects >> 6) & 0x01); // is_terminates(effects) -} - static jl_llvm_functions_t jl_emit_oc_wrapper(orc::ThreadSafeModule &m, jl_codegen_params_t ¶ms, jl_method_instance_t *mi, jl_value_t *rettype) { jl_llvm_functions_t declarations; @@ -10040,8 +10095,7 @@ static jl_llvm_functions_t jl_emit_oc_wrapper(orc::ThreadSafeModule &m, jl_codeg size_t nrealargs = jl_nparams(mi->specTypes); emit_specsig_to_fptr1(gf_thunk, returninfo.cc, returninfo.return_roots, mi->specTypes, rettype, true, nrealargs, ctx.emission_context, - prepare_call_in(gf_thunk->getParent(), jlopaque_closure_call_func), // TODO: this could call emit_oc_call directly - ctx.min_world, ctx.max_world); + prepare_call_in(gf_thunk->getParent(), jlopaque_closure_call_func)); // TODO: this could call emit_oc_call directly declarations.specFunctionObject = funcName; } return declarations; @@ -10054,89 +10108,20 @@ jl_llvm_functions_t jl_emit_codeinst( jl_codegen_params_t ¶ms) { JL_TIMING(CODEGEN, CODEGEN_Codeinst); - jl_timing_show_method_instance(codeinst->def, JL_TIMING_DEFAULT_BLOCK); - JL_GC_PUSH1(&src); + jl_timing_show_method_instance(jl_get_ci_mi(codeinst), JL_TIMING_DEFAULT_BLOCK); if (!src) { - src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred); - jl_method_instance_t *mi = codeinst->def; - jl_method_t *def = mi->def.method; - // Check if this is the generic method for opaque closure wrappers - - // if so, this must compile specptr such that it holds the specptr -> invoke wrapper + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); + // Assert that this this is the generic method for opaque closure wrappers: + // this signals to instead compile specptr such that it holds the specptr -> invoke wrapper // to satisfy the dispatching implementation requirements of jl_f_opaque_closure_call - if (def == jl_opaque_closure_method) { - JL_GC_POP(); + if (mi->def.method == jl_opaque_closure_method) { return jl_emit_oc_wrapper(m, params, mi, codeinst->rettype); } - if (src && (jl_value_t*)src != jl_nothing && jl_is_method(def)) - src = jl_uncompress_ir(def, codeinst, (jl_value_t*)src); - if (!src || !jl_is_code_info(src)) { - JL_GC_POP(); - m = orc::ThreadSafeModule(); - return jl_llvm_functions_t(); // failed - } - } - 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, codeinst->def, src, params); - - const std::string &specf = decls.specFunctionObject; - const std::string &f = decls.functionObject; - if (params.cache && !f.empty()) { - // Prepare debug info to receive this function - // record that this function name came from this linfo, - // so we can build a reverse mapping for debug-info. - bool toplevel = !jl_is_method(codeinst->def->def.method); - if (!toplevel) { - //Safe b/c params holds context lock - const DataLayout &DL = m.getModuleUnlocked()->getDataLayout(); - // but don't remember toplevel thunks because - // they may not be rooted in the gc for the life of the program, - // and the runtime doesn't notify us when the code becomes unreachable :( - if (!specf.empty()) - jl_add_code_in_flight(specf, codeinst, DL); - if (!f.empty() && f != "jl_fptr_args" && f != "jl_fptr_sparam") - jl_add_code_in_flight(f, codeinst, DL); - } - - jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred); - // don't change inferred state - if (inferred) { - jl_method_t *def = codeinst->def->def.method; - if (// keep code when keeping everything - !(JL_DELETE_NON_INLINEABLE) || - // aggressively keep code when debugging level >= 2 - // note that this uses the global jl_options.debug_level, not the local emission_ctx.debug_info_level - jl_options.debug_level > 1) { - // update the stored code - if (inferred != (jl_value_t*)src) { - // TODO: it is somewhat unclear what it means to be mutating this - if (jl_is_method(def)) { - src = (jl_code_info_t*)jl_compress_ir(def, src); - assert(jl_is_string(src)); - codeinst->relocatability = jl_string_data(src)[jl_string_len(src)-1]; - } - jl_atomic_store_release(&codeinst->inferred, (jl_value_t*)src); - jl_gc_wb(codeinst, src); - } - } - // delete non-inlineable code, since it won't be needed again - // because we already emitted LLVM code from it and the native - // Julia-level optimization will never need to see it - else if (jl_is_method(def) && // don't delete toplevel code - def->source != NULL && // don't delete code from optimized opaque closures that can't be reconstructed - inferred != jl_nothing && // and there is something to delete (test this before calling jl_ir_inlining_cost) - !effects_foldable(jl_atomic_load_relaxed(&codeinst->ipo_purity_bits)) && // don't delete code we may want for irinterp - ((jl_ir_inlining_cost(inferred) == UINT16_MAX) || // don't delete inlineable code - jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr) && // unless it is constant - !(params.imaging_mode || jl_options.incremental)) { // don't delete code when generating a precompile file - // Never end up in a situation where the codeinst has no invoke, but also no source, so we never fall - // through the cracks of SOURCE_MODE_ABI. - jl_callptr_t expected = NULL; - jl_atomic_cmpswap_relaxed(&codeinst->invoke, &expected, jl_fptr_wait_for_compiled_addr); - jl_atomic_store_release(&codeinst->inferred, jl_nothing); - } - } + m = orc::ThreadSafeModule(); + return jl_llvm_functions_t(); // user error } - JL_GC_POP(); + //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), codeinst->rettype, params); return decls; } @@ -10220,6 +10205,7 @@ static void init_jit_functions(void) add_named_global(jltypeassert_func, &jl_typeassert); add_named_global(jlapplytype_func, &jl_instantiate_type_in_env); add_named_global(jl_object_id__func, &jl_object_id_); + add_named_global(jl_alloc_genericmemory_unchecked_func, &jl_alloc_genericmemory_unchecked); add_named_global(jl_alloc_obj_func, (void*)NULL); add_named_global(jl_newbits_func, (void*)jl_new_bits); add_named_global(jl_typeof_func, (void*)NULL); diff --git a/src/datatype.c b/src/datatype.c index c78b00fdd2245..fd25cca503676 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -769,6 +769,8 @@ void jl_compute_field_offsets(jl_datatype_t *st) if (al > alignm) alignm = al; } + if (alignm > MAX_ALIGN) + alignm = MAX_ALIGN; // We cannot guarantee alignments over 16 bytes because that's what our heap is aligned as if (LLT_ALIGN(sz, alignm) > sz) { haspadding = 1; sz = LLT_ALIGN(sz, alignm); diff --git a/src/debug-registry.h b/src/debug-registry.h index 4d0b7a44f19e5..72189c60d3d40 100644 --- a/src/debug-registry.h +++ b/src/debug-registry.h @@ -14,7 +14,7 @@ typedef struct { int64_t slide; } objfileentry_t; -// Central registry for resolving function addresses to `jl_method_instance_t`s and +// Central registry for resolving function addresses to `jl_code_instance_t`s and // originating `ObjectFile`s (for the DWARF debug info). // // A global singleton instance is notified by the JIT whenever a new object is emitted, @@ -82,7 +82,7 @@ class JITDebugInfoRegistry struct image_info_t { uint64_t base; jl_image_fptrs_t fptrs; - jl_method_instance_t **fvars_linfo; + jl_code_instance_t **fvars_cinst; size_t fvars_n; }; @@ -124,7 +124,7 @@ class JITDebugInfoRegistry typedef rev_map objfilemap_t; objectmap_t objectmap{}; - rev_map> linfomap{}; + rev_map> cimap{}; // Maintain a mapping of unrealized function names -> linfo objects // so that when we see it get emitted, we can add a link back to the linfo @@ -145,7 +145,7 @@ class JITDebugInfoRegistry libc_frames_t libc_frames{}; void add_code_in_flight(llvm::StringRef name, jl_code_instance_t *codeinst, const llvm::DataLayout &DL) JL_NOTSAFEPOINT; - jl_method_instance_t *lookupLinfo(size_t pointer) JL_NOTSAFEPOINT; + jl_code_instance_t *lookupCodeInstance(size_t pointer) JL_NOTSAFEPOINT; void registerJITObject(const llvm::object::ObjectFile &Object, std::function getLoadAddress) JL_NOTSAFEPOINT; objectmap_t& getObjectMap() JL_NOTSAFEPOINT; diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 31f1ba8281a89..17e093cecb89a 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -94,12 +94,12 @@ void JITDebugInfoRegistry::add_code_in_flight(StringRef name, jl_code_instance_t (**codeinst_in_flight)[mangle(name, DL)] = codeinst; } -jl_method_instance_t *JITDebugInfoRegistry::lookupLinfo(size_t pointer) +jl_code_instance_t *JITDebugInfoRegistry::lookupCodeInstance(size_t pointer) { jl_lock_profile(); - auto region = linfomap.lower_bound(pointer); - jl_method_instance_t *linfo = NULL; - if (region != linfomap.end() && pointer < region->first + region->second.first) + auto region = cimap.lower_bound(pointer); + jl_code_instance_t *linfo = NULL; + if (region != cimap.end() && pointer < region->first + region->second.first) linfo = region->second.second; jl_unlock_profile(); return linfo; @@ -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 = codeinst->def; - if (jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure) + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); + 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); } @@ -371,14 +375,9 @@ void JITDebugInfoRegistry::registerJITObject(const object::ObjectFile &Object, codeinst_in_flight.erase(codeinst_it); } } - jl_method_instance_t *mi = NULL; - if (codeinst) { - JL_GC_PROMISE_ROOTED(codeinst); - mi = codeinst->def; - } jl_profile_atomic([&]() JL_NOTSAFEPOINT { - if (mi) - linfomap[Addr] = std::make_pair(Size, mi); + if (codeinst) + cimap[Addr] = std::make_pair(Size, codeinst); hassection = true; objectmap.insert(std::pair{SectionLoadAddr, SectionInfo{ ObjectCopy, @@ -506,7 +505,7 @@ static int lookup_pointer( std::size_t semi_pos = func_name.find(';'); if (semi_pos != std::string::npos) { func_name = func_name.substr(0, semi_pos); - frame->linfo = NULL; // Looked up on Julia side + frame->ci = NULL; // Looked up on Julia side } } } @@ -692,9 +691,9 @@ openDebugInfo(StringRef debuginfopath, const debug_link_info &info) JL_NOTSAFEPO } extern "C" JL_DLLEXPORT_CODEGEN void jl_register_fptrs_impl(uint64_t image_base, const jl_image_fptrs_t *fptrs, - jl_method_instance_t **linfos, size_t n) + jl_code_instance_t **cinfos, size_t n) { - getJITDebugRegistry().add_image_info({(uintptr_t) image_base, *fptrs, linfos, n}); + getJITDebugRegistry().add_image_info({(uintptr_t) image_base, *fptrs, cinfos, n}); } template @@ -1177,13 +1176,13 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip if (saddr == image.fptrs.clone_ptrs[i]) { uint32_t idx = image.fptrs.clone_idxs[i] & jl_sysimg_val_mask; if (idx < image.fvars_n) // items after this were cloned but not referenced directly by a method (such as our ccall PLT thunks) - frame0->linfo = image.fvars_linfo[idx]; + frame0->ci = image.fvars_cinst[idx]; break; } } for (size_t i = 0; i < image.fvars_n; i++) { if (saddr == image.fptrs.ptrs[i]) { - frame0->linfo = image.fvars_linfo[i]; + frame0->ci = image.fvars_cinst[i]; break; } } @@ -1255,16 +1254,16 @@ extern "C" JL_DLLEXPORT_CODEGEN int jl_getFunctionInfo_impl(jl_frame_t **frames_ int64_t slide; uint64_t symsize; if (jl_DI_for_fptr(pointer, &symsize, &slide, &Section, &context)) { - frames[0].linfo = getJITDebugRegistry().lookupLinfo(pointer); + frames[0].ci = getJITDebugRegistry().lookupCodeInstance(pointer); int nf = lookup_pointer(Section, context, frames_out, pointer, slide, true, noInline); return nf; } return jl_getDylibFunctionInfo(frames_out, pointer, skipC, noInline); } -extern "C" jl_method_instance_t *jl_gdblookuplinfo(void *p) JL_NOTSAFEPOINT +extern "C" jl_code_instance_t *jl_gdblookupci(void *p) JL_NOTSAFEPOINT { - return getJITDebugRegistry().lookupLinfo((size_t)p); + return getJITDebugRegistry().lookupCodeInstance((size_t)p); } #if defined(_OS_DARWIN_) && defined(LLVM_SHLIB) diff --git a/src/engine.cpp b/src/engine.cpp index 2b68de731c4dd..858f37b55e85e 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -139,7 +139,7 @@ void jl_engine_fulfill(jl_code_instance_t *ci, jl_code_info_t *src) { jl_task_t *ct = jl_current_task; std::unique_lock lock(engine_lock); - auto record = Reservations.find(InferKey{ci->def, ci->owner}); + auto record = Reservations.find(InferKey{jl_get_ci_mi(ci), ci->owner}); if (record == Reservations.end() || record->second.ci != ci) return; assert(jl_atomic_load_relaxed(&ct->tid) == record->second.tid); diff --git a/src/features_x86.h b/src/features_x86.h index 2ecc8fee32a38..b6e2b23985b4f 100644 --- a/src/features_x86.h +++ b/src/features_x86.h @@ -5,6 +5,13 @@ #else #define JL_X86_64ONLY_VER(x) x #endif +// The code is similar to what is here so the bits can be used as reference +// https://github.com/llvm/llvm-project/blob/3f7905733820851bc4f65cb4af693c3101cbf20d/llvm/lib/TargetParser/Host.cpp#L1257 + +// The way the bits here work is an index into the features array. This is a bit array +// The index works as follows: +// 32*i + j where i is the index into the array and j is the bit in the array. +// There is a reference to what each index corresponds to in _get_host_cpu // X86 features definition // EAX=1: ECX @@ -79,6 +86,7 @@ JL_FEATURE_DEF(avx512vp2intersect, 32 * 4 + 8, 0) JL_FEATURE_DEF(serialize, 32 * 4 + 14, 110000) JL_FEATURE_DEF(tsxldtrk, 32 * 4 + 16, 110000) JL_FEATURE_DEF(pconfig, 32 * 4 + 18, 0) +// JL_FEATURE_DEF(ibt, 32 * 4 + 20, 0) JL_FEATURE_DEF_NAME(amx_bf16, 32 * 4 + 22, 110000, "amx-bf16") JL_FEATURE_DEF(avx512fp16, 32 * 4 + 23, 140000) JL_FEATURE_DEF_NAME(amx_tile, 32 * 4 + 24, 110000, "amx-tile") @@ -110,10 +118,28 @@ JL_FEATURE_DEF(clzero, 32 * 8 + 0, 0) JL_FEATURE_DEF(wbnoinvd, 32 * 8 + 9, 0) // EAX=7,ECX=1: EAX +JL_FEATURE_DEF(sha512, 32 * 9 + 0, 170000) +JL_FEATURE_DEF(sm3, 32 * 9 + 1, 170000) +JL_FEATURE_DEF(sm4, 32 * 9 + 2, 170000) +JL_FEATURE_DEF(raoint, 32 * 9 + 3, 170000) JL_FEATURE_DEF(avxvnni, 32 * 9 + 4, 120000) JL_FEATURE_DEF(avx512bf16, 32 * 9 + 5, 0) +JL_FEATURE_DEF(cmpccxadd, 32 * 9 + 7, 160000) +JL_FEATURE_DEF_NAME(amx_fp16, 32 * 9 + 21, 160000, "amx-fp16") +JL_FEATURE_DEF(hreset, 32 * 9 + 22, 160000) +JL_FEATURE_DEF(avxifma, 32 * 9 + 23, 160000) + +// EAX=7,ECX=1: EBX +JL_FEATURE_DEF(avxvnniint8, 32 * 10 + 4, 160000) +JL_FEATURE_DEF(avxneconvert, 32 * 10 + 5, 160000) +JL_FEATURE_DEF_NAME(amx_complex, 32 * 10 + 8, 170000, "amx-complex") +JL_FEATURE_DEF(avxvnniint16, 32 * 10 + 10, 170000) +JL_FEATURE_DEF(prefetchi, 32 * 10 + 14, 160000) +JL_FEATURE_DEF(usermsr, 32 * 10 + 15, 170000) +// JL_FEATURE_DEF(avx10, 32 * 10 + 19, 170000) // TODO: What to do about avx10 and it's mess? +// JL_FEATURE_DEF(apxf, 32 * 10 + 21, 190000) // EAX=0x14,ECX=0: EBX -JL_FEATURE_DEF(ptwrite, 32 * 10 + 4, 0) +JL_FEATURE_DEF(ptwrite, 32 * 11 + 4, 0) #undef JL_X86_64ONLY_VER diff --git a/src/gc-common.c b/src/gc-common.c index c751b54f059f5..c07b707b17709 100644 --- a/src/gc-common.c +++ b/src/gc-common.c @@ -540,6 +540,38 @@ JL_DLLEXPORT jl_value_t *(jl_gc_alloc)(jl_ptls_t ptls, size_t sz, void *ty) return jl_gc_alloc_(ptls, sz, ty); } +JL_DLLEXPORT void *jl_malloc(size_t sz) +{ + return jl_gc_counted_malloc(sz); +} + +//_unchecked_calloc does not check for potential overflow of nm*sz +STATIC_INLINE void *_unchecked_calloc(size_t nm, size_t sz) { + size_t nmsz = nm*sz; + return jl_gc_counted_calloc(nmsz, 1); +} + +JL_DLLEXPORT void *jl_calloc(size_t nm, size_t sz) +{ + if (nm > SSIZE_MAX/sz) + return NULL; + return _unchecked_calloc(nm, sz); +} + +JL_DLLEXPORT void jl_free(void *p) +{ + if (p != NULL) { + size_t sz = memory_block_usable_size(p, 0); + return jl_gc_counted_free_with_size(p, sz); + } +} + +JL_DLLEXPORT void *jl_realloc(void *p, size_t sz) +{ + size_t old = p ? memory_block_usable_size(p, 0) : 0; + return jl_gc_counted_realloc_with_old_size(p, old, sz); +} + // =========================================================================== // // Generic Memory // =========================================================================== // @@ -557,17 +589,8 @@ size_t jl_genericmemory_nbytes(jl_genericmemory_t *m) JL_NOTSAFEPOINT // tracking Memorys with malloc'd storage void jl_gc_track_malloced_genericmemory(jl_ptls_t ptls, jl_genericmemory_t *m, int isaligned){ // This is **NOT** a GC safe point. - mallocmemory_t *ma; - if (ptls->gc_tls_common.heap.mafreelist == NULL) { - ma = (mallocmemory_t*)malloc_s(sizeof(mallocmemory_t)); - } - else { - ma = ptls->gc_tls_common.heap.mafreelist; - ptls->gc_tls_common.heap.mafreelist = ma->next; - } - ma->a = (jl_genericmemory_t*)((uintptr_t)m | !!isaligned); - ma->next = ptls->gc_tls_common.heap.mallocarrays; - ptls->gc_tls_common.heap.mallocarrays = ma; + void *a = (void*)((uintptr_t)m | !!isaligned); + small_arraylist_push(&ptls->gc_tls_common.heap.mallocarrays, a); } // =========================================================================== // @@ -677,6 +700,24 @@ JL_DLLEXPORT void jl_throw_out_of_memory_error(void) jl_throw(jl_memory_exception); } +// Sweeping mtarraylist_buffers: +// These buffers are made unreachable via `mtarraylist_resizeto` from mtarraylist.c +// and are freed at the end of GC via jl_gc_sweep_stack_pools_and_mtarraylist_buffers +void sweep_mtarraylist_buffers(void) JL_NOTSAFEPOINT +{ + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls = gc_all_tls_states[i]; + if (ptls == NULL) { + continue; + } + small_arraylist_t *buffers = &ptls->lazily_freed_mtarraylist_buffers; + void *buf; + while ((buf = small_arraylist_pop(buffers)) != NULL) { + free(buf); + } + } +} + #ifdef __cplusplus } #endif diff --git a/src/gc-common.h b/src/gc-common.h index 3007151009f7d..ca5e21084209e 100644 --- a/src/gc-common.h +++ b/src/gc-common.h @@ -24,6 +24,31 @@ extern "C" { #endif +// =========================================================================== // +// GC Big objects +// =========================================================================== // + +JL_EXTENSION typedef struct _bigval_t { + struct _bigval_t *next; + struct _bigval_t *prev; + size_t sz; +#ifdef _P64 // Add padding so that the value is 64-byte aligned + // (8 pointers of 8 bytes each) - (4 other pointers in struct) + void *_padding[8 - 4]; +#else + // (16 pointers of 4 bytes each) - (4 other pointers in struct) + void *_padding[16 - 4]; +#endif + //struct jl_taggedvalue_t <>; + union { + uintptr_t header; + struct { + uintptr_t gc:2; + } bits; + }; + // must be 64-byte aligned here, in 32 & 64 bit modes +} bigval_t; + // =========================================================================== // // GC Callbacks // =========================================================================== // @@ -61,12 +86,6 @@ extern jl_gc_callback_list_t *gc_cblist_notify_gc_pressure; // malloc wrappers, aligned allocation // =========================================================================== // -// data structure for tracking malloc'd genericmemory. -typedef struct _mallocmemory_t { - jl_genericmemory_t *a; // lowest bit is tagged if this is aligned memory - struct _mallocmemory_t *next; -} mallocmemory_t; - #if defined(_OS_WINDOWS_) STATIC_INLINE void *jl_malloc_aligned(size_t sz, size_t align) { @@ -193,4 +212,14 @@ extern jl_ptls_t* gc_all_tls_states; extern int gc_logging_enabled; +// =========================================================================== // +// MISC +// =========================================================================== // + +// number of stacks to always keep available per pool +#define MIN_STACK_MAPPINGS_PER_POOL 5 + +void _jl_free_stack(jl_ptls_t ptls, void *stkbuf, size_t bufsz) JL_NOTSAFEPOINT; +void sweep_mtarraylist_buffers(void) JL_NOTSAFEPOINT; + #endif // JL_GC_COMMON_H diff --git a/src/gc-debug.c b/src/gc-debug.c index 7c479484cde45..6e51064035b7b 100644 --- a/src/gc-debug.c +++ b/src/gc-debug.c @@ -1025,12 +1025,11 @@ void gc_stats_big_obj(void) v = v->next; } - mallocmemory_t *ma = ptls2->gc_tls.heap.mallocarrays; - while (ma != NULL) { - uint8_t bits =jl_astaggedvalue(ma->a)->bits.gc; + void **lst = ptls2->gc_tls.heap.mallocarrays.items; + for (size_t i = 0, l = ptls2->gc_tls.heap.mallocarrays.len; i < l; i++) { + jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[i] & ~(uintptr_t)1); + uint8_t bits = jl_astaggedvalue(m)->bits.gc; if (gc_marked(bits)) { - jl_genericmemory_t *m = (jl_genericmemory_t*)ma->a; - m = (jl_genericmemory_t*)((uintptr_t)m & ~(uintptr_t)1); size_t sz = jl_genericmemory_nbytes(m); if (gc_old(bits)) { assert(bits == GC_OLD_MARKED); @@ -1042,7 +1041,6 @@ void gc_stats_big_obj(void) stat.nbytes_used += sz; } } - ma = ma->next; } } jl_safe_printf("%lld kB (%lld%% old) in %lld large objects (%lld%% old)\n", diff --git a/src/gc-heap-snapshot.cpp b/src/gc-heap-snapshot.cpp index 72eb17115f4c7..f3793939610b5 100644 --- a/src/gc-heap-snapshot.cpp +++ b/src/gc-heap-snapshot.cpp @@ -380,7 +380,7 @@ size_t record_node_to_gc_snapshot(jl_value_t *a) JL_NOTSAFEPOINT ios_mem(&str_, 0); JL_STREAM* str = (JL_STREAM*)&str_; jl_static_show(str, (jl_value_t*)type); - + node_type = StringRef((const char*)str_.buf, str_.size); name = StringRef((const char*)str_.buf, str_.size); } diff --git a/src/gc-interface.h b/src/gc-interface.h index eb6687d52d9ab..826e91355b17a 100644 --- a/src/gc-interface.h +++ b/src/gc-interface.h @@ -46,6 +46,9 @@ typedef struct { uint64_t mark_time; uint64_t stack_pool_sweep_time; uint64_t total_sweep_time; + uint64_t total_sweep_page_walk_time; + uint64_t total_sweep_madvise_time; + uint64_t total_sweep_free_mallocd_memory_time; uint64_t total_mark_time; uint64_t total_stack_pool_sweep_time; uint64_t last_full_sweep; @@ -98,6 +101,13 @@ JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem); JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection); // Returns whether the thread with `tid` is a collector thread JL_DLLEXPORT int gc_is_collector_thread(int tid) JL_NOTSAFEPOINT; +// Returns which GC implementation is being used and possibly its version according to the list of supported GCs +// NB: it should clearly identify the GC by including e.g. ‘stock’ or ‘mmtk’ as a substring. +JL_DLLEXPORT const char* jl_gc_active_impl(void); +// Sweep Julia's stack pools and mtarray buffers. Note that this function has been added to the interface as +// each GC should implement it but it will most likely not be used by other code in the runtime. +// It still needs to be annotated with JL_DLLEXPORT since it is called from Rust by MMTk. +JL_DLLEXPORT void jl_gc_sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT; // ========================================================================= // // Metrics @@ -138,7 +148,6 @@ JL_DLLEXPORT uint64_t jl_gc_total_hrtime(void); // **must** also set the type of the returning object to be `ty`. The type `ty` may also be used to record // an allocation of that type in the allocation profiler. struct _jl_value_t *jl_gc_alloc_(struct _jl_tls_states_t * ptls, size_t sz, void *ty); - // Allocates small objects and increments Julia allocation counterst. Size of the object // header must be included in the object size. The (possibly unused in some implementations) // offset to the arena in which we're allocating is passed in the second parameter, and the @@ -198,6 +207,10 @@ JL_DLLEXPORT void *jl_gc_perm_alloc(size_t sz, int zero, unsigned align, // the allocated object. All objects stored in fields of this object // must be either permanently allocated or have other roots. struct _jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT; +// This function notifies the GC about memory addresses that are set when loading the boot image. +// The GC may use that information to, for instance, determine that such objects should +// be treated as marked and belonged to the old generation in nursery collections. +void jl_gc_notify_image_load(const char* img_data, size_t len); // ========================================================================= // // Runtime Write-Barriers diff --git a/src/gc-mmtk.c b/src/gc-mmtk.c new file mode 100644 index 0000000000000..5ec1e34cc1acd --- /dev/null +++ b/src/gc-mmtk.c @@ -0,0 +1,1183 @@ +#include "gc-common.h" +#include "gc-tls-mmtk.h" +#include "mmtkMutator.h" +#include "threading.h" + +// File exists in the binding +#include "mmtk.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// ========================================================================= // +// Julia specific +// ========================================================================= // + +extern jl_value_t *cmpswap_names JL_GLOBALLY_ROOTED; +extern const unsigned pool_sizes[]; +extern jl_mutex_t finalizers_lock; + +// FIXME: Should the values below be shared between both GC's? +// Note that MMTk uses a hard max heap limit, which is set by default +// as 70% of the free available memory. The min heap is set as the +// default_collect_interval variable below. + +// max_total_memory is a suggestion. We try very hard to stay +// under this limit, but we will go above it rather than halting. +#ifdef _P64 +typedef uint64_t memsize_t; +static const size_t default_collect_interval = 5600 * 1024 * sizeof(void*); +// We expose this to the user/ci as jl_gc_set_max_memory +static memsize_t max_total_memory = (memsize_t) 2 * 1024 * 1024 * 1024 * 1024 * 1024; +#else +typedef uint32_t memsize_t; +static const size_t default_collect_interval = 3200 * 1024 * sizeof(void*); +// Work really hard to stay within 2GB +// Alternative is to risk running out of address space +// on 32 bit architectures. +#define MAX32HEAP 1536 * 1024 * 1024 +static memsize_t max_total_memory = (memsize_t) MAX32HEAP; +#endif + +// ========================================================================= // +// Defined by the binding +// ========================================================================= // + +extern void mmtk_julia_copy_stack_check(int copy_stack); +extern void mmtk_gc_init(uintptr_t min_heap_size, uintptr_t max_heap_size, uintptr_t n_gcthreads, uintptr_t header_size, uintptr_t tag); +extern void mmtk_object_reference_write_post(void* mutator, const void* parent, const void* ptr); +extern void mmtk_object_reference_write_slow(void* mutator, const void* parent, const void* ptr); +extern void* mmtk_alloc(void* mutator, size_t size, size_t align, size_t offset, int allocator); +extern void mmtk_post_alloc(void* mutator, void* refer, size_t bytes, int allocator); +extern void mmtk_store_obj_size_c(void* obj, size_t size); +extern const void* MMTK_SIDE_LOG_BIT_BASE_ADDRESS; +extern const void* MMTK_SIDE_VO_BIT_BASE_ADDRESS; + +// ========================================================================= // +// GC Initialization and Control +// ========================================================================= // + +void jl_gc_init(void) { + // TODO: use jl_options.heap_size_hint to set MMTk's fixed heap size? (see issue: https://github.com/mmtk/mmtk-julia/issues/167) + JL_MUTEX_INIT(&finalizers_lock, "finalizers_lock"); + + arraylist_new(&to_finalize, 0); + arraylist_new(&finalizer_list_marked, 0); + + gc_num.allocd = 0; + gc_num.max_pause = 0; + gc_num.max_memory = 0; + + long long min_heap_size; + long long max_heap_size; + char* min_size_def = getenv("MMTK_MIN_HSIZE"); + char* min_size_gb = getenv("MMTK_MIN_HSIZE_G"); + + char* max_size_def = getenv("MMTK_MAX_HSIZE"); + char* max_size_gb = getenv("MMTK_MAX_HSIZE_G"); + + // default min heap currently set as Julia's default_collect_interval + if (min_size_def != NULL) { + char *p; + double min_size = strtod(min_size_def, &p); + min_heap_size = (long) 1024 * 1024 * min_size; + } else if (min_size_gb != NULL) { + char *p; + double min_size = strtod(min_size_gb, &p); + min_heap_size = (long) 1024 * 1024 * 1024 * min_size; + } else { + min_heap_size = default_collect_interval; + } + + // default max heap currently set as 70% the free memory in the system + if (max_size_def != NULL) { + char *p; + double max_size = strtod(max_size_def, &p); + max_heap_size = (long) 1024 * 1024 * max_size; + } else if (max_size_gb != NULL) { + char *p; + double max_size = strtod(max_size_gb, &p); + max_heap_size = (long) 1024 * 1024 * 1024 * max_size; + } else { + max_heap_size = uv_get_free_memory() * 70 / 100; + } + + // Assert that the number of stock GC threads is 0; MMTK uses the number of threads in jl_options.ngcthreads + assert(jl_n_gcthreads == 0); + + // Check that the julia_copy_stack rust feature has been defined when the COPY_STACK has been defined + int copy_stacks; + +#ifdef COPY_STACKS + copy_stacks = 1; +#else + copy_stacks = 0; +#endif + + mmtk_julia_copy_stack_check(copy_stacks); + + // if only max size is specified initialize MMTk with a fixed size heap + // TODO: We just assume mark threads means GC threads, and ignore the number of concurrent sweep threads. + // If the two values are the same, we can use either. Otherwise, we need to be careful. + uintptr_t gcthreads = jl_options.nmarkthreads; + if (max_size_def != NULL || (max_size_gb != NULL && (min_size_def == NULL && min_size_gb == NULL))) { + mmtk_gc_init(0, max_heap_size, gcthreads, (sizeof(jl_taggedvalue_t)), jl_buff_tag); + } else { + mmtk_gc_init(min_heap_size, max_heap_size, gcthreads, (sizeof(jl_taggedvalue_t)), jl_buff_tag); + } +} + +void jl_start_gc_threads(void) { + jl_ptls_t ptls = jl_current_task->ptls; + mmtk_initialize_collection((void *)ptls); +} + +void jl_init_thread_heap(struct _jl_tls_states_t *ptls) JL_NOTSAFEPOINT { + jl_thread_heap_common_t *heap = &ptls->gc_tls_common.heap; + small_arraylist_new(&heap->weak_refs, 0); + small_arraylist_new(&heap->live_tasks, 0); + for (int i = 0; i < JL_N_STACK_POOLS; i++) + small_arraylist_new(&heap->free_stacks[i], 0); + small_arraylist_new(&heap->mallocarrays, 0); + arraylist_new(&ptls->finalizers, 0); + // Initialize `lazily_freed_mtarraylist_buffers` + small_arraylist_new(&ptls->lazily_freed_mtarraylist_buffers, 0); + // Clear the malloc sz count + jl_atomic_store_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll, 0); + // Create mutator + MMTk_Mutator mmtk_mutator = mmtk_bind_mutator((void *)ptls, ptls->tid); + // Copy the mutator to the thread local storage + memcpy(&ptls->gc_tls.mmtk_mutator, mmtk_mutator, sizeof(MMTkMutatorContext)); + // Call post_bind to maintain a list of active mutators and to reclaim the old mutator (which is no longer needed) + mmtk_post_bind_mutator(&ptls->gc_tls.mmtk_mutator, mmtk_mutator); + memset(&ptls->gc_tls_common.gc_num, 0, sizeof(ptls->gc_tls_common.gc_num)); +} + +void jl_free_thread_gc_state(struct _jl_tls_states_t *ptls) { + mmtk_destroy_mutator(&ptls->gc_tls.mmtk_mutator); +} + +JL_DLLEXPORT void jl_gc_set_max_memory(uint64_t max_mem) { + // MMTk currently does not allow setting the heap size at runtime +} + +STATIC_INLINE void maybe_collect(jl_ptls_t ptls) +{ + // Just do a safe point for general maybe_collect + jl_gc_safepoint_(ptls); +} + +// This is only used for malloc. We need to know if we need to do GC. However, keeping checking with MMTk (mmtk_gc_poll), +// is expensive. So we only check for every few allocations. +static inline void malloc_maybe_collect(jl_ptls_t ptls, size_t sz) +{ + // We do not need to carefully maintain malloc_sz_since_last_poll. We just need to + // avoid using mmtk_gc_poll too frequently, and try to be precise on our heap usage + // as much as we can. + if (ptls->gc_tls.malloc_sz_since_last_poll > 4096) { + jl_atomic_store_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll, 0); + mmtk_gc_poll(ptls); + } else { + size_t curr = jl_atomic_load_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll); + jl_atomic_store_relaxed(&ptls->gc_tls.malloc_sz_since_last_poll, curr + sz); + jl_gc_safepoint_(ptls); + } +} + +// This is called when the user calls for a GC with Gc.gc() +JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection) { + jl_task_t *ct = jl_current_task; + jl_ptls_t ptls = ct->ptls; + if (jl_atomic_load_acquire(&jl_gc_disable_counter)) { + size_t localbytes = jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + gc_num.interval; + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, -(int64_t)gc_num.interval); + static_assert(sizeof(_Atomic(uint64_t)) == sizeof(gc_num.deferred_alloc), ""); + jl_atomic_fetch_add_relaxed((_Atomic(uint64_t)*)&gc_num.deferred_alloc, localbytes); + return; + } + mmtk_handle_user_collection_request(ptls, collection); +} + + +// Based on jl_gc_collect from gc-stock.c +// called when stopping the thread in `mmtk_block_for_gc` +JL_DLLEXPORT void jl_gc_prepare_to_collect(void) +{ + // FIXME: set to JL_GC_AUTO since we're calling it from mmtk + // maybe just remove this? + JL_PROBE_GC_BEGIN(JL_GC_AUTO); + + jl_task_t *ct = jl_current_task; + jl_ptls_t ptls = ct->ptls; + if (jl_atomic_load_acquire(&jl_gc_disable_counter)) { + size_t localbytes = jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + gc_num.interval; + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, -(int64_t)gc_num.interval); + static_assert(sizeof(_Atomic(uint64_t)) == sizeof(gc_num.deferred_alloc), ""); + jl_atomic_fetch_add_relaxed((_Atomic(uint64_t)*)&gc_num.deferred_alloc, localbytes); + return; + } + + int8_t old_state = jl_atomic_load_relaxed(&ptls->gc_state); + jl_atomic_store_release(&ptls->gc_state, JL_GC_STATE_WAITING); + // `jl_safepoint_start_gc()` makes sure only one thread can run the GC. + uint64_t t0 = jl_hrtime(); + if (!jl_safepoint_start_gc(ct)) { + jl_gc_state_set(ptls, old_state, JL_GC_STATE_WAITING); + jl_safepoint_wait_thread_resume(ct); // block in thread-suspend now if requested, after clearing the gc_state + return; + } + + JL_TIMING_SUSPEND_TASK(GC, ct); + JL_TIMING(GC, GC); + + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif + // Now we are ready to wait for other threads to hit the safepoint, + // we can do a few things that doesn't require synchronization. + // + // We must sync here with the tls_lock operations, so that we have a + // seq-cst order between these events now we know that either the new + // thread must run into our safepoint flag or we must observe the + // existence of the thread in the jl_n_threads count. + // + // TODO: concurrently queue objects + jl_fence(); + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + jl_gc_wait_for_the_world(gc_all_tls_states, gc_n_threads); + JL_PROBE_GC_STOP_THE_WORLD(); + + uint64_t t1 = jl_hrtime(); + uint64_t duration = t1 - t0; + if (duration > gc_num.max_time_to_safepoint) + gc_num.max_time_to_safepoint = duration; + gc_num.time_to_safepoint = duration; + gc_num.total_time_to_safepoint += duration; + + if (!jl_atomic_load_acquire(&jl_gc_disable_counter)) { + JL_LOCK_NOGC(&finalizers_lock); // all the other threads are stopped, so this does not make sense, right? otherwise, failing that, this seems like plausibly a deadlock +#ifndef __clang_gcanalyzer__ + mmtk_block_thread_for_gc(); +#endif + JL_UNLOCK_NOGC(&finalizers_lock); + } + + gc_n_threads = 0; + gc_all_tls_states = NULL; + jl_safepoint_end_gc(); + jl_gc_state_set(ptls, old_state, JL_GC_STATE_WAITING); + JL_PROBE_GC_END(); + jl_safepoint_wait_thread_resume(ct); // block in thread-suspend now if requested, after clearing the gc_state + + // Only disable finalizers on current thread + // Doing this on all threads is racy (it's impossible to check + // or wait for finalizers on other threads without dead lock). + if (!ptls->finalizers_inhibited && ptls->locks.len == 0) { + JL_TIMING(GC, GC_Finalizers); + run_finalizers(ct, 0); + } + JL_PROBE_GC_FINALIZER(); + +#ifdef _OS_WINDOWS_ + SetLastError(last_error); +#endif + errno = last_errno; +} + +// ========================================================================= // +// GC Statistics +// ========================================================================= // + +JL_DLLEXPORT const char* jl_gc_active_impl(void) { + const char* mmtk_version = get_mmtk_version(); + return mmtk_version; +} + +int64_t last_gc_total_bytes = 0; +int64_t last_live_bytes = 0; // live_bytes at last collection +int64_t live_bytes = 0; + +// FIXME: The functions combine_thread_gc_counts and reset_thread_gc_counts +// are currently nearly identical for mmtk and for stock. However, the stats +// are likely different (e.g., MMTk doesn't track the bytes allocated in the fastpath, +// but only when the slowpath is called). We might need to adapt these later so that +// the statistics are the same or as close as possible for each GC. +static void combine_thread_gc_counts(jl_gc_num_t *dest, int update_heap) JL_NOTSAFEPOINT +{ + int gc_n_threads; + jl_ptls_t* gc_all_tls_states; + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls = gc_all_tls_states[i]; + if (ptls) { + dest->allocd += (jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + gc_num.interval); + dest->malloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.malloc); + dest->realloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.realloc); + dest->poolalloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.poolalloc); + dest->bigalloc += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.bigalloc); + dest->freed += jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.free_acc); + if (update_heap) { + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.alloc_acc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.free_acc, 0); + } + } + } +} + +void reset_thread_gc_counts(void) JL_NOTSAFEPOINT +{ + int gc_n_threads; + jl_ptls_t* gc_all_tls_states; + gc_n_threads = jl_atomic_load_acquire(&jl_n_threads); + gc_all_tls_states = jl_atomic_load_relaxed(&jl_all_tls_states); + for (int i = 0; i < gc_n_threads; i++) { + jl_ptls_t ptls = gc_all_tls_states[i]; + if (ptls != NULL) { + // don't reset `pool_live_bytes` here + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, -(int64_t)gc_num.interval); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.malloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.realloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.poolalloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.bigalloc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.alloc_acc, 0); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.free_acc, 0); + } + } +} + +// Retrieves Julia's `GC_Num` (structure that stores GC statistics). +JL_DLLEXPORT jl_gc_num_t jl_gc_num(void) { + jl_gc_num_t num = gc_num; + combine_thread_gc_counts(&num, 0); + return num; +} + +JL_DLLEXPORT int64_t jl_gc_diff_total_bytes(void) JL_NOTSAFEPOINT { + int64_t oldtb = last_gc_total_bytes; + int64_t newtb; + jl_gc_get_total_bytes(&newtb); + last_gc_total_bytes = newtb; + return newtb - oldtb; +} + +JL_DLLEXPORT int64_t jl_gc_sync_total_bytes(int64_t offset) JL_NOTSAFEPOINT +{ + int64_t oldtb = last_gc_total_bytes; + int64_t newtb; + jl_gc_get_total_bytes(&newtb); + last_gc_total_bytes = newtb - offset; + return newtb - oldtb; +} + +JL_DLLEXPORT int64_t jl_gc_pool_live_bytes(void) { + return 0; +} + +void jl_gc_count_allocd(size_t sz) JL_NOTSAFEPOINT +{ + jl_ptls_t ptls = jl_current_task->ptls; + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + sz); +} + +void jl_gc_count_freed(size_t sz) JL_NOTSAFEPOINT +{ +} + +int64_t inc_live_bytes(int64_t inc) JL_NOTSAFEPOINT +{ + jl_timing_counter_inc(JL_TIMING_COUNTER_HeapSize, inc); + return live_bytes += inc; +} + +void jl_gc_reset_alloc_count(void) JL_NOTSAFEPOINT +{ + combine_thread_gc_counts(&gc_num, 0); + inc_live_bytes(gc_num.deferred_alloc + gc_num.allocd); + gc_num.allocd = 0; + gc_num.deferred_alloc = 0; + reset_thread_gc_counts(); +} + +JL_DLLEXPORT int64_t jl_gc_live_bytes(void) { + return last_live_bytes; +} + +JL_DLLEXPORT void jl_gc_get_total_bytes(int64_t *bytes) JL_NOTSAFEPOINT +{ + jl_gc_num_t num = gc_num; + combine_thread_gc_counts(&num, 0); + // Sync this logic with `base/util.jl:GC_Diff` + *bytes = (num.total_allocd + num.deferred_alloc + num.allocd); +} + +JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void) +{ + // FIXME: should probably return MMTk's heap size + return max_total_memory; +} + +// These are needed to collect MMTk statistics from a Julia program using ccall +JL_DLLEXPORT void (jl_mmtk_harness_begin)(void) +{ + jl_ptls_t ptls = jl_current_task->ptls; + mmtk_harness_begin(ptls); +} + +JL_DLLEXPORT void (jl_mmtk_harness_end)(void) +{ + mmtk_harness_end(); +} + +// ========================================================================= // +// Root Processing, Object Scanning and Julia-specific sweeping +// ========================================================================= // + +static void add_node_to_roots_buffer(RootsWorkClosure* closure, RootsWorkBuffer* buf, size_t* buf_len, void* root) { + if (root == NULL) + return; + + buf->ptr[*buf_len] = root; + *buf_len += 1; + if (*buf_len >= buf->cap) { + RootsWorkBuffer new_buf = (closure->report_nodes_func)(buf->ptr, *buf_len, buf->cap, closure->data, true); + *buf = new_buf; + *buf_len = 0; + } +} + +static void add_node_to_tpinned_roots_buffer(RootsWorkClosure* closure, RootsWorkBuffer* buf, size_t* buf_len, void* root) { + if (root == NULL) + return; + + buf->ptr[*buf_len] = root; + *buf_len += 1; + if (*buf_len >= buf->cap) { + RootsWorkBuffer new_buf = (closure->report_tpinned_nodes_func)(buf->ptr, *buf_len, buf->cap, closure->data, true); + *buf = new_buf; + *buf_len = 0; + } +} + +JL_DLLEXPORT void jl_gc_scan_vm_specific_roots(RootsWorkClosure* closure) +{ + // Create a new buf + RootsWorkBuffer buf = (closure->report_nodes_func)((void**)0, 0, 0, closure->data, true); + size_t len = 0; + + // add module + add_node_to_roots_buffer(closure, &buf, &len, jl_main_module); + + // buildin values + add_node_to_roots_buffer(closure, &buf, &len, jl_an_empty_vec_any); + add_node_to_roots_buffer(closure, &buf, &len, jl_module_init_order); + for (size_t i = 0; i < jl_current_modules.size; i += 2) { + if (jl_current_modules.table[i + 1] != HT_NOTFOUND) { + add_node_to_roots_buffer(closure, &buf, &len, jl_current_modules.table[i]); + } + } + add_node_to_roots_buffer(closure, &buf, &len, jl_anytuple_type_type); + for (size_t i = 0; i < N_CALL_CACHE; i++) { + jl_typemap_entry_t *v = jl_atomic_load_relaxed(&call_cache[i]); + add_node_to_roots_buffer(closure, &buf, &len, v); + } + add_node_to_roots_buffer(closure, &buf, &len, _jl_debug_method_invalidation); + + // constants + add_node_to_roots_buffer(closure, &buf, &len, jl_emptytuple_type); + add_node_to_roots_buffer(closure, &buf, &len, cmpswap_names); + + // jl_global_roots_table must be transitively pinned + RootsWorkBuffer tpinned_buf = (closure->report_tpinned_nodes_func)((void**)0, 0, 0, closure->data, true); + size_t tpinned_len = 0; + 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); +} + +JL_DLLEXPORT void jl_gc_scan_julia_exc_obj(void* obj_raw, void* closure, ProcessSlotFn process_slot) { + jl_task_t *ta = (jl_task_t*)obj_raw; + + if (ta->excstack) { // inlining label `excstack` from mark_loop + + // the excstack should always be a heap object + assert(mmtk_object_is_managed_by_mmtk(ta->excstack)); + + process_slot(closure, &ta->excstack); + jl_excstack_t *excstack = ta->excstack; + size_t itr = ta->excstack->top; + size_t bt_index = 0; + size_t jlval_index = 0; + while (itr > 0) { + size_t bt_size = jl_excstack_bt_size(excstack, itr); + jl_bt_element_t *bt_data = jl_excstack_bt_data(excstack, itr); + for (; bt_index < bt_size; bt_index += jl_bt_entry_size(bt_data + bt_index)) { + jl_bt_element_t *bt_entry = bt_data + bt_index; + if (jl_bt_is_native(bt_entry)) + continue; + // Found an extended backtrace entry: iterate over any + // GC-managed values inside. + size_t njlvals = jl_bt_num_jlvals(bt_entry); + while (jlval_index < njlvals) { + jl_value_t** new_obj_slot = &bt_entry[2 + jlval_index].jlvalue; + jlval_index += 1; + process_slot(closure, new_obj_slot); + } + jlval_index = 0; + } + + jl_bt_element_t *stack_raw = (jl_bt_element_t *)(excstack+1); + jl_value_t** stack_obj_slot = &stack_raw[itr-1].jlvalue; + + itr = jl_excstack_next(excstack, itr); + bt_index = 0; + jlval_index = 0; + process_slot(closure, stack_obj_slot); + } + } +} + +// This is used in mmtk_sweep_malloced_memory and it is slightly different +// from jl_gc_free_memory from gc-stock.c as the stock GC updates the +// information in the global variable gc_heap_stats (which is specific to the stock GC) +static void jl_gc_free_memory(jl_genericmemory_t *m, int isaligned) JL_NOTSAFEPOINT +{ + assert(jl_is_genericmemory(m)); + assert(jl_genericmemory_how(m) == 1 || jl_genericmemory_how(m) == 2); + char *d = (char*)m->ptr; + size_t freed_bytes = memory_block_usable_size(d, isaligned); + assert(freed_bytes != 0); + if (isaligned) + jl_free_aligned(d); + else + free(d); + gc_num.freed += freed_bytes; + gc_num.freecall++; +} + +JL_DLLEXPORT void jl_gc_mmtk_sweep_malloced_memory(void) JL_NOTSAFEPOINT +{ + void* iter = mmtk_new_mutator_iterator(); + jl_ptls_t ptls2 = (jl_ptls_t)mmtk_get_next_mutator_tls(iter); + while(ptls2 != NULL) { + size_t n = 0; + size_t l = ptls2->gc_tls_common.heap.mallocarrays.len; + void **lst = ptls2->gc_tls_common.heap.mallocarrays.items; + // filter without preserving order + while (n < l) { + jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[n] & ~1); + if (mmtk_is_live_object(m)) { + n++; + } + else { + int isaligned = (uintptr_t)lst[n] & 1; + jl_gc_free_memory(m, isaligned); + l--; + lst[n] = lst[l]; + } + } + ptls2->gc_tls_common.heap.mallocarrays.len = l; + ptls2 = (jl_ptls_t)mmtk_get_next_mutator_tls(iter); + } + mmtk_close_mutator_iterator(iter); +} + +#define jl_genericmemory_elsize(a) (((jl_datatype_t*)jl_typetagof(a))->layout->size) + +// if data is inlined inside the genericmemory object --- to->ptr needs to be updated when copying the array +JL_DLLEXPORT void jl_gc_update_inlined_array(void* from, void* to) { + jl_value_t* jl_from = (jl_value_t*) from; + jl_value_t* jl_to = (jl_value_t*) to; + + uintptr_t tag_to = (uintptr_t)jl_typeof(jl_to); + jl_datatype_t *vt = (jl_datatype_t*)tag_to; + + if(vt->name == jl_genericmemory_typename) { + jl_genericmemory_t *a = (jl_genericmemory_t*)jl_from; + jl_genericmemory_t *b = (jl_genericmemory_t*)jl_to; + int how = jl_genericmemory_how(a); + + if (how == 0 && mmtk_object_is_managed_by_mmtk(a->ptr)) { // a is inlined (a->ptr points into the mmtk object) + size_t offset_of_data = ((size_t)a->ptr - (size_t)a); + if (offset_of_data > 0) { + b->ptr = (void*)((size_t) b + offset_of_data); + } + } + } +} + +// modified sweep_stack_pools from gc-stacks.c +JL_DLLEXPORT void jl_gc_mmtk_sweep_stack_pools(void) +{ + // Stack sweeping algorithm: + // // deallocate stacks if we have too many sitting around unused + // for (stk in halfof(free_stacks)) + // free_stack(stk, pool_sz); + // // then sweep the task stacks + // for (t in live_tasks) + // if (!gc-marked(t)) + // stkbuf = t->stkbuf + // bufsz = t->bufsz + // if (stkbuf) + // push(free_stacks[sz], stkbuf) + assert(gc_n_threads); + for (int i = 0; i < jl_n_threads; i++) { + jl_ptls_t ptls2 = gc_all_tls_states[i]; + if (ptls2 == NULL) + continue; + + // free half of stacks that remain unused since last sweep + for (int p = 0; p < JL_N_STACK_POOLS; p++) { + small_arraylist_t *al = &ptls2->gc_tls_common.heap.free_stacks[p]; + size_t n_to_free; + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + n_to_free = al->len; // not alive yet or dead, so it does not need these anymore + } + else if (al->len > MIN_STACK_MAPPINGS_PER_POOL) { + n_to_free = al->len / 2; + if (n_to_free > (al->len - MIN_STACK_MAPPINGS_PER_POOL)) + n_to_free = al->len - MIN_STACK_MAPPINGS_PER_POOL; + } + else { + n_to_free = 0; + } + for (int n = 0; n < n_to_free; n++) { + void *stk = small_arraylist_pop(al); + free_stack(stk, pool_sizes[p]); + } + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(al); + } + } + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(ptls2->gc_tls_common.heap.free_stacks); + } + + small_arraylist_t *live_tasks = &ptls2->gc_tls_common.heap.live_tasks; + size_t n = 0; + size_t ndel = 0; + size_t l = live_tasks->len; + void **lst = live_tasks->items; + if (l == 0) + continue; + while (1) { + jl_task_t *t = (jl_task_t*)lst[n]; + if (mmtk_is_live_object(t)) { + jl_task_t *maybe_forwarded = (jl_task_t*)mmtk_get_possibly_forwarded(t); + live_tasks->items[n] = maybe_forwarded; + t = maybe_forwarded; + assert(jl_is_task(t)); + if (t->ctx.stkbuf == NULL) + ndel++; // jl_release_task_stack called + else + n++; + } else { + ndel++; + void *stkbuf = t->ctx.stkbuf; + size_t bufsz = t->ctx.bufsz; + if (stkbuf) { + t->ctx.stkbuf = NULL; + _jl_free_stack(ptls2, stkbuf, bufsz); + } +#ifdef _COMPILER_TSAN_ENABLED_ + if (t->ctx.tsan_state) { + __tsan_destroy_fiber(t->ctx.tsan_state); + t->ctx.tsan_state = NULL; + } +#endif + } + if (n >= l - ndel) + break; + void *tmp = lst[n]; + lst[n] = lst[n + ndel]; + lst[n + ndel] = tmp; + } + live_tasks->len -= ndel; + } +} + +JL_DLLEXPORT void jl_gc_sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT +{ + jl_gc_mmtk_sweep_stack_pools(); + sweep_mtarraylist_buffers(); +} + +JL_DLLEXPORT void* jl_gc_get_stackbase(int16_t tid) { + assert(tid >= 0); + jl_ptls_t ptls2 = jl_all_tls_states[tid]; + return ptls2->stackbase; +} + +JL_DLLEXPORT void jl_gc_update_stats(uint64_t inc, size_t mmtk_live_bytes, bool is_nursery_gc) { + gc_num.total_time += inc; + gc_num.pause += 1; + gc_num.full_sweep += !(is_nursery_gc); + gc_num.total_allocd += gc_num.allocd; + gc_num.allocd = 0; + live_bytes = mmtk_live_bytes; +} + +#define jl_genericmemory_data_owner_field_addr(a) ((jl_value_t**)((jl_genericmemory_t*)(a) + 1)) + +JL_DLLEXPORT void* jl_gc_get_owner_address_to_mmtk(void* m) { + return (void*)jl_genericmemory_data_owner_field_addr(m); +} + +// same as jl_genericmemory_how but with JL_DLLEXPORT +// we should probably inline this in Rust +JL_DLLEXPORT size_t jl_gc_genericmemory_how(void *arg) JL_NOTSAFEPOINT +{ + jl_genericmemory_t* m = (jl_genericmemory_t*)arg; + if (m->ptr == (void*)((char*)m + 16)) // JL_SMALL_BYTE_ALIGNMENT (from julia_internal.h) + return 0; + jl_value_t *owner = jl_genericmemory_data_owner_field(m); + if (owner == (jl_value_t*)m) + return 1; + if (owner == NULL) + return 2; + return 3; +} + +// ========================================================================= // +// Weak References and Finalizers +// ========================================================================= // + +JL_DLLEXPORT jl_weakref_t *jl_gc_new_weakref_th(jl_ptls_t ptls, jl_value_t *value) +{ + jl_weakref_t *wr = (jl_weakref_t*)jl_gc_alloc(ptls, sizeof(void*), jl_weakref_type); + wr->value = value; // NOTE: wb not needed here + mmtk_add_weak_candidate(wr); + return wr; +} + +JL_DLLEXPORT void* jl_gc_get_thread_finalizer_list(void* ptls_raw) { + jl_ptls_t ptls = (jl_ptls_t) ptls_raw; + return (void*)&ptls->finalizers; +} + +JL_DLLEXPORT void* jl_gc_get_to_finalize_list(void) { + return (void*)&to_finalize; +} + +JL_DLLEXPORT void* jl_gc_get_marked_finalizers_list(void) { + return (void*)&finalizer_list_marked; +} + +JL_DLLEXPORT int* jl_gc_get_have_pending_finalizers(void) { + return (int*)&jl_gc_have_pending_finalizers; +} + +// ========================================================================= // +// Allocation +// ========================================================================= // + +#define MMTK_DEFAULT_IMMIX_ALLOCATOR (0) +#define MMTK_IMMORTAL_BUMP_ALLOCATOR (0) + +int jl_gc_classify_pools(size_t sz, int *osize) +{ + if (sz > GC_MAX_SZCLASS) + return -1; // call big alloc function + size_t allocsz = sz + sizeof(jl_taggedvalue_t); + *osize = LLT_ALIGN(allocsz, 16); + return 0; // use MMTk's fastpath logic +} + +#define MMTK_MIN_ALIGNMENT 4 +// MMTk assumes allocation size is aligned to min alignment. +STATIC_INLINE size_t mmtk_align_alloc_sz(size_t sz) JL_NOTSAFEPOINT +{ + return (sz + MMTK_MIN_ALIGNMENT - 1) & ~(MMTK_MIN_ALIGNMENT - 1); +} + +STATIC_INLINE void* bump_alloc_fast(MMTkMutatorContext* mutator, uintptr_t* cursor, uintptr_t limit, size_t size, size_t align, size_t offset, int allocator) { + intptr_t delta = (-offset - *cursor) & (align - 1); + uintptr_t result = *cursor + (uintptr_t)delta; + + if (__unlikely(result + size > limit)) { + return (void*) mmtk_alloc(mutator, size, align, offset, allocator); + } else{ + *cursor = result + size; + return (void*)result; + } +} + +STATIC_INLINE void* mmtk_immix_alloc_fast(MMTkMutatorContext* mutator, size_t size, size_t align, size_t offset) { + ImmixAllocator* allocator = &mutator->allocators.immix[MMTK_DEFAULT_IMMIX_ALLOCATOR]; + return bump_alloc_fast(mutator, (uintptr_t*)&allocator->cursor, (intptr_t)allocator->limit, size, align, offset, 0); +} + +inline void mmtk_immix_post_alloc_slow(MMTkMutatorContext* mutator, void* obj, size_t size) { + mmtk_post_alloc(mutator, obj, size, 0); +} + +STATIC_INLINE void mmtk_immix_post_alloc_fast(MMTkMutatorContext* mutator, void* obj, size_t size) { + // FIXME: for now, we do nothing + // but when supporting moving, this is where we set the valid object (VO) bit +} + +STATIC_INLINE void* mmtk_immortal_alloc_fast(MMTkMutatorContext* mutator, size_t size, size_t align, size_t offset) { + BumpAllocator* allocator = &mutator->allocators.bump_pointer[MMTK_IMMORTAL_BUMP_ALLOCATOR]; + return bump_alloc_fast(mutator, (uintptr_t*)&allocator->cursor, (uintptr_t)allocator->limit, size, align, offset, 1); +} + +STATIC_INLINE void mmtk_immortal_post_alloc_fast(MMTkMutatorContext* mutator, void* obj, size_t size) { + // FIXME: Similarly, for now, we do nothing + // but when supporting moving, this is where we set the valid object (VO) bit + // and log (old gen) bit +} + +JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int osize, size_t align, void *ty) +{ + // safepoint + jl_gc_safepoint_(ptls); + + jl_value_t *v; + if ((uintptr_t)ty != jl_buff_tag) { + // v needs to be 16 byte aligned, therefore v_tagged needs to be offset accordingly to consider the size of header + jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->gc_tls.mmtk_mutator, LLT_ALIGN(osize, align), align, sizeof(jl_taggedvalue_t)); + v = jl_valueof(v_tagged); + mmtk_immix_post_alloc_fast(&ptls->gc_tls.mmtk_mutator, v, LLT_ALIGN(osize, align)); + } else { + // allocating an extra word to store the size of buffer objects + jl_taggedvalue_t *v_tagged = (jl_taggedvalue_t *)mmtk_immix_alloc_fast(&ptls->gc_tls.mmtk_mutator, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align), align, 0); + jl_value_t* v_tagged_aligned = ((jl_value_t*)((char*)(v_tagged) + sizeof(jl_taggedvalue_t))); + v = jl_valueof(v_tagged_aligned); + mmtk_store_obj_size_c(v, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align)); + mmtk_immix_post_alloc_fast(&ptls->gc_tls.mmtk_mutator, v, LLT_ALIGN(osize+sizeof(jl_taggedvalue_t), align)); + } + + ptls->gc_tls_common.gc_num.allocd += osize; + ptls->gc_tls_common.gc_num.poolalloc++; + + return v; +} + +JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_big(jl_ptls_t ptls, size_t sz) +{ + // safepoint + jl_gc_safepoint_(ptls); + + size_t offs = offsetof(bigval_t, header); + assert(sz >= sizeof(jl_taggedvalue_t) && "sz must include tag"); + static_assert(offsetof(bigval_t, header) >= sizeof(void*), "Empty bigval header?"); + static_assert(sizeof(bigval_t) % JL_HEAP_ALIGNMENT == 0, ""); + size_t allocsz = LLT_ALIGN(sz + offs, JL_CACHE_BYTE_ALIGNMENT); + if (allocsz < sz) { // overflow in adding offs, size was "negative" + assert(0 && "Error when allocating big object"); + jl_throw(jl_memory_exception); + } + + bigval_t *v = (bigval_t*)mmtk_alloc_large(&ptls->gc_tls.mmtk_mutator, allocsz, JL_CACHE_BYTE_ALIGNMENT, 0, 2); + + if (v == NULL) { + assert(0 && "Allocation failed"); + jl_throw(jl_memory_exception); + } + v->sz = allocsz; + + ptls->gc_tls_common.gc_num.allocd += allocsz; + ptls->gc_tls_common.gc_num.bigalloc++; + + jl_value_t *result = jl_valueof(&v->header); + mmtk_post_alloc(&ptls->gc_tls.mmtk_mutator, result, allocsz, 2); + + return result; +} + +// Instrumented version of jl_gc_small_alloc_inner, called into by LLVM-generated code. +JL_DLLEXPORT jl_value_t *jl_gc_small_alloc(jl_ptls_t ptls, int offset, int osize, jl_value_t* type) +{ + assert(jl_atomic_load_relaxed(&ptls->gc_state) == 0); + + jl_value_t *val = jl_mmtk_gc_alloc_default(ptls, osize, 16, NULL); + maybe_record_alloc_to_profile(val, osize, (jl_datatype_t*)type); + return val; +} + +// Instrumented version of jl_gc_big_alloc_inner, called into by LLVM-generated code. +JL_DLLEXPORT jl_value_t *jl_gc_big_alloc(jl_ptls_t ptls, size_t sz, jl_value_t *type) +{ + // TODO: assertion needed here? + assert(jl_atomic_load_relaxed(&ptls->gc_state) == 0); + + jl_value_t *val = jl_mmtk_gc_alloc_big(ptls, sz); + maybe_record_alloc_to_profile(val, sz, (jl_datatype_t*)type); + return val; +} + +inline jl_value_t *jl_gc_alloc_(jl_ptls_t ptls, size_t sz, void *ty) +{ + jl_value_t *v; + const size_t allocsz = sz + sizeof(jl_taggedvalue_t); + if (sz <= GC_MAX_SZCLASS) { + v = jl_mmtk_gc_alloc_default(ptls, allocsz, 16, ty); + } + else { + if (allocsz < sz) // overflow in adding offs, size was "negative" + jl_throw(jl_memory_exception); + v = jl_mmtk_gc_alloc_big(ptls, allocsz); + } + jl_set_typeof(v, ty); + maybe_record_alloc_to_profile(v, sz, (jl_datatype_t*)ty); + return v; +} + +// allocation wrappers that track allocation and let collection run +JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + void *data = malloc(sz); + if (data != NULL && pgcstack != NULL && ct->world_age) { + jl_ptls_t ptls = ct->ptls; + malloc_maybe_collect(ptls, sz); + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, sz); + } + return data; +} + +JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + void *data = calloc(nm, sz); + if (data != NULL && pgcstack != NULL && ct->world_age) { + jl_ptls_t ptls = ct->ptls; + malloc_maybe_collect(ptls, nm * sz); + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, nm * sz); + } + return data; +} + +JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + free(p); + if (pgcstack != NULL && ct->world_age) { + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, -sz); + } +} + +JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size_t sz) +{ + jl_gcframe_t **pgcstack = jl_get_pgcstack(); + jl_task_t *ct = jl_current_task; + if (pgcstack && ct->world_age) { + jl_ptls_t ptls = ct->ptls; + malloc_maybe_collect(ptls, sz); + if (sz < old) + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, old - sz); + else + jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, sz - old); + } + return realloc(p, sz); +} + +void *jl_gc_perm_alloc_nolock(size_t sz, int zero, unsigned align, unsigned offset) +{ + jl_ptls_t ptls = jl_current_task->ptls; + size_t allocsz = mmtk_align_alloc_sz(sz); + void* addr = mmtk_immortal_alloc_fast(&ptls->gc_tls.mmtk_mutator, allocsz, align, offset); + return addr; +} + +void *jl_gc_perm_alloc(size_t sz, int zero, unsigned align, unsigned offset) +{ + return jl_gc_perm_alloc_nolock(sz, zero, align, offset); +} + +jl_value_t *jl_gc_permobj(size_t sz, void *ty) JL_NOTSAFEPOINT +{ + const size_t allocsz = sz + sizeof(jl_taggedvalue_t); + unsigned align = (sz == 0 ? sizeof(void*) : (allocsz <= sizeof(void*) * 2 ? + sizeof(void*) * 2 : 16)); + jl_taggedvalue_t *o = (jl_taggedvalue_t*)jl_gc_perm_alloc(allocsz, 0, align, + sizeof(void*) % align); + + jl_ptls_t ptls = jl_current_task->ptls; + mmtk_immortal_post_alloc_fast(&ptls->gc_tls.mmtk_mutator, jl_valueof(o), allocsz); + o->header = (uintptr_t)ty; + return jl_valueof(o); +} + +JL_DLLEXPORT void *jl_gc_managed_malloc(size_t sz) +{ + jl_ptls_t ptls = jl_current_task->ptls; + maybe_collect(ptls); + size_t allocsz = LLT_ALIGN(sz, JL_CACHE_BYTE_ALIGNMENT); + if (allocsz < sz) // overflow in adding offs, size was "negative" + jl_throw(jl_memory_exception); + + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif + void *b = malloc_cache_align(allocsz); + if (b == NULL) + jl_throw(jl_memory_exception); + + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + allocsz); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.malloc, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.malloc) + 1); + // FIXME: Should these be part of mmtk's heap? + // malloc_maybe_collect(ptls, sz); + // jl_atomic_fetch_add_relaxed(&JULIA_MALLOC_BYTES, allocsz); +#ifdef _OS_WINDOWS_ + SetLastError(last_error); +#endif + errno = last_errno; + // jl_gc_managed_malloc is currently always used for allocating array buffers. + maybe_record_alloc_to_profile((jl_value_t*)b, sz, (jl_datatype_t*)jl_buff_tag); + return b; +} + +void jl_gc_notify_image_load(const char* img_data, size_t len) +{ + mmtk_set_vm_space((void*)img_data, len); +} + +// ========================================================================= // +// Code specific to stock that is not supported by MMTk +// ========================================================================= // + +// mutex for page profile +uv_mutex_t page_profile_lock; + +JL_DLLEXPORT void jl_gc_take_page_profile(ios_t *stream) +{ + uv_mutex_lock(&page_profile_lock); + const char *str = "Page profiler in unsupported in MMTk."; + ios_write(stream, str, strlen(str)); + uv_mutex_unlock(&page_profile_lock); +} + +// this seems to be needed by the gc tests +#define JL_GC_N_MAX_POOLS 51 +JL_DLLEXPORT double jl_gc_page_utilization_stats[JL_GC_N_MAX_POOLS]; + +STATIC_INLINE void gc_dump_page_utilization_data(void) JL_NOTSAFEPOINT +{ + // FIXME: MMTk would have to provide its own stats +} + +#define MMTK_GC_PAGE_SZ (1 << 12) // MMTk's page size is defined in mmtk-core constants + +JL_DLLEXPORT uint64_t jl_get_pg_size(void) +{ + return MMTK_GC_PAGE_SZ; +} + +// Not used by mmtk +// Number of GC threads that may run parallel marking +int jl_n_markthreads; +// Number of GC threads that may run concurrent sweeping (0 or 1) +int jl_n_sweepthreads; +// `tid` of first GC thread +int gc_first_tid; +// Number of threads sweeping stacks +_Atomic(int) gc_n_threads_sweeping_stacks; +// counter for sharing work when sweeping stacks +_Atomic(int) gc_ptls_sweep_idx; +// counter for round robin of giving back stack pages to the OS +_Atomic(int) gc_stack_free_idx = 0; + +JL_DLLEXPORT void jl_gc_queue_root(const struct _jl_value_t *ptr) JL_NOTSAFEPOINT +{ + mmtk_unreachable(); +} + +JL_DLLEXPORT void jl_gc_queue_multiroot(const struct _jl_value_t *root, const void *stored, + struct _jl_datatype_t *dt) JL_NOTSAFEPOINT +{ + mmtk_unreachable(); +} + +JL_DLLEXPORT int jl_gc_mark_queue_obj(jl_ptls_t ptls, jl_value_t *obj) +{ + mmtk_unreachable(); + return 0; +} + +JL_DLLEXPORT void jl_gc_mark_queue_objarray(jl_ptls_t ptls, jl_value_t *parent, + jl_value_t **objs, size_t nobjs) +{ + mmtk_unreachable(); +} + +JL_DLLEXPORT size_t jl_gc_max_internal_obj_size(void) +{ + // TODO: meaningful for MMTk? + return GC_MAX_SZCLASS; +} + +JL_DLLEXPORT void jl_gc_schedule_foreign_sweepfunc(jl_ptls_t ptls, jl_value_t *obj) +{ + // FIXME: do we need to implement this? +} + +// gc-debug functions +JL_DLLEXPORT jl_taggedvalue_t *jl_gc_find_taggedvalue_pool(char *p, size_t *osize_p) +{ + return NULL; +} + +void jl_gc_debug_critical_error(void) JL_NOTSAFEPOINT +{ +} + +int gc_is_collector_thread(int tid) JL_NOTSAFEPOINT +{ + return 0; +} + +void jl_gc_debug_print_status(void) JL_NOTSAFEPOINT +{ + // May not be accurate but should be helpful enough + uint64_t pool_count = gc_num.poolalloc; + uint64_t big_count = gc_num.bigalloc; + jl_safe_printf("Allocations: %" PRIu64 " " + "(Pool: %" PRIu64 "; Big: %" PRIu64 "); GC: %d\n", + pool_count + big_count, pool_count, big_count, gc_num.pause); +} + +JL_DLLEXPORT size_t jl_gc_external_obj_hdr_size(void) +{ + return sizeof(bigval_t); +} + +void jl_print_gc_stats(JL_STREAM *s) +{ +} + +JL_DLLEXPORT int jl_gc_enable_conservative_gc_support(void) +{ + return 0; +} + +JL_DLLEXPORT int jl_gc_conservative_gc_support_enabled(void) +{ + return 0; +} + +// TODO: if this is needed, it can be added in MMTk +JL_DLLEXPORT jl_value_t *jl_gc_internal_obj_base_ptr(void *p) +{ + return NULL; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/gc-stacks.c b/src/gc-stacks.c index a0ca2561c5cf9..9387c7fb065ec 100644 --- a/src/gc-stacks.c +++ b/src/gc-stacks.c @@ -1,7 +1,6 @@ // This file is a part of Julia. License is MIT: https://julialang.org/license #include "gc-common.h" -#include "gc-stock.h" #include "threading.h" #ifndef _OS_WINDOWS_ # include @@ -21,9 +20,6 @@ # endif #endif -// number of stacks to always keep available per pool -#define MIN_STACK_MAPPINGS_PER_POOL 5 - const size_t jl_guard_size = (4096 * 8); static _Atomic(uint32_t) num_stack_mappings = 0; @@ -203,99 +199,6 @@ JL_DLLEXPORT void *jl_malloc_stack(size_t *bufsz, jl_task_t *owner) JL_NOTSAFEPO return stk; } -void sweep_stack_pool_loop(void) JL_NOTSAFEPOINT -{ - // Stack sweeping algorithm: - // // deallocate stacks if we have too many sitting around unused - // for (stk in halfof(free_stacks)) - // free_stack(stk, pool_sz); - // // then sweep the task stacks - // for (t in live_tasks) - // if (!gc-marked(t)) - // stkbuf = t->stkbuf - // bufsz = t->bufsz - // if (stkbuf) - // push(free_stacks[sz], stkbuf) - jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, 1); - while (1) { - int i = jl_atomic_fetch_add_relaxed(&gc_ptls_sweep_idx, -1); - if (i < 0) - break; - jl_ptls_t ptls2 = gc_all_tls_states[i]; - if (ptls2 == NULL) - continue; - assert(gc_n_threads); - // free half of stacks that remain unused since last sweep - if (i == jl_atomic_load_relaxed(&gc_stack_free_idx)) { - for (int p = 0; p < JL_N_STACK_POOLS; p++) { - small_arraylist_t *al = &ptls2->gc_tls_common.heap.free_stacks[p]; - size_t n_to_free; - if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { - n_to_free = al->len; // not alive yet or dead, so it does not need these anymore - } - else if (al->len > MIN_STACK_MAPPINGS_PER_POOL) { - n_to_free = al->len / 2; - if (n_to_free > (al->len - MIN_STACK_MAPPINGS_PER_POOL)) - n_to_free = al->len - MIN_STACK_MAPPINGS_PER_POOL; - } - else { - n_to_free = 0; - } - for (int n = 0; n < n_to_free; n++) { - void *stk = small_arraylist_pop(al); - free_stack(stk, pool_sizes[p]); - } - if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { - small_arraylist_free(al); - } - } - } - if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { - small_arraylist_free(ptls2->gc_tls_common.heap.free_stacks); - } - - small_arraylist_t *live_tasks = &ptls2->gc_tls_common.heap.live_tasks; - size_t n = 0; - size_t ndel = 0; - size_t l = live_tasks->len; - void **lst = live_tasks->items; - if (l == 0) - continue; - while (1) { - jl_task_t *t = (jl_task_t*)lst[n]; - assert(jl_is_task(t)); - if (gc_marked(jl_astaggedvalue(t)->bits.gc)) { - if (t->ctx.stkbuf == NULL) - ndel++; // jl_release_task_stack called - else - n++; - } - else { - ndel++; - void *stkbuf = t->ctx.stkbuf; - size_t bufsz = t->ctx.bufsz; - if (stkbuf) { - t->ctx.stkbuf = NULL; - _jl_free_stack(ptls2, stkbuf, bufsz); - } -#ifdef _COMPILER_TSAN_ENABLED_ - if (t->ctx.tsan_state) { - __tsan_destroy_fiber(t->ctx.tsan_state); - t->ctx.tsan_state = NULL; - } -#endif - } - if (n >= l - ndel) - break; - void *tmp = lst[n]; - lst[n] = lst[n + ndel]; - lst[n + ndel] = tmp; - } - live_tasks->len -= ndel; - } - jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, -1); -} - // Builds a list of the live tasks. Racy: `live_tasks` can expand at any time. arraylist_t *jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT { diff --git a/src/gc-stock.c b/src/gc-stock.c index 61a013f347975..8118b3c5629ae 100644 --- a/src/gc-stock.c +++ b/src/gc-stock.c @@ -388,24 +388,18 @@ static void sweep_weak_refs(void) jl_ptls_t ptls2 = gc_all_tls_states[i]; if (ptls2 != NULL) { size_t n = 0; - size_t ndel = 0; + size_t i = 0; size_t l = ptls2->gc_tls_common.heap.weak_refs.len; void **lst = ptls2->gc_tls_common.heap.weak_refs.items; - if (l == 0) - continue; - while (1) { - jl_weakref_t *wr = (jl_weakref_t*)lst[n]; - if (gc_marked(jl_astaggedvalue(wr)->bits.gc)) + // filter with preserving order + for (i = 0; i < l; i++) { + jl_weakref_t *wr = (jl_weakref_t*)lst[i]; + if (gc_marked(jl_astaggedvalue(wr)->bits.gc)) { + lst[n] = wr; n++; - else - ndel++; - if (n >= l - ndel) - break; - void *tmp = lst[n]; - lst[n] = lst[n + ndel]; - lst[n + ndel] = tmp; + } } - ptls2->gc_tls_common.heap.weak_refs.len -= ndel; + ptls2->gc_tls_common.heap.weak_refs.len = n; } } } @@ -429,7 +423,7 @@ STATIC_INLINE void jl_batch_accum_free_size(jl_ptls_t ptls, uint64_t sz) JL_NOTS // big value list -// Size includes the tag and the tag is not cleared!! +// Size includes the tag and the tag field is undefined on return (must be set before the next GC safepoint) STATIC_INLINE jl_value_t *jl_gc_big_alloc_inner(jl_ptls_t ptls, size_t sz) { maybe_collect(ptls); @@ -454,6 +448,9 @@ STATIC_INLINE jl_value_t *jl_gc_big_alloc_inner(jl_ptls_t ptls, size_t sz) memset(v, 0xee, allocsz); #endif v->sz = allocsz; +#ifndef NDEBUG + v->header = 0; // must be initialized (and not gc_bigval_sentinel_tag) or gc_big_object_link assertions will get confused +#endif gc_big_object_link(ptls->gc_tls.heap.young_generation_of_bigvals, v); return jl_valueof(&v->header); } @@ -629,10 +626,9 @@ void jl_gc_reset_alloc_count(void) JL_NOTSAFEPOINT reset_thread_gc_counts(); } -static void jl_gc_free_memory(jl_value_t *v, int isaligned) JL_NOTSAFEPOINT +static void jl_gc_free_memory(jl_genericmemory_t *m, int isaligned) JL_NOTSAFEPOINT { - assert(jl_is_genericmemory(v)); - jl_genericmemory_t *m = (jl_genericmemory_t*)v; + assert(jl_is_genericmemory(m)); assert(jl_genericmemory_how(m) == 1 || jl_genericmemory_how(m) == 2); char *d = (char*)m->ptr; size_t freed_bytes = memory_block_usable_size(d, isaligned); @@ -654,25 +650,23 @@ static void sweep_malloced_memory(void) JL_NOTSAFEPOINT for (int t_i = 0; t_i < gc_n_threads; t_i++) { jl_ptls_t ptls2 = gc_all_tls_states[t_i]; if (ptls2 != NULL) { - mallocmemory_t *ma = ptls2->gc_tls_common.heap.mallocarrays; - mallocmemory_t **pma = &ptls2->gc_tls_common.heap.mallocarrays; - while (ma != NULL) { - mallocmemory_t *nxt = ma->next; - jl_value_t *a = (jl_value_t*)((uintptr_t)ma->a & ~1); - int bits = jl_astaggedvalue(a)->bits.gc; - if (gc_marked(bits)) { - pma = &ma->next; + size_t n = 0; + size_t l = ptls2->gc_tls_common.heap.mallocarrays.len; + void **lst = ptls2->gc_tls_common.heap.mallocarrays.items; + // filter without preserving order + while (n < l) { + jl_genericmemory_t *m = (jl_genericmemory_t*)((uintptr_t)lst[n] & ~1); + if (gc_marked(jl_astaggedvalue(m)->bits.gc)) { + n++; } else { - *pma = nxt; - int isaligned = (uintptr_t)ma->a & 1; - jl_gc_free_memory(a, isaligned); - ma->next = ptls2->gc_tls_common.heap.mafreelist; - ptls2->gc_tls_common.heap.mafreelist = ma; + int isaligned = (uintptr_t)lst[n] & 1; + jl_gc_free_memory(m, isaligned); + l--; + lst[n] = lst[l]; } - gc_time_count_mallocd_memory(bits); - ma = nxt; } + ptls2->gc_tls_common.heap.mallocarrays.len = l; } } gc_time_mallocd_memory_end(); @@ -990,9 +984,12 @@ STATIC_INLINE void gc_sweep_pool_page(gc_page_profiler_serializer_t *s, jl_gc_pa // sweep over all memory that is being used and not in a pool static void gc_sweep_other(jl_ptls_t ptls, int sweep_full) JL_NOTSAFEPOINT { + uint64_t t_free_mallocd_memory_start = jl_hrtime(); gc_sweep_foreign_objs(); sweep_malloced_memory(); sweep_big(ptls); + uint64_t t_free_mallocd_memory_end = jl_hrtime(); + gc_num.total_sweep_free_mallocd_memory_time += t_free_mallocd_memory_end - t_free_mallocd_memory_start; jl_engine_sweep(gc_all_tls_states); } @@ -1019,22 +1016,102 @@ void gc_sweep_wait_for_all_stacks(void) JL_NOTSAFEPOINT } } -void sweep_mtarraylist_buffers(void) JL_NOTSAFEPOINT +extern const unsigned pool_sizes[]; + +void sweep_stack_pool_loop(void) JL_NOTSAFEPOINT { - for (int i = 0; i < gc_n_threads; i++) { - jl_ptls_t ptls = gc_all_tls_states[i]; - if (ptls == NULL) { + // Stack sweeping algorithm: + // // deallocate stacks if we have too many sitting around unused + // for (stk in halfof(free_stacks)) + // free_stack(stk, pool_sz); + // // then sweep the task stacks + // for (t in live_tasks) + // if (!gc-marked(t)) + // stkbuf = t->stkbuf + // bufsz = t->bufsz + // if (stkbuf) + // push(free_stacks[sz], stkbuf) + jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, 1); + while (1) { + int i = jl_atomic_fetch_add_relaxed(&gc_ptls_sweep_idx, -1); + if (i < 0) + break; + jl_ptls_t ptls2 = gc_all_tls_states[i]; + if (ptls2 == NULL) continue; + assert(gc_n_threads); + // free half of stacks that remain unused since last sweep + if (i == jl_atomic_load_relaxed(&gc_stack_free_idx)) { + for (int p = 0; p < JL_N_STACK_POOLS; p++) { + small_arraylist_t *al = &ptls2->gc_tls_common.heap.free_stacks[p]; + size_t n_to_free; + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + n_to_free = al->len; // not alive yet or dead, so it does not need these anymore + } + else if (al->len > MIN_STACK_MAPPINGS_PER_POOL) { + n_to_free = al->len / 2; + if (n_to_free > (al->len - MIN_STACK_MAPPINGS_PER_POOL)) + n_to_free = al->len - MIN_STACK_MAPPINGS_PER_POOL; + } + else { + n_to_free = 0; + } + for (int n = 0; n < n_to_free; n++) { + void *stk = small_arraylist_pop(al); + free_stack(stk, pool_sizes[p]); + } + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(al); + } + } + } + if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) { + small_arraylist_free(ptls2->gc_tls_common.heap.free_stacks); } - small_arraylist_t *buffers = &ptls->lazily_freed_mtarraylist_buffers; - void *buf; - while ((buf = small_arraylist_pop(buffers)) != NULL) { - free(buf); + + small_arraylist_t *live_tasks = &ptls2->gc_tls_common.heap.live_tasks; + size_t n = 0; + size_t ndel = 0; + size_t l = live_tasks->len; + void **lst = live_tasks->items; + if (l == 0) + continue; + while (1) { + jl_task_t *t = (jl_task_t*)lst[n]; + assert(jl_is_task(t)); + if (gc_marked(jl_astaggedvalue(t)->bits.gc)) { + if (t->ctx.stkbuf == NULL) + ndel++; // jl_release_task_stack called + else + n++; + } + else { + ndel++; + void *stkbuf = t->ctx.stkbuf; + size_t bufsz = t->ctx.bufsz; + if (stkbuf) { + t->ctx.stkbuf = NULL; + _jl_free_stack(ptls2, stkbuf, bufsz); + } +#ifdef _COMPILER_TSAN_ENABLED_ + if (t->ctx.tsan_state) { + __tsan_destroy_fiber(t->ctx.tsan_state); + t->ctx.tsan_state = NULL; + } +#endif + } + if (n >= l - ndel) + break; + void *tmp = lst[n]; + lst[n] = lst[n + ndel]; + lst[n + ndel] = tmp; } + live_tasks->len -= ndel; } + jl_atomic_fetch_add(&gc_n_threads_sweeping_stacks, -1); } -void sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT +JL_DLLEXPORT void jl_gc_sweep_stack_pools_and_mtarraylist_buffers(jl_ptls_t ptls) JL_NOTSAFEPOINT { // initialize ptls index for parallel sweeping of stack pools assert(gc_n_threads); @@ -1306,58 +1383,63 @@ static void gc_sweep_pool(void) } } - // the actual sweeping - jl_gc_padded_page_stack_t *new_gc_allocd_scratch = (jl_gc_padded_page_stack_t *) calloc_s(n_threads * sizeof(jl_gc_padded_page_stack_t)); - jl_ptls_t ptls = jl_current_task->ptls; - gc_sweep_wake_all_pages(ptls, new_gc_allocd_scratch); - gc_sweep_pool_parallel(ptls); - gc_sweep_wait_for_all_pages(); - - // reset half-pages pointers - for (int t_i = 0; t_i < n_threads; t_i++) { - jl_ptls_t ptls2 = gc_all_tls_states[t_i]; - if (ptls2 != NULL) { - ptls2->gc_tls.page_metadata_allocd = new_gc_allocd_scratch[t_i].stack; - for (int i = 0; i < JL_GC_N_POOLS; i++) { - jl_gc_pool_t *p = &ptls2->gc_tls.heap.norm_pools[i]; - p->newpages = NULL; + uint64_t t_page_walk_start = jl_hrtime(); + { + // the actual sweeping + jl_gc_padded_page_stack_t *new_gc_allocd_scratch = (jl_gc_padded_page_stack_t *) calloc_s(n_threads * sizeof(jl_gc_padded_page_stack_t)); + jl_ptls_t ptls = jl_current_task->ptls; + gc_sweep_wake_all_pages(ptls, new_gc_allocd_scratch); + gc_sweep_pool_parallel(ptls); + gc_sweep_wait_for_all_pages(); + + // reset half-pages pointers + for (int t_i = 0; t_i < n_threads; t_i++) { + jl_ptls_t ptls2 = gc_all_tls_states[t_i]; + if (ptls2 != NULL) { + ptls2->gc_tls.page_metadata_allocd = new_gc_allocd_scratch[t_i].stack; + for (int i = 0; i < JL_GC_N_POOLS; i++) { + jl_gc_pool_t *p = &ptls2->gc_tls.heap.norm_pools[i]; + p->newpages = NULL; + } } } - } - // merge free lists - for (int t_i = 0; t_i < n_threads; t_i++) { - jl_ptls_t ptls2 = gc_all_tls_states[t_i]; - if (ptls2 == NULL) { - continue; - } - jl_gc_pagemeta_t *pg = jl_atomic_load_relaxed(&ptls2->gc_tls.page_metadata_allocd.bottom); - while (pg != NULL) { - jl_gc_pagemeta_t *pg2 = pg->next; - if (pg->fl_begin_offset != UINT16_MAX) { - char *cur_pg = pg->data; - jl_taggedvalue_t *fl_beg = (jl_taggedvalue_t*)(cur_pg + pg->fl_begin_offset); - jl_taggedvalue_t *fl_end = (jl_taggedvalue_t*)(cur_pg + pg->fl_end_offset); - *pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = fl_beg; - pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = &fl_end->next; + // merge free lists + for (int t_i = 0; t_i < n_threads; t_i++) { + jl_ptls_t ptls2 = gc_all_tls_states[t_i]; + if (ptls2 == NULL) { + continue; + } + jl_gc_pagemeta_t *pg = jl_atomic_load_relaxed(&ptls2->gc_tls.page_metadata_allocd.bottom); + while (pg != NULL) { + jl_gc_pagemeta_t *pg2 = pg->next; + if (pg->fl_begin_offset != UINT16_MAX) { + char *cur_pg = pg->data; + jl_taggedvalue_t *fl_beg = (jl_taggedvalue_t*)(cur_pg + pg->fl_begin_offset); + jl_taggedvalue_t *fl_end = (jl_taggedvalue_t*)(cur_pg + pg->fl_end_offset); + *pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = fl_beg; + pfl[t_i * JL_GC_N_POOLS + pg->pool_n] = &fl_end->next; + } + pg = pg2; } - pg = pg2; } - } - // null out terminal pointers of free lists - for (int t_i = 0; t_i < n_threads; t_i++) { - jl_ptls_t ptls2 = gc_all_tls_states[t_i]; - if (ptls2 != NULL) { - for (int i = 0; i < JL_GC_N_POOLS; i++) { - *pfl[t_i * JL_GC_N_POOLS + i] = NULL; + // null out terminal pointers of free lists + for (int t_i = 0; t_i < n_threads; t_i++) { + jl_ptls_t ptls2 = gc_all_tls_states[t_i]; + if (ptls2 != NULL) { + for (int i = 0; i < JL_GC_N_POOLS; i++) { + *pfl[t_i * JL_GC_N_POOLS + i] = NULL; + } } } - } - // cleanup - free(pfl); - free(new_gc_allocd_scratch); + // cleanup + free(pfl); + free(new_gc_allocd_scratch); + } + uint64_t t_page_walk_end = jl_hrtime(); + gc_num.total_sweep_page_walk_time += t_page_walk_end - t_page_walk_start; #ifdef _P64 // only enable concurrent sweeping on 64bit // wake thread up to sweep concurrently @@ -1365,7 +1447,10 @@ static void gc_sweep_pool(void) uv_sem_post(&gc_sweep_assists_needed); } else { + uint64_t t_madvise_start = jl_hrtime(); gc_free_pages(); + uint64_t t_madvise_end = jl_hrtime(); + gc_num.total_sweep_madvise_time += t_madvise_end - t_madvise_start; } #else gc_free_pages(); @@ -3096,7 +3181,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection) current_sweep_full = sweep_full; sweep_weak_refs(); uint64_t stack_pool_time = jl_hrtime(); - sweep_stack_pools_and_mtarraylist_buffers(ptls); + jl_gc_sweep_stack_pools_and_mtarraylist_buffers(ptls); stack_pool_time = jl_hrtime() - stack_pool_time; gc_num.total_stack_pool_sweep_time += stack_pool_time; gc_num.stack_pool_sweep_time = stack_pool_time; @@ -3439,8 +3524,7 @@ void jl_init_thread_heap(jl_ptls_t ptls) small_arraylist_new(&common_heap->live_tasks, 0); for (int i = 0; i < JL_N_STACK_POOLS; i++) small_arraylist_new(&common_heap->free_stacks[i], 0); - common_heap->mallocarrays = NULL; - common_heap->mafreelist = NULL; + small_arraylist_new(&common_heap->mallocarrays, 0); heap->young_generation_of_bigvals = (bigval_t*)calloc_s(sizeof(bigval_t)); // sentinel assert(gc_bigval_sentinel_tag != 0); // make sure the sentinel is initialized heap->young_generation_of_bigvals->header = gc_bigval_sentinel_tag; @@ -3655,61 +3739,6 @@ JL_DLLEXPORT uint64_t jl_gc_get_max_memory(void) // allocation wrappers that add to gc pressure -JL_DLLEXPORT void *jl_malloc(size_t sz) -{ - return jl_gc_counted_malloc(sz); -} - -//_unchecked_calloc does not check for potential overflow of nm*sz -STATIC_INLINE void *_unchecked_calloc(size_t nm, size_t sz) { - size_t nmsz = nm*sz; - return jl_gc_counted_calloc(nmsz, 1); -} - -JL_DLLEXPORT void *jl_calloc(size_t nm, size_t sz) -{ - if (nm > SSIZE_MAX/sz) - return NULL; - return _unchecked_calloc(nm, sz); -} - -JL_DLLEXPORT void jl_free(void *p) -{ - if (p != NULL) { - size_t sz = memory_block_usable_size(p, 0); - free(p); - jl_task_t *ct = jl_get_current_task(); - if (ct != NULL) - jl_batch_accum_free_size(ct->ptls, sz); - } -} - -JL_DLLEXPORT void *jl_realloc(void *p, size_t sz) -{ - size_t old = p ? memory_block_usable_size(p, 0) : 0; - void *data = realloc(p, sz); - jl_task_t *ct = jl_get_current_task(); - if (data != NULL && ct != NULL) { - sz = memory_block_usable_size(data, 0); - jl_ptls_t ptls = ct->ptls; - maybe_collect(ptls); - if (!(sz < old)) - jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, - jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + (sz - old)); - jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.realloc, - jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.realloc) + 1); - - int64_t diff = sz - old; - if (diff < 0) { - jl_batch_accum_free_size(ptls, -diff); - } - else { - jl_batch_accum_heap_size(ptls, diff); - } - } - return data; -} - JL_DLLEXPORT void *jl_gc_counted_malloc(size_t sz) { void *data = malloc(sz); @@ -3746,12 +3775,34 @@ JL_DLLEXPORT void *jl_gc_counted_calloc(size_t nm, size_t sz) JL_DLLEXPORT void jl_gc_counted_free_with_size(void *p, size_t sz) { - return jl_free(p); + free(p); + jl_task_t *ct = jl_get_current_task(); + if (ct != NULL) + jl_batch_accum_free_size(ct->ptls, sz); } JL_DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size_t sz) { - return jl_realloc(p, sz); + void *data = realloc(p, sz); + jl_task_t *ct = jl_get_current_task(); + if (data != NULL && ct != NULL) { + sz = memory_block_usable_size(data, 0); + jl_ptls_t ptls = ct->ptls; + maybe_collect(ptls); + if (!(sz < old)) + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.allocd, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.allocd) + (sz - old)); + jl_atomic_store_relaxed(&ptls->gc_tls_common.gc_num.realloc, + jl_atomic_load_relaxed(&ptls->gc_tls_common.gc_num.realloc) + 1); + int64_t diff = sz - old; + if (diff < 0) { + jl_batch_accum_free_size(ptls, -diff); + } + else { + jl_batch_accum_heap_size(ptls, diff); + } + } + return data; } // allocating blocks for Arrays and Strings @@ -4015,12 +4066,20 @@ JL_DLLEXPORT size_t jl_gc_external_obj_hdr_size(void) return sizeof(bigval_t); } - JL_DLLEXPORT void jl_gc_schedule_foreign_sweepfunc(jl_ptls_t ptls, jl_value_t *obj) { arraylist_push(&ptls->gc_tls.sweep_objs, obj); } +void jl_gc_notify_image_load(const char* img_data, size_t len) +{ + // Do nothing +} + +JL_DLLEXPORT const char* jl_gc_active_impl(void) { + return "Built with stock GC"; +} + #ifdef __cplusplus } #endif diff --git a/src/gc-stock.h b/src/gc-stock.h index b9a2e720f120a..d478ee1366da0 100644 --- a/src/gc-stock.h +++ b/src/gc-stock.h @@ -5,7 +5,6 @@ . non-moving, precise mark and sweep collector . pool-allocates small objects, keeps big objects on a simple list */ - #ifndef JL_GC_H #define JL_GC_H @@ -20,6 +19,7 @@ #include "julia_internal.h" #include "julia_assert.h" #include "threading.h" +#include "gc-common.h" #ifdef __cplusplus extern "C" { @@ -85,27 +85,6 @@ typedef struct _jl_gc_chunk_t { extern uintptr_t gc_bigval_sentinel_tag; -JL_EXTENSION typedef struct _bigval_t { - struct _bigval_t *next; - struct _bigval_t *prev; - size_t sz; -#ifdef _P64 // Add padding so that the value is 64-byte aligned - // (8 pointers of 8 bytes each) - (4 other pointers in struct) - void *_padding[8 - 4]; -#else - // (16 pointers of 4 bytes each) - (4 other pointers in struct) - void *_padding[16 - 4]; -#endif - //struct jl_taggedvalue_t <>; - union { - uintptr_t header; - struct { - uintptr_t gc:2; - } bits; - }; - // must be 64-byte aligned here, in 32 & 64 bit modes -} bigval_t; - // pool page metadata typedef struct _jl_gc_pagemeta_t { // next metadata structure in per-thread list @@ -519,9 +498,6 @@ extern uv_cond_t gc_threads_cond; extern uv_sem_t gc_sweep_assists_needed; extern _Atomic(int) gc_n_threads_marking; extern _Atomic(int) gc_n_threads_sweeping_pools; -extern _Atomic(int) gc_n_threads_sweeping_stacks; -extern _Atomic(int) gc_ptls_sweep_idx; -extern _Atomic(int) gc_stack_free_idx; extern _Atomic(int) n_threads_running; extern uv_barrier_t thread_init_done; void gc_mark_queue_all_roots(jl_ptls_t ptls, jl_gc_markqueue_t *mq); diff --git a/src/gc-tls-common.h b/src/gc-tls-common.h index ba36f5c1c238e..473668d648294 100644 --- a/src/gc-tls-common.h +++ b/src/gc-tls-common.h @@ -21,9 +21,8 @@ typedef struct { // that are holding onto a stack from the pool small_arraylist_t live_tasks; - // variables for tracking malloc'd arrays - struct _mallocmemory_t *mallocarrays; - struct _mallocmemory_t *mafreelist; + // variable for tracking malloc'd arrays + small_arraylist_t mallocarrays; #define JL_N_STACK_POOLS 16 small_arraylist_t free_stacks[JL_N_STACK_POOLS]; diff --git a/src/gc-tls-mmtk.h b/src/gc-tls-mmtk.h new file mode 100644 index 0000000000000..5b69aef5d55fb --- /dev/null +++ b/src/gc-tls-mmtk.h @@ -0,0 +1,23 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#ifndef JL_GC_TLS_H +#define JL_GC_TLS_H + +#include +#include "mmtkMutator.h" +#include "julia_atomics.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + MMTkMutatorContext mmtk_mutator; + _Atomic(size_t) malloc_sz_since_last_poll; +} jl_gc_tls_states_t; + +#ifdef __cplusplus +} +#endif + +#endif // JL_GC_TLS_H diff --git a/src/gc-tls.h b/src/gc-tls-stock.h similarity index 100% rename from src/gc-tls.h rename to src/gc-tls-stock.h diff --git a/src/genericmemory.c b/src/genericmemory.c index 2b02f021ccdd0..e435ec3b63c9f 100644 --- a/src/genericmemory.c +++ b/src/genericmemory.c @@ -24,49 +24,51 @@ JL_DLLEXPORT char *jl_genericmemory_typetagdata(jl_genericmemory_t *m) JL_NOTSAF return (char*)m->ptr + m->length * layout->size; } -#if defined(_P64) && defined(UINT128MAX) -typedef __uint128_t wideint_t; -#else -typedef uint64_t wideint_t; -#endif - #define MAXINTVAL (((size_t)-1)>>1) -jl_genericmemory_t *_new_genericmemory_(jl_value_t *mtype, size_t nel, int8_t isunion, int8_t zeroinit, size_t elsz) +// ONLY USE FROM CODEGEN. It only partially initializes the mem +JL_DLLEXPORT jl_genericmemory_t *jl_alloc_genericmemory_unchecked(jl_ptls_t ptls, size_t nbytes, jl_datatype_t *mtype) { - jl_task_t *ct = jl_current_task; - char *data; - jl_genericmemory_t *m; - if (nel == 0) // zero-sized allocation optimization - return (jl_genericmemory_t*)((jl_datatype_t*)mtype)->instance; - wideint_t prod = (wideint_t)nel * elsz; - if (isunion) { - // an extra byte for each isbits union memory element, stored at m->ptr + m->length - prod += nel; - } - if (nel >= MAXINTVAL || prod >= (wideint_t) MAXINTVAL) - jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); - size_t tot = (size_t)prod + LLT_ALIGN(sizeof(jl_genericmemory_t),JL_SMALL_BYTE_ALIGNMENT); + size_t tot = nbytes + LLT_ALIGN(sizeof(jl_genericmemory_t),JL_SMALL_BYTE_ALIGNMENT); int pooled = tot <= GC_MAX_SZCLASS; + char *data; + jl_genericmemory_t *m; if (!pooled) { - data = (char*)jl_gc_managed_malloc(prod); + data = (char*)jl_gc_managed_malloc(nbytes); tot = sizeof(jl_genericmemory_t) + sizeof(void*); } - m = (jl_genericmemory_t*)jl_gc_alloc(ct->ptls, tot, mtype); + m = (jl_genericmemory_t*)jl_gc_alloc(ptls, tot, mtype); if (pooled) { data = (char*)m + JL_SMALL_BYTE_ALIGNMENT; } else { int isaligned = 1; // jl_gc_managed_malloc is always aligned - jl_gc_track_malloced_genericmemory(ct->ptls, m, isaligned); + jl_gc_track_malloced_genericmemory(ptls, m, isaligned); jl_genericmemory_data_owner_field(m) = (jl_value_t*)m; } - m->length = nel; + // length set by codegen m->ptr = data; + return m; +} +jl_genericmemory_t *_new_genericmemory_(jl_value_t *mtype, size_t nel, int8_t isunion, int8_t zeroinit, size_t elsz) +{ + if (nel == 0) // zero-sized allocation optimization + return (jl_genericmemory_t*)((jl_datatype_t*)mtype)->instance; + size_t nbytes; + int overflow = __builtin_mul_overflow(nel, elsz, &nbytes); + if (isunion) { + // an extra byte for each isbits union memory element, stored at m->ptr + m->length + overflow |= __builtin_add_overflow(nel, nbytes, &nbytes); + } + if ((nel >= MAXINTVAL-1) || (nbytes >= MAXINTVAL-1) || overflow) + jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); + jl_task_t *ct = jl_current_task; + jl_genericmemory_t *m = jl_alloc_genericmemory_unchecked((jl_ptls_t) ct->ptls, nbytes, (jl_datatype_t*)mtype); + m->length = nel; if (zeroinit) - memset(data, 0, (size_t)prod); + memset((char*)m->ptr, 0, nbytes); return m; } @@ -150,13 +152,14 @@ JL_DLLEXPORT jl_genericmemory_t *jl_ptr_to_genericmemory(jl_value_t *mtype, void if (((uintptr_t)data) & ((align > JL_HEAP_ALIGNMENT ? JL_HEAP_ALIGNMENT : align) - 1)) jl_exceptionf(jl_argumenterror_type, "unsafe_wrap: pointer %p is not properly aligned to %u bytes", data, align); - wideint_t prod = (wideint_t)nel * elsz; + size_t nbytes; + int overflow = __builtin_mul_overflow(nel, elsz, &nbytes); if (isunion) { // an extra byte for each isbits union memory element, stored at m->ptr + m->length - prod += nel; + overflow |= __builtin_add_overflow(nel, nbytes, &nbytes); } - if (nel >= MAXINTVAL || prod >= (wideint_t) MAXINTVAL) - jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: too large for system address width"); + if ((nel >= MAXINTVAL) || (nbytes >= MAXINTVAL) || overflow) + jl_exceptionf(jl_argumenterror_type, "invalid GenericMemory size: the number of elements is either negative or too large for system address width"); int tsz = sizeof(jl_genericmemory_t) + sizeof(void*); m = (jl_genericmemory_t*)jl_gc_alloc(ct->ptls, tsz, mtype); m->ptr = data; diff --git a/src/gf.c b/src/gf.c index bbf065a4fac0d..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); } @@ -323,7 +324,7 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, jl_nothing, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); jl_mi_cache_insert(mi, codeinst); jl_atomic_store_relaxed(&codeinst->specptr.fptr1, fptr); jl_atomic_store_relaxed(&codeinst->invoke, jl_fptr_args); @@ -337,14 +338,71 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a return dt; } +// only relevant for bootstrapping. otherwise fairly broken. +static int emit_codeinst_and_edges(jl_code_instance_t *codeinst) +{ + jl_value_t *code = jl_atomic_load_relaxed(&codeinst->inferred); + if (code) { + if (jl_atomic_load_relaxed(&codeinst->invoke) != NULL) + return 1; + if (code != jl_nothing) { + JL_GC_PUSH1(&code); + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); + jl_method_t *def = mi->def.method; + if (jl_is_string(code) && jl_is_method(def)) + code = (jl_value_t*)jl_uncompress_ir(def, codeinst, (jl_value_t*)code); + if (jl_is_code_info(code)) { + jl_emit_codeinst_to_jit(codeinst, (jl_code_info_t*)code); + if (0) { + // next emit all the invoke edges too (if this seems profitable) + jl_array_t *src = ((jl_code_info_t*)code)->code; + for (size_t i = 0; i < jl_array_dim0(src); i++) { + jl_value_t *stmt = jl_array_ptr_ref(src, i); + if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == jl_assign_sym) + stmt = jl_exprarg(stmt, 1); + if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == jl_invoke_sym) { + jl_value_t *invoke = jl_exprarg(stmt, 0); + if (jl_is_code_instance(invoke)) + emit_codeinst_and_edges((jl_code_instance_t*)invoke); + } + } + } + JL_GC_POP(); + return 1; + } + JL_GC_POP(); + } + } + return 0; +} + +// Opportunistic SOURCE_MODE_ABI cache lookup, only for bootstrapping. +static jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) +{ + jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); + for (; codeinst; codeinst = jl_atomic_load_relaxed(&codeinst->next)) { + if (codeinst->owner != jl_nothing) + continue; + if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)) { + if (emit_codeinst_and_edges(codeinst)) + return codeinst; + } + } + return NULL; +} + // run type inference on lambda "mi" for given argument types. // returns the inferred source, and may cache the result in mi // if successful, also updates the mi argument to describe the validity of this src // if inference doesn't occur (or can't finish), returns NULL instead jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_t source_mode) { - if (jl_typeinf_func == NULL) - return NULL; + if (jl_typeinf_func == NULL) { + if (source_mode == SOURCE_MODE_ABI) + return jl_method_inferred_with_abi(mi, world); + else + return NULL; + } jl_task_t *ct = jl_current_task; if (ct->reentrant_timing & 0b1000) { // We must avoid attempting to re-enter inference here @@ -366,6 +424,10 @@ jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_ fargs[1] = (jl_value_t*)mi; fargs[2] = jl_box_ulong(world); fargs[3] = jl_box_uint8(source_mode); + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif jl_timing_show_method_instance(mi, JL_TIMING_DEFAULT_BLOCK); #ifdef TRACE_INFERENCE @@ -374,10 +436,6 @@ jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_ jl_static_show_func_sig(JL_STDERR, (jl_value_t*)mi->specTypes); jl_printf(JL_STDERR, "\n"); } -#endif - int last_errno = errno; -#ifdef _OS_WINDOWS_ - DWORD last_error = GetLastError(); #endif int last_pure = ct->ptls->in_pure_callback; ct->ptls->in_pure_callback = 0; @@ -507,7 +565,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( } codeinst = jl_new_codeinst( mi, owner, rettype, (jl_value_t*)jl_any_type, NULL, NULL, - 0, min_world, max_world, 0, jl_nothing, 0, di, edges); + 0, min_world, max_world, 0, jl_nothing, di, edges); jl_mi_cache_insert(mi, codeinst); return codeinst; } @@ -524,13 +582,39 @@ JL_DLLEXPORT int jl_mi_cache_has_ci(jl_method_instance_t *mi, return 0; } +// look for something with an egal ABI and properties that is already in the JIT (compiled=true) or simply in the cache (compiled=false) +JL_DLLEXPORT jl_code_instance_t *jl_get_ci_equiv(jl_code_instance_t *ci JL_PROPAGATES_ROOT, int compiled) JL_NOTSAFEPOINT +{ + jl_value_t *def = ci->def; + jl_method_instance_t *mi = jl_get_ci_mi(ci); + jl_value_t *owner = ci->owner; + jl_value_t *rettype = ci->rettype; + size_t min_world = jl_atomic_load_relaxed(&ci->min_world); + size_t max_world = jl_atomic_load_relaxed(&ci->max_world); + jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); + while (codeinst) { + if (codeinst != ci && + jl_atomic_load_relaxed(&codeinst->inferred) != NULL && + (!compiled || jl_atomic_load_relaxed(&codeinst->invoke) != NULL) && + jl_atomic_load_relaxed(&codeinst->min_world) <= min_world && + jl_atomic_load_relaxed(&codeinst->max_world) >= max_world && + jl_egal(codeinst->def, def) && + jl_egal(codeinst->owner, owner) && + jl_egal(codeinst->rettype, rettype)) { + return codeinst; + } + codeinst = jl_atomic_load_relaxed(&codeinst->next); + } + return (jl_code_instance_t*)jl_nothing; +} + + JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_method_instance_t *mi, jl_value_t *owner, jl_value_t *rettype, jl_value_t *exctype, jl_value_t *inferred_const, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /*, int absolute_max*/) { assert(min_world <= max_world && "attempting to set invalid world constraints"); @@ -538,7 +622,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_task_t *ct = jl_current_task; jl_code_instance_t *codeinst = (jl_code_instance_t*)jl_gc_alloc(ct->ptls, sizeof(jl_code_instance_t), jl_code_instance_type); - codeinst->def = mi; + codeinst->def = (jl_value_t*)mi; codeinst->owner = owner; jl_atomic_store_relaxed(&codeinst->edges, edges); jl_atomic_store_relaxed(&codeinst->min_world, min_world); @@ -561,7 +645,6 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_atomic_store_relaxed(&codeinst->next, NULL); jl_atomic_store_relaxed(&codeinst->ipo_purity_bits, effects); codeinst->analysis_results = analysis_results; - codeinst->relocatability = relocatability; return codeinst; } @@ -569,11 +652,10 @@ JL_DLLEXPORT void jl_update_codeinst( jl_code_instance_t *codeinst, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/) + jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/) { assert(min_world <= max_world && "attempting to set invalid world constraints"); //assert((!jl_is_method(codeinst->def->def.value) || max_world != ~(size_t)0 || min_world <= 1 || jl_svec_len(edges) != 0) && "missing edges"); - codeinst->relocatability = relocatability; codeinst->analysis_results = analysis_results; jl_gc_wb(codeinst, analysis_results); jl_atomic_store_relaxed(&codeinst->ipo_purity_bits, effects); @@ -631,7 +713,7 @@ JL_DLLEXPORT void jl_fill_codeinst( JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_uninit(jl_method_instance_t *mi, jl_value_t *owner) { - jl_code_instance_t *codeinst = jl_new_codeinst(mi, owner, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL); + jl_code_instance_t *codeinst = jl_new_codeinst(mi, owner, NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL); jl_atomic_store_relaxed(&codeinst->min_world, 1); // make temporarily invalid before returning, so that jl_fill_codeinst is valid later return codeinst; } @@ -1772,17 +1854,23 @@ static void invalidate_code_instance(jl_code_instance_t *replaced, size_t max_wo JL_GC_POP(); } //jl_static_show(JL_STDERR, (jl_value_t*)replaced->def); - if (!jl_is_method(replaced->def->def.method)) + jl_method_instance_t *replaced_mi = jl_get_ci_mi(replaced); + if (!jl_is_method(replaced_mi->def.method)) return; // shouldn't happen, but better to be safe - JL_LOCK(&replaced->def->def.method->writelock); + JL_LOCK(&replaced_mi->def.method->writelock); if (jl_atomic_load_relaxed(&replaced->max_world) == ~(size_t)0) { assert(jl_atomic_load_relaxed(&replaced->min_world) - 1 <= max_world && "attempting to set illogical world constraints (probable race condition)"); jl_atomic_store_release(&replaced->max_world, max_world); } assert(jl_atomic_load_relaxed(&replaced->max_world) <= max_world); // recurse to all backedges to update their valid range also - _invalidate_backedges(replaced->def, max_world, depth + 1); - JL_UNLOCK(&replaced->def->def.method->writelock); + _invalidate_backedges(replaced_mi, max_world, depth + 1); + JL_UNLOCK(&replaced_mi->def.method->writelock); +} + +JL_DLLEXPORT void jl_invalidate_code_instance(jl_code_instance_t *replaced, size_t max_world) +{ + invalidate_code_instance(replaced, max_world, 1); } static void _invalidate_backedges(jl_method_instance_t *replaced_mi, size_t max_world, int depth) { @@ -2329,7 +2417,7 @@ void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) int replaced_edge; if (invokeTypes) { // n.b. normally we must have mi.specTypes <: invokeTypes <: m.sig (though it might not strictly hold), so we only need to check the other subtypes - if (jl_egal(invokeTypes, caller->def->def.method->sig)) + if (jl_egal(invokeTypes, jl_get_ci_mi(caller)->def.method->sig)) replaced_edge = 0; // if invokeTypes == m.sig, then the only way to change this invoke is to replace the method itself else replaced_edge = jl_subtype(invokeTypes, type) && is_replacing(ambig, type, m, d, n, invokeTypes, NULL, morespec); @@ -2566,23 +2654,6 @@ jl_code_instance_t *jl_method_compiled(jl_method_instance_t *mi, size_t world) return NULL; } -// Opportunistic SOURCE_MODE_ABI cache lookup. -jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) -{ - jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); - for (; codeinst; codeinst = jl_atomic_load_relaxed(&codeinst->next)) { - if (codeinst->owner != jl_nothing) - continue; - - if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)) { - jl_value_t *code = jl_atomic_load_relaxed(&codeinst->inferred); - if (code && (code != jl_nothing || (jl_atomic_load_relaxed(&codeinst->invoke) != NULL))) - return codeinst; - } - } - return NULL; -} - jl_mutex_t precomp_statement_out_lock; _Atomic(uint8_t) jl_force_trace_compile_timing_enabled = 0; @@ -2721,6 +2792,7 @@ void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_c initial_invoke = jl_atomic_load_acquire(&ci->invoke); // happens-before for subsequent read of fptr } void *fptr = jl_atomic_load_relaxed(&ci->specptr.fptr); + // TODO: if fptr is NULL, it may mean we read this too fast, and should have spun and waited for jl_compile_codeinst to finish if (initial_invoke == NULL || fptr == NULL) { *invoke = initial_invoke; *specptr = NULL; @@ -2743,6 +2815,25 @@ void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_c jl_method_instance_t *jl_normalize_to_compilable_mi(jl_method_instance_t *mi JL_PROPAGATES_ROOT); +JL_DLLEXPORT void jl_add_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src) +{ + assert(jl_is_code_info(src)); + jl_emit_codeinst_to_jit(codeinst, src); + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); + if (jl_generating_output() && jl_is_method(mi->def.method) && jl_atomic_load_relaxed(&codeinst->inferred) == jl_nothing) { + jl_value_t *compressed = jl_compress_ir(mi->def.method, src); + // These should already be compatible (and should be an assert), but make sure of it anyways + if (jl_is_svec(src->edges)) { + jl_atomic_store_release(&codeinst->edges, (jl_svec_t*)src->edges); + jl_gc_wb(codeinst, src->edges); + } + jl_atomic_store_release(&codeinst->debuginfo, src->debuginfo); + jl_gc_wb(codeinst, src->debuginfo); + jl_atomic_store_release(&codeinst->inferred, compressed); + jl_gc_wb(codeinst, compressed); + } +} + jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t world) { // quick check if we already have a compiled result @@ -2813,15 +2904,14 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_method_instance_t *unspecmi = jl_atomic_load_relaxed(&def->unspecialized); if (unspecmi) { jl_code_instance_t *unspec = jl_atomic_load_relaxed(&unspecmi->cache); - jl_callptr_t unspec_invoke = NULL; - if (unspec && (unspec_invoke = jl_atomic_load_acquire(&unspec->invoke))) { + if (unspec && jl_atomic_load_acquire(&unspec->invoke) != NULL) { uint8_t specsigflags; jl_callptr_t invoke; void *fptr; jl_read_codeinst_invoke(unspec, &specsigflags, &invoke, &fptr, 1); jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); codeinst->rettype_const = unspec->rettype_const; jl_atomic_store_relaxed(&codeinst->specptr.fptr, fptr); jl_atomic_store_relaxed(&codeinst->invoke, invoke); @@ -2842,7 +2932,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t if (!jl_code_requires_compiler(src, 0)) { jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); jl_atomic_store_release(&codeinst->invoke, jl_fptr_interpret_call); jl_mi_cache_insert(mi, codeinst); record_precompile_statement(mi, 0, 0); @@ -2856,15 +2946,21 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t } // Ok, compilation is enabled. We'll need to try to compile something (probably). - // Try to find a codeinst we have already inferred (e.g. while we were compiling - // something else). - codeinst = jl_method_inferred_with_abi(mi, world); // Everything from here on is considered (user facing) compile time uint64_t start = jl_typeinf_timing_begin(); - int is_recompile = jl_atomic_load_relaxed(&mi->cache) != NULL; - // This codeinst hasn't been previously inferred do that now + // Is a recompile if there is cached code, and it was compiled (not only inferred) before + int is_recompile = 0; + jl_code_instance_t *codeinst_old = jl_atomic_load_relaxed(&mi->cache); + while (codeinst_old != NULL) { + if (jl_atomic_load_relaxed(&codeinst_old->invoke) != NULL) { + is_recompile = 1; + break; + } + codeinst_old = jl_atomic_load_relaxed(&codeinst_old->next); + } + // jl_type_infer will internally do a cache lookup and jl_engine_reserve call // to synchronize this across threads if (!codeinst) { @@ -2878,7 +2974,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t } if (codeinst) { - if (jl_atomic_load_acquire(&codeinst->invoke) != NULL) { + if (jl_is_compiled_codeinst(codeinst)) { jl_typeinf_timing_end(start, is_recompile); // Already compiled - e.g. constabi, or compiled by a different thread while we were waiting. return codeinst; @@ -2907,7 +3003,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_callptr_t ucache_invoke = jl_atomic_load_acquire(&ucache->invoke); if (ucache_invoke == NULL) { if ((!jl_is_method(def) || def->source == jl_nothing) && - !jl_cached_uninferred(jl_atomic_load_relaxed(&ucache->def->cache), world)) { + !jl_cached_uninferred(jl_atomic_load_relaxed(&jl_get_ci_mi(ucache)->cache), world)) { jl_throw(jl_new_struct(jl_missingcodeerror_type, (jl_value_t*)mi)); } jl_generate_fptr_for_unspecialized(ucache); @@ -2926,7 +3022,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t jl_read_codeinst_invoke(ucache, &specsigflags, &invoke, &fptr, 1); codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, NULL, NULL); codeinst->rettype_const = ucache->rettype_const; // unspec is always not specsig, but might use specptr jl_atomic_store_relaxed(&codeinst->specptr.fptr, fptr); @@ -2939,21 +3035,21 @@ 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 = m->def->sparam_vals; + jl_svec_t *sparams = jl_get_ci_mi(m)->sparam_vals; assert(sparams != jl_emptysvec); jl_fptr_sparam_t invoke = jl_atomic_load_relaxed(&m->specptr.fptr3); assert(invoke && "Forgot to set specptr for jl_fptr_sparam!"); @@ -2964,12 +3060,32 @@ jl_value_t *jl_fptr_wait_for_compiled(jl_value_t *f, jl_value_t **args, uint32_t { jl_callptr_t invoke = jl_atomic_load_acquire(&m->invoke); if (invoke == &jl_fptr_wait_for_compiled) { + int64_t last_alloc = jl_options.malloc_log ? jl_gc_diff_total_bytes() : 0; + int last_errno = errno; +#ifdef _OS_WINDOWS_ + DWORD last_error = GetLastError(); +#endif jl_compile_codeinst(m); +#ifdef _OS_WINDOWS_ + SetLastError(last_error); +#endif + errno = last_errno; + if (jl_options.malloc_log) + jl_gc_sync_total_bytes(last_alloc); // discard allocation count from compilation invoke = jl_atomic_load_acquire(&m->invoke); } return invoke(f, args, nargs, m); } +// test whether codeinst->invoke is usable already without further compilation needed +JL_DLLEXPORT int jl_is_compiled_codeinst(jl_code_instance_t *codeinst) +{ + jl_callptr_t invoke = jl_atomic_load_relaxed(&codeinst->invoke); + if (invoke == NULL || invoke == &jl_fptr_wait_for_compiled) + return 0; + return 1; +} + JL_DLLEXPORT const jl_callptr_t jl_fptr_args_addr = &jl_fptr_args; JL_DLLEXPORT const jl_callptr_t jl_fptr_const_return_addr = &jl_fptr_const_return; @@ -3084,7 +3200,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_method_match_to_mi(jl_method_match_t *matc } // compile-time method lookup -jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES_ROOT, size_t world, size_t *min_valid, size_t *max_valid, int mt_cache) +jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES_ROOT, size_t world, int mt_cache) { if (jl_has_free_typevars((jl_value_t*)types)) return NULL; // don't poison the cache due to a malformed query @@ -3096,10 +3212,6 @@ jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES size_t max_valid2 = ~(size_t)0; int ambig = 0; jl_value_t *matches = jl_matching_methods(types, jl_nothing, 1, 1, world, &min_valid2, &max_valid2, &ambig); - if (*min_valid < min_valid2) - *min_valid = min_valid2; - if (*max_valid > max_valid2) - *max_valid = max_valid2; if (matches == jl_nothing || jl_array_nrows(matches) != 1 || ambig) return NULL; JL_GC_PUSH1(&matches); @@ -3369,6 +3481,18 @@ JL_DLLEXPORT jl_value_t *jl_invoke(jl_value_t *F, jl_value_t **args, uint32_t na return _jl_invoke(F, args, nargs, mfunc, world); } +JL_DLLEXPORT jl_value_t *jl_invoke_oc(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_method_instance_t *mfunc) +{ + jl_opaque_closure_t *oc = (jl_opaque_closure_t*)F; + jl_task_t *ct = jl_current_task; + size_t last_age = ct->world_age; + size_t world = oc->world; + ct->world_age = world; + jl_value_t *ret = _jl_invoke(F, args, nargs, mfunc, world); + ct->world_age = last_age; + return ret; +} + STATIC_INLINE int sig_match_fast(jl_value_t *arg1t, jl_value_t **args, jl_value_t **sig, size_t n) { // NOTE: This function is a huge performance hot spot!! @@ -3667,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); @@ -3678,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); @@ -3685,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); @@ -3693,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/interpreter.c b/src/interpreter.c index fa4fba94a60a5..338853b56f692 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -154,7 +154,7 @@ static jl_value_t *do_invoke(jl_value_t **args, size_t nargs, interpreter_state if (codeinst->owner != jl_nothing) { jl_error("Failed to invoke or compile external codeinst"); } - result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, codeinst->def); + result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, jl_get_ci_mi(codeinst)); } } else { result = jl_invoke(argv[0], nargs == 2 ? NULL : &argv[1], nargs - 2, (jl_method_instance_t*)c); @@ -251,22 +251,15 @@ static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s) else if (head == jl_isdefined_sym) { jl_value_t *sym = args[0]; int defined = 0; - int allow_import = 1; - if (nargs == 2) { - assert(jl_is_bool(args[1]) && "malformed IR"); - allow_import = args[1] == jl_true; - } + assert(nargs == 1 && "malformed IR"); if (jl_is_slotnumber(sym) || jl_is_argument(sym)) { ssize_t n = jl_slot_number(sym); if (src == NULL || n > jl_source_nslots(src) || n < 1 || s->locals == NULL) jl_error("access to invalid slot number"); defined = s->locals[n - 1] != NULL; } - else if (jl_is_globalref(sym)) { - defined = jl_boundp(jl_globalref_mod(sym), jl_globalref_name(sym), allow_import); - } - else if (jl_is_symbol(sym)) { - defined = jl_boundp(s->module, (jl_sym_t*)sym, allow_import); + else if (jl_is_globalref(sym) || jl_is_symbol(sym)) { + jl_error("[Internal Error]: :isdefined on globalref should use `isdefinedglobal`"); } else if (jl_is_expr(sym) && ((jl_expr_t*)sym)->head == jl_static_parameter_sym) { ssize_t n = jl_unbox_long(jl_exprarg(sym, 0)); @@ -767,7 +760,7 @@ jl_code_info_t *jl_code_for_interpreter(jl_method_instance_t *mi, size_t world) jl_value_t *NOINLINE jl_fptr_interpret_call(jl_value_t *f, jl_value_t **args, uint32_t nargs, jl_code_instance_t *codeinst) { interpreter_state *s; - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); jl_task_t *ct = jl_current_task; size_t world = ct->world_age; jl_code_info_t *src = NULL; @@ -893,10 +886,7 @@ jl_value_t *NOINLINE jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info_t s->mi = NULL; s->ci = NULL; JL_GC_ENABLEFRAME(s); - jl_task_t *ct = jl_current_task; - size_t last_age = ct->world_age; jl_value_t *r = eval_body(stmts, s, 0, 1); - ct->world_age = last_age; JL_GC_POP(); return r; } 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/ircode.c b/src/ircode.c index 9e64e3fe2b574..99c5833ac3be7 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -1194,7 +1194,7 @@ JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t ios_close(s.s); JL_UNLOCK(&m->writelock); // Might GC if (metadata) { - code->parent = metadata->def; + code->parent = jl_get_ci_mi(metadata); jl_gc_wb(code, code->parent); code->rettype = metadata->rettype; jl_gc_wb(code, code->rettype); diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 80867daade267..0acb7beaca9ab 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -272,7 +272,7 @@ static void finish_params(Module *M, jl_codegen_params_t ¶ms) JL_NOTSAFEPOIN // the fiction that we don't know what loads from the global will return. Thus, we // need to emit a separate module for the globals before any functions are compiled, // to ensure that the globals are defined when they are compiled. - if (params.imaging_mode) { + if (jl_options.image_codegen) { if (!params.global_targets.empty()) { void **globalslots = new void*[params.global_targets.size()]; void **slot = globalslots; @@ -301,7 +301,6 @@ static void finish_params(Module *M, jl_codegen_params_t ¶ms) JL_NOTSAFEPOIN } } - static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t ¶ms, bool forceall=false) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER { jl_task_t *ct = jl_current_task; @@ -309,6 +308,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t std::swap(params.workqueue, edges); for (auto &it : edges) { jl_code_instance_t *codeinst = it.first; + JL_GC_PROMISE_ROOTED(codeinst); auto &proto = it.second; // try to emit code for this item from the workqueue StringRef invokeName = ""; @@ -321,7 +321,7 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t // But it must be consistent with the following invokenames lookup, which is protected by the engine_lock uint8_t specsigflags; void *fptr; - void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_callptr_t *invoke, void **specptr, int waitcompile) JL_NOTSAFEPOINT; // not a safepoint (or deadlock) in this file due to 0 parameter + void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_callptr_t *invoke, void **specptr, int waitcompile) JL_NOTSAFEPOINT; // declare it is not a safepoint (or deadlock) in this file due to 0 parameter jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); //if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) if (invoke == jl_fptr_args_addr) { @@ -349,6 +349,40 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t force = true; } } + if (preal_decl.empty()) { + // there may be an equivalent method already compiled (or at least registered with the JIT to compile), in which case we should be using that instead + jl_code_instance_t *compiled_ci = jl_get_ci_equiv(codeinst, 1); + if ((jl_value_t*)compiled_ci != jl_nothing) { + codeinst = compiled_ci; + uint8_t specsigflags; + void *fptr; + jl_read_codeinst_invoke(codeinst, &specsigflags, &invoke, &fptr, 0); + //if (specsig ? specsigflags & 0b1 : invoke == jl_fptr_args_addr) + if (invoke == jl_fptr_args_addr) { + preal_decl = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); + } + else if (specsigflags & 0b1) { + preal_decl = jl_ExecutionEngine->getFunctionAtAddress((uintptr_t)fptr, invoke, codeinst); + preal_specsig = true; + } + if (preal_decl.empty()) { + auto it = invokenames.find(codeinst); + if (it != invokenames.end()) { + auto &decls = it->second; + invokeName = decls.functionObject; + if (decls.functionObject == "jl_fptr_args") { + preal_decl = decls.specFunctionObject; + isedge = true; + } + else if (decls.functionObject != "jl_fptr_sparam" && decls.functionObject != "jl_f_opaque_closure_call") { + preal_decl = decls.specFunctionObject; + preal_specsig = true; + isedge = true; + } + } + } + } + } if (!preal_decl.empty() || force) { // if we have a prototype emitted, compare it to what we emitted earlier Module *mod = proto.decl->getParent(); @@ -379,10 +413,10 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t jl_init_function(proto.decl, params.TargetTriple); // TODO: maybe this can be cached in codeinst->specfptr? int8_t gc_state = jl_gc_unsafe_enter(ct->ptls); // codegen may contain safepoints (such as jl_subtype calls) - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure; - emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke, 0, 0); + emit_specsig_to_fptr1(proto.decl, proto.cc, proto.return_roots, mi->specTypes, codeinst->rettype, is_opaque_closure, nrealargs, params, pinvoke); jl_gc_unsafe_leave(ct->ptls, gc_state); preal_decl = ""; // no need to fixup the name } @@ -445,15 +479,6 @@ static int jl_analyze_workqueue(jl_code_instance_t *callee, jl_codegen_params_t return params.workqueue.size(); } -// test whether codeinst->invoke is usable already without further compilation needed -static bool jl_is_compiled_codeinst(jl_code_instance_t *codeinst) JL_NOTSAFEPOINT -{ - auto invoke = jl_atomic_load_relaxed(&codeinst->invoke); - if (invoke == nullptr || invoke == jl_fptr_wait_for_compiled_addr) - return false; - return true; -} - // move codeinst (and deps) from incompletemodules to emitted modules // and populate compileready from complete_graph static void prepare_compile(jl_code_instance_t *codeinst) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER @@ -569,7 +594,7 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst) jl_ExecutionEngine->addModule(std::move(TSM)); // may safepoint // If logging of the compilation stream is enabled, // then dump the method-instance specialization type to the stream - jl_method_instance_t *mi = codeinst->def; + jl_method_instance_t *mi = jl_get_ci_mi(codeinst); if (jl_is_method(mi->def.method)) { auto stream = *jl_ExecutionEngine->get_dump_compiles_stream(); if (stream) { @@ -674,10 +699,15 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst) } } -static void jl_emit_codeinst_to_jit( +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( jl_code_instance_t *codeinst, jl_code_info_t *src) { + if (jl_is_compiled_codeinst(codeinst)) + return; { // lock scope jl_unique_gcsafe_lock lock(engine_lock); if (invokenames.count(codeinst) || jl_is_compiled_codeinst(codeinst)) @@ -688,9 +718,9 @@ static void jl_emit_codeinst_to_jit( jl_codegen_params_t params(std::make_unique(), jl_ExecutionEngine->getDataLayout(), jl_ExecutionEngine->getTargetTriple()); // Locks the context params.getContext().setDiscardValueNames(true); params.cache = true; - params.imaging_mode = imaging_default(); + params.imaging_mode = 0; orc::ThreadSafeModule result_m = - jl_create_ts_module(name_from_method_instance(codeinst->def), params.tsctx, params.DL, params.TargetTriple); + jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)), params.tsctx, params.DL, params.TargetTriple); params.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0); JL_GC_PUSH1(¶ms.temporary_roots); jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, src, params); // contains safepoints @@ -698,7 +728,7 @@ static void jl_emit_codeinst_to_jit( JL_GC_POP(); return; } - jl_optimize_roots(params, codeinst->def, *result_m.getModuleUnlocked()); // contains safepoints + jl_optimize_roots(params, jl_get_ci_mi(codeinst), *result_m.getModuleUnlocked()); // contains safepoints params.temporary_roots = nullptr; JL_GC_POP(); { // drop lock before acquiring engine_lock @@ -707,13 +737,31 @@ static void jl_emit_codeinst_to_jit( jl_unique_gcsafe_lock lock(engine_lock); if (invokenames.count(codeinst) || jl_is_compiled_codeinst(codeinst)) return; // destroy everything + const std::string &specf = decls.specFunctionObject; + const std::string &f = decls.functionObject; + assert(!f.empty()); + // Prepare debug info to receive this function + // record that this function name came from this linfo, + // so we can build a reverse mapping for debug-info. + bool toplevel = !jl_is_method(jl_get_ci_mi(codeinst)->def.method); + if (!toplevel) { + // don't remember toplevel thunks because + // they may not be rooted in the gc for the life of the program, + // and the runtime doesn't notify us when the code becomes unreachable :( + if (!specf.empty()) + jl_add_code_in_flight(specf, codeinst, params.DL); + if (f != "jl_fptr_args" && f != "jl_fptr_sparam") + jl_add_code_in_flight(f, codeinst, params.DL); + } + jl_callptr_t expected = NULL; + jl_atomic_cmpswap_relaxed(&codeinst->invoke, &expected, jl_fptr_wait_for_compiled_addr); invokenames[codeinst] = std::move(decls); complete_emit(codeinst); params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock int waiting = jl_analyze_workqueue(codeinst, params); if (waiting) { auto release = std::move(params.tsctx_lock); // unlock again before moving from it - incompletemodules.insert(std::pair(codeinst, std::make_tuple(std::move(params), waiting))); + incompletemodules.try_emplace(codeinst, std::move(params), waiting); } else { finish_params(result_m.getModuleUnlocked(), params); @@ -721,46 +769,8 @@ static void jl_emit_codeinst_to_jit( emittedmodules[codeinst] = std::move(result_m); } -static void recursive_compile_graph( - jl_code_instance_t *codeinst, - jl_code_info_t *src) -{ - jl_emit_codeinst_to_jit(codeinst, src); - DenseSet Seen; - SmallVector workqueue; - workqueue.push_back(codeinst); - // if any edges were incomplete, try to complete them now - while (!workqueue.empty()) { - auto this_code = workqueue.pop_back_val(); - if (Seen.insert(this_code).second) { - if (this_code != codeinst) { - JL_GC_PROMISE_ROOTED(this_code); // rooted transitively from following edges from original argument - jl_emit_codeinst_to_jit(this_code, nullptr); // contains safepoints - } - jl_unique_gcsafe_lock lock(engine_lock); - auto edges = complete_graph.find(this_code); - if (edges != complete_graph.end()) { - workqueue.append(edges->second); - } - } - } -} - -// this generates llvm code for the lambda info -// and adds the result to the jitlayers -// (and the shadow module), -// and generates code for it -static void _jl_compile_codeinst( - jl_code_instance_t *codeinst, - jl_code_info_t *src) -{ - recursive_compile_graph(codeinst, src); - jl_compile_codeinst_now(codeinst); - assert(jl_is_compiled_codeinst(codeinst)); -} - -const char *jl_generate_ccallable(LLVMOrcThreadSafeModuleRef llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms); +const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t ¶ms); // compile a C-callable alias extern "C" JL_DLLEXPORT_CODEGEN @@ -774,45 +784,70 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void * 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(); + jl_codegen_params_t *pparams = (jl_codegen_params_t*)p; + DataLayout DL = pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout(); + Triple TargetTriple = pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple(); orc::ThreadSafeContext ctx; auto into = unwrap(llvmmod); - jl_codegen_params_t *pparams = (jl_codegen_params_t*)p; orc::ThreadSafeModule backing; + bool success = true; + const char *name = ""; if (into == NULL) { - if (!pparams) { - ctx = jl_ExecutionEngine->makeContext(); - } - backing = jl_create_ts_module("cextern", pparams ? pparams->tsctx : ctx, pparams ? pparams->DL : jl_ExecutionEngine->getDataLayout(), pparams ? pparams->TargetTriple : jl_ExecutionEngine->getTargetTriple()); + ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext(); + backing = jl_create_ts_module("cextern", ctx, DL, TargetTriple); into = &backing; } - bool success = true; - { - auto Lock = into->getContext().getLock(); - Module *M = into->getModuleUnlocked(); - jl_codegen_params_t params(into->getContext(), M->getDataLayout(), Triple(M->getTargetTriple())); - params.imaging_mode = imaging_default(); + { // params scope + jl_codegen_params_t params(into->getContext(), DL, TargetTriple); if (pparams == NULL) { - M->getContext().setDiscardValueNames(true); + params.cache = p == NULL; + params.imaging_mode = 0; + params.tsctx.getContext()->setDiscardValueNames(true); pparams = ¶ms; } - assert(pparams->tsctx.getContext() == into->getContext().getContext()); - const char *name = jl_generate_ccallable(wrap(into), sysimg, declrt, sigt, *pparams); - if (!sysimg) { - jl_unique_gcsafe_lock lock(extern_c_lock); - if (jl_ExecutionEngine->getGlobalValueAddress(name)) { - success = false; + Module &M = *into->getModuleUnlocked(); + assert(pparams->tsctx.getContext() == &M.getContext()); + name = jl_generate_ccallable(&M, sysimg, declrt, sigt, *pparams); + if (!sysimg && !p) { + { // drop lock to keep analyzer happy (since it doesn't know we have the only reference to it) + auto release = std::move(params.tsctx_lock); } - if (success && p == NULL) { - jl_jit_globals(params.global_targets); - assert(params.workqueue.empty()); - if (params._shared_module) { - jl_ExecutionEngine->optimizeDLSyms(*params._shared_module); // safepoint - jl_ExecutionEngine->addModule(orc::ThreadSafeModule(std::move(params._shared_module), params.tsctx)); + { // lock scope + jl_unique_gcsafe_lock lock(extern_c_lock); + if (jl_ExecutionEngine->getGlobalValueAddress(name)) + success = false; + } + params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock + if (success && params.cache) { + size_t newest_world = jl_atomic_load_acquire(&jl_world_counter); + for (auto &it : params.workqueue) { // really just zero or one, and just the ABI not the rest of the metadata + jl_code_instance_t *codeinst = it.first; + JL_GC_PROMISE_ROOTED(codeinst); + jl_code_instance_t *newest_ci = jl_type_infer(jl_get_ci_mi(codeinst), newest_world, SOURCE_MODE_ABI); + if (newest_ci) { + if (jl_egal(codeinst->rettype, newest_ci->rettype)) + it.first = codeinst; + jl_compile_codeinst_now(newest_ci); + } } + jl_analyze_workqueue(nullptr, params, true); + assert(params.workqueue.empty()); + finish_params(&M, params); } - if (success && llvmmod == NULL) { - jl_ExecutionEngine->optimizeDLSyms(*M); // safepoint - jl_ExecutionEngine->addModule(std::move(*into)); + } + pparams = nullptr; + } + if (!sysimg && success && llvmmod == NULL) { + { // lock scope + jl_unique_gcsafe_lock lock(extern_c_lock); + if (!jl_ExecutionEngine->getGlobalValueAddress(name)) { + { + auto Lock = backing.getContext().getLock(); + jl_ExecutionEngine->optimizeDLSyms(*backing.getModuleUnlocked()); // safepoint + } + jl_ExecutionEngine->addModule(std::move(backing)); + success = jl_ExecutionEngine->getGlobalValueAddress(name); + assert(success); } } } @@ -876,7 +911,7 @@ int jl_compile_codeinst_impl(jl_code_instance_t *ci) if (!jl_is_compiled_codeinst(ci)) { ++SpecFPtrCount; uint64_t start = jl_typeinf_timing_begin(); - _jl_compile_codeinst(ci, NULL); + jl_compile_codeinst_now(ci); jl_typeinf_timing_end(start, 0); newly_compiled = 1; } @@ -899,16 +934,15 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec) compiler_start_time = jl_hrtime(); jl_code_info_t *src = NULL; JL_GC_PUSH1(&src); - jl_method_t *def = unspec->def->def.method; + jl_method_t *def = jl_get_ci_mi(unspec)->def.method; if (jl_is_method(def)) { src = (jl_code_info_t*)def->source; if (src && (jl_value_t*)src != jl_nothing) src = jl_uncompress_ir(def, NULL, (jl_value_t*)src); } else { - jl_method_instance_t *mi = unspec->def; - jl_code_instance_t *uninferred = jl_cached_uninferred( - jl_atomic_load_relaxed(&mi->cache), 1); + jl_method_instance_t *mi = jl_get_ci_mi(unspec); + jl_code_instance_t *uninferred = jl_cached_uninferred(jl_atomic_load_relaxed(&mi->cache), 1); assert(uninferred); src = (jl_code_info_t*)jl_atomic_load_relaxed(&uninferred->inferred); assert(src); @@ -919,10 +953,16 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec) if (!jl_is_compiled_codeinst(unspec)) { assert(jl_is_code_info(src)); ++UnspecFPtrCount; + jl_svec_t *edges = (jl_svec_t*)src->edges; + if (jl_is_svec(edges)) { + jl_atomic_store_release(&unspec->edges, edges); // n.b. this assumes the field was always empty svec(), which is not entirely true + jl_gc_wb(unspec, edges); + } jl_debuginfo_t *debuginfo = src->debuginfo; jl_atomic_store_release(&unspec->debuginfo, debuginfo); // n.b. this assumes the field was previously NULL, which is not entirely true jl_gc_wb(unspec, debuginfo); - _jl_compile_codeinst(unspec, src); + jl_emit_codeinst_to_jit(unspec, src); + jl_compile_codeinst_now(unspec); } JL_UNLOCK(&jitlock); // Might GC } @@ -1270,9 +1310,7 @@ class ForwardingMemoryManager : public RuntimeDyld::MemoryManager { size_t Size) override { return MemMgr->registerEHFrames(Addr, LoadAddr, Size); } - virtual void deregisterEHFrames() override { - return MemMgr->deregisterEHFrames(); - } + virtual void deregisterEHFrames() override { /* not actually supported or allowed with this */ } virtual bool finalizeMemory(std::string *ErrMsg = nullptr) override { bool b = false; if (MemMgr.use_count() == 2) @@ -1343,7 +1381,7 @@ namespace { #endif #endif uint32_t target_flags = 0; - auto target = jl_get_llvm_target(imaging_default(), target_flags); + auto target = jl_get_llvm_target(jl_generating_output(), target_flags); auto &TheCPU = target.first; SmallVector targetFeatures(target.second.begin(), target.second.end()); std::string errorstr; @@ -2213,7 +2251,7 @@ StringRef JuliaOJIT::getFunctionAtAddress(uint64_t Addr, jl_callptr_t invoke, jl else { stream_fname << "jlsys_"; } - const char* unadorned_name = jl_symbol_name(codeinst->def->def.method->name); + const char* unadorned_name = jl_symbol_name(jl_get_ci_mi(codeinst)->def.method->name); stream_fname << unadorned_name << "_" << RLST_inc++; *fname = std::move(stream_fname.str()); // store to ReverseLocalSymbolTable addGlobalMapping(*fname, Addr); diff --git a/src/jitlayers.h b/src/jitlayers.h index 6665be6a33faa..4637670ec588c 100644 --- a/src/jitlayers.h +++ b/src/jitlayers.h @@ -68,8 +68,6 @@ using namespace llvm; -extern "C" jl_cgparams_t jl_default_cgparams; - DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ThreadSafeContext, LLVMOrcThreadSafeContextRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(orc::ThreadSafeModule, LLVMOrcThreadSafeModuleRef) @@ -78,10 +76,6 @@ void jl_merge_module(orc::ThreadSafeModule &dest, orc::ThreadSafeModule src) JL_ GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M) JL_NOTSAFEPOINT; DataLayout jl_create_datalayout(TargetMachine &TM) JL_NOTSAFEPOINT; -static inline bool imaging_default() JL_NOTSAFEPOINT { - return jl_options.image_codegen || (jl_generating_output() && (!jl_options.incremental || jl_options.use_pkgimages)); -} - struct OptimizationOptions { bool lower_intrinsics; bool dump_native; @@ -184,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; @@ -260,23 +259,27 @@ struct jl_codegen_params_t { bool external_linkage = false; bool imaging_mode; bool use_swiftcc = true; - jl_codegen_params_t(orc::ThreadSafeContext ctx, DataLayout DL, Triple triple) + jl_codegen_params_t(orc::ThreadSafeContext ctx, DataLayout DL, Triple triple) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER : tsctx(std::move(ctx)), tsctx_lock(tsctx.getLock()), DL(std::move(DL)), TargetTriple(std::move(triple)), - imaging_mode(imaging_default()) + imaging_mode(1) { // LLVM's RISC-V back-end currently does not support the Swift calling convention if (TargetTriple.isRISCV()) use_swiftcc = false; } + jl_codegen_params_t(jl_codegen_params_t &&) JL_NOTSAFEPOINT = default; + ~jl_codegen_params_t() JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE = default; }; jl_llvm_functions_t jl_emit_code( orc::ThreadSafeModule &M, jl_method_instance_t *mi, jl_code_info_t *src, + jl_value_t *abi_at, + jl_value_t *abi_rt, jl_codegen_params_t ¶ms); jl_llvm_functions_t jl_emit_codeinst( @@ -299,8 +302,7 @@ void emit_specsig_to_fptr1( jl_value_t *calltype, jl_value_t *rettype, bool is_for_opaque_closure, size_t nargs, jl_codegen_params_t ¶ms, - Function *target, - size_t min_world, size_t max_world) JL_NOTSAFEPOINT; + Function *target) JL_NOTSAFEPOINT; Function *get_or_emit_fptr1(StringRef Name, Module *M) JL_NOTSAFEPOINT; void jl_init_function(Function *F, const Triple &TT) JL_NOTSAFEPOINT; @@ -646,7 +648,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" diff --git a/src/jl_exported_data.inc b/src/jl_exported_data.inc index 8711c14514145..62acce6ce1d65 100644 --- a/src/jl_exported_data.inc +++ b/src/jl_exported_data.inc @@ -116,6 +116,7 @@ XX(jl_simplevector_type) \ XX(jl_slotnumber_type) \ XX(jl_ssavalue_type) \ + XX(jl_abioverride_type) \ XX(jl_stackovf_exception) \ XX(jl_string_type) \ XX(jl_symbol_type) \ diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 71a78b1c20fc7..c1b29a091511b 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -240,7 +240,6 @@ XX(jl_has_typevar_from_unionall) \ XX(jl_hrtime) \ XX(jl_idtable_rehash) \ - XX(jl_infer_thunk) \ XX(jl_init) \ XX(jl_init_options) \ XX(jl_init_restored_module) \ @@ -389,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) \ @@ -450,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) \ @@ -517,6 +515,7 @@ #define JL_CODEGEN_EXPORTED_FUNCS(YY) \ YY(jl_dump_function_ir) \ YY(jl_dump_method_asm) \ + YY(jl_emit_codeinst_to_jit) \ YY(jl_extern_c) \ YY(jl_get_llvmf_defn) \ YY(jl_get_llvm_function) \ @@ -542,6 +541,7 @@ YY(jl_dump_emitted_mi_name) \ YY(jl_dump_llvm_opt) \ YY(jl_dump_fptr_asm) \ + YY(jl_emit_native) \ YY(jl_get_function_id) \ YY(jl_type_to_llvm) \ YY(jl_getUnwindInfo) \ 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/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/jltypes.c b/src/jltypes.c index abd1f62092035..b478ce7ea98fd 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -910,7 +910,7 @@ JL_DLLEXPORT jl_value_t *jl_type_unionall(jl_tvar_t *v, jl_value_t *body) if (jl_options.depwarn) { if (jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) jl_error("Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead).\nYou may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`."); - jl_printf(JL_STDERR, "WARNING: Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead).\nYou may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`.\n"); + jl_printf(JL_STDERR, "WARNING: Wrapping `Vararg` directly in UnionAll is deprecated (wrap the tuple instead).\nYou may need to write `f(x::Vararg{T})` rather than `f(x::Vararg{<:T})` or `f(x::Vararg{T}) where T` instead of `f(x::Vararg{T} where T)`.\nTo make this warning an error, and hence obtain a stack trace, use `julia --depwarn=error`.\n"); } jl_vararg_t *vm = (jl_vararg_t*)body; int T_has_tv = vm->T && jl_has_typevar(vm->T, v); @@ -3638,7 +3638,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_code_instance_type = jl_new_datatype(jl_symbol("CodeInstance"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(18, + jl_perm_symsvec(17, "def", "owner", "next", @@ -3653,10 +3653,10 @@ void jl_init_types(void) JL_GC_DISABLED //"absolute_max", "ipo_purity_bits", "analysis_results", - "specsigflags", "precompile", "relocatability", + "specsigflags", "precompile", "invoke", "specptr"), // function object decls - jl_svec(18, - jl_method_instance_type, + jl_svec(17, + jl_any_type, jl_any_type, jl_any_type, jl_ulong_type, @@ -3672,13 +3672,12 @@ void jl_init_types(void) JL_GC_DISABLED jl_any_type, jl_bool_type, jl_bool_type, - jl_uint8_type, jl_any_type, jl_any_type), // fptrs jl_emptysvec, 0, 1, 1); jl_svecset(jl_code_instance_type->types, 2, jl_code_instance_type); - const static uint32_t code_instance_constfields[1] = { 0b000001000011100011 }; // Set fields 1, 2, 6-8, 13 as const - const static uint32_t code_instance_atomicfields[1] = { 0b110110111100011100 }; // Set fields 3-5, 9-12, 14-15, 17-18 as atomic + const static uint32_t code_instance_constfields[1] = { 0b00001000011100011 }; // Set fields 1, 2, 6-8, 13 as const + const static uint32_t code_instance_atomicfields[1] = { 0b11110111100011100 }; // Set fields 3-5, 9-12, 14-17 as atomic // Fields 4-5 are only operated on by construction and deserialization, so are effectively const at runtime // Fields ipo_purity_bits and analysis_results are not currently threadsafe or reliable, as they get mutated after optimization, but are not declared atomic // and there is no way to tell (during inference) if their value is finalized yet (to wait for them to be narrowed if applicable) @@ -3854,8 +3853,8 @@ void jl_init_types(void) JL_GC_DISABLED jl_svecset(jl_method_type->types, 13, jl_method_instance_type); //jl_svecset(jl_debuginfo_type->types, 0, jl_method_instance_type); // union(jl_method_instance_type, jl_method_type, jl_symbol_type) jl_svecset(jl_method_instance_type->types, 4, jl_code_instance_type); + jl_svecset(jl_code_instance_type->types, 15, jl_voidpointer_type); jl_svecset(jl_code_instance_type->types, 16, jl_voidpointer_type); - jl_svecset(jl_code_instance_type->types, 17, jl_voidpointer_type); jl_svecset(jl_binding_type->types, 0, jl_globalref_type); jl_svecset(jl_binding_partition_type->types, 3, jl_binding_partition_type); @@ -3952,6 +3951,7 @@ void post_boot_hooks(void) jl_weakref_type = (jl_datatype_t*)core("WeakRef"); jl_vecelement_typename = ((jl_datatype_t*)jl_unwrap_unionall(core("VecElement")))->name; jl_nulldebuginfo = (jl_debuginfo_t*)core("NullDebugInfo"); + jl_abioverride_type = (jl_datatype_t*)core("ABIOverride"); jl_init_box_caches(); diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index c522a565f462a..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- @@ -1022,7 +1023,7 @@ (call (core svec) ,@attrs) ,mut ,min-initialized)) (call (core _setsuper!) ,name ,super) - (if (isdefined (globalref (thismodule) ,name) (false)) + (if (call (core isdefinedglobal) (thismodule) (inert ,name) (false)) (block (= ,prev (globalref (thismodule) ,name)) (if (call (core _equiv_typedef) ,prev ,name) @@ -1084,7 +1085,7 @@ (= ,name (call (core _abstracttype) (thismodule) (inert ,name) (call (core svec) ,@params))) (call (core _setsuper!) ,name ,super) (call (core _typebody!) ,name) - (if (&& (isdefined (globalref (thismodule) ,name) (false)) + (if (&& (call (core isdefinedglobal) (thismodule) (inert ,name) (false)) (call (core _equiv_typedef) (globalref (thismodule) ,name) ,name)) (null) (const (globalref (thismodule) ,name) ,name)) @@ -1105,7 +1106,7 @@ (= ,name (call (core _primitivetype) (thismodule) (inert ,name) (call (core svec) ,@params) ,n)) (call (core _setsuper!) ,name ,super) (call (core _typebody!) ,name) - (if (&& (isdefined (globalref (thismodule) ,name) (false)) + (if (&& (call (core isdefinedglobal) (thismodule) (inert ,name) (false)) (call (core _equiv_typedef) (globalref (thismodule) ,name) ,name)) (null) (const (globalref (thismodule) ,name) ,name)) @@ -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) @@ -3683,11 +3690,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` @@ -3787,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))) @@ -4064,7 +4077,9 @@ f(x) = yt(x) (if (and (vinfo:asgn vi) (vinfo:capt vi)) `(call (core isdefined) ,sym (inert contents)) e)) - (else e)))) + (else (if (globalref? sym) + `(call (core isdefinedglobal) ,(cadr sym) (inert ,(caddr sym))) + e))))) ((_opaque_closure) (let* ((isva (car (cddddr e))) (nargs (cadr (cddddr e))) @@ -4240,7 +4255,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)))) @@ -4268,8 +4283,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) @@ -4288,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.expmap.in b/src/julia.expmap.in index 29366f6296a85..b28a714e75f69 100644 --- a/src/julia.expmap.in +++ b/src/julia.expmap.in @@ -2,7 +2,7 @@ global: pthread*; __stack_chk_*; - asprintf; + asprintf*; bitvector_*; ios_*; arraylist_*; @@ -10,33 +10,33 @@ jl_*; ijl_*; _jl_mutex_*; - rec_backtrace; + rec_backtrace*; julia_*; - libsupport_init; - localtime_r; - memhash; - memhash32; - memhash32_seed; - memhash_seed; - restore_signals; + libsupport_init*; + localtime_r*; + memhash*; + memhash32*; + memhash32_seed*; + memhash_seed*; + restore_signals*; u8_*; uv_*; - add_library_mapping; + add_library_mapping*; utf8proc_*; - jlbacktrace; - jlbacktracet; - _IO_stdin_used; - _Z24jl_coverage_data_pointerN4llvm9StringRefEi; - _Z22jl_coverage_alloc_lineN4llvm9StringRefEi; - _Z22jl_malloc_data_pointerN4llvm9StringRefEi; + jlbacktrace*; + jlbacktracet*; + _IO_stdin_used*; /* glibc expects this to be exported to detect which version of glibc is being used, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109 for further details */ + _Z24jl_coverage_data_pointerN4llvm9StringRefEi*; + _Z22jl_coverage_alloc_lineN4llvm9StringRefEi*; + _Z22jl_malloc_data_pointerN4llvm9StringRefEi*; _jl_timing_*; LLVMExtra*; JLJIT*; - llvmGetPassPluginInfo; + llvmGetPassPluginInfo*; /* freebsd */ - environ; - __progname; + environ*; + __progname*; local: *; diff --git a/src/julia.h b/src/julia.h index a9864aad16ccc..4c699ba059c65 100644 --- a/src/julia.h +++ b/src/julia.h @@ -20,7 +20,6 @@ #include "libsupport.h" #include #include -#include #include "htable.h" #include "arraylist.h" @@ -73,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; @@ -426,7 +424,7 @@ typedef struct _jl_opaque_closure_t { // This type represents an executable operation typedef struct _jl_code_instance_t { JL_DATA_TYPE - jl_method_instance_t *def; // method this is specialized from + jl_value_t *def; // MethodInstance or ABIOverride jl_value_t *owner; // Compiler token this belongs to, `jl_nothing` is reserved for native _Atomic(struct _jl_code_instance_t*) next; // pointer to the next cache entry @@ -468,7 +466,6 @@ typedef struct _jl_code_instance_t { // & 0b010 == invokeptr matches specptr // & 0b100 == From image _Atomic(uint8_t) precompile; // if set, this will be added to the output system image - uint8_t relocatability; // nonzero if all roots are built into sysimg or tagged by module key _Atomic(jl_callptr_t) invoke; // jlcall entry point usually, but if this codeinst belongs to an OC Method, then this is an jl_fptr_args_t fptr1 instead, unless it is not, because it is a special token object instead union _jl_generic_specptr_t { _Atomic(void*) fptr; @@ -479,8 +476,12 @@ typedef struct _jl_code_instance_t { } specptr; // private data for `jlcall entry point } jl_code_instance_t; -// all values are callable as Functions -typedef jl_value_t jl_function_t; +// May be used as the ->def field of a CodeInstance to override the ABI +typedef struct _jl_abi_override_t { + JL_DATA_TYPE + jl_value_t *abi; + jl_method_instance_t *def; +} jl_abi_override_t; typedef struct { JL_DATA_TYPE @@ -616,7 +617,7 @@ typedef struct _jl_weakref_t { // N.B: Needs to be synced with runtime_internals.jl enum jl_partition_kind { - // Constant: This binding partition is a constant declared using `const` + // Constant: This binding partition is a constant declared using `const _ = ...` // ->restriction holds the constant value BINDING_KIND_CONST = 0x0, // Import Constant: This binding partition is a constant declared using `import A` @@ -642,7 +643,11 @@ enum jl_partition_kind { BINDING_KIND_DECLARED = 0x7, // Guard: The binding was looked at, but no global or import was resolved at the time // ->restriction is NULL. - BINDING_KIND_GUARD = 0x8 + BINDING_KIND_GUARD = 0x8, + // Undef Constant: This binding partition is a constant declared using `const`, but + // without a value. + // ->restriction is NULL + BINDING_KIND_UNDEF_CONST = 0x9 }; #ifdef _P64 @@ -935,6 +940,7 @@ extern JL_DLLIMPORT jl_datatype_t *jl_fielderror_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_atomicerror_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_missingcodeerror_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_lineinfonode_type JL_GLOBALLY_ROOTED; +extern JL_DLLIMPORT jl_datatype_t *jl_abioverride_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_stackovf_exception JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_memory_exception JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_readonlymemory_exception JL_GLOBALLY_ROOTED; @@ -1570,7 +1576,9 @@ static inline int jl_field_isconst(jl_datatype_t *st, int i) JL_NOTSAFEPOINT #define jl_is_llvmpointer(v) (((jl_datatype_t*)jl_typeof(v))->name == jl_llvmpointer_typename) #define jl_is_intrinsic(v) jl_typetagis(v,jl_intrinsic_type) #define jl_is_addrspacecore(v) jl_typetagis(v,jl_addrspacecore_type) +#define jl_is_abioverride(v) jl_typetagis(v,jl_abioverride_type) #define jl_genericmemory_isbitsunion(a) (((jl_datatype_t*)jl_typetagof(a))->layout->flags.arrayelem_isunion) +#define jl_is_array_any(v) jl_typetagis(v,jl_array_any_type) JL_DLLEXPORT int jl_subtype(jl_value_t *a, jl_value_t *b); @@ -1949,6 +1957,7 @@ JL_DLLEXPORT jl_genericmemory_t *jl_ptr_to_genericmemory(jl_value_t *mtype, void size_t nel, int own_buffer); JL_DLLEXPORT jl_genericmemory_t *jl_alloc_genericmemory(jl_value_t *mtype, size_t nel); JL_DLLEXPORT jl_genericmemory_t *jl_pchar_to_memory(const char *str, size_t len); +JL_DLLEXPORT jl_genericmemory_t *jl_alloc_genericmemory_unchecked(jl_ptls_t ptls, size_t nbytes, jl_datatype_t *mtype); JL_DLLEXPORT jl_value_t *jl_genericmemory_to_string(jl_genericmemory_t *m, size_t len); JL_DLLEXPORT jl_genericmemory_t *jl_alloc_memory_any(size_t n); JL_DLLEXPORT jl_value_t *jl_genericmemoryref(jl_genericmemory_t *m, size_t i); // 0-indexed @@ -1996,7 +2005,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); @@ -2068,6 +2076,7 @@ JL_DLLEXPORT void JL_NORETURN jl_type_error_rt(const char *fname, jl_value_t *got JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_undefined_var_error(jl_sym_t *var, jl_value_t *scope JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_datatype_t *t, jl_sym_t *var); +JL_DLLEXPORT void JL_NORETURN jl_argument_error(char *str); JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str); JL_DLLEXPORT void JL_NORETURN jl_bounds_error(jl_value_t *v JL_MAYBE_UNROOTED, jl_value_t *t JL_MAYBE_UNROOTED); @@ -2226,6 +2235,7 @@ STATIC_INLINE int jl_vinfo_usedundef(uint8_t vi) JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t *F, jl_value_t **args, uint32_t nargs); JL_DLLEXPORT jl_value_t *jl_invoke(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_method_instance_t *meth); +JL_DLLEXPORT jl_value_t *jl_invoke_oc(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_method_instance_t *meth); JL_DLLEXPORT int32_t jl_invoke_api(jl_code_instance_t *linfo); STATIC_INLINE jl_value_t *jl_apply(jl_value_t **args, uint32_t nargs) @@ -2248,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; @@ -2263,71 +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: - // cached floating point environment - // only updated at task switch - fenv_t fenv; - - // 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_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/julia_internal.h b/src/julia_internal.h index 4741316093f95..0da6d412c8a49 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -208,14 +208,15 @@ 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 { 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; @@ -226,7 +227,7 @@ extern volatile int profile_all_tasks; // Ensures that we can safely read the `live_tasks`field of every TLS when profiling. // We want to avoid the case that a GC gets interleaved with `jl_profile_task` and shrinks // the `live_tasks` array while we are reading it or frees tasks that are being profiled. -// Because of that, this lock must be held in `jl_profile_task` and `sweep_stack_pools_and_mtarraylist_buffers`. +// Because of that, this lock must be held in `jl_profile_task` and `jl_gc_sweep_stack_pools_and_mtarraylist_buffers`. extern uv_mutex_t live_tasks_lock; // Ensures that we can safely write to `profile_bt_data_prof` and `profile_bt_size_cur`. // We want to avoid the case that: @@ -400,7 +401,7 @@ extern arraylist_t eytzinger_image_tree; extern arraylist_t eytzinger_idxs; extern JL_DLLEXPORT size_t jl_page_size; -extern jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED; +extern JL_DLLEXPORT jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED; extern JL_DLLEXPORT size_t jl_typeinf_world; extern _Atomic(jl_typemap_entry_t*) call_cache[N_CALL_CACHE] JL_GLOBALLY_ROOTED; @@ -667,14 +668,13 @@ typedef union { // Also defined in typeinfer.jl - See documentation there. #define SOURCE_MODE_NOT_REQUIRED 0x0 #define SOURCE_MODE_ABI 0x1 -#define SOURCE_MODE_FORCE_SOURCE 0x2 JL_DLLEXPORT jl_code_instance_t *jl_engine_reserve(jl_method_instance_t *m, jl_value_t *owner); JL_DLLEXPORT void jl_engine_fulfill(jl_code_instance_t *ci, jl_code_info_t *src); void jl_engine_sweep(jl_ptls_t *gc_all_tls_states) JL_NOTSAFEPOINT; int jl_engine_hasreserved(jl_method_instance_t *m, jl_value_t *owner) JL_NOTSAFEPOINT; -JL_DLLEXPORT jl_code_instance_t *jl_type_infer(jl_method_instance_t *li, size_t world, uint8_t source_mode); +JL_DLLEXPORT jl_code_instance_t *jl_type_infer(jl_method_instance_t *li JL_PROPAGATES_ROOT, size_t world, uint8_t source_mode); JL_DLLEXPORT jl_code_info_t *jl_gdbcodetyped1(jl_method_instance_t *mi, size_t world); JL_DLLEXPORT jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *meth JL_PROPAGATES_ROOT, size_t world); JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( @@ -683,6 +683,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( JL_DLLEXPORT jl_method_instance_t *jl_get_unspecialized(jl_method_t *def JL_PROPAGATES_ROOT); JL_DLLEXPORT void jl_read_codeinst_invoke(jl_code_instance_t *ci, uint8_t *specsigflags, jl_callptr_t *invoke, void **specptr, int waitcompile); JL_DLLEXPORT jl_method_instance_t *jl_method_match_to_mi(jl_method_match_t *match, size_t world, size_t min_valid, size_t max_valid, int mt_cache); +JL_DLLEXPORT void jl_add_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src); JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_uninit(jl_method_instance_t *mi, jl_value_t *owner); JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( @@ -691,13 +692,24 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_value_t *inferred_const, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, uint32_t effects, jl_value_t *analysis_results, - uint8_t relocatability, jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/); + jl_debuginfo_t *di, jl_svec_t *edges /* , int absolute_max*/); +JL_DLLEXPORT jl_code_instance_t *jl_get_ci_equiv(jl_code_instance_t *ci JL_PROPAGATES_ROOT, int compiled) JL_NOTSAFEPOINT; + +STATIC_INLINE jl_method_instance_t *jl_get_ci_mi(jl_code_instance_t *ci JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT +{ + jl_value_t *def = ci->def; + if (jl_is_abioverride(def)) + return ((jl_abi_override_t*)def)->def; + assert(jl_is_method_instance(def)); + return (jl_method_instance_t*)def; +} JL_DLLEXPORT const char *jl_debuginfo_file(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; JL_DLLEXPORT const char *jl_debuginfo_file1(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_module_t *jl_debuginfo_module1(jl_value_t *debuginfo_def) JL_NOTSAFEPOINT; JL_DLLEXPORT const char *jl_debuginfo_name(jl_value_t *func) JL_NOTSAFEPOINT; +JL_DLLEXPORT int jl_is_compiled_codeinst(jl_code_instance_t *codeinst) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_compile_method_instance(jl_method_instance_t *mi, jl_tupletype_t *types, size_t world); JL_DLLEXPORT void jl_compile_method_sig(jl_method_t *m, jl_value_t *types, jl_svec_t *sparams, size_t world); JL_DLLEXPORT int jl_compile_hint(jl_tupletype_t *types); @@ -707,8 +719,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); @@ -816,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); @@ -830,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; @@ -913,8 +926,13 @@ EXTERN_INLINE_DECLARE enum jl_partition_kind decode_restriction_kind(jl_ptr_kind uint8_t bits = (pku & 0x7); jl_value_t *val = (jl_value_t*)(pku & ~0x7); - if (val == NULL && bits == BINDING_KIND_IMPLICIT) { - return BINDING_KIND_GUARD; + if (val == NULL) { + if (bits == BINDING_KIND_IMPLICIT) { + return BINDING_KIND_GUARD; + } + if (bits == BINDING_KIND_CONST) { + return BINDING_KIND_UNDEF_CONST; + } } return (enum jl_partition_kind)bits; @@ -936,10 +954,14 @@ STATIC_INLINE jl_value_t *decode_restriction_value(jl_ptr_kind_union_t JL_PROPAG STATIC_INLINE jl_ptr_kind_union_t encode_restriction(jl_value_t *val, enum jl_partition_kind kind) JL_NOTSAFEPOINT { #ifdef _P64 - if (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED) + if (kind == BINDING_KIND_GUARD || kind == BINDING_KIND_DECLARED || kind == BINDING_KIND_FAILED || kind == BINDING_KIND_UNDEF_CONST) assert(val == NULL); + else if (kind == BINDING_KIND_IMPLICIT || kind == BINDING_KIND_CONST) + assert(val != NULL); if (kind == BINDING_KIND_GUARD) kind = BINDING_KIND_IMPLICIT; + else if (kind == BINDING_KIND_UNDEF_CONST) + kind = BINDING_KIND_CONST; assert((((uintptr_t)val) & 0x7) == 0); return ((jl_ptr_kind_union_t)val) | kind; #else @@ -953,6 +975,10 @@ STATIC_INLINE int jl_bkind_is_some_import(enum jl_partition_kind kind) JL_NOTSAF } STATIC_INLINE int jl_bkind_is_some_constant(enum jl_partition_kind kind) JL_NOTSAFEPOINT { + return kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT || kind == BINDING_KIND_UNDEF_CONST; +} + +STATIC_INLINE int jl_bkind_is_defined_constant(enum jl_partition_kind kind) JL_NOTSAFEPOINT { return kind == BINDING_KIND_CONST || kind == BINDING_KIND_CONST_IMPORT; } @@ -960,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 @@ -1195,12 +1221,11 @@ _Atomic(jl_value_t*) *jl_table_peek_bp(jl_genericmemory_t *a, jl_value_t *key) J JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t*); JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module); -JL_DLLEXPORT jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world, size_t *min_valid, size_t *max_valid, int mt_cache); +JL_DLLEXPORT jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types, size_t world, int mt_cache); jl_method_instance_t *jl_get_specialized(jl_method_t *m, jl_value_t *types, jl_svec_t *sp); JL_DLLEXPORT jl_value_t *jl_rettype_inferred(jl_value_t *owner, jl_method_instance_t *li JL_PROPAGATES_ROOT, size_t min_world, size_t max_world); JL_DLLEXPORT jl_value_t *jl_rettype_inferred_native(jl_method_instance_t *mi, size_t min_world, size_t max_world) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_code_instance_t *jl_method_compiled(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) JL_NOTSAFEPOINT; -JL_DLLEXPORT jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_value_t *type, size_t world); JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo( jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams); @@ -1212,7 +1237,6 @@ JL_DLLEXPORT void jl_mi_cache_insert(jl_method_instance_t *mi JL_ROOTING_ARGUMEN JL_DLLEXPORT int jl_mi_try_insert(jl_method_instance_t *mi JL_ROOTING_ARGUMENT, jl_code_instance_t *expected_ci, jl_code_instance_t *ci JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED); -JL_DLLEXPORT int jl_mi_cache_has_ci(jl_method_instance_t *mi, jl_code_instance_t *ci) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_code_instance_t *jl_cached_uninferred(jl_code_instance_t *codeinst, size_t world); JL_DLLEXPORT jl_code_instance_t *jl_cache_uninferred(jl_method_instance_t *mi, jl_code_instance_t *checked, size_t world, jl_code_instance_t *newci JL_MAYBE_UNROOTED); JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_for_uninferred(jl_method_instance_t *mi, jl_code_info_t *src); @@ -1342,7 +1366,7 @@ typedef struct { char *func_name; char *file_name; int line; - jl_method_instance_t *linfo; + jl_code_instance_t *ci; int fromC; int inlined; } jl_frame_t; @@ -1573,6 +1597,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); @@ -1644,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; @@ -1937,6 +1964,7 @@ JL_DLLEXPORT uint32_t jl_crc32c(uint32_t crc, const char *buf, size_t len); JL_DLLIMPORT void jl_generate_fptr_for_unspecialized(jl_code_instance_t *unspec); JL_DLLIMPORT int jl_compile_codeinst(jl_code_instance_t *unspec); JL_DLLIMPORT int jl_compile_extern_c(LLVMOrcThreadSafeModuleRef llvmmod, void *params, void *sysimg, jl_value_t *declrt, jl_value_t *sigt); +JL_DLLIMPORT void jl_emit_codeinst_to_jit(jl_code_instance_t *codeinst, jl_code_info_t *src); typedef struct { LLVMOrcThreadSafeModuleRef TSM; @@ -1951,7 +1979,8 @@ JL_DLLIMPORT jl_value_t *jl_dump_function_ir(jl_llvmf_dump_t *dump, char strip_i JL_DLLIMPORT jl_value_t *jl_dump_function_asm(jl_llvmf_dump_t *dump, char emit_mc, const char* asm_variant, const char *debuginfo, char binary, char raw); typedef jl_value_t *(*jl_codeinstance_lookup_t)(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t min_world, size_t max_world); -JL_DLLIMPORT void *jl_create_native(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int policy, int imaging_mode, int cache, size_t world, jl_codeinstance_lookup_t lookup); +JL_DLLIMPORT void *jl_create_native(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvmmod, int trim, int cache, size_t world); +JL_DLLIMPORT void *jl_emit_native(jl_array_t *codeinfos, LLVMOrcThreadSafeModuleRef llvmmod, const jl_cgparams_t *cgparams, int _external_linkage); JL_DLLIMPORT void jl_dump_native(void *native_code, const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname, const char *asm_fname, ios_t *z, ios_t *s, jl_emission_params_t *params); diff --git a/src/julia_locks.h b/src/julia_locks.h index 35bcf7dd97322..92d67b34b1692 100644 --- a/src/julia_locks.h +++ b/src/julia_locks.h @@ -116,7 +116,7 @@ class jl_unique_gcsafe_lock { { jl_task_t *ct = jl_current_task; gc_state = jl_gc_safe_enter(ct->ptls); // contains jl_gc_safepoint after enter - this->native = std::unique_lock(native); + this->native = std::unique_lock(native); ct->ptls->engine_nqueued++; // disables finalizers until inference is finished on this method graph } jl_unique_gcsafe_lock(jl_unique_gcsafe_lock &&native) = delete; diff --git a/src/julia_threads.h b/src/julia_threads.h index faa8ab9e0aaf4..061eb9266e7a7 100644 --- a/src/julia_threads.h +++ b/src/julia_threads.h @@ -4,7 +4,11 @@ #ifndef JL_THREADS_H #define JL_THREADS_H -#include "gc-tls.h" +#ifndef MMTK_GC +#include "gc-tls-stock.h" +#else +#include "gc-tls-mmtk.h" +#endif #include "gc-tls-common.h" #include "julia_atomics.h" #ifndef _OS_WINDOWS_ @@ -214,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` diff --git a/src/llvm-alloc-helpers.cpp b/src/llvm-alloc-helpers.cpp index 59fce1235e14e..194c6837860ca 100644 --- a/src/llvm-alloc-helpers.cpp +++ b/src/llvm-alloc-helpers.cpp @@ -250,8 +250,8 @@ void jl_alloc::runEscapeAnalysis(llvm::CallInst *I, EscapeAnalysisRequiredArgs r return true; } if (required.pass.gc_loaded_func == callee) { - required.use_info.haspreserve = true; - required.use_info.hasload = true; + // TODO add manual load->store forwarding + push_inst(inst); return true; } if (required.pass.typeof_func == callee) { diff --git a/src/llvm-alloc-opt.cpp b/src/llvm-alloc-opt.cpp index a9e1b1e02da42..7dd794a4d8847 100644 --- a/src/llvm-alloc-opt.cpp +++ b/src/llvm-alloc-opt.cpp @@ -752,11 +752,11 @@ void Optimizer::moveToStack(CallInst *orig_inst, size_t sz, bool has_ref, AllocF call->eraseFromParent(); return; } - //if (pass.gc_loaded_func == callee) { - // call->replaceAllUsesWith(new_i); - // call->eraseFromParent(); - // return; - //} + if (pass.gc_loaded_func == callee) { + // TODO: handle data pointer forwarding, length forwarding, and fence removal + user->replaceUsesOfWith(orig_i, Constant::getNullValue(orig_i->getType())); + return; + } if (pass.typeof_func == callee) { ++RemovedTypeofs; call->replaceAllUsesWith(tag); 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); } diff --git a/src/llvm-gc-interface-passes.h b/src/llvm-gc-interface-passes.h index 278987858eab7..7b2a4bb033203 100644 --- a/src/llvm-gc-interface-passes.h +++ b/src/llvm-gc-interface-passes.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -328,6 +329,7 @@ struct LateLowerGCFrame: private JuliaPassContext { private: CallInst *pgcstack; + Function *smallAllocFunc; void MaybeNoteDef(State &S, BBState &BBS, Value *Def, const ArrayRef &SafepointsSoFar, SmallVector &&RefinedPtr = SmallVector()); @@ -366,6 +368,7 @@ struct LateLowerGCFrame: private JuliaPassContext { void RefineLiveSet(LargeSparseBitVector &LS, State &S, ArrayRef CalleeRoots); Value *EmitTagPtr(IRBuilder<> &builder, Type *T, Type *T_size, Value *V); Value *EmitLoadTag(IRBuilder<> &builder, Type *T_size, Value *V); + Value* lowerGCAllocBytesLate(CallInst *target, Function &F); }; // The final GC lowering pass. This pass lowers platform-agnostic GC diff --git a/src/llvm-late-gc-lowering-mmtk.cpp b/src/llvm-late-gc-lowering-mmtk.cpp new file mode 100644 index 0000000000000..5539c8dbcf153 --- /dev/null +++ b/src/llvm-late-gc-lowering-mmtk.cpp @@ -0,0 +1,96 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#include "llvm-gc-interface-passes.h" + +Value* LateLowerGCFrame::lowerGCAllocBytesLate(CallInst *target, Function &F) +{ + assert(target->arg_size() == 3); + + IRBuilder<> builder(target); + auto ptls = target->getArgOperand(0); + auto type = target->getArgOperand(2); + if (auto CI = dyn_cast(target->getArgOperand(1))) { + size_t sz = (size_t)CI->getZExtValue(); + // This is strongly architecture and OS dependent + int osize; + int offset = jl_gc_classify_pools(sz, &osize); + if (offset >= 0) { + // In this case instead of lowering julia.gc_alloc_bytes to jl_gc_small_alloc + // We do a slowpath/fastpath check and lower it only on the slowpath, returning + // the cursor and updating it in the fastpath. + auto pool_osize_i32 = ConstantInt::get(Type::getInt32Ty(F.getContext()), osize); + auto pool_osize = ConstantInt::get(Type::getInt64Ty(F.getContext()), osize); + + // Should we generate fastpath allocation sequence here? We should always generate fastpath here for MMTk. + // Setting this to false will increase allocation overhead a lot, and should only be used for debugging. + const bool INLINE_FASTPATH_ALLOCATION = true; + + if (INLINE_FASTPATH_ALLOCATION) { + // Assuming we use the first immix allocator. + // FIXME: We should get the allocator index and type from MMTk. + auto allocator_offset = offsetof(jl_tls_states_t, gc_tls) + offsetof(jl_gc_tls_states_t, mmtk_mutator) + offsetof(MMTkMutatorContext, allocators) + offsetof(Allocators, immix); + + auto cursor_pos = ConstantInt::get(Type::getInt64Ty(target->getContext()), allocator_offset + offsetof(ImmixAllocator, cursor)); + auto limit_pos = ConstantInt::get(Type::getInt64Ty(target->getContext()), allocator_offset + offsetof(ImmixAllocator, limit)); + + auto cursor_ptr = builder.CreateInBoundsGEP(Type::getInt8Ty(target->getContext()), ptls, cursor_pos); + auto cursor = builder.CreateAlignedLoad(Type::getInt64Ty(target->getContext()), cursor_ptr, Align(sizeof(void *)), "cursor"); + + // offset = 8 + auto delta_offset = builder.CreateNSWSub(ConstantInt::get(Type::getInt64Ty(target->getContext()), 0), ConstantInt::get(Type::getInt64Ty(target->getContext()), 8)); + auto delta_cursor = builder.CreateNSWSub(ConstantInt::get(Type::getInt64Ty(target->getContext()), 0), cursor); + auto delta_op = builder.CreateNSWAdd(delta_offset, delta_cursor); + // alignment 16 (15 = 16 - 1) + auto delta = builder.CreateAnd(delta_op, ConstantInt::get(Type::getInt64Ty(target->getContext()), 15), "delta"); + auto result = builder.CreateNSWAdd(cursor, delta, "result"); + + auto new_cursor = builder.CreateNSWAdd(result, pool_osize); + + auto limit_ptr = builder.CreateInBoundsGEP(Type::getInt8Ty(target->getContext()), ptls, limit_pos); + auto limit = builder.CreateAlignedLoad(Type::getInt64Ty(target->getContext()), limit_ptr, Align(sizeof(void *)), "limit"); + + auto gt_limit = builder.CreateICmpSGT(new_cursor, limit); + + auto slowpath = BasicBlock::Create(target->getContext(), "slowpath", target->getFunction()); + auto fastpath = BasicBlock::Create(target->getContext(), "fastpath", target->getFunction()); + + auto next_instr = target->getNextNode(); + SmallVector Weights{1, 9}; + + MDBuilder MDB(F.getContext()); + SplitBlockAndInsertIfThenElse(gt_limit, next_instr, &slowpath, &fastpath, false, false, MDB.createBranchWeights(Weights)); + + builder.SetInsertPoint(next_instr); + auto phiNode = builder.CreatePHI(target->getCalledFunction()->getReturnType(), 2, "phi_fast_slow"); + + // slowpath + builder.SetInsertPoint(slowpath); + auto pool_offs = ConstantInt::get(Type::getInt32Ty(F.getContext()), 1); + auto new_call = builder.CreateCall(smallAllocFunc, { ptls, pool_offs, pool_osize_i32, type }); + new_call->setAttributes(new_call->getCalledFunction()->getAttributes()); + builder.CreateBr(next_instr->getParent()); + + // fastpath + builder.SetInsertPoint(fastpath); + builder.CreateStore(new_cursor, cursor_ptr); + + // ptls->gc_tls.gc_num.allocd += osize; + auto pool_alloc_pos = ConstantInt::get(Type::getInt64Ty(target->getContext()), offsetof(jl_tls_states_t, gc_tls_common) + offsetof(jl_gc_tls_states_common_t, gc_num)); + auto pool_alloc_tls = builder.CreateInBoundsGEP(Type::getInt8Ty(target->getContext()), ptls, pool_alloc_pos); + auto pool_allocd = builder.CreateAlignedLoad(Type::getInt64Ty(target->getContext()), pool_alloc_tls, Align(sizeof(void *))); + auto pool_allocd_total = builder.CreateAdd(pool_allocd, pool_osize); + builder.CreateStore(pool_allocd_total, pool_alloc_tls); + + auto v_raw = builder.CreateNSWAdd(result, ConstantInt::get(Type::getInt64Ty(target->getContext()), sizeof(jl_taggedvalue_t))); + auto v_as_ptr = builder.CreateIntToPtr(v_raw, smallAllocFunc->getReturnType()); + builder.CreateBr(next_instr->getParent()); + + phiNode->addIncoming(new_call, slowpath); + phiNode->addIncoming(v_as_ptr, fastpath); + phiNode->takeName(target); + return phiNode; + } + } + } + return target; +} diff --git a/src/llvm-late-gc-lowering-stock.cpp b/src/llvm-late-gc-lowering-stock.cpp new file mode 100644 index 0000000000000..2a11487773396 --- /dev/null +++ b/src/llvm-late-gc-lowering-stock.cpp @@ -0,0 +1,9 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#include "llvm-gc-interface-passes.h" + +Value* LateLowerGCFrame::lowerGCAllocBytesLate(CallInst *target, Function &F) +{ + // Do nothing for the stock GC + return target; +} diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index ff2cac6e49406..7d6fba65a79e7 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -2446,6 +2446,7 @@ void LateLowerGCFrame::PlaceRootsAndUpdateCalls(ArrayRef Colors, int PreAss bool LateLowerGCFrame::runOnFunction(Function &F, bool *CFGModified) { initAll(*F.getParent()); + smallAllocFunc = getOrDeclare(jl_well_known::GCSmallAlloc); LLVM_DEBUG(dbgs() << "GC ROOT PLACEMENT: Processing function " << F.getName() << "\n"); if (!pgcstack_getter && !adoptthread_func) return CleanupIR(F, nullptr, CFGModified); @@ -2460,6 +2461,31 @@ bool LateLowerGCFrame::runOnFunction(Function &F, bool *CFGModified) { std::map> CallFrames; // = OptimizeCallFrames(S, Ordering); PlaceRootsAndUpdateCalls(Colors.first, Colors.second, S, CallFrames); CleanupIR(F, &S, CFGModified); + + + // We lower the julia.gc_alloc_bytes intrinsic in this pass to insert slowpath/fastpath blocks for MMTk + // For now, we do nothing for the Stock GC + auto GCAllocBytes = getOrNull(jl_intrinsics::GCAllocBytes); + + if (GCAllocBytes) { + for (auto it = GCAllocBytes->user_begin(); it != GCAllocBytes->user_end(); ) { + if (auto *CI = dyn_cast(*it)) { + *CFGModified = true; + + assert(CI->getCalledOperand() == GCAllocBytes); + + auto newI = lowerGCAllocBytesLate(CI, F); + if (newI != CI) { + ++it; + CI->replaceAllUsesWith(newI); + CI->eraseFromParent(); + continue; + } + } + ++it; + } + } + return true; } diff --git a/src/method.c b/src/method.c index 8e3bb7d0060b7..4b39de9aa67e1 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); } - if (e->head == jl_method_sym || e->head == jl_module_sym || e->head == jl_throw_undef_if_not_sym) { - i++; + 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(); } - 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_exprargset(e, 1, rt); + } + if (!jl_is_svec(at)) { + JL_TRY { + at = jl_interpret_toplevel_expr_in(module, at, NULL, sparam_vals); } - 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_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."); } - 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); } @@ -1148,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; } @@ -1384,10 +1321,6 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, // at the time of writing the system image (such occur first in the list of // roots). These are the cases with `key = 0` that do not prevent // serialization. -// - CodeInstances have a `relocatability` field which when 1 indicates that -// every root is "safe," meaning it was either added at sysimg creation or is -// tagged with a non-zero `key`. Even a single unsafe root will cause this to -// have value 0. // Get the key of the current (final) block of roots static uint64_t current_root_id(jl_array_t *root_blocks) diff --git a/src/module.c b/src/module.c index 38f4b980a72fd..be6779727bfdc 100644 --- a/src/module.c +++ b/src/module.c @@ -290,7 +290,11 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding_wr(jl_module_t *m JL_PROPAGATES_ROOT, if (decode_restriction_kind(pku) != BINDING_KIND_DECLARED) { check_safe_newbinding(m, var); if (!alloc) - jl_errorf("Global %s.%s does not exist and cannot be assigned. Declare it using `global` before attempting assignment.", jl_symbol_name(m->name), jl_symbol_name(var)); + jl_errorf("Global %s.%s does not exist and cannot be assigned.\n" + "Note: Julia 1.9 and 1.10 inadvertently omitted this error check (#56933).\n" + "Hint: Declare it using `global %s` inside `%s` before attempting assignment.", + jl_symbol_name(m->name), jl_symbol_name(var), + jl_symbol_name(var), jl_symbol_name(m->name)); } jl_ptr_kind_union_t new_pku = encode_restriction((jl_value_t*)jl_any_type, BINDING_KIND_GLOBAL); if (!jl_atomic_cmpswap(&bpart->restriction, &pku, new_pku)) @@ -396,7 +400,10 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_if_resolved(jl_binding_t *b) JL_DLLEXPORT jl_value_t *jl_bpart_get_restriction_value(jl_binding_partition_t *bpart) { jl_ptr_kind_union_t pku = jl_atomic_load_relaxed(&bpart->restriction); - return decode_restriction_value(pku); + jl_value_t *v = decode_restriction_value(pku); + if (!v) + jl_throw(jl_undefref_exception); + return v; } typedef struct _modstack_t { @@ -404,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); } @@ -466,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; @@ -480,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; @@ -517,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)) @@ -531,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) @@ -554,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); @@ -587,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; } @@ -599,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); @@ -630,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) @@ -994,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); } @@ -1021,15 +1028,30 @@ 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); } -extern jl_mutex_t world_counter_lock; +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) + invalidate_code_for_globalref = jl_get_global(jl_base_module, jl_symbol("invalidate_code_for_globalref!")); + if (!invalidate_code_for_globalref) + jl_error("Binding invalidation is not permitted during bootstrap."); + if (jl_generating_output()) + 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_call3((jl_function_t*)invalidate_code_for_globalref, (jl_value_t*)ref, (jl_value_t*)invalidated_bpart, boxed_world); + JL_GC_POP(); +} + 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) { @@ -1039,10 +1061,12 @@ JL_DLLEXPORT void jl_disable_binding(jl_globalref_t *gr) JL_LOCK(&world_counter_lock); 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); - // TODO: Trigger invalidation here - (void)ct; jl_atomic_store_release(&bpart->max_world, new_max_world); + ct->world_age = jl_typeinf_world; + jl_invalidate_binding_refs(gr, bpart, new_max_world); + ct->world_age = last_world; jl_atomic_store_release(&jl_world_counter, new_max_world + 1); JL_UNLOCK(&world_counter_lock); } @@ -1050,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) @@ -1327,6 +1350,11 @@ JL_DLLEXPORT void jl_add_to_module_init_list(jl_value_t *mod) jl_array_ptr_1d_push(jl_module_init_order, mod); } +JL_DLLEXPORT jl_svec_t *jl_module_get_bindings(jl_module_t *m) +{ + return jl_atomic_load_relaxed(&m->bindings); +} + JL_DLLEXPORT void jl_init_restored_module(jl_value_t *mod) { if (!jl_generating_output() || jl_options.incremental) { diff --git a/src/mtarraylist.c b/src/mtarraylist.c index 7af265a86ab63..0a0f3fe867e39 100644 --- a/src/mtarraylist.c +++ b/src/mtarraylist.c @@ -14,8 +14,8 @@ extern "C" { // but there can be any number of observers typedef struct { - _Atomic(uint32_t) len; - uint32_t max; + _Atomic(size_t) len; + size_t max; _Atomic(_Atomic(void*)*) items; _Atomic(void*) _space[SMALL_AL_N_INLINE]; } small_mtarraylist_t; diff --git a/src/opaque_closure.c b/src/opaque_closure.c index e3334c037f5a9..a10b5c617753c 100644 --- a/src/opaque_closure.c +++ b/src/opaque_closure.c @@ -67,12 +67,14 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t ci = jl_compile_method_internal(mi, world); } - jl_fptr_args_t invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + jl_fptr_args_t callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; void *specptr = NULL; if (ci) { - invoke = (jl_fptr_args_t)jl_atomic_load_relaxed(&ci->invoke); - specptr = jl_atomic_load_relaxed(&ci->specptr.fptr); + uint8_t specsigflags; + jl_callptr_t invoke; + jl_read_codeinst_invoke(ci, &specsigflags, &invoke, &specptr, 1); + callptr = (jl_fptr_args_t)invoke; // codegen puts the object (or a jl_fptr_interpret_call token )here for us, even though it was the wrong type to put here selected_rt = ci->rettype; // If we're not allowed to generate a specsig with this, rt, fall @@ -82,7 +84,7 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t // TODO: It would be better to try to get a specialization with the // correct rt check here (or we could codegen a wrapper). specptr = NULL; // this will force codegen of the unspecialized version - invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; jl_value_t *ts[2] = {rt_lb, (jl_value_t*)ci->rettype}; selected_rt = jl_type_union(ts, 2); } @@ -90,18 +92,18 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t // TODO: It would be better to try to get a specialization with the // correct rt check here (or we could codegen a wrapper). specptr = NULL; // this will force codegen of the unspecialized version - invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; selected_rt = jl_type_intersection(rt_ub, selected_rt); } - if (invoke == (jl_fptr_args_t) jl_fptr_interpret_call) { - invoke = (jl_fptr_args_t)jl_interpret_opaque_closure; + if (callptr == (jl_fptr_args_t)jl_fptr_interpret_call) { + callptr = (jl_fptr_args_t)jl_interpret_opaque_closure; } - else if (invoke == (jl_fptr_args_t)jl_fptr_args && specptr) { - invoke = (jl_fptr_args_t)specptr; + else if (callptr == (jl_fptr_args_t)jl_fptr_args && specptr != NULL) { + callptr = (jl_fptr_args_t)specptr; } - else if (invoke == (jl_fptr_args_t)jl_fptr_const_return) { - invoke = jl_isa(ci->rettype_const, selected_rt) ? + else if (callptr == (jl_fptr_args_t)jl_fptr_const_return) { + callptr = jl_isa(ci->rettype_const, selected_rt) ? (jl_fptr_args_t)jl_fptr_const_opaque_closure : (jl_fptr_args_t)jl_fptr_const_opaque_closure_typeerror; captures = ci->rettype_const; @@ -116,15 +118,17 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t // OC wrapper methods are not world dependent and have no edges or other info ci = jl_get_method_inferred(mi_generic, selected_rt, 1, ~(size_t)0, NULL, NULL); - if (!jl_atomic_load_acquire(&ci->invoke)) - jl_compile_codeinst(ci); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible) + if (!jl_atomic_load_acquire(&ci->invoke)) { + jl_emit_codeinst_to_jit(ci, NULL); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible since it cannot have source) + jl_compile_codeinst(ci); + } specptr = jl_atomic_load_relaxed(&ci->specptr.fptr); } jl_opaque_closure_t *oc = (jl_opaque_closure_t*)jl_gc_alloc(ct->ptls, sizeof(jl_opaque_closure_t), oc_type); oc->source = source; oc->captures = captures; oc->world = world; - oc->invoke = invoke; + oc->invoke = callptr; oc->specptr = specptr; JL_GC_POP(); @@ -165,7 +169,7 @@ JL_DLLEXPORT jl_opaque_closure_t *jl_new_opaque_closure_from_code_info(jl_tuplet if (!jl_is_svec(edges)) edges = jl_emptysvec; // OC doesn't really have edges, so just drop them for now inst = jl_new_codeinst(mi, jl_nothing, rt_ub, (jl_value_t*)jl_any_type, NULL, (jl_value_t*)ci, - 0, world, world, 0, jl_nothing, 0, ci->debuginfo, edges); + 0, world, world, 0, jl_nothing, ci->debuginfo, edges); jl_mi_cache_insert(mi, inst); } diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 8c9054c0d65ff..39f896ba656d2 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -527,6 +527,7 @@ static void buildIntrinsicLoweringPipeline(ModulePassManager &MPM, PassBuilder * JULIA_PASS(FPM.addPass(LateLowerGCPass())); JULIA_PASS(FPM.addPass(FinalLowerGCPass())); if (O.getSpeedupLevel() >= 2) { + FPM.addPass(DSEPass()); FPM.addPass(GVNPass()); FPM.addPass(SCCPPass()); FPM.addPass(DCEPass()); diff --git a/src/precompile_utils.c b/src/precompile_utils.c index 81c60ba70d29f..8906b3eb586d3 100644 --- a/src/precompile_utils.c +++ b/src/precompile_utils.c @@ -203,8 +203,8 @@ static int precompile_enq_specialization_(jl_method_instance_t *mi, void *closur else if (jl_atomic_load_relaxed(&codeinst->invoke) != jl_fptr_const_return) { jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred); if (inferred && - inferred != jl_nothing && - (jl_options.compile_enabled != JL_OPTIONS_COMPILE_ALL && jl_ir_inlining_cost(inferred) == UINT16_MAX)) { + (jl_options.compile_enabled == JL_OPTIONS_COMPILE_ALL || inferred == jl_nothing || + ((jl_is_string(inferred) || jl_is_code_info(inferred)) && jl_ir_inlining_cost(inferred) == UINT16_MAX))) { do_compile = 1; } else if (jl_atomic_load_relaxed(&codeinst->invoke) != NULL || jl_atomic_load_relaxed(&codeinst->precompile)) { @@ -264,10 +264,8 @@ static void *jl_precompile_(jl_array_t *m, int external_linkage) jl_value_t *item = jl_array_ptr_ref(m, i); if (jl_is_method_instance(item)) { mi = (jl_method_instance_t*)item; - size_t min_world = 0; - size_t max_world = ~(size_t)0; if (mi != jl_atomic_load_relaxed(&mi->def.method->unspecialized) && !jl_isa_compileable_sig((jl_tupletype_t*)mi->specTypes, mi->sparam_vals, mi->def.method)) - mi = jl_get_specialization1((jl_tupletype_t*)mi->specTypes, jl_atomic_load_acquire(&jl_world_counter), &min_world, &max_world, 0); + mi = jl_get_specialization1((jl_tupletype_t*)mi->specTypes, jl_atomic_load_acquire(&jl_world_counter), 0); if (mi) jl_array_ptr_1d_push(m2, (jl_value_t*)mi); } @@ -277,9 +275,7 @@ static void *jl_precompile_(jl_array_t *m, int external_linkage) jl_array_ptr_1d_push(m2, item); } } - void *native_code = jl_create_native(m2, NULL, NULL, 0, 1, external_linkage, - jl_atomic_load_acquire(&jl_world_counter), - NULL); + void *native_code = jl_create_native(m2, NULL, 0, external_linkage, jl_atomic_load_acquire(&jl_world_counter)); JL_GC_POP(); return native_code; } @@ -338,7 +334,7 @@ static void *jl_precompile_worklist(jl_array_t *worklist, jl_array_t *extext_met n = jl_array_nrows(new_ext_cis); for (i = 0; i < n; i++) { jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(new_ext_cis, i); - precompile_enq_specialization_(ci->def, m); + precompile_enq_specialization_(jl_get_ci_mi(ci), m); } } } @@ -374,8 +370,7 @@ static void *jl_precompile_trimmed(size_t world) jl_value_t *ccallable = NULL; JL_GC_PUSH2(&m, &ccallable); jl_method_instance_t *mi; - while (1) - { + while (1) { mi = (jl_method_instance_t*)arraylist_pop(jl_entrypoint_mis); if (mi == NULL) break; @@ -387,10 +382,7 @@ static void *jl_precompile_trimmed(size_t world) jl_array_ptr_1d_push(m, ccallable); } - jl_cgparams_t params = jl_default_cgparams; - params.trim = jl_options.trim; - void *native_code = jl_create_native(m, NULL, ¶ms, 0, /* imaging */ 1, 0, - world, NULL); + void *native_code = jl_create_native(m, NULL, jl_options.trim, 0, world); JL_GC_POP(); return native_code; } diff --git a/src/processor_x86.cpp b/src/processor_x86.cpp index f1dff063de1d9..bf765be160ed2 100644 --- a/src/processor_x86.cpp +++ b/src/processor_x86.cpp @@ -96,9 +96,10 @@ enum class CPU : uint32_t { amd_znver2, amd_znver3, amd_znver4, + amd_znver5, }; -static constexpr size_t feature_sz = 11; +static constexpr size_t feature_sz = 12; static constexpr FeatureName feature_names[] = { #define JL_FEATURE_DEF(name, bit, llvmver) {#name, bit, llvmver}, #define JL_FEATURE_DEF_NAME(name, bit, llvmver, str) {str, bit, llvmver}, @@ -141,6 +142,10 @@ static constexpr FeatureDep deps[] = { {vpclmulqdq, avx}, {vpclmulqdq, pclmul}, {avxvnni, avx2}, + {avxvnniint8, avx2}, + {avxvnniint16, avx2}, + {avxifma, avx2}, + {avxneconvert, avx2}, {avx512f, avx2}, {avx512dq, avx512f}, {avx512ifma, avx512f}, @@ -159,6 +164,8 @@ static constexpr FeatureDep deps[] = { {avx512fp16, avx512vl}, {amx_int8, amx_tile}, {amx_bf16, amx_tile}, + {amx_fp16, amx_tile}, + {amx_complex, amx_tile}, {sse4a, sse3}, {xop, fma4}, {fma4, avx}, @@ -166,6 +173,9 @@ static constexpr FeatureDep deps[] = { {xsaveopt, xsave}, {xsavec, xsave}, {xsaves, xsave}, + {sha512, avx2}, + {sm3, avx}, + {sm4, avx2}, }; // We require cx16 on 64bit by default. This can be overwritten with `-cx16` @@ -236,6 +246,7 @@ constexpr auto znver2 = znver1 | get_feature_masks(clwb, rdpid, wbnoinvd); constexpr auto znver3 = znver2 | get_feature_masks(shstk, pku, vaes, vpclmulqdq); constexpr auto znver4 = znver3 | get_feature_masks(avx512f, avx512cd, avx512dq, avx512bw, avx512vl, avx512ifma, avx512vbmi, avx512vbmi2, avx512vnni, avx512bitalg, avx512vpopcntdq, avx512bf16, gfni, shstk, xsaves); +constexpr auto znver5 = znver4 | get_feature_masks(avxvnni, movdiri, movdir64b, avx512vp2intersect, prefetchi, avxvnni); } @@ -298,6 +309,7 @@ static constexpr CPUSpec cpus[] = { {"znver2", CPU::amd_znver2, CPU::generic, 0, Feature::znver2}, {"znver3", CPU::amd_znver3, CPU::amd_znver2, 120000, Feature::znver3}, {"znver4", CPU::amd_znver4, CPU::amd_znver3, 160000, Feature::znver4}, + {"znver5", CPU::amd_znver5, CPU::amd_znver4, 190000, Feature::znver5}, }; static constexpr size_t ncpu_names = sizeof(cpus) / sizeof(cpus[0]); @@ -575,6 +587,9 @@ static CPU get_amd_processor_name(uint32_t family, uint32_t model, const uint32_ return CPU::amd_znver4; } return CPU::amd_znver3; // fallback + case 26: + // if (model <= 0x77) + return CPU::amd_znver5; } } @@ -660,11 +675,12 @@ static NOINLINE std::pair> _get_host_cpu(void) int32_t info7[4]; jl_cpuidex(info7, 7, 1); features[9] = info7[0]; + features[10] = info7[1]; } if (maxleaf >= 0x14) { int32_t info14[4]; jl_cpuidex(info14, 0x14, 0); - features[10] = info14[1]; + features[11] = info14[1]; } // Fix up AVX bits to account for OS support and match LLVM model @@ -705,7 +721,20 @@ static NOINLINE std::pair> _get_host_cpu(void) else { cpu = uint32_t(CPU::generic); } - + /* Feature bits to register map + feature[0] = ecx + feature[1] = edx + feature[2] = leaf 7 ebx + feature[3] = leaf 7 ecx + feature[4] = leaf 7 edx + feature[5] = leaf 0x80000001 ecx + feature[6] = leaf 0x80000001 edx + feature[7] = leaf 0xd subleaf 1 eax + feature[8] = leaf 0x80000008 ebx + feature[9] = leaf 7 ebx subleaf 1 eax + feature[10] = leaf 7 ebx subleaf 1 ebx + feature[11] = leaf 0x14 ebx + */ return std::make_pair(cpu, features); } diff --git a/src/rtutils.c b/src/rtutils.c index fcc4a489d3f38..00a5b639d8683 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -157,6 +157,13 @@ JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_datatype_t *t, jl_sym_t * jl_throw(jl_new_struct(jl_fielderror_type, t, var)); } +JL_DLLEXPORT void JL_NORETURN jl_argument_error(char *str) // == jl_exceptionf(jl_argumenterror_type, "%s", str) +{ + jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str)); + JL_GC_PUSH1(&msg); + jl_throw(jl_new_struct(jl_argumenterror_type, msg)); +} + JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str) // == jl_exceptionf(jl_atomicerror_type, "%s", str) { jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str)); diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index 80281b733bf44..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) \ @@ -1398,13 +1396,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_) 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/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..788539b1f5096 100644 --- a/src/signals-unix.c +++ b/src/signals-unix.c @@ -308,20 +308,18 @@ int exc_reg_is_write_fault(uintptr_t esr) { #else #include #include +#include -int jl_lock_stackwalk(void) +void jl_with_stackwalk_lock(void (*f)(void*), void *ctx) { - jl_lock_profile(); - return 0; -} - -void jl_unlock_stackwalk(int lockret) -{ - (void)lockret; - jl_unlock_profile(); + 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_)) int is_write_fault(void *context) { ucontext_t *ctx = (ucontext_t*)context; @@ -435,7 +433,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 +505,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 +585,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 +600,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 +804,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 +819,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); + + jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[tid]; - // 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 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 task id (never null) - profile_bt_data_prof[profile_bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls2->current_task); + // 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 cpu cycle clock - profile_bt_data_prof[profile_bt_size_cur++].uintptr = cycleclock(); + // store cpu cycle clock + profile_bt_data_prof[profile_bt_size_cur++].uintptr = cycleclock(); - // 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 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; - // 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; + // 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); + // 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 +1037,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 +1048,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 +1069,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 +1085,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 d6fca2c909f23..14dc5709671dc 100644 --- a/src/stackwalk.c +++ b/src/stackwalk.c @@ -624,7 +624,7 @@ JL_DLLEXPORT jl_value_t *jl_lookup_code_address(void *ip, int skipC) jl_svecset(r, 1, jl_empty_sym); free(frame.file_name); jl_svecset(r, 2, jl_box_long(frame.line)); - jl_svecset(r, 3, frame.linfo != NULL ? (jl_value_t*)frame.linfo : jl_nothing); + jl_svecset(r, 3, frame.ci != NULL ? (jl_value_t*)frame.ci : jl_nothing); jl_svecset(r, 4, jl_box_bool(frame.fromC)); jl_svecset(r, 5, jl_box_bool(frame.inlined)); } @@ -1249,6 +1249,36 @@ 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 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; @@ -1270,15 +1300,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 diff --git a/src/staticdata.c b/src/staticdata.c index 65584c015e228..ff352cd8c152f 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" @@ -101,7 +101,7 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 193 +#define NUM_TAGS 196 // An array of references that need to be restored from the sysimg // This is a manually constructed dual of the gvars array, which would be produced by codegen for Julia code, for C. @@ -216,6 +216,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_addrspace_typename); INSERT_TAG(jl_addrspacecore_type); INSERT_TAG(jl_debuginfo_type); + INSERT_TAG(jl_abioverride_type); // special typenames INSERT_TAG(jl_tuple_typename); @@ -290,6 +291,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_builtin_replacefield); INSERT_TAG(jl_builtin_setfieldonce); INSERT_TAG(jl_builtin_fieldtype); + INSERT_TAG(jl_builtin_memorynew); INSERT_TAG(jl_builtin_memoryref); INSERT_TAG(jl_builtin_memoryrefoffset); INSERT_TAG(jl_builtin_memoryrefget); @@ -309,6 +311,7 @@ jl_value_t **const*const get_tags(void) { INSERT_TAG(jl_builtin_compilerbarrier); INSERT_TAG(jl_builtin_getglobal); INSERT_TAG(jl_builtin_setglobal); + INSERT_TAG(jl_builtin_isdefinedglobal); INSERT_TAG(jl_builtin_swapglobal); INSERT_TAG(jl_builtin_modifyglobal); INSERT_TAG(jl_builtin_replaceglobal); @@ -497,7 +500,6 @@ void *native_functions; // opaque jl_native_code_desc_t blob used for fetching // table of struct field addresses to rewrite during saving static htable_t field_replace; static htable_t bits_replace; -static htable_t relocatable_ext_cis; // array of definitions for the predefined function pointers // (reverse of fptr_to_id) @@ -505,10 +507,10 @@ static htable_t relocatable_ext_cis; static const jl_fptr_args_t id_to_fptrs[] = { &jl_f_throw, &jl_f_throw_methoderror, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa, &jl_f_typeassert, &jl_f__apply_iterate, &jl_f__apply_pure, - &jl_f__call_latest, &jl_f__call_in_world, &jl_f__call_in_world_total, &jl_f_isdefined, + &jl_f__call_latest, &jl_f__call_in_world, &jl_f__call_in_world_total, &jl_f_isdefined, &jl_f_isdefinedglobal, &jl_f_tuple, &jl_f_svec, &jl_f_intrinsic_call, &jl_f_getfield, &jl_f_setfield, &jl_f_swapfield, &jl_f_modifyfield, &jl_f_setfieldonce, - &jl_f_replacefield, &jl_f_fieldtype, &jl_f_nfields, &jl_f_apply_type, + &jl_f_replacefield, &jl_f_fieldtype, &jl_f_nfields, &jl_f_apply_type, &jl_f_memorynew, &jl_f_memoryref, &jl_f_memoryrefoffset, &jl_f_memoryrefget, &jl_f_memoryref_isassigned, &jl_f_memoryrefset, &jl_f_memoryrefswap, &jl_f_memoryrefmodify, &jl_f_memoryrefreplace, &jl_f_memoryrefsetonce, &jl_f_applicable, &jl_f_invoke, &jl_f_sizeof, &jl_f__expr, &jl_f__typevar, @@ -657,6 +659,7 @@ static void jl_load_sysimg_so(void) plen = (size_t *)&jl_system_image_size; else jl_dlsym(jl_sysimg_handle, "jl_system_image_size", (void **)&plen, 1); + jl_gc_notify_image_load(sysimg_data, *plen); jl_restore_system_image_data(sysimg_data, *plen); } @@ -769,6 +772,16 @@ static uintptr_t jl_fptr_id(void *fptr) return *(uintptr_t*)pbp; } +static int effects_foldable(uint32_t effects) +{ + // N.B.: This needs to be kept in sync with Core.Compiler.is_foldable(effects, true) + return ((effects & 0x7) == 0) && // is_consistent(effects) + (((effects >> 10) & 0x03) == 0) && // is_noub(effects) + (((effects >> 3) & 0x03) == 0) && // is_effect_free(effects) + ((effects >> 6) & 0x01); // is_terminates(effects) +} + + // `jl_queue_for_serialization` adds items to `serialization_order` #define jl_queue_for_serialization(s, v) jl_queue_for_serialization_((s), (jl_value_t*)(v), 1, 0) static void jl_queue_for_serialization_(jl_serializer_state *s, jl_value_t *v, int recursive, int immediate) JL_GC_DISABLED; @@ -898,18 +911,41 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ } if (s->incremental && jl_is_code_instance(v)) { jl_code_instance_t *ci = (jl_code_instance_t*)v; + jl_method_instance_t *mi = jl_get_ci_mi(ci); // make sure we don't serialize other reachable cache entries of foreign methods // Should this now be: // if (ci !in ci->defs->cache) // record_field_change((jl_value_t**)&ci->next, NULL); // Why are we checking that the method/module this originates from is in_image? // and then disconnect this CI? - if (jl_object_in_image((jl_value_t*)ci->def->def.value)) { + if (jl_object_in_image((jl_value_t*)mi->def.value)) { // TODO: if (ci in ci->defs->cache) record_field_change((jl_value_t**)&ci->next, NULL); } - if (jl_atomic_load_relaxed(&ci->inferred) && !is_relocatable_ci(&relocatable_ext_cis, ci)) - record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + jl_value_t *inferred = jl_atomic_load_relaxed(&ci->inferred); + if (inferred && inferred != jl_nothing) { // disregard if there is nothing here to delete (e.g. builtins, unspecialized) + jl_method_t *def = mi->def.method; + if (jl_is_method(def)) { // don't delete toplevel code + int is_relocatable = jl_is_code_info(inferred) || + (jl_is_string(inferred) && jl_string_len(inferred) > 0 && jl_string_data(inferred)[jl_string_len(inferred) - 1]); + if (!is_relocatable) { + record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + } + else if (def->source == NULL) { + // don't delete code from optimized opaque closures that can't be reconstructed (and builtins) + } + else if (jl_atomic_load_relaxed(&ci->max_world) != ~(size_t)0 || // delete all code that cannot run + jl_atomic_load_relaxed(&ci->invoke) == jl_fptr_const_return) { // delete all code that just returns a constant + record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + } + else if (native_functions && // don't delete any code if making a ji file + !effects_foldable(jl_atomic_load_relaxed(&ci->ipo_purity_bits)) && // don't delete code we may want for irinterp + jl_ir_inlining_cost(inferred) == UINT16_MAX) { // don't delete inlineable code + // delete the code now: if we thought it was worth keeping, it would have been converted to object code + record_field_change((jl_value_t**)&ci->inferred, jl_nothing); + } + } + } } if (immediate) // must be things that can be recursively handled, and valid as type parameters @@ -1638,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) @@ -1771,7 +1817,6 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED jl_atomic_store_release(&newci->min_world, 1); jl_atomic_store_release(&newci->max_world, 0); } - newci->relocatability = 0; } jl_atomic_store_relaxed(&newci->invoke, NULL); jl_atomic_store_relaxed(&newci->specsigflags, 0); @@ -1782,7 +1827,7 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED fptr_id = JL_API_CONST; } else { - if (jl_is_method(ci->def->def.method)) { + if (jl_is_method(jl_get_ci_mi(ci)->def.method)) { builtin_id = jl_fptr_id(jl_atomic_load_relaxed(&ci->specptr.fptr)); if (builtin_id) { // found in the table of builtins assert(builtin_id >= 2); @@ -2325,9 +2370,9 @@ static void jl_update_all_fptrs(jl_serializer_state *s, jl_image_t *image) offset = ~offset; } jl_code_instance_t *codeinst = (jl_code_instance_t*)(base + offset); - assert(jl_is_method(codeinst->def->def.method) && jl_atomic_load_relaxed(&codeinst->invoke) != jl_fptr_const_return); + assert(jl_is_method(jl_get_ci_mi(codeinst)->def.method) && jl_atomic_load_relaxed(&codeinst->invoke) != jl_fptr_const_return); assert(specfunc ? jl_atomic_load_relaxed(&codeinst->invoke) != NULL : jl_atomic_load_relaxed(&codeinst->invoke) == NULL); - linfos[i] = codeinst->def; // now it's a MethodInstance + linfos[i] = jl_get_ci_mi(codeinst); // now it's a MethodInstance void *fptr = fvars.ptrs[i]; for (; clone_idx < fvars.nclones; clone_idx++) { uint32_t idx = fvars.clone_idxs[clone_idx] & jl_sysimg_val_mask; @@ -2679,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; @@ -2835,7 +2879,7 @@ static void jl_prepare_serialization_data(jl_array_t *mod_array, jl_array_t *new // Extract `new_ext_cis` and `edges` now (from info prepared by jl_collect_methcache_from_mod) *method_roots_list = jl_alloc_vec_any(0); // Collect the new method roots for external specializations - jl_collect_new_roots(&relocatable_ext_cis, *method_roots_list, *new_ext_cis, worklist_key); + jl_collect_new_roots(*method_roots_list, *new_ext_cis, worklist_key); *edges = jl_alloc_vec_any(0); jl_collect_internal_cis(*edges, world); } @@ -3338,7 +3382,6 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli assert((ct->reentrant_timing & 0b1110) == 0); ct->reentrant_timing |= 0b1000; if (worklist) { - htable_new(&relocatable_ext_cis, 0); jl_prepare_serialization_data(mod_array, newly_inferred, jl_worklist_key(worklist), &extext_methods, &new_ext_cis, &method_roots_list, &edges); if (!emit_split) { @@ -3355,8 +3398,6 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli jl_save_system_image_to_stream(ff, mod_array, worklist, extext_methods, new_ext_cis, method_roots_list, edges); if (_native_data != NULL) native_functions = NULL; - if (worklist) - htable_free(&relocatable_ext_cis); // make sure we don't run any Julia code concurrently before this point // Re-enable running julia code for postoutput hooks, atexit, etc. jl_gc_enable_finalizers(ct, 1); @@ -4078,12 +4119,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)); @@ -4093,12 +4135,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); } } } @@ -4198,6 +4239,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_package_image_from_file(const char *fname, j jl_dlsym(pkgimg_handle, "jl_system_image_data", (void **)&pkgimg_data, 1); size_t *plen; jl_dlsym(pkgimg_handle, "jl_system_image_size", (void **)&plen, 1); + jl_gc_notify_image_load(pkgimg_data, *plen); jl_image_t pkgimage = jl_init_processor_pkgimg(pkgimg_handle); diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index ea0b7216155bd..1985357321a3a 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -188,7 +188,7 @@ static int has_backedge_to_worklist(jl_method_instance_t *mi, htable_t *visited, jl_code_instance_t *be; i = get_next_edge(mi->backedges, i, NULL, &be); JL_GC_PROMISE_ROOTED(be); // get_next_edge propagates the edge for us here - int child_found = has_backedge_to_worklist(be->def, visited, stack); + int child_found = has_backedge_to_worklist(jl_get_ci_mi(be), visited, stack); if (child_found == 1 || child_found == 2) { // found what we were looking for, so terminate early found = 1; @@ -215,17 +215,6 @@ static int has_backedge_to_worklist(jl_method_instance_t *mi, htable_t *visited, return found; } -static int is_relocatable_ci(htable_t *relocatable_ext_cis, jl_code_instance_t *ci) -{ - if (!ci->relocatability) - return 0; - jl_method_instance_t *mi = ci->def; - jl_method_t *m = mi->def.method; - if (!ptrhash_has(relocatable_ext_cis, ci) && jl_object_in_image((jl_value_t*)m) && (!jl_is_method(m) || jl_object_in_image((jl_value_t*)m->module))) - return 0; - return 1; -} - // Given the list of CodeInstances that were inferred during the build, select // those that are (1) external, (2) still valid, (3) are inferred to be called // from the worklist or explicitly added by a `precompile` statement, and @@ -247,9 +236,7 @@ static jl_array_t *queue_external_cis(jl_array_t *list) for (i = n0; i-- > 0; ) { jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(list, i); assert(jl_is_code_instance(ci)); - if (!ci->relocatability) - continue; - jl_method_instance_t *mi = ci->def; + jl_method_instance_t *mi = jl_get_ci_mi(ci); jl_method_t *m = mi->def.method; if (ci->owner == jl_nothing && jl_atomic_load_relaxed(&ci->inferred) && jl_is_method(m) && jl_object_in_image((jl_value_t*)m->module)) { int found = has_backedge_to_worklist(mi, &visited, &stack); @@ -275,7 +262,7 @@ static jl_array_t *queue_external_cis(jl_array_t *list) } // New roots for external methods -static void jl_collect_new_roots(htable_t *relocatable_ext_cis, jl_array_t *roots, jl_array_t *new_ext_cis, uint64_t key) +static void jl_collect_new_roots(jl_array_t *roots, jl_array_t *new_ext_cis, uint64_t key) { htable_t mset; htable_new(&mset, 0); @@ -283,10 +270,9 @@ static void jl_collect_new_roots(htable_t *relocatable_ext_cis, jl_array_t *root for (size_t i = 0; i < l; i++) { jl_code_instance_t *ci = (jl_code_instance_t*)jl_array_ptr_ref(new_ext_cis, i); assert(jl_is_code_instance(ci)); - jl_method_t *m = ci->def->def.method; + jl_method_t *m = jl_get_ci_mi(ci)->def.method; assert(jl_is_method(m)); ptrhash_put(&mset, (void*)m, (void*)m); - ptrhash_put(relocatable_ext_cis, (void*)ci, (void*)ci); } int nwithkey; void *const *table = mset.table; @@ -764,360 +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(codeinst->def) && jl_is_method(codeinst->def->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_code_instance(edge)) - edge = (jl_value_t*)((jl_code_instance_t*)edge)->def; - 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_code_instance_t*)callee)->def; - 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 = codeinst->def; - 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; - } - 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/src/support/arraylist.h b/src/support/arraylist.h index a83bd2808756c..8d4ef61ba251c 100644 --- a/src/support/arraylist.h +++ b/src/support/arraylist.h @@ -5,7 +5,7 @@ #define AL_N_INLINE 29 -#define SMALL_AL_N_INLINE 6 +#define SMALL_AL_N_INLINE 5 #ifdef __cplusplus extern "C" { @@ -13,7 +13,7 @@ extern "C" { #include "analyzer_annotations.h" -typedef struct { +typedef struct { // 32 words size_t len; size_t max; void **items; @@ -27,9 +27,9 @@ JL_DLLEXPORT void arraylist_push(arraylist_t *a, void *elt) JL_NOTSAFEPOINT; JL_DLLEXPORT void *arraylist_pop(arraylist_t *a) JL_NOTSAFEPOINT; JL_DLLEXPORT void arraylist_grow(arraylist_t *a, size_t n) JL_NOTSAFEPOINT; -typedef struct { - uint32_t len; - uint32_t max; +typedef struct { // 8 words + size_t len; + size_t max; void **items; void *_space[SMALL_AL_N_INLINE]; } small_arraylist_t; diff --git a/src/task.c b/src/task.c index 1a50d6fcbcf65..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) @@ -541,7 +513,6 @@ JL_NO_ASAN static void ctx_switch(jl_task_t *lastt) jl_set_pgcstack(&t->gcstack); jl_signal_fence(); lastt->ptls = NULL; - fegetenv(&lastt->fenv); #ifdef MIGRATE_TASKS ptls->previous_task = lastt; #endif @@ -734,7 +705,6 @@ JL_DLLEXPORT void jl_switch(void) JL_NOTSAFEPOINT_LEAVE JL_NOTSAFEPOINT_ENTER 0 == ptls->finalizers_inhibited); ptls->finalizers_inhibited = finalizers_inhibited; jl_timing_block_task_enter(ct, ptls, blk); (void)blk; - fesetenv(&ct->fenv); sig_atomic_t other_defer_signal = ptls->defer_signal; ptls->defer_signal = defer_signal; @@ -1147,7 +1117,6 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, jl_value_t *completion t->excstack = NULL; t->ctx.started = 0; t->priority = 0; - fegetenv(&t->fenv); jl_atomic_store_relaxed(&t->tid, -1); t->threadpoolid = ct->threadpoolid; t->ptls = NULL; @@ -1254,7 +1223,6 @@ CFI_NORETURN if (!pt->sticky && !pt->ctx.copy_stack) jl_atomic_store_release(&pt->tid, -1); #endif - fesetenv(&ct->fenv); ct->ctx.started = 1; if (ct->metrics_enabled) { diff --git a/src/threading.c b/src/threading.c index ac9cc276d613a..77956786af3f4 100644 --- a/src/threading.c +++ b/src/threading.c @@ -773,6 +773,10 @@ void jl_init_threading(void) } int16_t ngcthreads = jl_n_markthreads + jl_n_sweepthreads; + if (strstr(jl_gc_active_impl(), "MMTk")) { + ngcthreads = 0; + } + jl_all_tls_states_size = nthreads + nthreadsi + ngcthreads; jl_n_threads_per_pool = (int*)malloc_s(2 * sizeof(int)); jl_n_threads_per_pool[0] = nthreadsi; diff --git a/src/toplevel.c b/src/toplevel.c index 21737119af9a6..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 { @@ -157,7 +156,7 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex else { jl_binding_t *b = jl_get_module_binding(parent_module, name, 1); jl_binding_partition_t *bpart = jl_get_binding_partition(b, ct->world_age); - jl_ptr_kind_union_t pku = encode_restriction(NULL, BINDING_KIND_CONST); + jl_ptr_kind_union_t pku = encode_restriction(NULL, BINDING_KIND_UNDEF_CONST); jl_ptr_kind_union_t new_pku = encode_restriction((jl_value_t*)newm, BINDING_KIND_CONST); if (!jl_atomic_cmpswap(&bpart->restriction, &pku, new_pku)) { if (decode_restriction_kind(pku) != BINDING_KIND_CONST) { @@ -640,7 +639,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_for_uninferred(jl_method_instan jl_code_instance_t *ci = jl_new_codeinst(mi, (jl_value_t*)jl_uninferred_sym, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, (jl_value_t*)src, 0, src->min_world, src->max_world, - 0, NULL, 1, NULL, NULL); + 0, NULL, NULL, NULL); return ci; } @@ -740,17 +739,21 @@ 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) { if (jl_bkind_is_some_constant(decode_restriction_kind(pku))) { if (!val) { - JL_GC_POP(); - return bpart; + break; } jl_value_t *old = decode_restriction_value(pku); JL_GC_PROMISE_ROOTED(old); @@ -781,13 +784,30 @@ 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, BINDING_KIND_CONST); + return jl_declare_constant_val2(b, mod, var, val, val ? BINDING_KIND_CONST : BINDING_KIND_UNDEF_CONST); } JL_DLLEXPORT void jl_eval_const_decl(jl_module_t *m, jl_value_t *arg, jl_value_t *val) @@ -870,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; @@ -909,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 @@ -920,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; @@ -968,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) { @@ -1049,12 +1074,12 @@ 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; if (!has_defs && jl_get_module_infer(m) != 0) { - (void)jl_type_infer(mfunc, world, SOURCE_MODE_NOT_REQUIRED); + (void)jl_type_infer(mfunc, world, SOURCE_MODE_ABI); } result = jl_invoke(/*func*/NULL, /*args*/NULL, /*nargs*/0, mfunc); ct->world_age = last_age; @@ -1063,9 +1088,12 @@ 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; result = jl_interpret_toplevel_thunk(m, thk); + ct->world_age = last_age; } JL_GC_POP(); @@ -1075,8 +1103,8 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val JL_DLLEXPORT jl_value_t *jl_toplevel_eval(jl_module_t *m, jl_value_t *v) { const char *filename = jl_filename; - int lieno = jl_lineno; - return jl_toplevel_eval_flex(m, v, 1, 0, &filename, &lieno); + int lineno = jl_lineno; + return jl_toplevel_eval_flex(m, v, 1, 0, &filename, &lineno); } // Check module `m` is open for `eval/include`, or throw an error. @@ -1135,20 +1163,6 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex) return v; } -JL_DLLEXPORT jl_value_t *jl_infer_thunk(jl_code_info_t *thk, jl_module_t *m) -{ - jl_method_instance_t *li = jl_method_instance_for_thunk(thk, m); - JL_GC_PUSH1(&li); - jl_resolve_globals_in_ir((jl_array_t*)thk->code, m, NULL, 0); - jl_task_t *ct = jl_current_task; - jl_code_instance_t *ci = jl_type_infer(li, ct->world_age, SOURCE_MODE_NOT_REQUIRED); - JL_GC_POP(); - if (ci) - return ci->rettype; - return (jl_value_t*)jl_any_type; -} - - //------------------------------------------------------------------------------ // Code loading: combined parse+eval for include() @@ -1177,14 +1191,13 @@ static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text, jl_task_t *ct = jl_current_task; int last_lineno = jl_lineno; const char *last_filename = jl_filename; - size_t last_age = ct->world_age; int lineno = 0; jl_lineno = 0; const char *filename_str = jl_string_data(filename); jl_filename = filename_str; - int err = 0; JL_TRY { + size_t last_age = ct->world_age; ct->world_age = jl_atomic_load_acquire(&jl_world_counter); for (size_t i = 0; i < jl_expr_nargs(ast); i++) { expression = jl_exprarg(ast, i); @@ -1200,23 +1213,20 @@ static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text, ct->world_age = jl_atomic_load_relaxed(&jl_world_counter); result = jl_toplevel_eval_flex(module, expression, 1, 1, &filename_str, &lineno); } + ct->world_age = last_age; } JL_CATCH { - result = jl_box_long(jl_lineno); // (ab)use result to root error line - err = 1; - goto finally; // skip jl_restore_excstack - } -finally: - ct->world_age = last_age; - jl_lineno = last_lineno; - jl_filename = last_filename; - if (err) { + result = jl_box_long(lineno); // (ab)use result to root error line + jl_lineno = last_lineno; + jl_filename = last_filename; if (jl_loaderror_type == NULL) jl_rethrow(); else jl_rethrow_other(jl_new_struct(jl_loaderror_type, filename, result, jl_current_exception(ct))); } + jl_lineno = last_lineno; + jl_filename = last_filename; JL_GC_POP(); return result; } diff --git a/stdlib/ArgTools.version b/stdlib/ArgTools.version index 09090a62ce0bf..914746c1a6900 100644 --- a/stdlib/ArgTools.version +++ b/stdlib/ArgTools.version @@ -1,4 +1,4 @@ ARGTOOLS_BRANCH = master -ARGTOOLS_SHA1 = 997089b9cd56404b40ff766759662e16dc1aab4b +ARGTOOLS_SHA1 = 1314758ad02ff5e9e5ca718920c6c633b467a84a ARGTOOLS_GIT_URL := https://github.com/JuliaIO/ArgTools.jl.git ARGTOOLS_TAR_URL = https://api.github.com/repos/JuliaIO/ArgTools.jl/tarball/$1 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/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" diff --git a/stdlib/Distributed.version b/stdlib/Distributed.version index 02eac7eadf0ad..4a7ab49defed2 100644 --- a/stdlib/Distributed.version +++ b/stdlib/Distributed.version @@ -1,4 +1,4 @@ DISTRIBUTED_BRANCH = master -DISTRIBUTED_SHA1 = 6c7cdb5860fa5cb9ca191ce9c52a3d25a9ab3781 +DISTRIBUTED_SHA1 = c6136853451677f1957bec20ecce13419cde3a12 DISTRIBUTED_GIT_URL := https://github.com/JuliaLang/Distributed.jl DISTRIBUTED_TAR_URL = https://api.github.com/repos/JuliaLang/Distributed.jl/tarball/$1 diff --git a/stdlib/Downloads.version b/stdlib/Downloads.version index b539771fbdb47..40004d8337091 100644 --- a/stdlib/Downloads.version +++ b/stdlib/Downloads.version @@ -1,4 +1,4 @@ DOWNLOADS_BRANCH = master -DOWNLOADS_SHA1 = 89d3c7dded535a77551e763a437a6d31e4d9bf84 +DOWNLOADS_SHA1 = e692e77fb5427bf3c6e81514b323c39a88217eec DOWNLOADS_GIT_URL := https://github.com/JuliaLang/Downloads.jl.git DOWNLOADS_TAR_URL = https://api.github.com/repos/JuliaLang/Downloads.jl/tarball/$1 diff --git a/stdlib/GMP_jll/Project.toml b/stdlib/GMP_jll/Project.toml index 3a6fa12c95aef..a31688d0a9c07 100644 --- a/stdlib/GMP_jll/Project.toml +++ b/stdlib/GMP_jll/Project.toml @@ -1,6 +1,6 @@ name = "GMP_jll" uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" -version = "6.3.0+1" +version = "6.3.0+2" [deps] Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index aa13fa3cdd31d..4a320282610cd 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -166,6 +166,7 @@ function versioninfo(io::IO=stdout; verbose::Bool=false) end println(io, " WORD_SIZE: ", Sys.WORD_SIZE) println(io, " LLVM: libLLVM-",Base.libllvm_version," (", Sys.JIT, ", ", Sys.CPU_NAME, ")") + println(io, " GC: ", unsafe_string(ccall(:jl_gc_active_impl, Ptr{UInt8}, ()))) println(io, """Threads: $(Threads.nthreads(:default)) default, $(Threads.nthreads(:interactive)) interactive, \ $(Threads.ngcthreads()) GC (on $(Sys.CPU_THREADS) virtual cores)""") diff --git a/stdlib/LazyArtifacts.version b/stdlib/LazyArtifacts.version index 4246ec3ad5d1a..8988e27bcb4ac 100644 --- a/stdlib/LazyArtifacts.version +++ b/stdlib/LazyArtifacts.version @@ -1,4 +1,4 @@ LAZYARTIFACTS_BRANCH = main -LAZYARTIFACTS_SHA1 = e9a36338d5d0dfa4b222f4e11b446cbb7ea5836c +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 diff --git a/stdlib/LibCURL_jll/Project.toml b/stdlib/LibCURL_jll/Project.toml index d17090a1e5c3b..61d44beac14e1 100644 --- a/stdlib/LibCURL_jll/Project.toml +++ b/stdlib/LibCURL_jll/Project.toml @@ -1,11 +1,11 @@ name = "LibCURL_jll" uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" +version = "8.11.1+1" [deps] LibSSH2_jll = "29816b5a-b9ab-546f-933c-edad1886dfa8" nghttp2_jll = "8e850ede-7688-5339-a07c-302acd2aaf8d" -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" Zlib_jll = "83775a58-1f1d-513f-b197-d71354ab007a" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/LibCURL_jll/src/LibCURL_jll.jl b/stdlib/LibCURL_jll/src/LibCURL_jll.jl index 3291c97d811cb..5c1c2aa14b23a 100644 --- a/stdlib/LibCURL_jll/src/LibCURL_jll.jl +++ b/stdlib/LibCURL_jll/src/LibCURL_jll.jl @@ -3,7 +3,11 @@ ## dummy stub for https://github.com/JuliaBinaryWrappers/LibCURL_jll.jl baremodule LibCURL_jll -using Base, Libdl, nghttp2_jll +using Base, Libdl, nghttp2_jll, LibSSH2_jll, Zlib_jll +if !(Sys.iswindows() || Sys.isapple()) + # On Windows and macOS we use system SSL/crypto libraries + using OpenSSL_jll +end const PATH_list = String[] const LIBPATH_list = String[] diff --git a/stdlib/LibGit2/src/callbacks.jl b/stdlib/LibGit2/src/callbacks.jl index 043e04e0dfad6..c4156d4a44c71 100644 --- a/stdlib/LibGit2/src/callbacks.jl +++ b/stdlib/LibGit2/src/callbacks.jl @@ -43,7 +43,7 @@ end function user_abort() ensure_initialized() # Note: Potentially it could be better to just throw a Julia error. - ccall((:giterr_set_str, libgit2), Cvoid, + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "Aborting, user cancelled credential request.") return Cint(Error.EUSER) @@ -51,7 +51,7 @@ end function prompt_limit() ensure_initialized() - ccall((:giterr_set_str, libgit2), Cvoid, + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "Aborting, maximum number of prompts reached.") return Cint(Error.EAUTH) @@ -59,7 +59,7 @@ end function exhausted_abort() ensure_initialized() - ccall((:giterr_set_str, libgit2), Cvoid, + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "All authentication methods have failed.") return Cint(Error.EAUTH) @@ -339,7 +339,7 @@ function credentials_callback(libgit2credptr::Ptr{Ptr{Cvoid}}, url_ptr::Cstring, if err == 0 if p.explicit !== nothing ensure_initialized() - ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(Error.Callback), "The explicitly provided credential is incompatible with the requested " * "authentication methods.") end diff --git a/stdlib/LibGit2/src/consts.jl b/stdlib/LibGit2/src/consts.jl index 8c140e8c2aa30..1a523b381982b 100644 --- a/stdlib/LibGit2/src/consts.jl +++ b/stdlib/LibGit2/src/consts.jl @@ -45,8 +45,7 @@ const BLAME_USE_MAILMAP = Cuint(1 << 5) const BLAME_IGNORE_WHITESPACE = Cuint(1 << 6) # checkout -const CHECKOUT_NONE = Cuint(0) -const CHECKOUT_SAFE = Cuint(1 << 0) +const CHECKOUT_SAFE = Cuint(0) const CHECKOUT_FORCE = Cuint(1 << 1) const CHECKOUT_RECREATE_MISSING = Cuint(1 << 2) const CHECKOUT_ALLOW_CONFLICTS = Cuint(1 << 4) @@ -67,6 +66,7 @@ const CHECKOUT_DONT_REMOVE_EXISTING = Cuint(1 << 22) const CHECKOUT_DONT_WRITE_INDEX = Cuint(1 << 23) const CHECKOUT_DRY_RUN = Cuint(1 << 24) const CHECKOUT_CONFLICT_STYLE_ZDIFF3 = Cuint(1 << 25) +const CHECKOUT_NONE = Cuint(1 << 30) const CHECKOUT_UPDATE_SUBMODULES = Cuint(1 << 16) const CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = Cuint(1 << 17) diff --git a/stdlib/LibGit2/src/error.jl b/stdlib/LibGit2/src/error.jl index 1a493006ea1b5..6647d803d3193 100644 --- a/stdlib/LibGit2/src/error.jl +++ b/stdlib/LibGit2/src/error.jl @@ -19,7 +19,7 @@ export GitError EUNMERGED = Cint(-10), # merge in progress prevented op ENONFASTFORWARD = Cint(-11), # ref not fast-forwardable EINVALIDSPEC = Cint(-12), # name / ref not in valid format - EMERGECONFLICT = Cint(-13), # merge conflict prevented op + ECONFLICT = Cint(-13), # Checkout conflicts prevented operation ELOCKED = Cint(-14), # lock file prevented op EMODIFIED = Cint(-15), # ref value does not match expected EAUTH = Cint(-16), # authentication error @@ -27,6 +27,11 @@ export GitError EAPPLIED = Cint(-18), # patch/merge has already been applied EPEEL = Cint(-19), # the requested peel operation is not possible EEOF = Cint(-20), # unexpected EOF + EINVALID = Cint(-21), # Invalid operation or input + EUNCOMMITTED = Cint(-22), # Uncommitted changes in index prevented operation + EDIRECTORY = Cint(-23), # The operation is not valid for a directory + EMERGECONFLICT = Cint(-24), # A merge conflict exists and cannot continue + PASSTHROUGH = Cint(-30), # internal only ITEROVER = Cint(-31), # signals end of iteration RETRY = Cint(-32), # internal only @@ -34,7 +39,11 @@ export GitError EINDEXDIRTY = Cint(-34), # unsaved changes in the index would be overwritten EAPPLYFAIL = Cint(-35), # patch application failed EOWNER = Cint(-36), # the object is not owned by the current user - TIMEOUT = Cint(-37)) # The operation timed out + TIMEOUT = Cint(-37), # The operation timed out + EUNCHANGED = Cint(-38), # There were no changes + ENOTSUPPORTED = Cint(-39), # An option is not supported + EREADONLY = Cint(-40), # The subject is read-only +) @enum(Class, None, NoMemory, @@ -88,7 +97,7 @@ Base.show(io::IO, err::GitError) = print(io, "GitError(Code:$(err.code), Class:$ function last_error() ensure_initialized() - err = ccall((:giterr_last, libgit2), Ptr{ErrorStruct}, ()) + err = ccall((:git_error_last, libgit2), Ptr{ErrorStruct}, ()) if err != C_NULL err_obj = unsafe_load(err) err_class = Class(err_obj.class) diff --git a/stdlib/LibGit2/src/types.jl b/stdlib/LibGit2/src/types.jl index 9228bec175737..181baa4991a9b 100644 --- a/stdlib/LibGit2/src/types.jl +++ b/stdlib/LibGit2/src/types.jl @@ -237,6 +237,9 @@ Matches the [`git_remote_callbacks`](https://libgit2.org/libgit2/#HEAD/type/git_ @static if LibGit2.VERSION >= v"0.99.0" resolve_url::Ptr{Cvoid} = C_NULL end + @static if LibGit2.VERSION >= v"1.9.0" + update_refs::Ptr{Cvoid} = C_NULL + end end @assert Base.allocatedinline(RemoteCallbacks) @@ -924,7 +927,9 @@ struct ConfigEntry end include_depth::Cuint level::GIT_CONFIG - free::Ptr{Cvoid} + @static if LibGit2.VERSION < v"1.9.0" + free::Ptr{Cvoid} + end @static if LibGit2.VERSION < v"1.8.0" # In 1.8.0, the unused payload value has been removed payload::Ptr{Cvoid} @@ -936,6 +941,17 @@ function Base.show(io::IO, ce::ConfigEntry) print(io, "ConfigEntry(\"", unsafe_string(ce.name), "\", \"", unsafe_string(ce.value), "\")") end +""" + LibGit2.ConfigBackendEntry + +Matches the [`git_config_backend_entry`](https://libgit2.org/libgit2/#HEAD/type/git_config_backend_entry) struct. +""" +struct ConfigBackendEntry + entry::ConfigEntry + free::Ptr{Cvoid} +end +@assert Base.allocatedinline(ConfigBackendEntry) + """ LibGit2.split_cfg_entry(ce::LibGit2.ConfigEntry) -> Tuple{String,String,String,String} @@ -1138,15 +1154,20 @@ The fields represent: * `final_commit_id`: the [`GitHash`](@ref) of the commit where this section was last changed. * `final_start_line_number`: the *one based* line number in the file where the hunk starts, in the *final* version of the file. - * `final_signature`: the signature of the person who last modified this hunk. You will + * `final_signature`: the signature of the author of `final_commit_id`. You will + need to pass this to `Signature` to access its fields. + * `final_committer`: the signature of the committer of `final_commit_id`. You will need to pass this to `Signature` to access its fields. * `orig_commit_id`: the [`GitHash`](@ref) of the commit where this hunk was first found. * `orig_path`: the path to the file where the hunk originated. This may be different than the current/final path, for instance if the file has been moved. * `orig_start_line_number`: the *one based* line number in the file where the hunk starts, in the *original* version of the file at `orig_path`. - * `orig_signature`: the signature of the person who introduced this hunk. You will + * `orig_signature`: the signature of the author who introduced this hunk. You will + need to pass this to `Signature` to access its fields. + * `orig_committer`: the signature of the committer who introduced this hunk. You will need to pass this to `Signature` to access its fields. + * `summary`: a string summary. * `boundary`: `'1'` if the original commit is a "boundary" commit (for instance, if it's equal to an oldest commit set in `options`). """ @@ -1156,12 +1177,21 @@ The fields represent: final_commit_id::GitHash = GitHash() final_start_line_number::Csize_t = Csize_t(0) final_signature::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + @static if LibGit2.VERSION >= v"1.9.0" + final_committer::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + end orig_commit_id::GitHash = GitHash() orig_path::Cstring = Cstring(C_NULL) orig_start_line_number::Csize_t = Csize_t(0) orig_signature::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + @static if LibGit2.VERSION >= v"1.9.0" + orig_committer::Ptr{SignatureStruct} = Ptr{SignatureStruct}(C_NULL) + end + @static if LibGit2.VERSION >= v"1.9.0" + summary::Cstring = Cstring(C_NULL) + end boundary::Char = '\0' end @assert Base.allocatedinline(BlameHunk) diff --git a/stdlib/LibGit2/test/libgit2-tests.jl b/stdlib/LibGit2/test/libgit2-tests.jl index 9ab75ed1dc39b..b186f67c65cf1 100644 --- a/stdlib/LibGit2/test/libgit2-tests.jl +++ b/stdlib/LibGit2/test/libgit2-tests.jl @@ -1070,7 +1070,7 @@ mktempdir() do dir # test workaround for git_tree_walk issue # https://github.com/libgit2/libgit2/issues/4693 - ccall((:giterr_set_str, libgit2), Cvoid, (Cint, Cstring), + ccall((:git_error_set_str, libgit2), Cvoid, (Cint, Cstring), Cint(LibGit2.Error.Invalid), "previous error") try # file needs to exist in tree in order to trigger the stop walk condition @@ -1152,6 +1152,7 @@ mktempdir() do dir function setup_clone_repo(cache_repo::AbstractString, path::AbstractString; name="AAAA", email="BBBB@BBBB.COM") repo = LibGit2.clone(cache_repo, path) + LibGit2.fetch(repo) # need to set this for merges to succeed cfg = LibGit2.GitConfig(repo) LibGit2.set!(cfg, "user.name", name) diff --git a/stdlib/LibGit2_jll/Project.toml b/stdlib/LibGit2_jll/Project.toml index ceeb394f26231..216fe9c3c6b41 100644 --- a/stdlib/LibGit2_jll/Project.toml +++ b/stdlib/LibGit2_jll/Project.toml @@ -1,9 +1,9 @@ name = "LibGit2_jll" uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.0+0" +version = "1.9.0+0" [deps] -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" LibSSH2_jll = "29816b5a-b9ab-546f-933c-edad1886dfa8" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/LibGit2_jll/src/LibGit2_jll.jl b/stdlib/LibGit2_jll/src/LibGit2_jll.jl index 15d303dfea6ee..c69deb4a9d932 100644 --- a/stdlib/LibGit2_jll/src/LibGit2_jll.jl +++ b/stdlib/LibGit2_jll/src/LibGit2_jll.jl @@ -3,7 +3,11 @@ ## dummy stub for https://github.com/JuliaBinaryWrappers/LibGit2_jll.jl baremodule LibGit2_jll -using Base, Libdl, MbedTLS_jll, LibSSH2_jll +using Base, Libdl, LibSSH2_jll +if !(Sys.iswindows() || Sys.isapple()) + # On Windows and macOS we use system SSL/crypto libraries + using OpenSSL_jll +end const PATH_list = String[] const LIBPATH_list = String[] @@ -20,9 +24,9 @@ libgit2_path::String = "" if Sys.iswindows() const libgit2 = "libgit2.dll" elseif Sys.isapple() - const libgit2 = "@rpath/libgit2.1.8.dylib" + const libgit2 = "@rpath/libgit2.1.9.dylib" else - const libgit2 = "libgit2.so.1.8" + const libgit2 = "libgit2.so.1.9" end function __init__() diff --git a/stdlib/LibGit2_jll/test/runtests.jl b/stdlib/LibGit2_jll/test/runtests.jl index 5bc74760b1603..06edefe335a2f 100644 --- a/stdlib/LibGit2_jll/test/runtests.jl +++ b/stdlib/LibGit2_jll/test/runtests.jl @@ -7,5 +7,5 @@ using Test, Libdl, LibGit2_jll minor = Ref{Cint}(0) patch = Ref{Cint}(0) @test ccall((:git_libgit2_version, libgit2), Cint, (Ref{Cint}, Ref{Cint}, Ref{Cint}), major, minor, patch) == 0 - @test VersionNumber(major[], minor[], patch[]) == v"1.8.0" + @test VersionNumber(major[], minor[], patch[]) == v"1.9.0" end diff --git a/stdlib/LibSSH2_jll/Project.toml b/stdlib/LibSSH2_jll/Project.toml index def4fb02e399c..09f07b559344c 100644 --- a/stdlib/LibSSH2_jll/Project.toml +++ b/stdlib/LibSSH2_jll/Project.toml @@ -1,9 +1,9 @@ name = "LibSSH2_jll" uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" +version = "1.11.3+1" [deps] -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" diff --git a/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl b/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl index 351cbe0e3729b..e9392fe34a918 100644 --- a/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl +++ b/stdlib/LibSSH2_jll/src/LibSSH2_jll.jl @@ -3,7 +3,11 @@ ## dummy stub for https://github.com/JuliaBinaryWrappers/LibSSH2_jll.jl baremodule LibSSH2_jll -using Base, Libdl, MbedTLS_jll +using Base, Libdl +if !Sys.iswindows() + # On Windows we use system SSL/crypto libraries + using OpenSSL_jll +end const PATH_list = String[] const LIBPATH_list = String[] diff --git a/stdlib/LibSSH2_jll/test/runtests.jl b/stdlib/LibSSH2_jll/test/runtests.jl index 58cfd9ac024cc..9a05270317752 100644 --- a/stdlib/LibSSH2_jll/test/runtests.jl +++ b/stdlib/LibSSH2_jll/test/runtests.jl @@ -3,6 +3,9 @@ using Test, Libdl, LibSSH2_jll @testset "LibSSH2_jll" begin - # We use a `startswith()` here because when built from source, this returns "1.9.0_DEV" - vn = startswith(unsafe_string(ccall((:libssh2_version, libssh2), Cstring, (Cint,), 0)), "1.9.0") + vn = unsafe_string(ccall((:libssh2_version, libssh2), Cstring, (Cint,), 0)) + # Depending on how LibSSH2_jll was installed (downloaded from + # BinaryBuilder or built from source here), the version number is + # either "1.11.1" or "1.11.1_DEV", respectively. + @test startswith(vn, "1.11.1") end diff --git a/stdlib/LibUV_jll/Project.toml b/stdlib/LibUV_jll/Project.toml index 74aae1c9249df..c6ec3ae228647 100644 --- a/stdlib/LibUV_jll/Project.toml +++ b/stdlib/LibUV_jll/Project.toml @@ -1,6 +1,6 @@ name = "LibUV_jll" uuid = "183b4373-6708-53ba-ad28-60e28bb38547" -version = "2.0.1+19" +version = "2.0.1+20" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/LinearAlgebra.version b/stdlib/LinearAlgebra.version index d6a33ea421adf..3dac27119172a 100644 --- a/stdlib/LinearAlgebra.version +++ b/stdlib/LinearAlgebra.version @@ -1,4 +1,4 @@ LINEARALGEBRA_BRANCH = master -LINEARALGEBRA_SHA1 = 56d561c22e1ab8e0421160edbdd42f3f194ecfa8 +LINEARALGEBRA_SHA1 = 1137b4c7fa8297cef17c4ae0982d7d89d4ab7dd8 LINEARALGEBRA_GIT_URL := https://github.com/JuliaLang/LinearAlgebra.jl.git LINEARALGEBRA_TAR_URL = https://api.github.com/repos/JuliaLang/LinearAlgebra.jl/tarball/$1 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/Makefile b/stdlib/Makefile index a10503a3566c6..3975f24b7ae3b 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -17,7 +17,7 @@ VERSDIR := v$(shell cut -d. -f1-2 < $(JULIAHOME)/VERSION) DIRS := $(build_datarootdir)/julia/stdlib/$(VERSDIR) $(build_prefix)/manifest/$(VERSDIR) $(foreach dir,$(DIRS),$(eval $(call dir_target,$(dir)))) -JLLS = DSFMT GMP CURL LIBGIT2 LLVM LIBSSH2 LIBUV MBEDTLS MPFR NGHTTP2 \ +JLLS = DSFMT GMP CURL LIBGIT2 LLVM LIBSSH2 LIBUV OPENSSL MPFR NGHTTP2 \ BLASTRAMPOLINE OPENBLAS OPENLIBM P7ZIP PCRE LIBSUITESPARSE ZLIB \ LLVMUNWIND CSL UNWIND LLD diff --git a/stdlib/Manifest.toml b/stdlib/Manifest.toml index 8953aa93ce4b2..f029a210320cc 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.12.0-DEV" manifest_format = "2.0" -project_hash = "d3a1f6b706609fe0c59521e1d770be6e2b8c489d" +project_hash = "1cb1aede0b4f0a2f12806233b9f188a63d6acf04" [[deps.ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" @@ -58,7 +58,7 @@ version = "1.11.0" [[deps.GMP_jll]] deps = ["Artifacts", "Libdl"] uuid = "781609d7-10c4-51f6-84f2-b8444358ff6d" -version = "6.3.0+1" +version = "6.3.0+2" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -78,7 +78,7 @@ version = "18.1.7+3" [[deps.LLVMLibUnwind_jll]] deps = ["Artifacts", "Libdl"] uuid = "47c5dbc3-30ba-59ef-96a6-123e260183d9" -version = "12.0.1+0" +version = "19.1.4+0" [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] @@ -91,9 +91,9 @@ uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" version = "0.6.4" [[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.6.0+0" +version = "8.11.1+1" [[deps.LibGit2]] deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] @@ -101,19 +101,19 @@ uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" version = "1.11.0" [[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.8.0+0" +version = "1.9.0+0" [[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +deps = ["Artifacts", "Libdl", "OpenSSL_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.0+1" +version = "1.11.3+1" [[deps.LibUV_jll]] deps = ["Artifacts", "Libdl"] uuid = "183b4373-6708-53ba-ad28-60e28bb38547" -version = "2.0.1+19" +version = "2.0.1+20" [[deps.LibUnwind_jll]] deps = ["Artifacts", "Libdl"] @@ -143,22 +143,17 @@ deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" version = "1.11.0" -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+1" - [[deps.Mmap]] uuid = "a63ad114-7e13-5084-954f-fe012c677804" version = "1.11.0" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2024.3.11" +version = "2024.11.26" [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" +version = "1.3.0" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] @@ -168,12 +163,17 @@ version = "0.3.28+3" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+3" +version = "0.8.5+0" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.15+1" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.43.0+1" +version = "10.44.0+1" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] @@ -243,7 +243,7 @@ version = "1.11.0" [[deps.SuiteSparse_jll]] deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.8.0+1" +version = "7.8.3+2" [[deps.TOML]] deps = ["Dates"] @@ -272,12 +272,12 @@ version = "1.11.0" [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.3.1+1" +version = "1.3.1+2" [[deps.dSFMT_jll]] deps = ["Artifacts", "Libdl"] uuid = "05ff407c-b0c1-5878-9df8-858cc2e60c36" -version = "2.2.5+1" +version = "2.2.5+2" [[deps.libLLVM_jll]] deps = ["Artifacts", "Libdl"] @@ -287,14 +287,14 @@ version = "18.1.7+3" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.0+0" +version = "5.12.0+0" [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.63.0+1" +version = "1.64.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.5.0+1" +version = "17.5.0+2" diff --git a/stdlib/Markdown/docs/src/index.md b/stdlib/Markdown/docs/src/index.md index ad620c22eae5d..926e3921d339d 100644 --- a/stdlib/Markdown/docs/src/index.md +++ b/stdlib/Markdown/docs/src/index.md @@ -420,6 +420,7 @@ custom flavour of Markdown can be used, but this should generally be unnecessary Markdown.MD Markdown.@md_str Markdown.@doc_str +Markdown.parse Markdown.html Markdown.latex ``` diff --git a/stdlib/Markdown/src/Common/block.jl b/stdlib/Markdown/src/Common/block.jl index 1b5cc1a752bcb..247c894769f15 100644 --- a/stdlib/Markdown/src/Common/block.jl +++ b/stdlib/Markdown/src/Common/block.jl @@ -21,7 +21,7 @@ function paragraph(stream::IO, md::MD) char == '\r' && !eof(stream) && peek(stream, Char) == '\n' && read(stream, Char) if prev_char == '\\' write(buffer, '\n') - elseif blankline(stream) || parse(stream, md, breaking = true) + elseif blankline(stream) || _parse(stream, md, breaking = true) break else write(buffer, ' ') diff --git a/stdlib/Markdown/src/GitHub/GitHub.jl b/stdlib/Markdown/src/GitHub/GitHub.jl index 61807d267511d..676ae4a137779 100644 --- a/stdlib/Markdown/src/GitHub/GitHub.jl +++ b/stdlib/Markdown/src/GitHub/GitHub.jl @@ -44,7 +44,7 @@ function github_paragraph(stream::IO, md::MD) for char in readeach(stream, Char) if char == '\n' eof(stream) && break - if blankline(stream) || parse(stream, md, breaking = true) + if blankline(stream) || _parse(stream, md, breaking = true) break else write(buffer, '\n') diff --git a/stdlib/Markdown/src/Markdown.jl b/stdlib/Markdown/src/Markdown.jl index 0d45d9e534df2..8d79cc93d6171 100644 --- a/stdlib/Markdown/src/Markdown.jl +++ b/stdlib/Markdown/src/Markdown.jl @@ -35,6 +35,8 @@ include("render/terminal/render.jl") export @md_str, @doc_str +public MD, parse + const MARKDOWN_FACES = [ :markdown_header => Face(weight=:bold), :markdown_h1 => Face(height=1.25, inherit=:markdown_header), @@ -57,7 +59,16 @@ const MARKDOWN_FACES = [ __init__() = foreach(addface!, MARKDOWN_FACES) parse(markdown::String; flavor = julia) = parse(IOBuffer(markdown), flavor = flavor) + +""" + Markdown.parse(markdown::AbstractString) -> MD + +Parse `markdown` as Julia-flavored Markdown text and return the corresponding `MD` object. + +See also [`@md_str`](@ref). +""" parse(markdown::AbstractString; flavor = julia) = parse(String(markdown), flavor = flavor) + parse_file(file::AbstractString; flavor = julia) = parse(read(file, String), flavor = flavor) function mdexpr(s, flavor = :julia) @@ -74,6 +85,8 @@ end Parse the given string as Markdown text and return a corresponding [`MD`](@ref) object. +See also [`Markdown.parse`](@ref Markdown.parse(::AbstractString)). + # Examples ```jldoctest julia> s = md"# Hello, world!" diff --git a/stdlib/Markdown/src/parse/parse.jl b/stdlib/Markdown/src/parse/parse.jl index 389099b2984f6..dee1e781bfbef 100644 --- a/stdlib/Markdown/src/parse/parse.jl +++ b/stdlib/Markdown/src/parse/parse.jl @@ -15,8 +15,6 @@ mutable struct MD new(content, meta) end -public MD - MD(xs...) = MD(vcat(xs...)) function MD(cfg::Config, xs...) @@ -85,7 +83,7 @@ parseinline(s, md::MD) = parseinline(s, md, config(md)) # Block parsing -function parse(stream::IO, block::MD, config::Config; breaking = false) +function _parse(stream::IO, block::MD, config::Config; breaking = false) skipblank(stream) eof(stream) && return false for parser in (breaking ? config.breaking : [config.breaking; config.regular]) @@ -94,12 +92,17 @@ function parse(stream::IO, block::MD, config::Config; breaking = false) return false end -parse(stream::IO, block::MD; breaking = false) = - parse(stream, block, config(block), breaking = breaking) +_parse(stream::IO, block::MD; breaking = false) = + _parse(stream, block, config(block), breaking = breaking) + +""" + parse(stream::IO) -> MD +Parse the content of `stream` as Julia-flavored Markdown text and return the corresponding `MD` object. +""" function parse(stream::IO; flavor = julia) isa(flavor, Symbol) && (flavor = flavors[flavor]) markdown = MD(flavor) - while parse(stream, markdown, flavor) end + while _parse(stream, markdown, flavor) end return markdown end diff --git a/stdlib/MbedTLS_jll/src/MbedTLS_jll.jl b/stdlib/MbedTLS_jll/src/MbedTLS_jll.jl deleted file mode 100644 index 6367213e2c4ab..0000000000000 --- a/stdlib/MbedTLS_jll/src/MbedTLS_jll.jl +++ /dev/null @@ -1,61 +0,0 @@ -# This file is a part of Julia. License is MIT: https://julialang.org/license - -## dummy stub for https://github.com/JuliaBinaryWrappers/MbedTLS_jll.jl - -baremodule MbedTLS_jll -using Base, Libdl - -const PATH_list = String[] -const LIBPATH_list = String[] - -export libmbedcrypto, libmbedtls, libmbedx509 - -# These get calculated in __init__() -const PATH = Ref("") -const LIBPATH = Ref("") -artifact_dir::String = "" -libmbedcrypto_handle::Ptr{Cvoid} = C_NULL -libmbedcrypto_path::String = "" -libmbedtls_handle::Ptr{Cvoid} = C_NULL -libmbedtls_path::String = "" -libmbedx509_handle::Ptr{Cvoid} = C_NULL -libmbedx509_path::String = "" - -if Sys.iswindows() - const libmbedcrypto = "libmbedcrypto.dll" - const libmbedtls = "libmbedtls.dll" - const libmbedx509 = "libmbedx509.dll" -elseif Sys.isapple() - const libmbedcrypto = "@rpath/libmbedcrypto.7.dylib" - const libmbedtls = "@rpath/libmbedtls.14.dylib" - const libmbedx509 = "@rpath/libmbedx509.1.dylib" -else - const libmbedcrypto = "libmbedcrypto.so.7" - const libmbedtls = "libmbedtls.so.14" - const libmbedx509 = "libmbedx509.so.1" -end - -function __init__() - global libmbedcrypto_handle = dlopen(libmbedcrypto) - global libmbedcrypto_path = dlpath(libmbedcrypto_handle) - global libmbedtls_handle = dlopen(libmbedtls) - global libmbedtls_path = dlpath(libmbedtls_handle) - global libmbedx509_handle = dlopen(libmbedx509) - global libmbedx509_path = dlpath(libmbedx509_handle) - global artifact_dir = dirname(Sys.BINDIR) - LIBPATH[] = dirname(libmbedtls_path) - push!(LIBPATH_list, LIBPATH[]) -end - -# JLLWrappers API compatibility shims. Note that not all of these will really make sense. -# For instance, `find_artifact_dir()` won't actually be the artifact directory, because -# there isn't one. It instead returns the overall Julia prefix. -is_available() = true -find_artifact_dir() = artifact_dir -dev_jll() = error("stdlib JLLs cannot be dev'ed") -best_wrapper = nothing -get_libmbedcrypto_path() =libmbedcrypto_path -get_libmbedtls_path() = libmbedtls_path -get_libmbedx509_path() = libmbedx509_path - -end # module MbedTLS_jll diff --git a/stdlib/MbedTLS_jll/test/runtests.jl b/stdlib/MbedTLS_jll/test/runtests.jl deleted file mode 100644 index 5813a813a1e1f..0000000000000 --- a/stdlib/MbedTLS_jll/test/runtests.jl +++ /dev/null @@ -1,10 +0,0 @@ -# This file is a part of Julia. License is MIT: https://julialang.org/license - -using Test, Libdl, MbedTLS_jll - -@testset "MbedTLS_jll" begin - vstr = zeros(UInt8, 32) - ccall((:mbedtls_version_get_string, libmbedcrypto), Cvoid, (Ref{UInt8},), vstr) - vn = VersionNumber(unsafe_string(pointer(vstr))) - @test vn == v"2.28.6" -end 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" diff --git a/stdlib/NetworkOptions.version b/stdlib/NetworkOptions.version index 221b9b934f1a1..69b56e03ed89e 100644 --- a/stdlib/NetworkOptions.version +++ b/stdlib/NetworkOptions.version @@ -1,4 +1,4 @@ NETWORKOPTIONS_BRANCH = master -NETWORKOPTIONS_SHA1 = 8eec5cb0acec4591e6db3c017f7499426cd8e352 +NETWORKOPTIONS_SHA1 = c090626d3feee6d6a5c476346d22d6147c9c6d2d NETWORKOPTIONS_GIT_URL := https://github.com/JuliaLang/NetworkOptions.jl.git NETWORKOPTIONS_TAR_URL = https://api.github.com/repos/JuliaLang/NetworkOptions.jl/tarball/$1 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. diff --git a/stdlib/OpenLibm_jll/Project.toml b/stdlib/OpenLibm_jll/Project.toml index a4c559e1ff4ef..431528ee3f400 100644 --- a/stdlib/OpenLibm_jll/Project.toml +++ b/stdlib/OpenLibm_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenLibm_jll" uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+3" +version = "0.8.5+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/MbedTLS_jll/Project.toml b/stdlib/OpenSSL_jll/Project.toml similarity index 66% rename from stdlib/MbedTLS_jll/Project.toml rename to stdlib/OpenSSL_jll/Project.toml index 61f3ea0d8b4dc..0773311e11043 100644 --- a/stdlib/MbedTLS_jll/Project.toml +++ b/stdlib/OpenSSL_jll/Project.toml @@ -1,13 +1,13 @@ -name = "MbedTLS_jll" -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.6+1" +name = "OpenSSL_jll" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.15+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [compat] -julia = "1.8" +julia = "1.6" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl b/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl new file mode 100644 index 0000000000000..bba9a0a299de9 --- /dev/null +++ b/stdlib/OpenSSL_jll/src/OpenSSL_jll.jl @@ -0,0 +1,58 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +## dummy stub for https://github.com/JuliaBinaryWrappers/OpenSSL_jll.jl + +baremodule OpenSSL_jll +using Base, Libdl, Base.BinaryPlatforms + +const PATH_list = String[] +const LIBPATH_list = String[] + +export libcrypto, libssl + +# These get calculated in __init__() +const PATH = Ref("") +const LIBPATH = Ref("") +artifact_dir::String = "" +libcrypto_handle::Ptr{Cvoid} = C_NULL +libcrypto_path::String = "" +libssl_handle::Ptr{Cvoid} = C_NULL +libssl_path::String = "" + +if Sys.iswindows() + if arch(HostPlatform()) == "x86_64" + const libcrypto = "libcrypto-3-x64.dll" + const libssl = "libssl-3-x64.dll" + else + const libcrypto = "libcrypto-3.dll" + const libssl = "libssl-3.dll" + end +elseif Sys.isapple() + const libcrypto = "@rpath/libcrypto.3.dylib" + const libssl = "@rpath/libssl.3.dylib" +else + const libcrypto = "libcrypto.so.3" + const libssl = "libssl.so.3" +end + +function __init__() + global libcrypto_handle = dlopen(libcrypto) + global libcrypto_path = dlpath(libcrypto_handle) + global libssl_handle = dlopen(libssl) + global libssl_path = dlpath(libssl_handle) + global artifact_dir = dirname(Sys.BINDIR) + LIBPATH[] = dirname(libssl_path) + push!(LIBPATH_list, LIBPATH[]) +end + +# JLLWrappers API compatibility shims. Note that not all of these will really make sense. +# For instance, `find_artifact_dir()` won't actually be the artifact directory, because +# there isn't one. It instead returns the overall Julia prefix. +is_available() = true +find_artifact_dir() = artifact_dir +dev_jll() = error("stdlib JLLs cannot be dev'ed") +best_wrapper = nothing +get_libcrypto_path() = libcrypto_path +get_libssl_path() = libssl_path + +end # module OpenSSL_jll diff --git a/stdlib/OpenSSL_jll/test/runtests.jl b/stdlib/OpenSSL_jll/test/runtests.jl new file mode 100644 index 0000000000000..35431d04bfcac --- /dev/null +++ b/stdlib/OpenSSL_jll/test/runtests.jl @@ -0,0 +1,10 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +using Test, Libdl, OpenSSL_jll + +@testset "OpenSSL_jll" begin + major = ccall((:OPENSSL_version_major, libcrypto), Cuint, ()) + minor = ccall((:OPENSSL_version_minor, libcrypto), Cuint, ()) + patch = ccall((:OPENSSL_version_patch, libcrypto), Cuint, ()) + @test VersionNumber(major, minor, patch) == v"3.0.15" +end diff --git a/stdlib/PCRE2_jll/Project.toml b/stdlib/PCRE2_jll/Project.toml index fee83c7ce552c..24ac196a3b8a9 100644 --- a/stdlib/PCRE2_jll/Project.toml +++ b/stdlib/PCRE2_jll/Project.toml @@ -1,6 +1,6 @@ name = "PCRE2_jll" uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.44.0+0" +version = "10.44.0+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 9ef9ca4b04376..4240c77105583 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = master -PKG_SHA1 = d84a1a38b6466fa7400e9ad2874a0ef963a10456 +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 diff --git a/stdlib/Project.toml b/stdlib/Project.toml index cc7ba99dd4e4f..92996cf017d0d 100644 --- a/stdlib/Project.toml +++ b/stdlib/Project.toml @@ -28,12 +28,12 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" MPFR_jll = "3a97d323-0669-5f0c-9066-3539efd106a3" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" -MbedTLS_jll = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" Mmap = "a63ad114-7e13-5084-954f-fe012c677804" MozillaCACerts_jll = "14a3606d-f60d-562e-9121-12d972cd8159" NetworkOptions = "ca575930-c2e3-43a9-ace4-1e988b2c1908" OpenBLAS_jll = "4536629a-c528-5b80-bd46-f80d51c5b363" OpenLibm_jll = "05823500-19ac-5b8b-9628-191a04bc5112" +OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95" PCRE2_jll = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" diff --git a/stdlib/REPL/docs/src/index.md b/stdlib/REPL/docs/src/index.md index 6250fc84dc6b2..eabd7e729280e 100644 --- a/stdlib/REPL/docs/src/index.md +++ b/stdlib/REPL/docs/src/index.md @@ -68,7 +68,7 @@ It's possible, as an experimental feature, to specify the attributes used by the ```julia-repl julia> rand(2, 2) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 0.8833 0.329197 0.719708 0.59114 @@ -78,7 +78,7 @@ julia> show(IOContext(stdout, :compact => false), "text/plain", rand(2, 2)) julia> Base.active_repl.options.iocontext[:compact] = false; julia> rand(2, 2) -2×2 Array{Float64,2}: +2×2 Matrix{Float64}: 0.2083967319174056 0.13330606013126012 0.6244375177790158 0.9777957560761545 ``` @@ -368,13 +368,13 @@ julia> π julia> e\_1[TAB] = [1,0] julia> e₁ = [1,0] -2-element Array{Int64,1}: +2-element Vector{Int64}: 1 0 julia> e\^1[TAB] = [1 0] julia> e¹ = [1 0] -1×2 Array{Int64,2}: +1×2 Matrix{Int64}: 1 0 julia> \sqrt[TAB]2 # √ is equivalent to the sqrt function diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 0bffb1a1015cd..c63c5a557acd8 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -639,16 +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) - return CC.RTEffects(Const(ccall(:jl_get_globalref_value, Any, (Any,), g)), Union{}, CC.EFFECTS_TOTAL) + if CC.is_defined_const_binding(CC.binding_kind(partition)) + return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( + 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 CC.RTEffects(Union{}, UndefVarError, CC.EFFECTS_THROWS) + return Pair{CC.RTEffects, Union{Nothing, Core.BindingPartition}}( + 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) @@ -714,7 +722,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, @@ -1077,7 +1085,7 @@ function complete_keyword_argument(partial::String, last_idx::Int, context_modul kwargs_flag == 2 && return fail # one of the previous kwargs is invalid methods = Completion[] - complete_methods!(methods, funct, Any[Vararg{Any}], kwargs_ex, -1, kwargs_flag == 1) + complete_methods!(methods, funct, Any[Vararg{Any}], kwargs_ex, shift ? -1 : MAX_METHOD_COMPLETIONS, kwargs_flag == 1) # TODO: use args_ex instead of Any[Vararg{Any}] and only provide kwarg completion for # method calls compatible with the current arguments. diff --git a/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl b/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl index 5c3ecf3808c49..fd660fc0f7824 100644 --- a/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl +++ b/stdlib/REPL/src/TerminalMenus/MultiSelectMenu.jl @@ -38,7 +38,7 @@ end """ - MultiSelectMenu(options::Array{String,1}; pagesize::Int=10, selected=[], kwargs...) + MultiSelectMenu(options::Vector{String}; pagesize::Int=10, selected=[], kwargs...) Create a MultiSelectMenu object. Use `request(menu::MultiSelectMenu)` to get user input. It returns a `Set` containing the indices of options that @@ -46,7 +46,7 @@ were selected by the user. # Arguments - - `options::Array{String, 1}`: Options to be displayed + - `options::Vector{String}`: Options to be displayed - `pagesize::Int=10`: The number of options to be displayed at one time, the menu will scroll if length(options) > pagesize - `selected=[]`: pre-selected items. `i ∈ selected` means that `options[i]` is preselected. diff --git a/stdlib/REPL/src/TerminalMenus/RadioMenu.jl b/stdlib/REPL/src/TerminalMenus/RadioMenu.jl index 32a6373b719d7..8e35e37f7f973 100644 --- a/stdlib/REPL/src/TerminalMenus/RadioMenu.jl +++ b/stdlib/REPL/src/TerminalMenus/RadioMenu.jl @@ -31,9 +31,9 @@ end """ - RadioMenu(options::Array{String,1}; pagesize::Int=10, - keybindings::Vector{Char}=Char[], - kwargs...) + RadioMenu(options::Vector{String}; pagesize::Int=10, + keybindings::Vector{Char}=Char[], + kwargs...) Create a RadioMenu object. Use `request(menu::RadioMenu)` to get user input. `request()` returns an `Int` which is the index of the option selected by the @@ -41,7 +41,7 @@ user. # Arguments - - `options::Array{String, 1}`: Options to be displayed + - `options::Vector{String}`: Options to be displayed - `pagesize::Int=10`: The number of options to be displayed at one time, the menu will scroll if length(options) > pagesize - `keybindings::Vector{Char}=Char[]`: Shortcuts to pick corresponding entry from `options` diff --git a/stdlib/REPL/src/docview.jl b/stdlib/REPL/src/docview.jl index 566046f325499..313994505b3ee 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) @@ -416,7 +417,9 @@ function summarize(io::IO, m::Module, binding::Binding; nlines::Int = 200) if !isnothing(readme_path) readme_lines = readlines(readme_path) isempty(readme_lines) && return # don't say we are going to print empty file - println(io, "# Displaying contents of readme found at `$(readme_path)`") + println(io) + println(io, "---") + println(io, "_Package description from `$(basename(readme_path))`:_") for line in first(readme_lines, nlines) println(io, line) end @@ -659,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/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/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 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/Random/src/Random.jl b/stdlib/Random/src/Random.jl index 26116d3bf4c81..2d75f49480a7b 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -355,7 +355,7 @@ See also [`randn`](@ref) for normally distributed numbers, and [`rand!`](@ref) a # Examples ```julia-repl julia> rand(Int, 2) -2-element Array{Int64,1}: +2-element Vector{Int64}: 1339893410598768192 1575814717733606317 @@ -368,7 +368,7 @@ julia> rand((2, 3)) 3 julia> rand(Float64, (2, 3)) -2×3 Array{Float64,2}: +2×3 Matrix{Float64}: 0.999717 0.0143835 0.540787 0.696556 0.783855 0.938235 ``` 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), diff --git a/stdlib/SHA.version b/stdlib/SHA.version index f22bb33dc7ea2..a5d4372d5798b 100644 --- a/stdlib/SHA.version +++ b/stdlib/SHA.version @@ -1,4 +1,4 @@ SHA_BRANCH = master -SHA_SHA1 = aaf2df61ff8c3898196587a375d3cf213bd40b41 +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 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/stdlib/Sockets/src/addrinfo.jl b/stdlib/Sockets/src/addrinfo.jl index 93194b85d4e8c..f5599b8623a0b 100644 --- a/stdlib/Sockets/src/addrinfo.jl +++ b/stdlib/Sockets/src/addrinfo.jl @@ -58,7 +58,7 @@ Uses the operating system's underlying `getaddrinfo` implementation, which may d # Examples ```julia-repl julia> getalladdrinfo("google.com") -2-element Array{IPAddr,1}: +2-element Vector{IPAddr}: ip"172.217.6.174" ip"2607:f8b0:4000:804::200e" ``` @@ -307,7 +307,7 @@ The `loopback` keyword argument dictates whether loopback addresses (e.g. `ip"12 # Examples ```julia-repl julia> getipaddrs() -5-element Array{IPAddr,1}: +5-element Vector{IPAddr}: ip"198.51.100.17" ip"203.0.113.2" ip"2001:db8:8:4:445e:5fff:fe5d:5500" @@ -315,7 +315,7 @@ julia> getipaddrs() ip"fe80::445e:5fff:fe5d:5500" julia> getipaddrs(IPv6) -3-element Array{IPv6,1}: +3-element Vector{IPv6}: ip"2001:db8:8:4:445e:5fff:fe5d:5500" ip"2001:db8:8:4:c164:402e:7e3c:3668" ip"fe80::445e:5fff:fe5d:5500" diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index af6fac41ddf84..0234c754191f8 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 1b4933ccc7b1f97427ff88bd7ba58950021f2c60 +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 diff --git a/stdlib/Statistics.version b/stdlib/Statistics.version index 1449dcee29b79..3df70d30ba7e6 100644 --- a/stdlib/Statistics.version +++ b/stdlib/Statistics.version @@ -1,4 +1,4 @@ STATISTICS_BRANCH = master -STATISTICS_SHA1 = 68869af06e8cdeb7aba1d5259de602da7328057f +STATISTICS_SHA1 = d49c2bf4f81e1efb4980a35fe39c815ef8396297 STATISTICS_GIT_URL := https://github.com/JuliaStats/Statistics.jl.git STATISTICS_TAR_URL = https://api.github.com/repos/JuliaStats/Statistics.jl/tarball/$1 diff --git a/stdlib/StyledStrings.version b/stdlib/StyledStrings.version index 5e58a5456148a..c72f7a8399725 100644 --- a/stdlib/StyledStrings.version +++ b/stdlib/StyledStrings.version @@ -1,4 +1,4 @@ STYLEDSTRINGS_BRANCH = main -STYLEDSTRINGS_SHA1 = 056e843b2d428bb9735b03af0cff97e738ac7e14 +STYLEDSTRINGS_SHA1 = 8985a37ac054c37d084a03ad2837208244824877 STYLEDSTRINGS_GIT_URL := https://github.com/JuliaLang/StyledStrings.jl.git STYLEDSTRINGS_TAR_URL = https://api.github.com/repos/JuliaLang/StyledStrings.jl/tarball/$1 diff --git a/stdlib/SuiteSparse_jll/Project.toml b/stdlib/SuiteSparse_jll/Project.toml index c91ef6743d653..3a1dc50a103fb 100644 --- a/stdlib/SuiteSparse_jll/Project.toml +++ b/stdlib/SuiteSparse_jll/Project.toml @@ -1,6 +1,6 @@ name = "SuiteSparse_jll" uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.8.0+1" +version = "7.8.3+2" [deps] libblastrampoline_jll = "8e850b90-86db-534c-a0d3-1478176c7d93" diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index 464cb2ac9de9c..79fdb89399d42 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1071,8 +1071,9 @@ mutable struct DefaultTestSet <: AbstractTestSet time_end::Union{Float64,Nothing} failfast::Bool file::Union{String,Nothing} + rng::Union{Nothing,AbstractRNG} end -function DefaultTestSet(desc::AbstractString; verbose::Bool = false, showtiming::Bool = true, failfast::Union{Nothing,Bool} = nothing, source = nothing) +function DefaultTestSet(desc::AbstractString; verbose::Bool = false, showtiming::Bool = true, failfast::Union{Nothing,Bool} = nothing, source = nothing, rng = nothing) if isnothing(failfast) # pass failfast state into child testsets parent_ts = get_testset() @@ -1082,7 +1083,7 @@ function DefaultTestSet(desc::AbstractString; verbose::Bool = false, showtiming: failfast = false end end - return DefaultTestSet(String(desc)::String, [], 0, false, verbose, showtiming, time(), nothing, failfast, extract_file(source)) + return DefaultTestSet(String(desc)::String, [], 0, false, verbose, showtiming, time(), nothing, failfast, extract_file(source), rng) end extract_file(source::LineNumberNode) = extract_file(source.file) extract_file(file::Symbol) = string(file) @@ -1194,7 +1195,7 @@ function print_test_results(ts::AbstractTestSet, depth_pad=0) duration_width = max(textwidth("Time"), textwidth(tc.duration)) # Calculate the alignment of the test result counts by # recursively walking the tree of test sets - align = max(get_alignment(ts, 0), textwidth("Test Summary:")) + align = max(get_alignment(ts, depth_pad), textwidth("Test Summary:")) # Print the outer test set header once printstyled(rpad("Test Summary:", align, " "), " |", " "; bold=true) if pass_width > 0 @@ -1219,6 +1220,13 @@ function print_test_results(ts::AbstractTestSet, depth_pad=0) println() # Recursively print a summary at every level print_counts(ts, depth_pad, align, pass_width, fail_width, error_width, broken_width, total_width, duration_width, timing) + # Print the RNG of the outer testset if there are failures + if total != total_pass + total_broken + rng = get_rng(ts) + if !isnothing(rng) + println("RNG of the outermost testset: ", rng) + end + end end @@ -1290,6 +1298,24 @@ function filter_errors(ts::DefaultTestSet) efs end +""" + Test.get_rng(ts::AbstractTestSet) -> Union{Nothing,AbstractRNG} + +Return the global random number generator (RNG) associated to the input testset `ts`. +If no RNG is associated to it, return `nothing`. +""" +get_rng(::AbstractTestSet) = nothing +get_rng(ts::DefaultTestSet) = ts.rng +""" + Test.set_rng!(ts::AbstractTestSet, rng::AbstractRNG) -> AbstractRNG + +Set the global random number generator (RNG) associated to the input testset `ts` to `rng`. +If no RNG is associated to it, do nothing. +In any case, always return the input `rng`. +""" +set_rng!(::AbstractTestSet, rng::AbstractRNG) = rng +set_rng!(ts::DefaultTestSet, rng::AbstractRNG) = ts.rng = rng + """ TestCounts @@ -1494,14 +1520,17 @@ along with a summary of the test results. Any custom testset type (subtype of `AbstractTestSet`) can be given and it will also be used for any nested `@testset` invocations. The given options are only applied to the test set where they are given. The default test set type -accepts three boolean options: -- `verbose`: if `true`, the result summary of the nested testsets is shown even +accepts the following options: +- `verbose::Bool`: if `true`, the result summary of the nested testsets is shown even when they all pass (the default is `false`). -- `showtiming`: if `true`, the duration of each displayed testset is shown +- `showtiming::Bool`: if `true`, the duration of each displayed testset is shown (the default is `true`). -- `failfast`: if `true`, any test failure or error will cause the testset and any +- `failfast::Bool`: if `true`, any test failure or error will cause the testset and any child testsets to return immediately (the default is `false`). This can also be set globally via the env var `JULIA_TEST_FAILFAST`. +- `rng::Random.AbstractRNG`: use the given random number generator (RNG) as the global one + for the testset. `rng` must be `copy!`-able. This option can be useful to locally + reproduce stochastic test failures which only depend on the state of the global RNG. !!! compat "Julia 1.8" `@testset test_func()` requires at least Julia 1.8. @@ -1509,6 +1538,9 @@ accepts three boolean options: !!! compat "Julia 1.9" `failfast` requires at least Julia 1.9. +!!! compat "Julia 1.12" + The `rng` option requires at least Julia 1.12. + The description string accepts interpolation from the loop indices. If no description is provided, one is constructed based on the variables. If a function call is provided, its name will be used. @@ -1521,13 +1553,19 @@ method, which by default will return a list of the testset objects used in each iteration. Before the execution of the body of a `@testset`, there is an implicit -call to `Random.seed!(seed)` where `seed` is the current seed of the global RNG. +call to `copy!(Random.default_rng(), rng)` where `rng` is the RNG of the current task, or +the value of the RNG passed via the `rng` option. Moreover, after the execution of the body, the state of the global RNG is restored to what it was before the `@testset`. This is meant to ease reproducibility in case of failure, and to allow seamless re-arrangements of `@testset`s regardless of their side-effect on the global RNG state. +!!! note "RNG of nested testsets" + Unless changed with the `rng` option, the same RNG is set at the beginning of all + nested testsets. The RNG printed to screen when a testset has failures is the global RNG of + the outermost testset even if inner testsets have different RNGs manually set by the user. + ## Examples ```jldoctest; filter = r"trigonometric identities | 4 4 [0-9\\.]+s" julia> @testset "trigonometric identities" begin @@ -1717,9 +1755,11 @@ function testset_beginend_call(args, tests, source) # by wrapping the body in a function local default_rng_orig = copy(default_rng()) local tls_seed_orig = copy(Random.get_tls_seed()) + local tls_seed = isnothing(get_rng(ts)) ? set_rng!(ts, tls_seed_orig) : get_rng(ts) try # default RNG is reset to its state from last `seed!()` to ease reproduce a failed test - copy!(Random.default_rng(), tls_seed_orig) + copy!(Random.default_rng(), tls_seed) + copy!(Random.get_tls_seed(), Random.default_rng()) let $(esc(tests)) end @@ -1800,10 +1840,10 @@ function testset_forloop(args, testloop, source) finish_errored = true push!(arr, finish(ts)) finish_errored = false - copy!(default_rng(), tls_seed_orig) + copy!(default_rng(), tls_seed) end ts = if ($testsettype === $DefaultTestSet) && $(isa(source, LineNumberNode)) - $(testsettype)($desc; source=$(QuoteNode(source.file)), $options...) + $(testsettype)($desc; source=$(QuoteNode(source.file)), $options..., rng=tls_seed) else $(testsettype)($desc; $options...) end @@ -1825,10 +1865,12 @@ function testset_forloop(args, testloop, source) local arr = Vector{Any}() local first_iteration = true local ts + local rng_option = get($(options), :rng, nothing) local finish_errored = false local default_rng_orig = copy(default_rng()) local tls_seed_orig = copy(Random.get_tls_seed()) - copy!(Random.default_rng(), tls_seed_orig) + local tls_seed = isnothing(rng_option) ? copy(Random.get_tls_seed()) : rng_option + copy!(Random.default_rng(), tls_seed) try let $(Expr(:for, Expr(:block, [esc(v) for v in loopvars]...), blk)) diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 0c08f78ef356f..02523dc6fd911 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, _ @@ -1712,13 +1712,13 @@ end # this tests both the `TestCounts` parts as well as the fallback `x`s expected = r""" - 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 - no-record | x x x x ? \s*?s - b | 1 1 \s*\d*.\ds - ERROR: Some tests did not pass: 3 passed, 1 failed, 1 errored, 1 broken. + 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 + no-record \| x x x x \? \s*\?s + b \| 1 1 \s*\d*.\ds + RNG of the outermost testset: .* """ cmd = `$(Base.julia_cmd()) --startup-file=no --color=no $f` @@ -1753,3 +1753,20 @@ module M54082 end @test only(result) isa Test.Fail end end + +@testset "Set RNG of testset" begin + rng1 = Xoshiro(0x2e026445595ed28e, 0x07bb81ac4c54926d, 0x83d7d70843e8bad6, 0xdbef927d150af80b, 0xdbf91ddf2534f850) + rng2 = Xoshiro(0xc380f460355639ee, 0xb39bc754b7d63bbf, 0x1551dbcfb5ed5668, 0x71ab5a18fec21a25, 0x649d0c1be1ca5436) + rng3 = Xoshiro(0xee97f5b53f7cdc49, 0x480ac387b0527d3d, 0x614b416502a9e0f5, 0x5250cb36e4a4ceb1, 0xed6615c59e475fa0) + + @testset rng=rng1 begin + @test rand() == rand(rng1) + end + + @testset rng=rng2 "Outer" begin + @test rand() == rand(rng2) + @testset rng=rng3 "Inner: $(i)" for i in 1:10 + @test rand() == rand(rng3) + end + end +end diff --git a/stdlib/Zlib_jll/Project.toml b/stdlib/Zlib_jll/Project.toml index dfe9ce845c8e0..40acd335c2327 100644 --- a/stdlib/Zlib_jll/Project.toml +++ b/stdlib/Zlib_jll/Project.toml @@ -1,6 +1,6 @@ name = "Zlib_jll" uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.3.1+1" +version = "1.3.1+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/dSFMT_jll/Project.toml b/stdlib/dSFMT_jll/Project.toml index ca51184b75264..30209421a9994 100644 --- a/stdlib/dSFMT_jll/Project.toml +++ b/stdlib/dSFMT_jll/Project.toml @@ -1,6 +1,6 @@ name = "dSFMT_jll" uuid = "05ff407c-b0c1-5878-9df8-858cc2e60c36" -version = "2.2.5+1" +version = "2.2.5+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/libblastrampoline_jll/Project.toml b/stdlib/libblastrampoline_jll/Project.toml index 8d5a3b7b20bcc..d1dde4c6074a7 100644 --- a/stdlib/libblastrampoline_jll/Project.toml +++ b/stdlib/libblastrampoline_jll/Project.toml @@ -1,6 +1,6 @@ name = "libblastrampoline_jll" uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.11.2+0" +version = "5.12.0+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/nghttp2_jll/Project.toml b/stdlib/nghttp2_jll/Project.toml index acc9444ab4a26..030f4a8a0b9d1 100644 --- a/stdlib/nghttp2_jll/Project.toml +++ b/stdlib/nghttp2_jll/Project.toml @@ -1,6 +1,6 @@ name = "nghttp2_jll" uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.63.0+1" +version = "1.64.0+1" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/nghttp2_jll/test/runtests.jl b/stdlib/nghttp2_jll/test/runtests.jl index d667ce53e5252..13e7adaad9df6 100644 --- a/stdlib/nghttp2_jll/test/runtests.jl +++ b/stdlib/nghttp2_jll/test/runtests.jl @@ -11,5 +11,5 @@ end @testset "nghttp2_jll" begin info = unsafe_load(ccall((:nghttp2_version,libnghttp2), Ptr{nghttp2_info}, (Cint,), 0)) - @test VersionNumber(unsafe_string(info.version_str)) == v"1.63.0" + @test VersionNumber(unsafe_string(info.version_str)) == v"1.64.0" end diff --git a/stdlib/p7zip_jll/Project.toml b/stdlib/p7zip_jll/Project.toml index 09a39880af418..214c5b19a8a4b 100644 --- a/stdlib/p7zip_jll/Project.toml +++ b/stdlib/p7zip_jll/Project.toml @@ -1,6 +1,6 @@ name = "p7zip_jll" uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.5.0+1" +version = "17.5.0+2" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/stdlib.mk b/stdlib/stdlib.mk index b79059d3368b1..006b7a276a3b3 100644 --- a/stdlib/stdlib.mk +++ b/stdlib/stdlib.mk @@ -8,8 +8,8 @@ INDEPENDENT_STDLIBS := \ Markdown Mmap NetworkOptions Profile Printf Pkg REPL Serialization SharedArrays \ SparseArrays Statistics StyledStrings SuiteSparse_jll Tar Test TOML Unicode UUIDs \ dSFMT_jll GMP_jll libLLVM_jll LLD_jll LLVMLibUnwind_jll LibUnwind_jll LibUV_jll \ - LibCURL_jll LibSSH2_jll LibGit2_jll nghttp2_jll MozillaCACerts_jll MbedTLS_jll \ - MPFR_jll OpenLibm_jll PCRE2_jll p7zip_jll Zlib_jll + LibCURL_jll LibSSH2_jll LibGit2_jll nghttp2_jll MozillaCACerts_jll \ + MPFR_jll OpenLibm_jll OpenSSL_jll PCRE2_jll p7zip_jll Zlib_jll STDLIBS := $(STDLIBS_WITHIN_SYSIMG) $(INDEPENDENT_STDLIBS) VERSDIR := v$(shell cut -d. -f1-2 < $(JULIAHOME)/VERSION) 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/abstractarray.jl b/test/abstractarray.jl index 4af4099eced45..d1f30eacafacc 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -908,7 +908,7 @@ test_ind2sub(TestAbstractArray) include("generic_map_tests.jl") generic_map_tests(map, map!) -@test_throws ArgumentError map!(-, [1]) +@test map!(-, [1]) == [-1] test_UInt_indexing(TestAbstractArray) test_13315(TestAbstractArray) @@ -2206,3 +2206,24 @@ end @test b.ref === a.ref end end +@testset "AbstractArrayMath" begin + @testset "IsReal" begin + A = [1, 2, 3, 4] + @test isreal(A) == true + B = [1.1, 2.2, 3.3, 4.4] + @test isreal(B) == true + C = [1, 2.2, 3] + @test isreal(C) == true + D = Real[] + @test isreal(D) == true + E = [1 + 1im, 2 - 2im] + @test isreal(E) == false + struct MyReal <: Real + value::Float64 + end + F = [MyReal(1.0), MyReal(2.0)] + @test isreal(F) == true + G = ["a", "b", "c"] + @test_throws MethodError isreal(G) + end +end 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/arrayops.jl b/test/arrayops.jl index ca378c3f3036b..655e14675bfb4 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -307,34 +307,40 @@ end @test_throws ArgumentError dropdims(a, dims=3) @test_throws ArgumentError dropdims(a, dims=4) @test_throws ArgumentError dropdims(a, dims=6) - - - a = rand(8, 7) - @test @inferred(insertdims(a, dims=1)) == @inferred(insertdims(a, dims=(1,))) == reshape(a, (1, 8, 7)) - @test @inferred(insertdims(a, dims=3)) == @inferred(insertdims(a, dims=(3,))) == reshape(a, (8, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3))) == reshape(a, (1, 8, 1, 7)) - @test @inferred(insertdims(a, dims=(1, 2, 3))) == reshape(a, (1, 1, 1, 8, 7)) - @test @inferred(insertdims(a, dims=(1, 4))) == reshape(a, (1, 8, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3, 5))) == reshape(a, (1, 8, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 2, 4, 6))) == reshape(a, (1, 1, 8, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3, 4, 6))) == reshape(a, (1, 8, 1, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 4, 6, 3))) == reshape(a, (1, 8, 1, 1, 7, 1)) - @test @inferred(insertdims(a, dims=(1, 3, 5, 6))) == reshape(a, (1, 8, 1, 7, 1, 1)) - - @test_throws ArgumentError insertdims(a, dims=(1, 1, 2, 3)) - @test_throws ArgumentError insertdims(a, dims=(1, 2, 2, 3)) - @test_throws ArgumentError insertdims(a, dims=(1, 2, 3, 3)) - @test_throws UndefKeywordError insertdims(a) - @test_throws ArgumentError insertdims(a, dims=0) - @test_throws ArgumentError insertdims(a, dims=(1, 2, 1)) - @test_throws ArgumentError insertdims(a, dims=4) - @test_throws ArgumentError insertdims(a, dims=6) - - # insertdims and dropdims are inverses - b = rand(1,1,1,5,1,1,7) - for dims in [1, (1,), 2, (2,), 3, (3,), (1,3), (1,2,3), (1,2), (1,3,5), (1,2,5,6), (1,3,5,6), (1,3,5,6), (1,6,5,3)] - @test dropdims(insertdims(a; dims); dims) == a - @test insertdims(dropdims(b; dims); dims) == b + @testset "insertdims" begin + a = rand(8, 7) + @test @inferred(insertdims(a, dims=1)) == @inferred(insertdims(a, dims=(1,))) == reshape(a, (1, 8, 7)) + @test @inferred(insertdims(a, dims=3)) == @inferred(insertdims(a, dims=(3,))) == reshape(a, (8, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3))) == reshape(a, (1, 8, 1, 7)) + @test @inferred(insertdims(a, dims=(1, 2, 3))) == reshape(a, (1, 1, 1, 8, 7)) + @test @inferred(insertdims(a, dims=(1, 4))) == reshape(a, (1, 8, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 5))) == reshape(a, (1, 8, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 2, 4, 6))) == reshape(a, (1, 1, 8, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 4, 6))) == reshape(a, (1, 8, 1, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 4, 6, 3))) == reshape(a, (1, 8, 1, 1, 7, 1)) + @test @inferred(insertdims(a, dims=(1, 3, 5, 6))) == reshape(a, (1, 8, 1, 7, 1, 1)) + @test_throws ArgumentError insertdims(a, dims=(1, 1, 2, 3)) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 2, 3)) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 3, 3)) + @test_throws UndefKeywordError insertdims(a) + @test_throws ArgumentError insertdims(a, dims=0) + @test_throws ArgumentError insertdims(a, dims=(1, 2, 1)) + @test_throws ArgumentError insertdims(a, dims=4) + @test_throws ArgumentError insertdims(a, dims=6) + A = reshape(1:6, 2, 3) + @test_throws ArgumentError insertdims(A, dims=(2, 2)) + D = insertdims(A, dims=()) + @test size(D) == size(A) + @test D == A + E = ones(2, 3, 4) + F = insertdims(E, dims=(2, 4, 6)) + @test size(F) == (2, 1, 3, 1, 4, 1) + # insertdims and dropdims are inverses + b = rand(1,1,1,5,1,1,7) + for dims in [1, (1,), 2, (2,), 3, (3,), (1,3), (1,2,3), (1,2), (1,3,5), (1,2,5,6), (1,3,5,6), (1,3,5,6), (1,6,5,3)] + @test dropdims(insertdims(a; dims); dims) == a + @test insertdims(dropdims(b; dims); dims) == b + end end sz = (5,8,7) diff --git a/test/bitarray.jl b/test/bitarray.jl index 67d8fae0eda6d..fd5c1421a256f 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -1,7 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license using Base: findprevnot, findnextnot -using Random, LinearAlgebra, Test +using Random, Test, LinearAlgebra # Ideally, these tests should not depend on LinearAlgebra isdefined(Main, :SizedArrays) || @eval Main include("testhelpers/SizedArrays.jl") using .Main.SizedArrays @@ -15,7 +15,6 @@ tc(r1,r2) = false bitcheck(b::BitArray) = Test._check_bitarray_consistency(b) bitcheck(x) = true -bcast_setindex!(b, x, I...) = (b[I...] .= x; b) function check_bitop_call(ret_type, func, args...; kwargs...) r2 = func(map(x->(isa(x, BitArray) ? Array(x) : x), args)...; kwargs...) @@ -34,6 +33,9 @@ macro check_bit_operation(ex) Expr(:call, :check_bitop_call, nothing, map(esc, ex.args)...) end +bcast_setindex!(b, x, I...) = (b[I...] .= x; b) + + let t0 = time_ns() global timesofar function timesofar(str) @@ -1641,69 +1643,6 @@ end timesofar("cat") -@testset "Linear algebra" begin - b1 = bitrand(v1) - b2 = bitrand(v1) - @check_bit_operation dot(b1, b2) Int - - b1 = bitrand(n1, n2) - @test_throws ArgumentError tril(b1, -n1 - 2) - @test_throws ArgumentError tril(b1, n2) - @test_throws ArgumentError triu(b1, -n1) - @test_throws ArgumentError triu(b1, n2 + 2) - for k in (-n1 - 1):(n2 - 1) - @check_bit_operation tril(b1, k) BitMatrix - end - for k in (-n1 + 1):(n2 + 1) - @check_bit_operation triu(b1, k) BitMatrix - end - - for sz = [(n1,n1), (n1,n2), (n2,n1)], (f,isf) = [(tril,istril), (triu,istriu)] - b1 = bitrand(sz...) - @check_bit_operation isf(b1) Bool - b1 = f(bitrand(sz...)) - @check_bit_operation isf(b1) Bool - end - - b1 = bitrand(n1,n1) - b1 .|= copy(b1') - @check_bit_operation issymmetric(b1) Bool - @check_bit_operation ishermitian(b1) Bool - - b1 = bitrand(n1) - b2 = bitrand(n2) - @check_bit_operation kron(b1, b2) BitVector - - b1 = bitrand(s1, s2) - b2 = bitrand(s3, s4) - @check_bit_operation kron(b1, b2) BitMatrix - - b1 = bitrand(v1) - @check_bit_operation diff(b1) Vector{Int} - - b1 = bitrand(n1, n2) - @check_bit_operation diff(b1, dims=1) Matrix{Int} - @check_bit_operation diff(b1, dims=2) Matrix{Int} - - b1 = bitrand(n1, n1) - @test ((svdb1, svdb1A) = (svd(b1), svd(Array(b1))); - svdb1.U == svdb1A.U && svdb1.S == svdb1A.S && svdb1.V == svdb1A.V) - @test ((qrb1, qrb1A) = (qr(b1), qr(Array(b1))); - Matrix(qrb1.Q) == Matrix(qrb1A.Q) && qrb1.R == qrb1A.R) - - b1 = bitrand(v1) - @check_bit_operation diagm(0 => b1) BitMatrix - - b1 = bitrand(v1) - b2 = bitrand(v1) - @check_bit_operation diagm(-1 => b1, 1 => b2) BitMatrix - - b1 = bitrand(n1, n1) - @check_bit_operation diag(b1) -end - -timesofar("linalg") - @testset "findmax, findmin" begin b1 = trues(0) @test_throws ArgumentError findmax(b1) diff --git a/test/boundscheck_exec.jl b/test/boundscheck_exec.jl index 10f46eb4a8031..3b2f853999229 100644 --- a/test/boundscheck_exec.jl +++ b/test/boundscheck_exec.jl @@ -297,4 +297,53 @@ end typeintersect(Int, Integer) end |> only === Type{Int} +if bc_opt == bc_default + # Array/Memory escape analysis + function no_allocate(T::Type{<:Union{Memory, Vector}}) + v = T(undef, 2) + v[1] = 2 + v[2] = 3 + return v[1] + v[2] + end + function test_alloc(::Type{T}; broken=false) where T + @test (@allocated no_allocate(T)) == 0 broken=broken + end + 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})) + end + end + function f() # this was causing a bug on an in progress version of #55913. + m = Memory{Float64}(undef, 4) + m .= 1.0 + s = 0.0 + for x ∈ m + s += x + end + s + end + @test f() === 4.0 + function confuse_alias_analysis() + mem0 = Memory{Int}(undef, 1) + mem1 = Memory{Int}(undef, 1) + @inbounds mem0[1] = 3 + for width in 1:2 + @inbounds mem1[1] = mem0[1] + mem0 = mem1 + end + mem0[1] + end + @test confuse_alias_analysis() == 3 + @test (@allocated confuse_alias_analysis()) == 0 + function no_alias_prove(n) + m1 = Memory{Int}(undef,n) + m2 = Memory{Int}(undef,n) + m1 === m2 + end + no_alias_prove(1) + @test_broken (@allocated no_alias_prove(5)) == 0 +end + end diff --git a/test/broadcast.jl b/test/broadcast.jl index b2232258744ac..0f5bdf7a40bb1 100644 --- a/test/broadcast.jl +++ b/test/broadcast.jl @@ -876,6 +876,31 @@ let @test copy(bc) == [v for v in bc] == collect(bc) @test eltype(copy(bc)) == eltype([v for v in bc]) == eltype(collect(bc)) @test ndims(copy(bc)) == ndims([v for v in bc]) == ndims(collect(bc)) == ndims(bc) + + struct MyFill{T,N} <: AbstractArray{T,N} + val :: T + sz :: NTuple{N,Int} + end + Base.size(M::MyFill) = M.sz + function Base.getindex(M::MyFill{<:Any,N}, i::Vararg{Int, N}) where {N} + checkbounds(M, i...) + M.val + end + Base.IndexStyle(::Type{<:Base.Broadcast.Broadcasted{<:Any,<:Any,<:Any,<:Tuple{MyFill}}}) = IndexLinear() + bc = Broadcast.instantiate(Broadcast.broadcasted(+, MyFill(2, (3,3)))) + @test IndexStyle(bc) == IndexLinear() + @test eachindex(bc) === Base.OneTo(9) + @test bc[2] == bc[CartesianIndex(2,1)] + + for bc in Any[ + Broadcast.broadcasted(+, collect(reshape(1:9, 3, 3)), 1:3), # IndexCartesian + Broadcast.broadcasted(+, [1,2], 2), # IndexLinear + ] + bci = Broadcast.instantiate(bc) + for (Ilin, Icart) in zip(eachindex(IndexLinear(), bc), eachindex(IndexCartesian(), bc)) + @test bc[Ilin] == bc[Icart] + end + end end # issue 43847: collect preserves shape of broadcasted @@ -905,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) 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/channels.jl b/test/channels.jl index eed7a7ecc0566..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 @@ -499,12 +516,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 @@ -550,8 +590,11 @@ end # make sure 1-shot timers work let a = [] Timer(t -> push!(a, 1), 0.01, interval = 0) - sleep(0.2) - @test a == [1] + @test timedwait(() -> a == [1], 10) === :ok +end +let a = [] + Timer(t -> push!(a, 1), 0.01, interval = 0, spawn = true) + @test timedwait(() -> a == [1], 10) === :ok end # make sure that we don't accidentally create a one-shot timer diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 5df174694049d..3ff7836223b84 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -818,6 +818,26 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` @test occursin(" ms =# precompile(Tuple{typeof(Main.foo), Int", _stderr) end + # Base.@trace_compile (local version of the 2 above args) + let + io = IOBuffer() + v = writereadpipeline( + """ + f(x::Int) = 1 + applyf(container) = f(container[1]) + Base.@trace_compile @eval applyf([100]) + Base.@trace_compile @eval applyf(Any[100]) + f(::Bool) = 2 + Base.@trace_compile @eval applyf([true]) + Base.@trace_compile @eval applyf(Any[true]) + """, + `$exename -i`, + stderr=io) + _stderr = String(take!(io)) + @test length(findall(r"precompile\(", _stderr)) == 5 + @test length(findall(r" # recompile", _stderr)) == 1 + end + # --trace-dispatch let io = IOBuffer() @@ -1218,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/copy.jl b/test/copy.jl index 559bf5d3e757a..f5cc57c86feaa 100644 --- a/test/copy.jl +++ b/test/copy.jl @@ -253,6 +253,15 @@ end @test copyto!(s, String[]) == [1, 2] # No error end +@testset "circular reference arrays" begin + # issue 56775 + p = Any[nothing] + p[1] = p + p2 = deepcopy(p) + @test p2 === p2[1] + @test p2 !== p +end + @testset "deepcopy_internal arrays" begin @test (@inferred Base.deepcopy_internal(zeros(), IdDict())) == zeros() end diff --git a/test/core.jl b/test/core.jl index 7e4f655222ea5..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) @@ -4505,6 +4505,15 @@ for T in (Any, ValueWrapper) end end +#test grow_end ccall directly since it's used in the C source +for ET in [Nothing, Int, Union{Int, Nothing}, Any] + for n in [0, 1, 10] + arr = Vector{ET}(undef, n) + ccall(:jl_array_grow_end, Cvoid, (Any, UInt), arr, 1) + @test length(arr) == n+1 + end +end + # check if we can run multiple finalizers at the same time # Use a `@noinline` function to make sure the inefficient gc root generation # doesn't keep the object alive. 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() diff --git a/test/dict.jl b/test/dict.jl index 909afb3607907..83d35ae18bb85 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -787,6 +787,13 @@ end [v for (k, v) in d] == [d[x[1]] for (i, x) in enumerate(d)] end +@testset "consistency of dict iteration order (issue #56841)" begin + dict = Dict(randn() => randn() for _ = 1:100) + @test all(zip(dict, keys(dict), values(dict), pairs(dict))) do (d, k, v, p) + d == p && first(d) == first(p) == k && last(d) == last(p) == v + end +end + @testset "generators, similar" begin d = Dict(:a=>"a") # TODO: restore when 0.7 deprecation is removed 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`. """) diff --git a/test/errorshow.jl b/test/errorshow.jl index 7a3d50d599f2e..f83bbe31b7cc4 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -791,8 +791,22 @@ backtrace() @test occursin("g28442", output[3]) @test lstrip(output[5])[1:3] == "[2]" @test occursin("f28442", output[5]) - @test occursin("the above 2 lines are repeated 5000 more times", output[7]) - @test lstrip(output[8])[1:7] == "[10003]" + is_windows_32_bit = Sys.iswindows() && (Sys.WORD_SIZE == 32) + if is_windows_32_bit + # These tests are currently broken (intermittently/non-determistically) on 32-bit Windows. + # https://github.com/JuliaLang/julia/issues/55900 + # Instead of skipping them entirely, we skip one, and we loosen the other. + + # Broken test: @test occursin("the above 2 lines are repeated 5000 more times", output[7]) + @test occursin("the above 2 lines are repeated ", output[7]) + @test occursin(" more times", output[7]) + + # Broken test: @test lstrip(output[8])[1:7] == "[10003]" + @test_broken false + else + @test occursin("the above 2 lines are repeated 5000 more times", output[7]) + @test lstrip(output[8])[1:7] == "[10003]" + end end @testset "Line number correction" begin diff --git a/test/gmp.jl b/test/gmp.jl index 13413abe55f9d..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 @@ -468,6 +506,34 @@ end end end +@testset "modular invert" begin + # test invert is correct and does not mutate + a = BigInt(3) + b = BigInt(7) + i = BigInt(5) + @test Base.GMP.MPZ.invert(a, b) == i + @test a == BigInt(3) + @test b == BigInt(7) + + # test in place invert does mutate first argument + a = BigInt(3) + b = BigInt(7) + i = BigInt(5) + i_inplace = BigInt(3) + Base.GMP.MPZ.invert!(i_inplace, b) + @test i_inplace == i + + # test in place invert does mutate only first argument + a = BigInt(3) + b = BigInt(7) + i = BigInt(5) + i_inplace = BigInt(0) + Base.GMP.MPZ.invert!(i_inplace, a, b) + @test i_inplace == i + @test a == BigInt(3) + @test b == BigInt(7) +end + @testset "math ops returning BigFloat" begin # operations that when applied to Int64 give Float64, should give BigFloat @test typeof(exp(a)) == BigFloat diff --git a/test/intfuncs.jl b/test/intfuncs.jl index 6f1bde69dddfe..38f29344d2f30 100644 --- a/test/intfuncs.jl +++ b/test/intfuncs.jl @@ -191,6 +191,13 @@ end @test lcm(T[2, 4, 6]) ⟷ T(12) end + + # Issue #55379 + @test lcm([1//2; 1//2]) === lcm([1//2, 1//2]) === lcm(1//2, 1//2) === 1//2 + @test gcd(Int[]) === 0 + @test lcm(Int[]) === 1 + @test gcd(Rational{Int}[]) === 0//1 + @test_throws ArgumentError("lcm has no identity for Rational{$Int}") lcm(Rational{Int}[]) end ⟷(a::Tuple{T, T, T}, b::Tuple{T, T, T}) where T <: Union{Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128} = a === b 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 diff --git a/test/iterators.jl b/test/iterators.jl index d1e7525c43465..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,23 +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 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] @@ -648,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 @@ -683,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 @@ -704,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 @@ -719,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 @@ -751,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() @@ -798,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'] @@ -809,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) @@ -886,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} @@ -898,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 @@ -956,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 @@ -968,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 @@ -981,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 @@ -1010,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 diff --git a/test/llvmcall.jl b/test/llvmcall.jl index c83ac05b1ec48..ddf66ca680d45 100644 --- a/test/llvmcall.jl +++ b/test/llvmcall.jl @@ -157,7 +157,7 @@ module ObjLoadTest nothing end @test_throws(ErrorException("@ccallable was already defined for this method name"), - @eval @ccallable Cvoid jl_the_callback(not_the_method::Int) = "other") + @eval @ccallable String jl_the_callback(not_the_method::Int) = "other") # Make sure everything up until here gets compiled @test jl_the_callback() === nothing @test jl_the_callback(1) == "other" 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/math.jl b/test/math.jl index d794facb02d25..7070fe63ba931 100644 --- a/test/math.jl +++ b/test/math.jl @@ -382,6 +382,10 @@ end end end +@testset "https://github.com/JuliaLang/julia/issues/56782" begin + @test isnan(exp(reinterpret(Float64, 0x7ffbb14880000000))) +end + @testset "test abstractarray trig functions" begin TAA = rand(2,2) TAA = (TAA + TAA')/2. diff --git a/test/meta.jl b/test/meta.jl index 5fb1ebc0d3647..e9e344bba2e22 100644 --- a/test/meta.jl +++ b/test/meta.jl @@ -274,8 +274,13 @@ ci = code_lowered(g, Tuple{Val{true}})[1] @eval isdefined_globalref(x) = $(Expr(:isdefined, GlobalRef(Base, :foo))) ci = code_lowered(isdefined_globalref, Tuple{Int})[1] @test Meta.partially_inline!(copy(ci.code), Any[isdefined_globalref, 1], Tuple{typeof(isdefined_globalref), Int}, - [], 0, 0, :propagate)[1] == Expr(:isdefined, GlobalRef(Base, :foo)) + [], 0, 0, :propagate)[1] == Expr(:call, GlobalRef(Core, :isdefinedglobal), Base, QuoteNode(:foo)) + withunreachable(s::String) = sin(s) + ci = code_lowered(withunreachable, Tuple{String})[1] + ci.code[end] = Core.ReturnNode() + @test Meta.partially_inline!(copy(ci.code), Any[withunreachable, "foo"], Tuple{typeof(withunreachable), String}, + [], 0, 0, :propagate)[end] == Core.ReturnNode() end @testset "Base.Meta docstrings" begin diff --git a/test/misc.jl b/test/misc.jl index 5bbc2c3c65fa2..7070fd49f5f36 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1612,3 +1612,15 @@ let errs = IOBuffer() '`, devnull, stdout, errs) @test occursin("disable_new_worlds", String(take!(errs))) end + +@testset "`@constprop`, `@assume_effects` handling of an unknown setting" begin + for x ∈ ("constprop", "assume_effects") + try + eval(Meta.parse("Base.@$x :unknown f() = 3")) + error("unexpectedly reached") + catch e + e::LoadError + @test e.error isa ArgumentError + end + end +end diff --git a/test/opaque_closure.jl b/test/opaque_closure.jl index 79c456de127bd..6c988b068a668 100644 --- a/test/opaque_closure.jl +++ b/test/opaque_closure.jl @@ -347,9 +347,12 @@ let (bt, did_gc) = make_oc_and_collect_bt() GC.gc(true); GC.gc(true); GC.gc(true); @test did_gc[] @test any(stacktrace(bt)) do frame - isa(frame.linfo, Core.MethodInstance) || return false - isa(frame.linfo.def, Method) || return false - return frame.linfo.def.is_for_opaque_closure + li = frame.linfo + isa(li, Core.CodeInstance) && (li = li.def) + isa(li, Core.ABIOverride) && (li = li.def) + isa(li, Core.MethodInstance) || return false + isa(li.def, Method) || return false + return li.def.is_for_opaque_closure end 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 4c2c7034577d5..a2824a24c8bce 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 Sys.detectwsl() + 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" diff --git a/test/precompile.jl b/test/precompile.jl index 1607d4c6b502b..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") @@ -750,10 +754,9 @@ precompile_test_harness("code caching") do dir struct X end struct X2 end @noinline function f(d) - @noinline - d[X()] = nothing + @noinline d[X()] = nothing end - @noinline fpush(dest) = push!(dest, X()) + @noinline fpush(dest) = @noinline push!(dest, X()) function callboth() f(Dict{X,Any}()) fpush(X[]) @@ -797,24 +800,12 @@ precompile_test_harness("code caching") do dir end end @test hasspec - # Test that compilation adds to method roots with appropriate provenance - m = which(setindex!, (Dict{M.X,Any}, Any, M.X)) - @test Memory{M.X} ∈ m.roots - # Check that roots added outside of incremental builds get attributed to a moduleid of 0 - Base.invokelatest() do - Dict{M.X2,Any}()[M.X2()] = nothing - end - @test Memory{M.X2} ∈ m.roots - groups = group_roots(m) - @test Memory{M.X} ∈ groups[Mid] # attributed to M - @test Memory{M.X2} ∈ groups[0] # activate module is not known - @test !isempty(groups[Bid]) # Check that internal methods and their roots are accounted appropriately minternal = which(M.getelsize, (Vector,)) mi = minternal.specializations::Core.MethodInstance @test mi.specTypes == Tuple{typeof(M.getelsize),Vector{Int32}} ci = mi.cache - @test ci.relocatability == 0 + @test (codeunits(ci.inferred::String)[end]) === 0x01 @test ci.inferred !== nothing # ...and that we can add "untracked" roots & non-relocatable CodeInstances to them too Base.invokelatest() do @@ -825,19 +816,19 @@ precompile_test_harness("code caching") do dir mi = mispecs[2]::Core.MethodInstance mi.specTypes == Tuple{typeof(M.getelsize),Vector{M.X2}} ci = mi.cache - @test ci.relocatability == 0 + @test (codeunits(ci.inferred::String)[end]) == 0x00 # PkgA loads PkgB, and both add roots to the same `push!` method (both before and after loading B) Cache_module2 = :Cachea1544c83560f0c99 write(joinpath(dir, "$Cache_module2.jl"), """ module $Cache_module2 struct Y end - @noinline f(dest) = push!(dest, Y()) + @noinline f(dest) = @noinline push!(dest, Y()) callf() = f(Y[]) callf() using $(Cache_module) struct Z end - @noinline g(dest) = push!(dest, Z()) + @noinline g(dest) = @noinline push!(dest, Z()) callg() = g(Z[]) callg() end @@ -915,7 +906,7 @@ precompile_test_harness("code caching") do dir # external callers mods = Module[] for be in mi.backedges - push!(mods, (be.def.def::Method).module) # XXX + push!(mods, ((be.def::Core.MethodInstance).def::Method).module) # XXX end @test MA ∈ mods @test MB ∈ mods @@ -1017,9 +1008,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() @@ -1107,6 +1098,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) @@ -1123,6 +1125,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) @@ -1143,26 +1147,29 @@ precompile_test_harness("invoke") do dir # Issue #44320 f44320(::Real) = 3 + # Issue #57115 + f57115(::Int) = 1 call_getlast(x) = getlast(x) - # force precompilation + # force precompilation, force call so that inlining heuristics don't affect the result begin Base.Experimental.@force_compile - callf(3) - callg(3) - callh(3) - callq(3) - callqi(3) - callfnc(3) - callgnc(3) - callhnc(3) - callqnc(3) - callqnci(3) - internal(3) - internalnc(3) - call_getlast([1,2,3]) + @noinline callf(3) + @noinline callg(3) + @noinline callh(3) + @noinline callq(3) + @noinline callqi(3) + @noinline callfnc(3) + @noinline callgnc(3) + @noinline callhnc(3) + @noinline callqnc(3) + @noinline callqnci(3) + @noinline internal(3) + @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 @@ -1194,9 +1201,15 @@ precompile_test_harness("invoke") do dir for func in (M.f, M.g, M.internal, M.fnc, M.gnc, M.internalnc) m = get_method_for_type(func, Real) mi = m.specializations::Core.MethodInstance - @test length(mi.backedges) == 2 + @test length(mi.backedges) == 2 || length(mi.backedges) == 4 # internalnc might have a constprop edge @test mi.backedges[1] === Tuple{typeof(func), Real} @test isa(mi.backedges[2], Core.CodeInstance) + if length(mi.backedges) == 4 + @test mi.backedges[3] === Tuple{typeof(func), Real} + @test isa(mi.backedges[4], Core.CodeInstance) + @test mi.backedges[2] !== mi.backedges[4] + @test mi.backedges[2].def === mi.backedges[4].def + end @test mi.cache.max_world == typemax(mi.cache.max_world) end for func in (M.q, M.qnc) @@ -1215,7 +1228,7 @@ precompile_test_harness("invoke") do dir m = only(methods(M.callq)) @test nvalid(m.specializations::Core.MethodInstance) == 0 m = only(methods(M.callqnc)) - @test nvalid(m.specializations::Core.MethodInstance) == 0 + @test nvalid(m.specializations::Core.MethodInstance) == 1 m = only(methods(M.callqi)) @test (m.specializations::Core.MethodInstance).specTypes == Tuple{typeof(M.callqi), Int} m = only(methods(M.callqnci)) @@ -1224,6 +1237,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) @@ -1728,8 +1765,7 @@ precompile_test_harness("issue #46296") do load_path mi = first(Base.specializations(first(methods(identity)))) ci = Core.CodeInstance(mi, nothing, Any, Any, nothing, nothing, zero(Int32), typemin(UInt), - typemax(UInt), zero(UInt32), nothing, 0x00, - Core.DebugInfo(mi), Core.svec()) + typemax(UInt), zero(UInt32), nothing, Core.DebugInfo(mi), Core.svec()) __init__() = @assert ci isa Core.CodeInstance @@ -1828,16 +1864,18 @@ 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 - mi = ci.def + mi = ci.def::Core.MethodInstance mi.specTypes == Tuple{typeof(Base.repl_cmd), Int, String} end end diff --git a/test/rebinding.jl b/test/rebinding.jl index c93c34be7a75c..10da27ce3ad8f 100644 --- a/test/rebinding.jl +++ b/test/rebinding.jl @@ -31,6 +31,20 @@ 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) + const delete_me = 1 + f_return_delete_me() = delete_me + @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 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/sets.jl b/test/sets.jl index b78d2f15dd989..4d52cb243620c 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -1037,6 +1037,8 @@ end @test !isempty(A) A = empty!(A) @test isempty(A) + @test isnothing(sizehint!(A, 10)) + @test Base.copymutable(A) == copy(A) end @testset "⊊, ⊋" begin diff --git a/test/show.jl b/test/show.jl index 07916c249d533..75f04c1e02096 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1861,6 +1861,9 @@ end B = @view ones(2)[r] Base.showarg(io, B, false) @test String(take!(io)) == "view(::Vector{Float64}, $(repr(r)))" + + Base.showarg(io, reshape(UnitRange{Int64}(1,1)), false) + @test String(take!(io)) == "reshape(::UnitRange{Int64})" end @testset "Methods" begin diff --git a/test/sorting.jl b/test/sorting.jl index 71af50429027a..e16b30de5bfc8 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -94,6 +94,22 @@ end vcat(2000, (x:x+99 for x in 1900:-100:100)..., 1:99) end +function tuple_sort_test(x) + @test issorted(sort(x)) + length(x) > 9 && return # length > 9 uses a vector fallback + @test 0 == @allocated sort(x) +end +@testset "sort(::NTuple)" begin + @test sort(()) == () + @test sort((9,8,3,3,6,2,0,8)) == (0,2,3,3,6,8,8,9) + @test sort((9,8,3,3,6,2,0,8), by=x->x÷3) == (2,0,3,3,8,6,8,9) + for i in 1:40 + tuple_sort_test(rand(NTuple{i, Float64})) + end + @test_throws MethodError sort((1,2,3.0)) + @test Base.infer_return_type(sort, Tuple{Tuple{Vararg{Int}}}) == Tuple{Vararg{Int}} +end + @testset "partialsort" begin @test partialsort([3,6,30,1,9],3) == 6 @test partialsort([3,6,30,1,9],3:4) == [6,9] @@ -913,6 +929,20 @@ end end @test sort([1,2,3], alg=MySecondAlg()) == [9,9,9] @test all(sort(v, alg=Base.Sort.InitialOptimizations(MySecondAlg())) .=== vcat(fill(9, 100), fill(missing, 10))) + + # Tuple extensions (custom alg) + @test_throws MethodError sort((1,2,3), alg=MyFirstAlg()) + Base.Sort._sort(v::NTuple, ::MyFirstAlg, o::Base.Order.Ordering, kw) = (17,2,9) + @test sort((1,2,3), alg=MyFirstAlg()) == (17,2,9) + + struct TupleFoo + x::Int + end + + # Tuple extensions (custom type) + @test_throws MethodError sort(TupleFoo.((3,1,2))) + Base.Sort._sort(v::NTuple{N, TupleFoo}, ::Base.Sort.DefaultStable, o::Base.Order.Ordering, kw) where N = v + @test sort(TupleFoo.((3,1,2))) === TupleFoo.((3,1,2)) end @testset "sort!(v, lo, hi, alg, order)" begin 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/stacktraces.jl b/test/stacktraces.jl index 12da6d571013e..ca553c2a2e801 100644 --- a/test/stacktraces.jl +++ b/test/stacktraces.jl @@ -92,9 +92,10 @@ can_inline = Bool(Base.JLOptions().can_inline) for (frame, func, inlined) in zip(trace, [g,h,f], (can_inline, can_inline, false)) @test frame.func === typeof(func).name.mt.name # broken until #50082 can be addressed - @test frame.linfo.def.module === which(func, (Any,)).module broken=inlined - @test frame.linfo.def === which(func, (Any,)) broken=inlined - @test frame.linfo.specTypes === Tuple{typeof(func), Int} broken=inlined + mi = isa(frame.linfo, Core.CodeInstance) ? frame.linfo.def : frame.linfo + @test mi.def.module === which(func, (Any,)).module broken=inlined + @test mi.def === which(func, (Any,)) broken=inlined + @test mi.specTypes === Tuple{typeof(func), Int} broken=inlined # line @test frame.file === Symbol(@__FILE__) @test !frame.from_c diff --git a/test/strings/annotated.jl b/test/strings/annotated.jl index 3379452d3e871..dbb81cb48acbc 100644 --- a/test/strings/annotated.jl +++ b/test/strings/annotated.jl @@ -71,6 +71,9 @@ "AnnotatedString{String}(\"some string\", [(1:4, :thing, 0x01), (6:11, :other, 0x02), (1:11, :all, 0x03)])" @test eval(Meta.parse(repr(str))) == str @test sprint(show, MIME("text/plain"), str) == "\"some string\"" + + a = Base.AnnotatedString("hello", [(1:5, :label, 1)]) + @test first(a) == Base.AnnotatedChar('h', [(:label, 1)]) end @testset "AnnotatedChar" begin @@ -247,4 +250,8 @@ end @test write(wrapio, Base.AnnotatedChar('a', [(:y, 2)])) == 1 @test read(seekstart(aio), Base.AnnotatedString) == Base.AnnotatedString("heya", [(1:3, :x, 1), (4:4, :y, 2)]) + # show-ing an AnnotatedIOBuffer + aio = Base.AnnotatedIOBuffer() + write(aio, Base.AnnotatedString("hello", [(1:5, :tag, 1)])) + @test sprint(show, aio) == "Base.AnnotatedIOBuffer(5 bytes, 1 annotation)" end diff --git a/test/strings/basic.jl b/test/strings/basic.jl index bc4e5ae66419a..f90ce8c697ed8 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -430,6 +430,8 @@ end @test Symbol(gstr) === Symbol("12") + @test eltype(gstr) == Char + @test firstindex(gstr) == 1 @test sizeof(gstr) == 2 @test ncodeunits(gstr) == 2 @test length(gstr) == 2 @@ -1421,3 +1423,20 @@ end @test transcode(String, transcode(UInt8, transcode(UInt16, str))) == str end end + +if Sys.iswindows() + @testset "cwstring" begin + # empty string + str_0 = "" + # string with embedded NUL character + str_1 = "Au\000B" + # string with terminating NUL character + str_2 = "Wordu\000" + # "Regular" string with UTF-8 characters of differing byte counts + str_3 = "aܣ𒀀" + @test Base.cwstring(str_0) == UInt16[0x0000] + @test_throws ArgumentError Base.cwstring(str_1) + @test_throws ArgumentError Base.cwstring(str_2) + @test Base.cwstring(str_3) == UInt16[0x0061, 0x0723, 0xd808, 0xdc00, 0x0000] + end +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 diff --git a/test/syntax.jl b/test/syntax.jl index 315f2d8b0f38b..aaeeea7aec161 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -476,7 +476,7 @@ let err = try catch e e end - @test err.line == 7 + @test err.line in (5, 7) end # PR #17393 @@ -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 @@ -3919,28 +3920,28 @@ module ExtendedIsDefined import .Import.x4 @test x2 == 2 # Resolve the binding @eval begin - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x2))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x3))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x4))) + @test Core.isdefinedglobal(@__MODULE__, :x1) + @test Core.isdefinedglobal(@__MODULE__, :x2) + @test Core.isdefinedglobal(@__MODULE__, :x3) + @test Core.isdefinedglobal(@__MODULE__, :x4) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x2), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x3), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x4), false)) + @test Core.isdefinedglobal(@__MODULE__, :x1, false) + @test !Core.isdefinedglobal(@__MODULE__, :x2, false) + @test !Core.isdefinedglobal(@__MODULE__, :x3, false) + @test !Core.isdefinedglobal(@__MODULE__, :x4, false) end @eval begin @Base.Experimental.force_compile - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x2))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x3))) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x4))) + @test Core.isdefinedglobal(@__MODULE__, :x1) + @test Core.isdefinedglobal(@__MODULE__, :x2) + @test Core.isdefinedglobal(@__MODULE__, :x3) + @test Core.isdefinedglobal(@__MODULE__, :x4) - @test $(Expr(:isdefined, GlobalRef(@__MODULE__, :x1), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x2), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x3), false)) - @test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x4), false)) + @test Core.isdefinedglobal(@__MODULE__, :x1, false) + @test !Core.isdefinedglobal(@__MODULE__, :x2, false) + @test !Core.isdefinedglobal(@__MODULE__, :x3, false) + @test !Core.isdefinedglobal(@__MODULE__, :x4, false) end end @@ -3971,11 +3972,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 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 diff --git a/test/testhelpers/OffsetArrays.jl b/test/testhelpers/OffsetArrays.jl index e895372a34974..5acaa88064245 100644 --- a/test/testhelpers/OffsetArrays.jl +++ b/test/testhelpers/OffsetArrays.jl @@ -5,7 +5,7 @@ # This test file is designed to exercise support for generic indexing, # even though offset arrays aren't implemented in Base. -# OffsetArrays v1.11.2 +# OffsetArrays v1.15.0 # No compat patch and docstrings module OffsetArrays @@ -73,10 +73,15 @@ end IdOffsetRange(r::IdOffsetRange) = r # Constructor to make `show` round-trippable +# try to preserve typeof(values) if the indices are known to be 1-based +_subtractindexoffset(values, indices::Union{Base.OneTo, IdentityUnitRange{<:Base.OneTo}}, offset) = values +_subtractindexoffset(values, indices, offset) = _subtractoffset(values, offset) function IdOffsetRange(; values::AbstractUnitRange{<:Integer}, indices::AbstractUnitRange{<:Integer}) length(values) == length(indices) || throw(ArgumentError("values and indices must have the same length")) + values_nooffset = no_offset_view(values) offset = first(indices) - 1 - return IdOffsetRange(values .- offset, offset) + values_minus_offset = _subtractindexoffset(values_nooffset, indices, offset) + return IdOffsetRange(values_minus_offset, offset) end # Conversions to an AbstractUnitRange{Int} (and to an OrdinalRange{Int,Int} on Julia v"1.6") are necessary @@ -110,12 +115,19 @@ offset_coerce(::Type{I}, r::AbstractUnitRange) where I<:AbstractUnitRange = @inline Base.unsafe_indices(r::IdOffsetRange) = (Base.axes1(r),) @inline Base.length(r::IdOffsetRange) = length(r.parent) @inline Base.isempty(r::IdOffsetRange) = isempty(r.parent) +#= We specialize on reduced_indices to work around cases where the parent axis type doesn't +support reduced_index, but the axes do support reduced_indices +The difference is that reduced_index expects the axis type to remain unchanged, +which may not always be possible, eg. for statically sized axes +See https://github.com/JuliaArrays/OffsetArrays.jl/issues/204 +=# +function Base.reduced_indices(inds::Tuple{IdOffsetRange, Vararg{IdOffsetRange}}, d::Int) + parents_reduced = Base.reduced_indices(map(parent, inds), d) + ntuple(i -> IdOffsetRange(parents_reduced[i], inds[i].offset), Val(length(inds))) +end Base.reduced_index(i::IdOffsetRange) = typeof(i)(first(i):first(i)) # Workaround for #92 on Julia < 1.4 Base.reduced_index(i::IdentityUnitRange{<:IdOffsetRange}) = typeof(i)(first(i):first(i)) -for f in [:firstindex, :lastindex] - @eval @inline Base.$f(r::IdOffsetRange) = $f(r.parent) + r.offset -end for f in [:first, :last] # coerce the type to deal with values that get promoted on addition (eg. Bool) @eval @inline Base.$f(r::IdOffsetRange) = eltype(r)($f(r.parent) + r.offset) @@ -142,7 +154,7 @@ end @inline function Base.getindex(r::IdOffsetRange, i::Integer) i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) @boundscheck checkbounds(r, i) - @inbounds eltype(r)(r.parent[oftype(r.offset, i) - r.offset] + r.offset) + @inbounds eltype(r)(r.parent[i - r.offset] + r.offset) end # Logical indexing following https://github.com/JuliaLang/julia/pull/31829 @@ -186,18 +198,20 @@ for R in [:IIUR, :IdOffsetRange] end # offset-preserve broadcasting -Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(-), r::IdOffsetRange{T}, x::Integer) where T = - IdOffsetRange{T}(r.parent .- x, r.offset) -Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), r::IdOffsetRange{T}, x::Integer) where T = - IdOffsetRange{T}(r.parent .+ x, r.offset) -Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::IdOffsetRange{T}) where T = - IdOffsetRange{T}(x .+ r.parent, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(-), r::IdOffsetRange, x::Integer) = + IdOffsetRange(r.parent .- x, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), r::IdOffsetRange, x::Integer) = + IdOffsetRange(r.parent .+ x, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(+), x::Integer, r::IdOffsetRange) = + IdOffsetRange(x .+ r.parent, r.offset) +Broadcast.broadcasted(::Base.Broadcast.DefaultArrayStyle{1}, ::typeof(big), r::IdOffsetRange) = + IdOffsetRange(big.(r.parent), r.offset) Base.show(io::IO, r::IdOffsetRange) = print(io, IdOffsetRange, "(values=",first(r), ':', last(r),", indices=",first(eachindex(r)),':',last(eachindex(r)), ")") # Optimizations @inline Base.checkindex(::Type{Bool}, inds::IdOffsetRange, i::Real) = Base.checkindex(Bool, inds.parent, i - inds.offset) -Base._firstslice(r::IdOffsetRange) = IdOffsetRange(Base._firstslice(r.parent), r.offset) +Base._firstslice(i::IdOffsetRange) = IdOffsetRange(Base._firstslice(i.parent), i.offset) ######################################################################################################## # origin.jl @@ -309,12 +323,12 @@ _popreshape(A::AbstractArray, ax, inds) = A # Technically we know the length of CartesianIndices but we need to convert it first, so here we # don't put it in OffsetAxisKnownLength. -const OffsetAxisKnownLength = Union{Integer,AbstractUnitRange} -const OffsetAxis = Union{OffsetAxisKnownLength,Colon} -const ArrayInitializer = Union{UndefInitializer,Missing,Nothing} +const OffsetAxisKnownLength = Union{Integer, AbstractUnitRange} +const OffsetAxis = Union{OffsetAxisKnownLength, Colon} +const ArrayInitializer = Union{UndefInitializer, Missing, Nothing} ## OffsetArray -struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N} +struct OffsetArray{T,N,AA<:AbstractArray{T,N}} <: AbstractArray{T,N} parent::AA offsets::NTuple{N,Int} @inline function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, Int}; checkoverflow = true) where {T, N, AA<:AbstractArray{T,N}} @@ -482,6 +496,10 @@ Base.parent(A::OffsetArray) = A.parent # Base.Broadcast.BroadcastStyle(::Type{<:OffsetArray{<:Any, <:Any, AA}}) where AA = Base.Broadcast.BroadcastStyle(AA) @inline Base.size(A::OffsetArray) = size(parent(A)) +# specializing length isn't necessary, as length(A) = prod(size(A)), +# but specializing length enables constant-propagation for statically sized arrays +# see https://github.com/JuliaArrays/OffsetArrays.jl/pull/304 +@inline Base.length(A::OffsetArray) = length(parent(A)) @inline Base.axes(A::OffsetArray) = map(IdOffsetRange, axes(parent(A)), A.offsets) @inline Base.axes(A::OffsetArray, d) = d <= ndims(A) ? IdOffsetRange(axes(parent(A), d), A.offsets[d]) : IdOffsetRange(axes(parent(A), d)) @@ -528,7 +546,9 @@ _similar_axes_or_length(A, T, ax::I, ::I) where {I} = similar(A, T, map(_indexle _similar_axes_or_length(AT, ax::I, ::I) where {I} = similar(AT, map(_indexlength, ax)) # reshape accepts a single colon -Base.reshape(A::AbstractArray, inds::OffsetAxis...) = reshape(A, inds) +# this method is limited to AbstractUnitRange{<:Integer} to avoid method overwritten errors if Base defines the same, +# see https://github.com/JuliaLang/julia/pull/56850 +Base.reshape(A::AbstractArray, inds::Union{Integer, Colon, AbstractUnitRange{<:Integer}}...) = reshape(A, inds) function Base.reshape(A::AbstractArray, inds::Tuple{Vararg{OffsetAxis}}) AR = reshape(no_offset_view(A), map(_indexlength, inds)) O = OffsetArray(AR, map(_offset, axes(AR), inds)) @@ -553,21 +573,9 @@ _reshape2(A, inds) = reshape(A, inds) _reshape2(A::OffsetArray, inds) = reshape(parent(A), inds) _reshape_nov(A, inds) = _reshape(no_offset_view(A), inds) -Base.reshape(A::OffsetArray, inds::Tuple{OffsetAxis,Vararg{OffsetAxis}}) = - OffsetArray(_reshape(parent(A), inds), map(_toaxis, inds)) # And for non-offset axes, we can just return a reshape of the parent directly -Base.reshape(A::OffsetArray, inds::Tuple{Union{Integer,Base.OneTo},Vararg{Union{Integer,Base.OneTo}}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Tuple{Integer,Vararg{Integer}}) = _reshape_nov(A, inds) -Base.reshape(A::OffsetArray, inds::Tuple{Union{Colon, Integer}, Vararg{Union{Colon, Integer}}}) = _reshape_nov(A, inds) Base.reshape(A::OffsetArray, inds::Dims) = _reshape_nov(A, inds) -Base.reshape(A::OffsetVector, ::Colon) = A -Base.reshape(A::OffsetVector, ::Tuple{Colon}) = A -Base.reshape(A::OffsetArray, inds::Union{Int,Colon}...) = reshape(A, inds) -Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = _reshape_nov(A, inds) -# The following two additional methods for Colon are added to resolve method ambiguities to -# Base: https://github.com/JuliaLang/julia/pull/45387#issuecomment-1132859663 -Base.reshape(A::OffsetArray, inds::Colon) = _reshape_nov(A, inds) -Base.reshape(A::OffsetArray, inds::Tuple{Colon}) = _reshape_nov(A, inds) # permutedims in Base does not preserve axes, and can not be fixed in a non-breaking way # This is a stopgap solution @@ -583,7 +591,7 @@ Base.fill!(A::OffsetArray, x) = parent_call(Ap -> fill!(Ap, x), A) # Δi = i - first(r) # i′ = first(r.parent) + Δi # and one obtains the result below. -parentindex(r::IdOffsetRange, i) = oftype(r.offset, i) - r.offset +parentindex(r::IdOffsetRange, i) = i - r.offset @propagate_inbounds Base.getindex(A::OffsetArray{<:Any,0}) = A.parent[] @@ -632,7 +640,7 @@ Base.copy(A::OffsetArray) = parent_call(copy, A) Base.strides(A::OffsetArray) = strides(parent(A)) Base.elsize(::Type{OffsetArray{T,N,A}}) where {T,N,A} = Base.elsize(A) -Base.cconvert(::Type{Ptr{T}}, A::OffsetArray{T}) where {T} = Base.cconvert(Ptr{T}, parent(A)) +Base.cconvert(P::Type{Ptr{T}}, A::OffsetArray{T}) where {T} = Base.cconvert(P, parent(A)) # For fast broadcasting: ref https://discourse.julialang.org/t/why-is-there-a-performance-hit-on-broadcasting-with-offsetarrays/32194 Base.dataids(A::OffsetArray) = Base.dataids(parent(A)) @@ -732,15 +740,6 @@ if eltype(IIUR) === Int Base.map(::Type{T}, r::IdentityUnitRange) where {T<:Real} = _indexedby(map(T, UnitRange(r)), axes(r)) end -# mapreduce is faster with an IdOffsetRange than with an OffsetUnitRange -# We therefore convert OffsetUnitRanges to IdOffsetRanges with the same values and axes -function Base.mapreduce(f, op, A1::OffsetUnitRange{<:Integer}, As::OffsetUnitRange{<:Integer}...; kw...) - As = (A1, As...) - ofs = map(A -> first(axes(A,1)) - 1, As) - AIds = map((A, of) -> IdOffsetRange(_subtractoffset(parent(A), of), of), As, ofs) - mapreduce(f, op, AIds...; kw...) -end - # Optimize certain reductions that treat an OffsetVector as a list for f in [:minimum, :maximum, :extrema, :sum] @eval Base.$f(r::OffsetRange) = $f(parent(r)) @@ -762,7 +761,8 @@ Base.append!(A::OffsetVector, items) = (append!(A.parent, items); A) Base.empty!(A::OffsetVector) = (empty!(A.parent); A) # These functions keep the summary compact -function Base.inds2string(inds::Tuple{Vararg{Union{IdOffsetRange, IdentityUnitRange{<:IdOffsetRange}}}}) +const OffsetIndices = Union{IdOffsetRange, IdentityUnitRange{<:IdOffsetRange}} +function Base.inds2string(inds::Tuple{OffsetIndices, Vararg{OffsetIndices}}) Base.inds2string(map(UnitRange, inds)) end Base.showindices(io::IO, ind1::IdOffsetRange, inds::IdOffsetRange...) = Base.showindices(io, map(UnitRange, (ind1, inds...))...) @@ -786,7 +786,33 @@ function Base.replace_in_print_matrix(A::OffsetArray{<:Any,1}, i::Integer, j::In Base.replace_in_print_matrix(parent(A), ip, j, s) end +# Actual unsafe_wrap implementation +@inline function _unsafe_wrap(pointer::Ptr{T}, inds::NTuple{N, OffsetAxisKnownLength}; own = false, kw...) where {T,N} + _checkindices(N, inds, "indices") + AA = Base.unsafe_wrap(Array, pointer, map(_indexlength, inds); own=own) + OffsetArray{T, N, typeof(AA)}(AA, map(_indexoffset, inds); kw...) +end +const OffsetArrayUnion{T,N} = Union{Type{OffsetArray}, Type{OffsetArray{T}}, Type{OffsetArray{T,N}}, Type{OffsetArray{T1, N} where T1}} where {T,N} + +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::NTuple{N, OffsetAxisKnownLength}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end +# Avoid ambiguity +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::NTuple{N, <:Integer}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::Vararg{OffsetAxisKnownLength,N}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end +# Avoid ambiguity +@inline function Base.unsafe_wrap(::OffsetArrayUnion{T,N}, pointer::Ptr{T}, inds::Vararg{Integer,N}; kw...) where {T,N} + _unsafe_wrap(pointer, inds; kw...) +end + no_offset_view(A::OffsetArray) = no_offset_view(parent(A)) +no_offset_view(a::Base.Slice{<:Base.OneTo}) = a +no_offset_view(a::Base.Slice) = Base.Slice(UnitRange(a)) +no_offset_view(S::SubArray) = view(parent(S), map(no_offset_view, parentindices(S))...) no_offset_view(a::Array) = a no_offset_view(i::Number) = i no_offset_view(A::AbstractArray) = _no_offset_view(axes(A), A) @@ -802,9 +828,12 @@ _no_offset_view(::Any, A::AbstractUnitRange) = UnitRange(A) # These two helpers are deliberately not exported; their meaning can be very different in # other scenarios and will be very likely to cause name conflicts if exported. ##### + +_halfroundInt(v, r::RoundingMode) = div(v, 2, r) + function center(A::AbstractArray, r::RoundingMode=RoundDown) map(axes(A)) do inds - round(Int, (length(inds)-1)/2, r) + first(inds) + _halfroundInt(length(inds)-1, r) + first(inds) end end diff --git a/test/threads.jl b/test/threads.jl index 4d928ca05da16..179279dbab4e6 100644 --- a/test/threads.jl +++ b/test/threads.jl @@ -16,7 +16,8 @@ let lk = ReentrantLock() t2 = @async (notify(c2); trylock(lk)) wait(c1) wait(c2) - @test t1.queue === lk.cond_wait.waitq + # wait for the task to park in the queue (it may be spinning) + @test timedwait(() -> t1.queue === lk.cond_wait.waitq, 1.0) == :ok @test t2.queue !== lk.cond_wait.waitq @test istaskdone(t2) @test !fetch(t2) 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 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]