diff --git a/Compiler/LICENSE.md b/Compiler/LICENSE.md index 028a39923ef04..dbbcd7506fc1e 100644 --- a/Compiler/LICENSE.md +++ b/Compiler/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2009-2024: Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors: https://github.com/JuliaLang/julia/contributors +Copyright (c) 2009-2025: Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors: https://github.com/JuliaLang/julia/contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Compiler/Project.toml b/Compiler/Project.toml index 994634f5a8b78..1a0cdf4abca39 100644 --- a/Compiler/Project.toml +++ b/Compiler/Project.toml @@ -1,6 +1,6 @@ name = "Compiler" uuid = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" -version = "0.0.3" +version = "0.1.1" [compat] julia = "1.10" diff --git a/Compiler/README.md b/Compiler/README.md new file mode 100644 index 0000000000000..ae5aaa3f60792 --- /dev/null +++ b/Compiler/README.md @@ -0,0 +1,45 @@ +# The `Compiler` module + +This directory maintains the implementation of the Julia compiler. + +Through a bootstrapping process, it is bundled into the Julia runtime as `Base.Compiler`. + +You can also use this `Compiler` module as the `Compiler` standard library by following the steps below. + +## How to use + +To utilize this `Compiler.jl` standard library, you need to declare it as a dependency in +your `Project.toml` as follows: +> Project.toml +```toml +[deps] +Compiler = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1" + +[compat] +Compiler = "0.1" +``` + +With the setup above, [the special placeholder version (v0.1)](https://github.com/JuliaLang/BaseCompiler.jl) +will be installed by default.[^1] + +[^1]: Currently, only version v0.1 is registered in the [General](https://github.com/JuliaRegistries/General) registry. + +If needed, you can switch to a custom implementation of the `Compiler` module by running +```julia-repl +pkg> dev /path/to/Compiler.jl # to use a local implementation +``` +or +```julia-repl +pkg> add https://url/of/Compiler/branch # to use a remote implementation +``` +This feature is particularly useful for developing or experimenting with alternative compiler implementations. + +> [!note] +> The Compiler.jl standard library is available starting from Julia v1.10. +> However, switching to a custom compiler implementation is supported only from +> Julia v1.12 onwards. + +> [!warning] +> When using a custom, non-`Base` version of `Compiler` implementation, it may be necessary +> to run `InteractiveUtils.@activate Compiler` to ensure proper functionality of certain +> reflection utilities. diff --git a/Compiler/src/Compiler.jl b/Compiler/src/Compiler.jl index 981001cb2fbe6..080cdc6f7ee0e 100644 --- a/Compiler/src/Compiler.jl +++ b/Compiler/src/Compiler.jl @@ -38,7 +38,7 @@ else using Core.Intrinsics, Core.IR using Core: ABIOverride, Builtin, CodeInstance, IntrinsicFunction, MethodInstance, MethodMatch, - MethodTable, PartialOpaque, SimpleVector, TypeofVararg, + MethodTable, MethodCache, PartialOpaque, SimpleVector, TypeofVararg, _apply_iterate, apply_type, compilerbarrier, donotdelete, memoryref_isassigned, memoryrefget, memoryrefnew, memoryrefoffset, memoryrefset!, print, println, show, svec, typename, unsafe_write, write diff --git a/Compiler/src/abstractinterpretation.jl b/Compiler/src/abstractinterpretation.jl index 01faba6b37d1f..4947368e87858 100644 --- a/Compiler/src/abstractinterpretation.jl +++ b/Compiler/src/abstractinterpretation.jl @@ -363,15 +363,13 @@ function find_union_split_method_matches(interp::AbstractInterpreter, 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 thismatches = findall(sig_n, method_table(interp); limit = max_methods) if thismatches === nothing return FailedMethodMatch("For one of the union split cases, too many methods matched") end valid_worlds = intersect(valid_worlds, thismatches.valid_worlds) thisfullmatch = any(match::MethodMatch->match.fully_covers, thismatches) + mt = Core.GlobalMethods thisinfo = MethodMatchInfo(thismatches, mt, sig_n, thisfullmatch) push!(infos, thisinfo) for idx = 1:length(thismatches) @@ -385,11 +383,6 @@ function find_union_split_method_matches(interp::AbstractInterpreter, argtypes:: end function find_simple_method_matches(interp::AbstractInterpreter, @nospecialize(atype), max_methods::Int) - mt = ccall(:jl_method_table_for, Any, (Any,), atype) - if mt === nothing - return FailedMethodMatch("Could not identify method table for call") - end - mt = mt::MethodTable matches = findall(atype, method_table(interp); limit = max_methods) if matches === nothing # this means too many methods matched @@ -397,6 +390,7 @@ function find_simple_method_matches(interp::AbstractInterpreter, @nospecialize(a return FailedMethodMatch("Too many methods matched") end fullmatch = any(match::MethodMatch->match.fully_covers, matches) + mt = Core.GlobalMethods info = MethodMatchInfo(matches, mt, atype, fullmatch) applicable = MethodMatchTarget[MethodMatchTarget(matches[idx], info.edges, idx) for idx = 1:length(matches)] return MethodMatches(applicable, info, matches.valid_worlds) diff --git a/Compiler/src/bootstrap.jl b/Compiler/src/bootstrap.jl index a847d1fb835c7..74943fc765f17 100644 --- a/Compiler/src/bootstrap.jl +++ b/Compiler/src/bootstrap.jl @@ -10,7 +10,7 @@ function activate_codegen!() Core.eval(Compiler, quote let typeinf_world_age = Base.tls_world_age() @eval Core.OptimizedGenerics.CompilerPlugins.typeinf(::Nothing, mi::MethodInstance, source_mode::UInt8) = - Base.invoke_in_world($(Expr(:$, :typeinf_world_age)), typeinf_ext_toplevel, mi, Base.tls_world_age(), source_mode) + Base.invoke_in_world($(Expr(:$, :typeinf_world_age)), typeinf_ext_toplevel, mi, Base.tls_world_age(), source_mode, Compiler.TRIM_NO) end end) end @@ -67,7 +67,7 @@ function bootstrap!() end 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.") - typeinf_ext_toplevel(mi, world, isa_compileable_sig(mi) ? SOURCE_MODE_ABI : SOURCE_MODE_NOT_REQUIRED) + typeinf_ext_toplevel(mi, world, isa_compileable_sig(mi) ? SOURCE_MODE_ABI : SOURCE_MODE_NOT_REQUIRED, TRIM_NO) end end end diff --git a/Compiler/src/ssair/inlining.jl b/Compiler/src/ssair/inlining.jl index 120b891f09a9f..f5fd8c8882649 100644 --- a/Compiler/src/ssair/inlining.jl +++ b/Compiler/src/ssair/inlining.jl @@ -126,10 +126,11 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn block = block_for_inst(ir, idx) inline_into_block!(state, block) - if !isempty(inlinee_cfg.blocks[1].preds) + if length(inlinee_cfg.blocks[1].preds) > 1 need_split_before = true + else + @assert inlinee_cfg.blocks[1].preds[1] == 0 end - last_block_idx = last(state.cfg.blocks[block].stmts) if false # TODO: ((idx+1) == last_block_idx && isa(ir[SSAValue(last_block_idx)], GotoNode)) need_split = false @@ -166,12 +167,18 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn end new_block_range = (length(state.new_cfg_blocks)-length(inlinee_cfg.blocks)+1):length(state.new_cfg_blocks) - # Fixup the edges of the newely added blocks + # Fixup the edges of the newly added blocks for (old_block, new_block) in enumerate(bb_rename_range) if old_block != 1 || need_split_before p = state.new_cfg_blocks[new_block].preds let bb_rename_range = bb_rename_range map!(p, p) do old_pred_block + # the meaning of predecessor 0 depends on the block we encounter it: + # - in the first block, it represents the function entry and so needs to be re-mapped + if old_block == 1 && old_pred_block == 0 + return first(bb_rename_range) - 1 + end + # - elsewhere, it represents external control-flow from a caught exception which is un-affected by inlining return old_pred_block == 0 ? 0 : bb_rename_range[old_pred_block] end end @@ -186,10 +193,6 @@ function cfg_inline_item!(ir::IRCode, idx::Int, todo::InliningTodo, state::CFGIn end end - if need_split_before - push!(state.new_cfg_blocks[first(bb_rename_range)].preds, first(bb_rename_range)-1) - end - any_edges = false for (old_block, new_block) in enumerate(bb_rename_range) if (length(state.new_cfg_blocks[new_block].succs) == 0) @@ -399,7 +402,7 @@ function ir_inline_item!(compact::IncrementalCompact, idx::Int, argexprs::Vector else bb_offset, post_bb_id = popfirst!(todo_bbs) # This implements the need_split_before flag above - need_split_before = !isempty(item.ir.cfg.blocks[1].preds) + need_split_before = length(item.ir.cfg.blocks[1].preds) > 1 if need_split_before finish_current_bb!(compact, 0) end diff --git a/Compiler/src/ssair/ir.jl b/Compiler/src/ssair/ir.jl index e6c8f3a6d2c78..d7f0dbedcbec5 100644 --- a/Compiler/src/ssair/ir.jl +++ b/Compiler/src/ssair/ir.jl @@ -105,6 +105,9 @@ function compute_basic_blocks(stmts::Vector{Any}) end # Compute successors/predecessors for (num, b) in enumerate(blocks) + if b.stmts.start == 1 + push!(b.preds, 0) # the entry block has a virtual predecessor + end terminator = stmts[last(b.stmts)] if isa(terminator, ReturnNode) # return never has any successors diff --git a/Compiler/src/stmtinfo.jl b/Compiler/src/stmtinfo.jl index 6a85bc6605d3f..1c6d47ec53b57 100644 --- a/Compiler/src/stmtinfo.jl +++ b/Compiler/src/stmtinfo.jl @@ -47,21 +47,20 @@ end add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo) = _add_edges_impl(edges, info) function _add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, mi_edge::Bool=false) if !fully_covering(info) - # add legacy-style missing backedge info also exists = false for i in 2:length(edges) - if edges[i] === info.mt && edges[i-1] == info.atype + if edges[i] === Core.GlobalMethods && edges[i-1] == info.atype exists = true break end end if !exists push!(edges, info.atype) - push!(edges, info.mt) + push!(edges, Core.GlobalMethods) end end nmatches = length(info.results) - if nmatches == length(info.edges) == 1 + if nmatches == length(info.edges) == 1 && fully_covering(info) # try the optimized format for the representation, if possible and applicable # if this doesn't succeed, the backedge will be less precise, # but the forward edge will maintain the precision @@ -79,13 +78,15 @@ function _add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, mi_edge::Boo end end # add check for whether this lookup already existed in the edges list + # encode nmatches as negative if fully_covers is false + encoded_nmatches = fully_covering(info) ? nmatches : -nmatches for i in 1:length(edges) - if edges[i] === nmatches && edges[i+1] == info.atype + if edges[i] === encoded_nmatches && edges[i+1] == info.atype # TODO: must also verify the CodeInstance match too return nothing end end - push!(edges, nmatches, info.atype) + push!(edges, encoded_nmatches, info.atype) for i = 1:nmatches edge = info.edges[i] m = info.results[i] @@ -102,7 +103,7 @@ function add_one_edge!(edges::Vector{Any}, edge::MethodInstance) i = 1 while i <= length(edges) edgeᵢ = edges[i] - edgeᵢ isa Int && (i += 2 + edgeᵢ; continue) + edgeᵢ isa Int && (i += 2 + abs(edgeᵢ); continue) edgeᵢ isa CodeInstance && (edgeᵢ = get_ci_mi(edgeᵢ)) edgeᵢ isa MethodInstance || (i += 1; continue) if edgeᵢ === edge && !(i > 1 && edges[i-1] isa Type) @@ -117,7 +118,7 @@ function add_one_edge!(edges::Vector{Any}, edge::CodeInstance) i = 1 while i <= length(edges) edgeᵢ_orig = edgeᵢ = edges[i] - edgeᵢ isa Int && (i += 2 + edgeᵢ; continue) + edgeᵢ isa Int && (i += 2 + abs(edgeᵢ); continue) 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) diff --git a/Compiler/src/tfuncs.jl b/Compiler/src/tfuncs.jl index e9fe671b2f781..fd378bcc3626c 100644 --- a/Compiler/src/tfuncs.jl +++ b/Compiler/src/tfuncs.jl @@ -405,6 +405,9 @@ end return isdefined_tfunc(𝕃, arg1, sym) end @nospecs function isdefined_tfunc(𝕃::AbstractLattice, arg1, sym) + if arg1 isa MustAlias + arg1 = widenmustalias(arg1) + end arg1t = arg1 isa Const ? typeof(arg1.val) : isconstType(arg1) ? typeof(arg1.parameters[1]) : widenconst(arg1) a1 = unwrap_unionall(arg1t) if isa(a1, DataType) && !isabstracttype(a1) @@ -3156,15 +3159,12 @@ function _hasmethod_tfunc(interp::AbstractInterpreter, argtypes::Vector{Any}, sv isdispatchelem(ft) || return CallMeta(Bool, Any, Effects(), NoCallInfo()) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below types = rewrap_unionall(Tuple{ft, unwrapped.parameters...}, types)::Type end - mt = ccall(:jl_method_table_for, Any, (Any,), types) - if !isa(mt, MethodTable) - return CallMeta(Bool, Any, EFFECTS_THROWS, NoCallInfo()) - end match, valid_worlds = findsup(types, method_table(interp)) update_valid_age!(sv, valid_worlds) if match === nothing rt = Const(false) vresults = MethodLookupResult(Any[], valid_worlds, true) + mt = Core.GlobalMethods vinfo = MethodMatchInfo(vresults, mt, types, false) # XXX: this should actually be an info with invoke-type edge else rt = Const(true) diff --git a/Compiler/src/typeinfer.jl b/Compiler/src/typeinfer.jl index 2e7c7a5018e06..8fdfaa2966b8f 100644 --- a/Compiler/src/typeinfer.jl +++ b/Compiler/src/typeinfer.jl @@ -572,12 +572,17 @@ function finishinfer!(me::InferenceState, interp::AbstractInterpreter, cycleid:: nothing end -# record the backedges -function store_backedges(caller::CodeInstance, edges::SimpleVector) - isa(caller.def.def, Method) || return # don't add backedges to toplevel method instance - i = 1 - while true - i > length(edges) && return nothing +# Iterate a series of back-edges that need registering, based on the provided forward edge list. +# Back-edges are returned as (invokesig, item), where the item is a Binding, MethodInstance, or +# MethodTable. +struct ForwardToBackedgeIterator + forward_edges::SimpleVector +end + +function Base.iterate(it::ForwardToBackedgeIterator, i::Int = 1) + edges = it.forward_edges + i > length(edges) && return nothing + while i ≤ length(edges) item = edges[i] if item isa Int i += 2 @@ -587,32 +592,55 @@ function store_backedges(caller::CodeInstance, edges::SimpleVector) i += 1 continue elseif isa(item, Core.Binding) - i += 1 - maybe_add_binding_backedge!(item, caller) - continue + return ((nothing, item), i + 1) end if isa(item, CodeInstance) - item = item.def - end - if isa(item, MethodInstance) # regular dispatch - ccall(:jl_method_instance_add_backedge, Cvoid, (Any, Any, Any), item, nothing, caller) - i += 1 + item = get_ci_mi(item) + return ((nothing, item), i + 1) + elseif isa(item, MethodInstance) # regular dispatch + return ((nothing, item), i + 1) else + invokesig = item callee = edges[i+1] - if isa(callee, MethodTable) # abstract dispatch (legacy style edges) - ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any, Any), callee, item, caller) - i += 2 - continue - elseif isa(callee, Method) - # ignore `Method`-edges (from e.g. failed `abstract_call_method`) - i += 2 - continue - # `invoke` edge - elseif isa(callee, CodeInstance) - callee = get_ci_mi(callee) + isa(callee, Method) && (i += 2; continue) # ignore `Method`-edges (from e.g. failed `abstract_call_method`) + if isa(callee, MethodTable) + # abstract dispatch (legacy style edges) + return ((invokesig, callee), i + 2) + else + # `invoke` edge + callee = isa(callee, CodeInstance) ? get_ci_mi(callee) : callee::MethodInstance + return ((invokesig, callee), i + 2) + end + end + end + return nothing +end + +# record the backedges +function store_backedges(caller::CodeInstance, edges::SimpleVector) + isa(caller.def.def, Method) || return # don't add backedges to toplevel method instance + + backedges = ForwardToBackedgeIterator(edges) + for (i, (invokesig, item)) in enumerate(backedges) + # check for any duplicate edges we've already registered + duplicate_found = false + for (i′, (invokesig′, item′)) in enumerate(backedges) + i == i′ && break + if item′ === item && invokesig′ == invokesig + duplicate_found = true + break + end + end + + if !duplicate_found + if item isa Core.Binding + maybe_add_binding_backedge!(item, caller) + elseif item isa MethodTable + ccall(:jl_method_table_add_backedge, Cvoid, (Any, Any), invokesig, caller) + else + item::MethodInstance + ccall(:jl_method_instance_add_backedge, Cvoid, (Any, Any, Any), item, invokesig, caller) end - ccall(:jl_method_instance_add_backedge, Cvoid, (Any, Any, Any), callee, item, caller) - i += 2 end end nothing @@ -1333,16 +1361,30 @@ function collectinvokes!(workqueue::CompilationQueue, ci::CodeInfo, sptypes::Vec # No dynamic dispatch to resolve / enqueue continue end + elseif isexpr(stmt, :cfunction) && length(stmt.args) == 5 + (pointer_type, f, rt, at, call_type) = stmt.args + linfo = ci.parent - let workqueue = invokelatest_queue - # make a best-effort attempt to enqueue the relevant code for the finalizer - mi = compileable_specialization_for_call(workqueue.interp, atype) - mi === nothing && continue + linfo isa MethodInstance || continue + at isa SimpleVector || continue - push!(workqueue, mi) + ft = argextype(f, ci, sptypes) + argtypes = Any[ft] + for i = 1:length(at) + push!(argtypes, sp_type_rewrap(at[i], linfo, #= isreturn =# false)) end + atype = argtypes_to_type(argtypes) + else + # TODO: handle other StmtInfo like OpaqueClosure? + continue + end + let workqueue = invokelatest_queue + # make a best-effort attempt to enqueue the relevant code for the dynamic invokelatest call + mi = compileable_specialization_for_call(workqueue.interp, atype) + mi === nothing && continue + + push!(workqueue, mi) end - # TODO: handle other StmtInfo like @cfunction and OpaqueClosure? end end @@ -1403,8 +1445,9 @@ function typeinf_ext_toplevel(interp::AbstractInterpreter, mi::MethodInstance, s 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) +function typeinf_ext_toplevel(mi::MethodInstance, world::UInt, source_mode::UInt8, trim_mode::UInt8) + inf_params = InferenceParams(; force_enable_inference = trim_mode != TRIM_NO) + interp = NativeInterpreter(world; inf_params) return typeinf_ext_toplevel(interp, mi, source_mode) end @@ -1487,11 +1530,11 @@ end # This is a bridge for the C code calling `jl_typeinf_func()` on set of Method matches # The trim_mode can be any of: -const TRIM_NO = 0 -const TRIM_SAFE = 1 -const TRIM_UNSAFE = 2 -const TRIM_UNSAFE_WARN = 3 -function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim_mode::Int) +const TRIM_NO = 0x0 +const TRIM_SAFE = 0x1 +const TRIM_UNSAFE = 0x2 +const TRIM_UNSAFE_WARN = 0x3 +function typeinf_ext_toplevel(methods::Vector{Any}, worlds::Vector{UInt}, trim_mode::UInt8) inf_params = InferenceParams(; force_enable_inference = trim_mode != TRIM_NO) # Create an "invokelatest" queue to enable eager compilation of speculative diff --git a/Compiler/src/utilities.jl b/Compiler/src/utilities.jl index dfcff03d70f0e..d5a2fcfc478ff 100644 --- a/Compiler/src/utilities.jl +++ b/Compiler/src/utilities.jl @@ -158,10 +158,8 @@ end function get_compileable_sig(method::Method, @nospecialize(atype), sparams::SimpleVector) isa(atype, DataType) || return nothing - mt = ccall(:jl_method_get_table, Any, (Any,), method) - mt === nothing && return nothing - return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint), - mt, atype, sparams, method, #=int return_if_compileable=#1) + return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Cint), + atype, sparams, method, #=int return_if_compileable=#1) end diff --git a/Compiler/src/verifytrim.jl b/Compiler/src/verifytrim.jl index 09a189b2ff223..eb775bfa290ce 100644 --- a/Compiler/src/verifytrim.jl +++ b/Compiler/src/verifytrim.jl @@ -14,7 +14,7 @@ using ..Compiler: argextype, empty!, error, get, get_ci_mi, get_world_counter, getindex, getproperty, hasintersect, haskey, in, isdispatchelem, isempty, isexpr, iterate, length, map!, max, pop!, popfirst!, push!, pushfirst!, reinterpret, reverse!, reverse, setindex!, - setproperty!, similar, singleton_type, sptypes_from_meth_instance, + setproperty!, similar, singleton_type, sptypes_from_meth_instance, sp_type_rewrap, unsafe_pointer_to_objref, widenconst, isconcretetype, # misc @nospecialize, @assert, C_NULL @@ -256,9 +256,27 @@ function verify_codeinstance!(interp::NativeInterpreter, codeinst::CodeInstance, warn = true # downgrade must-throw calls to be only a warning end elseif isexpr(stmt, :cfunction) + length(stmt.args) != 5 && continue # required by IR legality + (pointer_type, f, rt, at, call_type) = stmt.args + + at isa SimpleVector || continue # required by IR legality + ft = argextype(f, codeinfo, sptypes) + argtypes = Any[ft] + for i = 1:length(at) + push!(argtypes, sp_type_rewrap(at[i], get_ci_mi(codeinst), #= isreturn =# false)) + end + atype = argtypes_to_type(argtypes) + + mi = compileable_specialization_for_call(interp, atype) + if mi !== nothing + # n.b.: Codegen may choose unpredictably to emit this `@cfunction` as a dynamic invoke or a full + # dynamic call, but in either case it guarantees that the required adapter(s) are emitted. All + # that we are required to verify here is that the callee CodeInstance is covered. + ci = get(caches, mi, nothing) + ci isa CodeInstance && continue + end + error = "unresolved cfunction" - #TODO: parse the cfunction expression to check the target is defined - warn = true elseif isexpr(stmt, :foreigncall) foreigncall = stmt.args[1] if foreigncall isa QuoteNode diff --git a/Compiler/test/codegen.jl b/Compiler/test/codegen.jl index 7c985727d001f..be2df190764a0 100644 --- a/Compiler/test/codegen.jl +++ b/Compiler/test/codegen.jl @@ -1058,3 +1058,9 @@ let io = IOBuffer() str = String(take!(io)) @test !occursin("jtbaa_unionselbyte", str) end + +let io = IOBuffer() + code_llvm(io, (x, y) -> (@atomic x[1] = y; nothing), (AtomicMemory{Pair{Any,Any}}, Pair{Any,Any},), raw=true, optimize=false) + str = String(take!(io)) + @test occursin("julia.write_barrier", str) +end diff --git a/Compiler/test/inference.jl b/Compiler/test/inference.jl index 7eba4b683463c..fb17f1991dc45 100644 --- a/Compiler/test/inference.jl +++ b/Compiler/test/inference.jl @@ -2310,12 +2310,6 @@ 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 @@ -2590,6 +2584,19 @@ end |> only === Compiler.InterMustAlias return 0 end == Integer +# `isdefined` accuracy for `MustAlias` +@test Base.infer_return_type((Any,); interp=MustAliasInterpreter()) do x + xx = Ref{Any}(x) + xxx = Some{Any}(xx) + Val(isdefined(xxx.value, :x)) +end == Val{true} + +@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 + function f25579(g) h = g[] t = (h === nothing) diff --git a/Compiler/test/invalidation.jl b/Compiler/test/invalidation.jl index 32f462f06f4e9..0135009673aef 100644 --- a/Compiler/test/invalidation.jl +++ b/Compiler/test/invalidation.jl @@ -161,6 +161,42 @@ begin @test "42" == String(take!(GLOBAL_BUFFER)) end +begin + deduped_callee(x::Int) = @noinline rand(Int) + deduped_caller1(x::Int) = @noinline deduped_callee(x) + deduped_caller2(x::Int) = @noinline deduped_callee(x) + + # run inference on both `deduped_callerx` and `deduped_callee` + let (src, rt) = code_typed((Int,); interp=InvalidationTester()) do x + @inline deduped_caller1(x) + @inline deduped_caller2(x) + end |> only + @test rt === Int + @test any(isinvoke(:deduped_callee), src.code) + end + + # Verify that adding the backedge again does not actually add a new backedge + let mi = Base.method_instance(deduped_caller1, (Int,)), + ci = mi.cache + + callee_mi = Base.method_instance(deduped_callee, (Int,)) + + # Inference should have added the callers to the callee's backedges + @test ci in callee_mi.backedges + + # In practice, inference will never end up calling `store_backedges` + # twice on the same CodeInstance like this - we only need to check + # that de-duplication works for a single invocation + N = length(callee_mi.backedges) + Core.Compiler.store_backedges(ci, Core.svec(callee_mi, callee_mi)) + N′ = length(callee_mi.backedges) + + # A single `store_backedges` invocation should de-duplicate any of the + # edges it is adding. + @test N′ - N == 1 + end +end + # we can avoid adding backedge even if the callee's return type is not the top # when the return value is not used within the caller begin take!(GLOBAL_BUFFER) diff --git a/Compiler/test/ssair.jl b/Compiler/test/ssair.jl index 3026202466599..80faac97d83a4 100644 --- a/Compiler/test/ssair.jl +++ b/Compiler/test/ssair.jl @@ -818,3 +818,23 @@ let cl = Int32[32, 1, 1, 1000, 240, 230] cl2 = ccall(:jl_uncompress_codelocs, Any, (Any, Int), str, 2) @test cl == cl2 end + +#57153 check that the CFG has a #0 block predecessor and that we don't fail to compile code that observes that +function _worker_task57153() + while true + r = let + try + if @noinline rand(Bool) + return nothing + end + q, m + finally + missing + end + end + r[1]::Bool + end +end +let ir = Base.code_ircode(_worker_task57153, (), optimize_until="CC: COMPACT_2")[1].first + @test findfirst(x->x==0, ir.cfg.blocks[1].preds) !== nothing +end diff --git a/Compiler/test/verifytrim.jl b/Compiler/test/verifytrim.jl index e7d57571b1db0..a84afd6933266 100644 --- a/Compiler/test/verifytrim.jl +++ b/Compiler/test/verifytrim.jl @@ -36,24 +36,27 @@ let infos = typeinf_ext_toplevel(Any[Core.svec(Nothing, Tuple{typeof(finalizer), \[1\] finalizer\(f::Any, o::Any\)""", repr) end +# test that basic `cfunction` generation is allowed, when the dispatch target can be resolved make_cfunction() = @cfunction(+, Float64, (Int64,Int64)) +let infos = typeinf_ext_toplevel(Any[Core.svec(Ptr{Cvoid}, Tuple{typeof(make_cfunction)})], [Base.get_world_counter()], TRIM_UNSAFE) + errors, parents = get_verify_typeinf_trim(infos) + @test isempty(errors) +end # use TRIM_UNSAFE to bypass verifier inside typeinf_ext_toplevel -let infos = typeinf_ext_toplevel(Any[Core.svec(Ptr{Cvoid}, Tuple{typeof(make_cfunction)})], [Base.get_world_counter()], TRIM_UNSAFE) +make_cfunction_bad(@nospecialize(f::Any)) = @cfunction($f, Float64, (Int64,Int64))::Base.CFunction +let infos = typeinf_ext_toplevel(Any[Core.svec(Base.CFunction, Tuple{typeof(make_cfunction_bad), Any})], [Base.get_world_counter()], TRIM_UNSAFE) errors, parents = get_verify_typeinf_trim(infos) - @test_broken isempty(errors) # missing cfunction + @test !isempty(errors) # missing cfunction - desc = only(errors) - @test desc.first - desc = desc.second + (is_warning, desc) = only(errors) + @test !is_warning @test desc isa CallMissing @test occursin("cfunction", desc.desc) repr = sprint(verify_print_error, desc, parents) - @test occursin( - r"""^unresolved cfunction from statement \$\(Expr\(:cfunction, Ptr{Nothing}, :\(\$\(QuoteNode\(\+\)\)\), Float64, :\(svec\(Int64, Int64\)::Core.SimpleVector\), :\(:ccall\)\)\)::Ptr{Nothing} + @test occursin(r"""^unresolved cfunction from statement \$\(Expr\(:cfunction, Base.CFunction, :\(f::Any\), Float64, :\(svec\(Int64, Int64\)::Core.SimpleVector\), :\(:ccall\)\)\)::Base.CFunction Stacktrace: - \[1\] make_cfunction\(\)""", repr) - + \[1\] make_cfunction_bad\(f::Any\)""", repr) resize!(infos, 1) @test infos[1] isa Core.SimpleVector && infos[1][1] isa Type && infos[1][2] isa Type errors, parents = get_verify_typeinf_trim(infos) @@ -61,11 +64,11 @@ let infos = typeinf_ext_toplevel(Any[Core.svec(Ptr{Cvoid}, Tuple{typeof(make_cfu @test !desc.first desc = desc.second @test desc isa CCallableMissing - @test desc.rt == Ptr{Cvoid} - @test desc.sig == Tuple{typeof(make_cfunction)} + @test desc.rt == Base.CFunction + @test desc.sig == Tuple{typeof(make_cfunction_bad), Any} @test occursin("unresolved ccallable", desc.desc) repr = sprint(verify_print_error, desc, parents) - @test repr == "unresolved ccallable for Tuple{$(typeof(make_cfunction))} => Ptr{Nothing}\n\n" + @test repr == "unresolved ccallable for Tuple{$(typeof(make_cfunction_bad)), Any} => Base.CFunction\n\n" end let infos = typeinf_ext_toplevel(Any[Core.svec(Base.SecretBuffer, Tuple{Type{Base.SecretBuffer}})], [Base.get_world_counter()], TRIM_UNSAFE) diff --git a/Makefile b/Makefile index 3a529177b62de..9a75c65673be8 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ julia-deps: | $(DIRS) $(build_datarootdir)/julia/base $(build_datarootdir)/julia julia-stdlib: | $(DIRS) julia-deps @$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT)/stdlib -julia-base: julia-deps $(build_sysconfdir)/julia/startup.jl $(build_man1dir)/julia.1 $(build_datarootdir)/julia/julia-config.jl $(build_datarootdir)/julia/juliac.jl $(build_datarootdir)/julia/juliac-buildscript.jl +julia-base: julia-deps $(build_sysconfdir)/julia/startup.jl $(build_man1dir)/julia.1 $(build_datarootdir)/julia/julia-config.jl $(build_datarootdir)/julia/juliac/juliac.jl $(build_datarootdir)/julia/juliac/juliac-buildscript.jl $(build_datarootdir)/julia/juliac/juliac-trim-base.jl $(build_datarootdir)/julia/juliac/juliac-trim-stdlib.jl @$(MAKE) $(QUIET_MAKE) -C $(BUILDROOT)/base julia-libccalltest: julia-deps @@ -190,6 +190,7 @@ $(build_sysconfdir)/julia/startup.jl: $(JULIAHOME)/etc/startup.jl | $(build_sysc @cp $< $@ $(build_datarootdir)/julia/%: $(JULIAHOME)/contrib/% | $(build_datarootdir)/julia + mkdir -p $(dir $@) $(INSTALL_M) $< $(dir $@) $(build_depsbindir)/stringreplace: $(JULIAHOME)/contrib/stringreplace.c | $(build_depsbindir) diff --git a/NEWS.md b/NEWS.md index f2e667378e5a0..94957fa86f5bb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -36,9 +36,10 @@ Language changes * Julia now defaults to 1 "interactive" thread, in addition to the 1 default "worker" thread. i.e. `-t1,1`. This means in default configuration the main task and repl (when in interactive mode), which both run on thread 1, now run within the `interactive` threadpool. The libuv IO loop also runs on thread 1, - helping efficient utilization of the worker threadpool used by `Threads.@spawn`. Pass `0` to disable the - interactive thread i.e. `-t1,0` or `JULIA_NUM_THREADS=1,0`, or `-tauto,0` etc. The zero is explicitly - required to disable it, `-t2` will set the equivalent of `-t2,1` ([#57087]). + helping efficient utilization of the worker threadpool used by `Threads.@spawn`. Asking for specifically 1 thread + (`-t1`/`JULIA_NUM_THREADS=1`) or passing `0` will disable the interactive thread i.e. `-t1,0` or `JULIA_NUM_THREADS=1,0` + , or `-tauto,0` etc. Asking for more than 1 thread will enable the interactive thread so + `-t2` will set the equivalent of `-t2,1` ([#57087]). * When a method is replaced with an exactly equivalent one, the old method is not deleted. Instead, the new method takes priority and becomes more specific than the old method. Thus if the new method is deleted later, the old method will resume operating. This can be useful in mocking frameworks (as in SparseArrays, @@ -134,6 +135,8 @@ New library features * `Timer` now has readable `timeout` and `interval` properties, and a more descriptive `show` method ([#57081]). * `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]). +* `setprecision` with a function argument (typically a `do` block) is now thread safe. Other forms + should be avoided, and types should switch to an implementation using `ScopedValue` ([#51362]). Standard library changes ------------------------ @@ -225,8 +228,10 @@ Tooling Improvements [#40989]: https://github.com/JuliaLang/julia/issues/40989 [#45793]: https://github.com/JuliaLang/julia/issues/45793 [#49355]: https://github.com/JuliaLang/julia/issues/49355 +[#49933]: https://github.com/JuliaLang/julia/issues/49933 [#50988]: https://github.com/JuliaLang/julia/issues/50988 [#51149]: https://github.com/JuliaLang/julia/issues/51149 +[#51362]: https://github.com/JuliaLang/julia/issues/51362 [#51810]: https://github.com/JuliaLang/julia/issues/51810 [#52103]: https://github.com/JuliaLang/julia/issues/52103 [#52999]: https://github.com/JuliaLang/julia/issues/52999 @@ -284,3 +289,4 @@ Tooling Improvements [#57087]: https://github.com/JuliaLang/julia/issues/57087 [#57109]: https://github.com/JuliaLang/julia/issues/57109 [#57253]: https://github.com/JuliaLang/julia/issues/57253 +[#57727]: https://github.com/JuliaLang/julia/issues/57727 diff --git a/base/Base_compiler.jl b/base/Base_compiler.jl index 16633ba01a17b..6eb4bf4f1a68b 100644 --- a/base/Base_compiler.jl +++ b/base/Base_compiler.jl @@ -215,7 +215,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke), f, T, args...) return invoke(Core.kwcall, T, kwargs, f, args...) end # invoke does not have its own call cache, but kwcall for invoke does -setfield!(typeof(invoke).name.mt, :max_args, 3, :monotonic) # invoke, f, T, args... +setfield!(typeof(invoke).name, :max_args, Int32(3), :monotonic) # invoke, f, T, args... # define applicable(f, T, args...; kwargs...), without kwargs wrapping # to forward to applicable @@ -249,7 +249,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invokelatest), f, args...) @inline return Core.invokelatest(Core.kwcall, kwargs, f, args...) end -setfield!(typeof(invokelatest).name.mt, :max_args, 2, :monotonic) # invokelatest, f, args... +setfield!(typeof(invokelatest).name, :max_args, Int32(2), :monotonic) # invokelatest, f, args... """ invoke_in_world(world, f, args...; kwargs...) @@ -283,7 +283,7 @@ function Core.kwcall(kwargs::NamedTuple, ::typeof(invoke_in_world), world::UInt, @inline return Core.invoke_in_world(world, Core.kwcall, kwargs, f, args...) end -setfield!(typeof(invoke_in_world).name.mt, :max_args, 3, :monotonic) # invoke_in_world, world, f, args... +setfield!(typeof(invoke_in_world).name, :max_args, Int32(3), :monotonic) # invoke_in_world, world, f, args... # core operations & types include("promotion.jl") diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 2632592ede7c1..ac49209273adf 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -2553,16 +2553,23 @@ function _typed_hvncat_dims(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as end # discover number of rows or columns + # d1 dimension is increased by 1 to appropriately handle 0-length arrays for i ∈ 1:dims[d1] outdims[d1] += cat_size(as[i], d1) end + # adjustment to handle 0-length arrays + first_dim_zero = outdims[d1] == 0 + if first_dim_zero + outdims[d1] = dims[d1] + end + currentdims = zeros(Int, N) blockcount = 0 elementcount = 0 for i ∈ eachindex(as) elementcount += cat_length(as[i]) - currentdims[d1] += cat_size(as[i], d1) + currentdims[d1] += first_dim_zero ? 1 : cat_size(as[i], d1) if currentdims[d1] == outdims[d1] currentdims[d1] = 0 for d ∈ (d2, 3:N...) @@ -2590,6 +2597,10 @@ function _typed_hvncat_dims(::Type{T}, dims::NTuple{N, Int}, row_first::Bool, as throw(DimensionMismatch("argument $i has too many elements along axis $d1")) end end + # restore 0-length adjustment + if first_dim_zero + outdims[d1] = 0 + end outlen = prod(outdims) elementcount == outlen || diff --git a/base/deprecated.jl b/base/deprecated.jl index eeb7c0e60638e..aba3aa89909b3 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -211,7 +211,7 @@ macro deprecate(old, new, export_old=true) maybe_export, :($(esc(old)) = begin $meta - depwarn($"`$oldcall` is deprecated, use `$newcall` instead.", Core.Typeof($(esc(fnexpr))).name.mt.name) + depwarn($"`$oldcall` is deprecated, use `$newcall` instead.", Core.Typeof($(esc(fnexpr))).name.singletonname) $(esc(new)) end)) else @@ -222,7 +222,7 @@ macro deprecate(old, new, export_old=true) export_old ? Expr(:export, esc(old)) : nothing, :(function $(esc(old))(args...; kwargs...) $meta - depwarn($"`$old` is deprecated, use `$new` instead.", Core.Typeof($(esc(old))).name.mt.name) + depwarn($"`$old` is deprecated, use `$new` instead.", Core.Typeof($(esc(old))).name.singletonname) $(esc(new))(args...; kwargs...) end)) end @@ -557,4 +557,11 @@ true """ isbindingresolved +# Some packages call this function +function to_power_type(x::Number) + T = promote_type(typeof(x), typeof(x*x)) + convert(T, x) +end +to_power_type(x) = oftype(x*x, x) + # END 1.12 deprecations diff --git a/base/docs/bindings.jl b/base/docs/bindings.jl index 5c65a35659f81..5a0e8e01762e2 100644 --- a/base/docs/bindings.jl +++ b/base/docs/bindings.jl @@ -42,6 +42,6 @@ end aliasof(b::Binding) = defined(b) ? (a = aliasof(resolve(b), b); defined(a) ? a : b) : b aliasof(d::DataType, b) = Binding(d.name.module, d.name.name) -aliasof(λ::Function, b) = (m = typeof(λ).name.mt; Binding(m.module, m.name)) +aliasof(λ::Function, b) = (m = typeof(λ).name; Binding(m.module, m.singletonname)) aliasof(m::Module, b) = Binding(m, nameof(m)) aliasof(other, b) = b diff --git a/base/errorshow.jl b/base/errorshow.jl index 6aab526f87c6c..9df363a8c5e9f 100644 --- a/base/errorshow.jl +++ b/base/errorshow.jl @@ -326,7 +326,7 @@ function showerror(io::IO, ex::MethodError) print(io, "\nUse square brackets [] for indexing an Array.") end # Check for local functions that shadow methods in Base - let name = ft.name.mt.name + let name = ft.name.singletonname if f_is_function && isdefined(Base, name) basef = getfield(Base, name) if basef !== f && hasmethod(basef, arg_types) @@ -378,7 +378,7 @@ end function showerror(io::IO, exc::FieldError) @nospecialize - print(io, "FieldError: type $(exc.type |> nameof) has no field `$(exc.field)`") + print(io, "FieldError: type $(exc.type.name.wrapper) has no field `$(exc.field)`") Base.Experimental.show_error_hints(io, exc) end @@ -1117,7 +1117,7 @@ Experimental.register_error_hint(fielderror_dict_hint_handler, FieldError) function fielderror_listfields_hint_handler(io, exc) fields = fieldnames(exc.type) if isempty(fields) - print(io, "; $(nameof(exc.type)) has no fields at all.") + print(io, "; $(exc.type.name.wrapper) has no fields at all.") else print(io, ", available fields: $(join(map(k -> "`$k`", fields), ", "))") end diff --git a/base/essentials.jl b/base/essentials.jl index 5068acf24cbc1..bf48f24f5234c 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -684,7 +684,7 @@ Neither `convert` nor `cconvert` should take a Julia object and turn it into a ` """ function cconvert end -cconvert(T::Type, x) = x isa T ? x : convert(T, x) # do the conversion eagerly in most cases +cconvert(::Type{T}, x) where {T} = x isa T ? x : convert(T, x) # do the conversion eagerly in most cases cconvert(::Type{Union{}}, x...) = convert(Union{}, x...) cconvert(::Type{<:Ptr}, x) = x # but defer the conversion to Ptr to unsafe_convert unsafe_convert(::Type{T}, x::T) where {T} = x # unsafe_convert (like convert) defaults to assuming the convert occurred diff --git a/base/intfuncs.jl b/base/intfuncs.jl index 552a51c33fb12..3f26d2597f9d9 100644 --- a/base/intfuncs.jl +++ b/base/intfuncs.jl @@ -335,11 +335,6 @@ function invmod(n::T) where {T<:BitInteger} end # ^ for any x supporting * -function to_power_type(x::Number) - T = promote_type(typeof(x), typeof(x*x)) - convert(T, x) -end -to_power_type(x) = oftype(x*x, x) @noinline throw_domerr_powbysq(::Any, p) = throw(DomainError(p, LazyString( "Cannot raise an integer x to a negative power ", p, ".", "\nConvert input to float."))) @@ -355,12 +350,23 @@ to_power_type(x) = oftype(x*x, x) "or write float(x)^", p, " or Rational.(x)^", p, "."))) # The * keyword supports `*=checked_mul` for `checked_pow` @assume_effects :terminates_locally function power_by_squaring(x_, p::Integer; mul=*) - x = to_power_type(x_) + x_squared_ = x_ * x_ + x_squared_type = typeof(x_squared_) + T = if x_ isa Number + promote_type(typeof(x_), x_squared_type) + else + x_squared_type + end + x = convert(T, x_) + square_is_useful = mul === * if p == 1 return copy(x) elseif p == 0 return one(x) elseif p == 2 + if square_is_useful # avoid performing the same multiplication a second time when possible + return convert(T, x_squared_) + end return mul(x, x) elseif p < 0 isone(x) && return copy(x) @@ -369,6 +375,11 @@ to_power_type(x) = oftype(x*x, x) end t = trailing_zeros(p) + 1 p >>= t + if square_is_useful # avoid performing the same multiplication a second time when possible + if (t -= 1) > 0 + x = convert(T, x_squared_) + end + end while (t -= 1) > 0 x = mul(x, x) end diff --git a/base/invalidation.jl b/base/invalidation.jl index e974bcd226de8..b55b09e29961d 100644 --- a/base/invalidation.jl +++ b/base/invalidation.jl @@ -15,36 +15,6 @@ function iterate(gri::GlobalRefIterator, 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, 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 foreachgr(visit, src::CodeInfo) stmts = src.code for i = 1:length(stmts) @@ -97,20 +67,28 @@ function invalidate_method_for_globalref!(gr::GlobalRef, method::Method, invalid binding = convert(Core.Binding, gr) if isdefined(method, :source) src = _uncompressed_ir(method) - old_stmts = src.code invalidate_all = should_invalidate_code_for_globalref(gr, src) end + if invalidate_all && !Base.generating_output() + @atomic method.did_scan_source |= 0x4 + end + invalidated_any = false for mi in specializations(method) isdefined(mi, :cache) || continue ci = mi.cache + invalidated = false while true if ci.max_world > new_max_world && (invalidate_all || scan_edge_list(ci, binding)) ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), ci, new_max_world) + invalidated = true end isdefined(ci, :next) || break ci = ci.next end + invalidated && ccall(:jl_maybe_log_binding_invalidation, Cvoid, (Any,), mi) + invalidated_any |= invalidated end + return invalidated_any end export_affecting_partition_flags(bpart::Core.BindingPartition) = @@ -134,30 +112,33 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core need_to_invalidate_export = export_affecting_partition_flags(invalidated_bpart) !== export_affecting_partition_flags(new_bpart) + invalidated_any = false + queued_bindings = Tuple{Core.Binding, Core.BindingPartition, Core.BindingPartition}[] # defer handling these to keep the logging coherent if need_to_invalidate_code if (b.flags & BINDING_FLAG_ANY_IMPLICIT_EDGES) != 0 nmethods = ccall(:jl_module_scanned_methods_length, Csize_t, (Any,), gr.mod) for i = 1:nmethods method = ccall(:jl_module_scanned_methods_getindex, Any, (Any, Csize_t), gr.mod, i)::Method - invalidate_method_for_globalref!(gr, method, invalidated_bpart, new_max_world) + invalidated_any |= invalidate_method_for_globalref!(gr, method, invalidated_bpart, new_max_world) end end - if isdefined(b, :backedges) - for edge in b.backedges - if isa(edge, CodeInstance) - ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), edge, new_max_world) - elseif isa(edge, Core.Binding) - isdefined(edge, :partitions) || continue - latest_bpart = edge.partitions - latest_bpart.max_world == typemax(UInt) || continue - is_some_imported(binding_kind(latest_bpart)) || continue - if is_some_binding_imported(binding_kind(latest_bpart)) - partition_restriction(latest_bpart) === b || continue - end - invalidate_code_for_globalref!(edge, latest_bpart, latest_bpart, new_max_world) - else - invalidate_method_for_globalref!(gr, edge::Method, invalidated_bpart, new_max_world) + nbackedges = ccall(:jl_binding_backedges_length, Csize_t, (Any,), b) + for i = 1:nbackedges + edge = ccall(:jl_binding_backedges_getindex, Any, (Any, Csize_t), b, i) + if isa(edge, CodeInstance) + ccall(:jl_invalidate_code_instance, Cvoid, (Any, UInt), edge, new_max_world) + invalidated_any = true + elseif isa(edge, Core.Binding) + isdefined(edge, :partitions) || continue + latest_bpart = edge.partitions + latest_bpart.max_world == typemax(UInt) || continue + is_some_imported(binding_kind(latest_bpart)) || continue + if is_some_binding_imported(binding_kind(latest_bpart)) + partition_restriction(latest_bpart) === b || continue end + push!(queued_bindings, (edge, latest_bpart, latest_bpart)) + else + invalidated_any |= invalidate_method_for_globalref!(gr, edge::Method, invalidated_bpart, new_max_world) end end end @@ -168,7 +149,7 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core usings_backedges = ccall(:jl_get_module_usings_backedges, Any, (Any,), gr.mod) if usings_backedges !== nothing for user::Module in usings_backedges::Vector{Any} - user_binding = ccall(:jl_get_module_binding_or_nothing, Any, (Any, Any), user, gr.name) + user_binding = ccall(:jl_get_module_binding_or_nothing, Any, (Any, Any), user, gr.name)::Union{Core.Binding, Nothing} user_binding === nothing && continue isdefined(user_binding, :partitions) || continue latest_bpart = user_binding.partitions @@ -178,11 +159,16 @@ function invalidate_code_for_globalref!(b::Core.Binding, invalidated_bpart::Core ccall(:jl_maybe_reresolve_implicit, Any, (Any, Csize_t), user_binding, new_max_world) : latest_bpart if need_to_invalidate_code || new_bpart !== latest_bpart - invalidate_code_for_globalref!(convert(Core.Binding, user_binding), latest_bpart, new_bpart, new_max_world) + push!(queued_bindings, (convert(Core.Binding, user_binding), latest_bpart, new_bpart)) end end end end + invalidated_any && ccall(:jl_maybe_log_binding_invalidation, Cvoid, (Any,), invalidated_bpart) + for (edge, invalidated_bpart, new_bpart) in queued_bindings + invalidated_any |= invalidate_code_for_globalref!(edge, invalidated_bpart, new_bpart, new_max_world) + end + return invalidated_any end invalidate_code_for_globalref!(gr::GlobalRef, invalidated_bpart::Core.BindingPartition, new_bpart::Core.BindingPartition, new_max_world::UInt) = invalidate_code_for_globalref!(convert(Core.Binding, gr), invalidated_bpart, new_bpart, new_max_world) @@ -199,7 +185,7 @@ function binding_was_invalidated(b::Core.Binding) b.partitions.min_world > unsafe_load(cglobal(:jl_require_world, UInt)) end -function scan_new_method!(methods_with_invalidated_source::IdSet{Method}, method::Method, image_backedges_only::Bool) +function scan_new_method!(method::Method, image_backedges_only::Bool) isdefined(method, :source) || return if image_backedges_only && !has_image_globalref(method) return @@ -212,21 +198,20 @@ function scan_new_method!(methods_with_invalidated_source::IdSet{Method}, method # TODO: We could turn this into an addition if condition. For now, use it as a reasonably cheap # additional consistency chekc @assert !image_backedges_only - push!(methods_with_invalidated_source, method) + @atomic method.did_scan_source |= 0x4 end maybe_add_binding_backedge!(b, method) end + @atomic method.did_scan_source |= 0x1 end -function scan_new_methods(extext_methods::Vector{Any}, internal_methods::Vector{Any}, image_backedges_only::Bool) - methods_with_invalidated_source = IdSet{Method}() +function scan_new_methods!(extext_methods::Vector{Any}, internal_methods::Vector{Any}, image_backedges_only::Bool) for method in internal_methods if isa(method, Method) - scan_new_method!(methods_with_invalidated_source, method, image_backedges_only) + scan_new_method!(method, image_backedges_only) end end for tme::Core.TypeMapEntry in extext_methods - scan_new_method!(methods_with_invalidated_source, tme.func::Method, image_backedges_only) + scan_new_method!(tme.func::Method, image_backedges_only) end - return methods_with_invalidated_source end diff --git a/base/iobuffer.jl b/base/iobuffer.jl index d121082f3585d..ca2757201aae8 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -771,7 +771,7 @@ function take!(io::IOBuffer) elseif io.writable data = wrap(Array, memoryref(io.data, io.ptr), nbytes) else - data = read!(io, data) + error("Unreachable IOBuffer state") end end if io.writable diff --git a/base/libuv.jl b/base/libuv.jl index 35b1a9097293e..5e9bdfaf1e75c 100644 --- a/base/libuv.jl +++ b/base/libuv.jl @@ -39,8 +39,15 @@ macro handle_as(hand, typ) end end -associate_julia_struct(handle::Ptr{Cvoid}, @nospecialize(jlobj)) = +function _uv_hook_close end + +function associate_julia_struct(handle::Ptr{Cvoid}, jlobj::T) where T + # This `cfunction` is not used anywhere, but it triggers compilation of this + # MethodInstance for `--trim` so that it will be available when dispatched to + # by `jl_uv_call_close_callback()` + _ = @cfunction(Base._uv_hook_close, Cvoid, (Ref{T},)) ccall(:jl_uv_associate_julia_struct, Cvoid, (Ptr{Cvoid}, Any), handle, jlobj) +end disassociate_julia_struct(uv) = disassociate_julia_struct(uv.handle) disassociate_julia_struct(handle::Ptr{Cvoid}) = handle != C_NULL && ccall(:jl_uv_disassociate_julia_struct, Cvoid, (Ptr{Cvoid},), handle) @@ -52,14 +59,14 @@ iolock_end() = ccall(:jl_iolock_end, Cvoid, ()) # and should thus not be garbage collected const uvhandles = IdDict() const preserve_handle_lock = Threads.SpinLock() -function preserve_handle(x) +@nospecializeinfer function preserve_handle(@nospecialize(x)) lock(preserve_handle_lock) v = get(uvhandles, x, 0)::Int uvhandles[x] = v + 1 unlock(preserve_handle_lock) nothing end -function unpreserve_handle(x) +@nospecializeinfer function unpreserve_handle(@nospecialize(x)) lock(preserve_handle_lock) v = get(uvhandles, x, 0)::Int if v == 0 diff --git a/base/loading.jl b/base/loading.jl index 49179fa73447d..de212f79e93b7 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -2213,7 +2213,7 @@ const include_callbacks = Any[] # used to optionally track dependencies when requiring a module: const _concrete_dependencies = Pair{PkgId,UInt128}[] # these dependency versions are "set in stone", because they are explicitly loaded, and the process should try to avoid invalidating them -const _require_dependencies = Any[] # a list of (mod, abspath, fsize, hash, mtime) tuples that are the file dependencies of the module currently being precompiled +const _require_dependencies = Any[] # a list of (mod::Module, abspath::String, fsize::UInt64, hash::UInt32, mtime::Float64) tuples that are the file dependencies of the module currently being precompiled const _track_dependencies = Ref(false) # set this to true to track the list of file dependencies function _include_dependency(mod::Module, _path::AbstractString; track_content::Bool=true, @@ -2239,9 +2239,9 @@ function _include_dependency!(dep_list::Vector{Any}, track_dependencies::Bool, else @lock require_lock begin if track_content - hash = isdir(path) ? _crc32c(join(readdir(path))) : open(_crc32c, path, "r") + hash = (isdir(path) ? _crc32c(join(readdir(path))) : open(_crc32c, path, "r"))::UInt32 # use mtime=-1.0 here so that fsize==0 && mtime==0.0 corresponds to a missing include_dependency - push!(dep_list, (mod, path, filesize(path), hash, -1.0)) + push!(dep_list, (mod, path, UInt64(filesize(path)), hash, -1.0)) else push!(dep_list, (mod, path, UInt64(0), UInt32(0), mtime(path))) end @@ -3337,7 +3337,7 @@ mutable struct CacheHeaderIncludes const modpath::Vector{String} # seemingly not needed in Base, but used by Revise end -function CacheHeaderIncludes(dep_tuple::Tuple{Module, String, Int64, UInt32, Float64}) +function CacheHeaderIncludes(dep_tuple::Tuple{Module, String, UInt64, UInt32, Float64}) return CacheHeaderIncludes(PkgId(dep_tuple[1]), dep_tuple[2:end]..., String[]) end diff --git a/base/lock.jl b/base/lock.jl index 79e0ba264df15..2da4d47c3734b 100644 --- a/base/lock.jl +++ b/base/lock.jl @@ -674,6 +674,9 @@ calls in the same process will return exactly the same value. This is useful in code that will be precompiled, as it allows setting up caches or other state which won't get serialized. +!!! compat "Julia 1.12" + This type requires Julia 1.12 or later. + ## Example ```jldoctest @@ -784,6 +787,9 @@ if that behavior is correct within your library's threading-safety design. See also: [`OncePerTask`](@ref). +!!! compat "Julia 1.12" + This type requires Julia 1.12 or later. + ## Example ```jldoctest @@ -912,6 +918,9 @@ exactly once per Task. All future calls in the same Task will return exactly the See also: [`task_local_storage`](@ref). +!!! compat "Julia 1.12" + This type requires Julia 1.12 or later. + ## Example ```jldoctest diff --git a/base/logging/logging.jl b/base/logging/logging.jl index c4a3d21fed982..c44e74ffa627b 100644 --- a/base/logging/logging.jl +++ b/base/logging/logging.jl @@ -411,9 +411,13 @@ function logmsg_code(_module, file, line, level, message, exs...) end line = $(log_data._line) local msg, kwargs - $(logrecord) && $handle_message_nothrow( - logger, level, msg, _module, group, id, file, line; - kwargs...) + if $(logrecord) + @assert @isdefined(msg) "Assertion to tell the compiler about the definedness of this variable" + @assert @isdefined(kwargs) "Assertion to tell the compiler about the definedness of this variable" + $handle_message_nothrow( + logger, level, msg, _module, group, id, file, line; + kwargs...) + end end end end diff --git a/base/methodshow.jl b/base/methodshow.jl index 7fdefc9b7311f..dd391a46d170a 100644 --- a/base/methodshow.jl +++ b/base/methodshow.jl @@ -81,7 +81,7 @@ function kwarg_decl(m::Method, kwtype = nothing) if m.sig !== Tuple # OpaqueClosure or Builtin kwtype = typeof(Core.kwcall) sig = rewrap_unionall(Tuple{kwtype, NamedTuple, (unwrap_unionall(m.sig)::DataType).parameters...}, m.sig) - kwli = ccall(:jl_methtable_lookup, Any, (Any, Any, UInt), kwtype.name.mt, sig, get_world_counter()) + kwli = ccall(:jl_methtable_lookup, Any, (Any, UInt), sig, get_world_counter()) if kwli !== nothing kwli = kwli::Method slotnames = ccall(:jl_uncompress_argnames, Vector{Symbol}, (Any,), kwli.slot_syms) @@ -259,10 +259,10 @@ function show_method(io::IO, m::Method; modulecolor = :light_black, digit_align_ end function show_method_list_header(io::IO, ms::MethodList, namefmt::Function) - mt = ms.mt - name = mt.name - hasname = isdefined(mt.module, name) && - typeof(getfield(mt.module, name)) <: Function + tn = ms.tn + name = tn.singletonname + hasname = isdefined(tn.module, name) && + typeof(getfield(tn.module, name)) <: Function n = length(ms) m = n==1 ? "method" : "methods" print(io, "# $n $m") @@ -271,18 +271,18 @@ function show_method_list_header(io::IO, ms::MethodList, namefmt::Function) if hasname what = (startswith(sname, '@') ? "macro" - : mt.module === Core && mt.defs isa Core.TypeMapEntry && (mt.defs.func::Method).sig === Tuple ? + : tn.module === Core && tn.wrapper <: Core.Builtin ? "builtin function" : # else "generic function") print(io, " for ", what, " ", namedisplay, " from ") - col = get!(() -> popfirst!(STACKTRACE_MODULECOLORS), STACKTRACE_FIXEDCOLORS, parentmodule_before_main(ms.mt.module)) + col = get!(() -> popfirst!(STACKTRACE_MODULECOLORS), STACKTRACE_FIXEDCOLORS, parentmodule_before_main(tn.module)) - printstyled(io, ms.mt.module, color=col) + printstyled(io, tn.module, color=col) elseif '#' in sname print(io, " for anonymous function ", namedisplay) - elseif mt === _TYPE_NAME.mt + elseif tn === _TYPE_NAME || iskindtype(tn.wrapper) print(io, " for type constructor") else print(io, " for callable object") @@ -293,6 +293,8 @@ end # Determine the `modulecolor` value to pass to `show_method` function _modulecolor(method::Method) mmt = get_methodtable(method) + # TODO: this looks like a buggy bit of internal hacking, so disable for now + return nothing if mmt === nothing || mmt.module === parentmodule(method) return nothing end @@ -314,10 +316,10 @@ function _modulecolor(method::Method) end function show_method_table(io::IO, ms::MethodList, max::Int=-1, header::Bool=true) - mt = ms.mt - name = mt.name - hasname = isdefined(mt.module, name) && - typeof(getfield(mt.module, name)) <: Function + tn = ms.tn + name = tn.singletonname + hasname = isdefined(tn.module, name) && + typeof(getfield(tn.module, name)) <: Function if header show_method_list_header(io, ms, str -> "\""*str*"\"") end @@ -363,7 +365,7 @@ end show(io::IO, ms::MethodList) = show_method_table(io, ms) show(io::IO, ::MIME"text/plain", ms::MethodList) = show_method_table(io, ms) -show(io::IO, mt::Core.MethodTable) = show_method_table(io, MethodList(mt)) +show(io::IO, mt::Core.MethodTable) = print(io, mt.module, ".", mt.name, " is a Core.MethodTable with ", length(mt), " methods.") function inbase(m::Module) if m == Base @@ -458,7 +460,6 @@ function show(io::IO, ::MIME"text/html", m::Method) end function show(io::IO, mime::MIME"text/html", ms::MethodList) - mt = ms.mt show_method_list_header(io, ms, str -> ""*str*"") print(io, "") end -show(io::IO, mime::MIME"text/html", mt::Core.MethodTable) = show(io, mime, MethodList(mt)) - # pretty-printing of AbstractVector{Method} function show(io::IO, mime::MIME"text/plain", mt::AbstractVector{Method}) last_shown_line_infos = get(io, :last_shown_line_infos, nothing) diff --git a/base/mpfr.jl b/base/mpfr.jl index 0d52510447b2f..2175fb56cc526 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -1178,9 +1178,29 @@ Often used as `setprecision(T, precision) do ... end` Note: `nextfloat()`, `prevfloat()` do not use the precision mentioned by `setprecision`. +!!! warning + There is a fallback implementation of this method that calls `precision` + and `setprecision`, but it should no longer be relied on. Instead, you + should define the 3-argument form directly in a way that uses `ScopedValue`, + or recommend that callers use `ScopedValue` and `@with` themselves. + !!! compat "Julia 1.8" The `base` keyword requires at least Julia 1.8. """ +function setprecision(f::Function, ::Type{T}, prec::Integer; kws...) where T + depwarn(""" + The fallback `setprecision(::Function, ...)` method is deprecated. Packages overloading this method should + implement their own specialization using `ScopedValue` instead. + """, :setprecision) + old_prec = precision(T) + setprecision(T, prec; kws...) + try + return f() + finally + setprecision(T, old_prec) + end +end + function setprecision(f::Function, ::Type{BigFloat}, prec::Integer; base::Integer=2) Base.ScopedValues.@with(CURRENT_PRECISION => _convert_precision_from_base(prec, base), f()) end diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 40fff7243cd55..ee0cf9690b469 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -446,12 +446,12 @@ module IteratorsMD end @inline function __inc(state::Tuple{Int,Int,Vararg{Int}}, indices::Tuple{OrdinalRangeInt,OrdinalRangeInt,Vararg{OrdinalRangeInt}}) rng = indices[1] - I = state[1] + step(rng) if state[1] != last(rng) + I = state[1] + step(rng) return true, (I, tail(state)...) end - valid, I = __inc(tail(state), tail(indices)) - return valid, (first(rng), I...) + valid, Itail = __inc(tail(state), tail(indices)) + return valid, (first(rng), Itail...) end # 0-d cartesian ranges are special-cased to iterate once and only once diff --git a/base/operators.jl b/base/operators.jl index d01902e302359..f7c431a234e13 100644 --- a/base/operators.jl +++ b/base/operators.jl @@ -632,7 +632,7 @@ function afoldl(op, a, bs...) end return y end -setfield!(typeof(afoldl).name.mt, :max_args, 34, :monotonic) +setfield!(typeof(afoldl).name, :max_args, Int32(34), :monotonic) for op in (:+, :*, :&, :|, :xor, :min, :max, :kron) @eval begin diff --git a/base/partr.jl b/base/partr.jl index 6053a584af5ba..d488330f0c87e 100644 --- a/base/partr.jl +++ b/base/partr.jl @@ -107,7 +107,6 @@ function multiq_sift_down(heap::taskheap, idx::Int32) end end - function multiq_size(tpid::Int8) nt = UInt32(Threads._nthreads_in_pool(tpid)) tp = tpid + 1 @@ -138,7 +137,6 @@ function multiq_size(tpid::Int8) return heap_p end - function multiq_insert(task::Task, priority::UInt16) tpid = ccall(:jl_get_task_threadpoolid, Int8, (Any,), task) @assert tpid > -1 @@ -171,10 +169,8 @@ function multiq_insert(task::Task, priority::UInt16) return true end - function multiq_deletemin() - local rn1, rn2 - local prio1, prio2 + local rn1::UInt32 tid = Threads.threadid() tp = ccall(:jl_threadpoolid, Int8, (Int16,), tid-1) + 1 @@ -208,6 +204,8 @@ function multiq_deletemin() end end + @assert @isdefined(rn1) "Assertion to tell the compiler about the definedness of this variable" + heap = tpheaps[rn1] task = heap.tasks[1] if ccall(:jl_set_task_tid, Cint, (Any, Cint), task, tid-1) == 0 diff --git a/base/precompilation.jl b/base/precompilation.jl index c24026aa2a8ef..c51297ee2a791 100644 --- a/base/precompilation.jl +++ b/base/precompilation.jl @@ -355,7 +355,7 @@ Base.show(io::IO, err::PkgPrecompileError) = print(io, "PkgPrecompileError: ", e import Base: StaleCacheKey -can_fancyprint(io::IO) = io isa Base.TTY && (get(ENV, "CI", nothing) != "true") +can_fancyprint(io::IO) = @something(get(io, :force_fancyprint, nothing), (io isa Base.TTY && (get(ENV, "CI", nothing) != "true"))) function printpkgstyle(io, header, msg; color=:green) printstyled(io, header; color, bold=true) diff --git a/base/reduce.jl b/base/reduce.jl index 60bff3acb52ed..2a6a268f2e6c1 100644 --- a/base/reduce.jl +++ b/base/reduce.jl @@ -609,63 +609,6 @@ julia> prod(1:5; init = 1.0) prod(a; kw...) = mapreduce(identity, mul_prod, a; kw...) ## maximum, minimum, & extrema -_fast(::typeof(min),x,y) = min(x,y) -_fast(::typeof(max),x,y) = max(x,y) -function _fast(::typeof(max), x::AbstractFloat, y::AbstractFloat) - ifelse(isnan(x), - x, - ifelse(x > y, x, y)) -end - -function _fast(::typeof(min),x::AbstractFloat, y::AbstractFloat) - ifelse(isnan(x), - x, - ifelse(x < y, x, y)) -end - -isbadzero(::typeof(max), x::AbstractFloat) = (x == zero(x)) & signbit(x) -isbadzero(::typeof(min), x::AbstractFloat) = (x == zero(x)) & !signbit(x) -isbadzero(op, x) = false -isgoodzero(::typeof(max), x) = isbadzero(min, x) -isgoodzero(::typeof(min), x) = isbadzero(max, x) - -function mapreduce_impl(f, op::Union{typeof(max), typeof(min)}, - A::AbstractArrayOrBroadcasted, first::Int, last::Int) - a1 = @inbounds A[first] - v1 = mapreduce_first(f, op, a1) - v2 = v3 = v4 = v1 - chunk_len = 256 - start = first + 1 - simdstop = start + chunk_len - 4 - while simdstop <= last - 3 - for i in start:4:simdstop - v1 = _fast(op, v1, f(@inbounds(A[i+0]))) - v2 = _fast(op, v2, f(@inbounds(A[i+1]))) - v3 = _fast(op, v3, f(@inbounds(A[i+2]))) - v4 = _fast(op, v4, f(@inbounds(A[i+3]))) - end - checkbounds(A, simdstop+3) - start += chunk_len - simdstop += chunk_len - end - v = op(op(v1,v2),op(v3,v4)) - for i in start:last - @inbounds ai = A[i] - v = op(v, f(ai)) - end - - # enforce correct order of 0.0 and -0.0 - # e.g. maximum([0.0, -0.0]) === 0.0 - # should hold - if isbadzero(op, v) - for i in first:last - x = @inbounds A[i] - isgoodzero(op,x) && return x - end - end - return v -end - """ maximum(f, itr; [init]) diff --git a/base/reflection.jl b/base/reflection.jl index 51a781002469d..c3766447f87fe 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -933,13 +933,7 @@ this is a compiler-generated name. For explicitly-declared subtypes of `Function`, it is the name of the function's type. """ function nameof(f::Function) - t = typeof(f) - mt = t.name.mt - if mt === Symbol.name.mt - # uses shared method table, so name is not unique to this function type - return nameof(t) - end - return mt.name + return typeof(f).name.singletonname end function nameof(f::Core.IntrinsicFunction) @@ -1275,16 +1269,17 @@ 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...) +getglobalref(gr::GlobalRef, world::UInt) = ccall(:jl_eval_globalref, Any, (Any, UInt), gr, world) -function invokelatest_gr(gr::GlobalRef, @nospecialize args...; kwargs...) +function invokelatest_gr(gr::GlobalRef, args...; kwargs...) @inline kwargs = merge(NamedTuple(), kwargs) + world = get_world_counter() + f = getglobalref(gr, world) if isempty(kwargs) - return invokelatest(apply_gr, gr, args...) + return invoke_in_world(world, f, args...) end - return invokelatest(apply_gr_kw, kwargs, gr, args...) + return invoke_in_world(world, Core.kwcall, kwargs, f, args...) end """ diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 4feb14539f9dc..b88c7b06621d9 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -313,13 +313,13 @@ end _maybe_reshape(::IndexSCartesian2, A::ReshapedReinterpretArray, I...) = A # fallbacks -function _getindex(::IndexSCartesian2, A::AbstractArray{T,N}, I::Vararg{Int, N}) where {T,N} +function _getindex(::IndexSCartesian2, A::AbstractArray, I::Vararg{Int, N}) where {N} @_propagate_inbounds_meta - getindex(A, I...) + _getindex(IndexCartesian(), A, I...) end -function _setindex!(::IndexSCartesian2, A::AbstractArray{T,N}, v, I::Vararg{Int, N}) where {T,N} +function _setindex!(::IndexSCartesian2, A::AbstractArray, v, I::Vararg{Int, N}) where {N} @_propagate_inbounds_meta - setindex!(A, v, I...) + _setindex!(IndexCartesian(), A, v, I...) end # fallbacks for array types that use "pass-through" indexing (e.g., `IndexStyle(A) = IndexStyle(parent(A))`) # but which don't handle SCartesianIndex2 diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index f65a7d8c9561a..97c7a189f138b 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -36,7 +36,7 @@ length(R::ReshapedArrayIterator) = length(R.iter) eltype(::Type{<:ReshapedArrayIterator{I}}) where {I} = @isdefined(I) ? ReshapedIndex{eltype(I)} : Any @noinline throw_dmrsa(dims, len) = - throw(DimensionMismatch("new dimensions $(dims) must be consistent with array length $len")) + throw(DimensionMismatch(LazyString("new dimensions ", dims, " must be consistent with array length ", len))) ## reshape(::Array, ::Dims) returns a new Array (to avoid conditionally aliasing the structure, only the data) # reshaping to same # of dimensions diff --git a/base/runtime_internals.jl b/base/runtime_internals.jl index b6190b3e9044e..f48b4734a7b8b 100644 --- a/base/runtime_internals.jl +++ b/base/runtime_internals.jl @@ -1266,6 +1266,8 @@ Returns the world the [current_task()](@ref) is executing within. """ tls_world_age() = ccall(:jl_get_tls_world_age, UInt, ()) +get_require_world() = unsafe_load(cglobal(:jl_require_world, UInt)) + """ propertynames(x, private=false) @@ -1304,14 +1306,14 @@ hasproperty(x, s::Symbol) = s in propertynames(x) Make method `m` uncallable and force recompilation of any methods that use(d) it. """ function delete_method(m::Method) - ccall(:jl_method_table_disable, Cvoid, (Any, Any), get_methodtable(m), m) + ccall(:jl_method_table_disable, Cvoid, (Any,), m) end # type for reflecting and pretty-printing a subset of methods mutable struct MethodList <: AbstractArray{Method,1} ms::Array{Method,1} - mt::Core.MethodTable + tn::Core.TypeName # contains module.singletonname globalref for altering some aspects of printing end size(m::MethodList) = size(m.ms) @@ -1322,10 +1324,10 @@ function MethodList(mt::Core.MethodTable) visit(mt) do m push!(ms, m) end - return MethodList(ms, mt) + return MethodList(ms, Any.name) end -function matches_to_methods(ms::Array{Any,1}, mt::Core.MethodTable, mod) +function matches_to_methods(ms::Array{Any,1}, tn::Core.TypeName, mod) # Lack of specialization => a comprehension triggers too many invalidations via _collect, so collect the methods manually ms = Method[(ms[i]::Core.MethodMatch).method for i in 1:length(ms)] # Remove shadowed methods with identical type signatures @@ -1340,7 +1342,7 @@ function matches_to_methods(ms::Array{Any,1}, mt::Core.MethodTable, mod) mod === nothing || filter!(ms) do m return parentmodule(m) ∈ mod end - return MethodList(ms, mt) + return MethodList(ms, tn) end """ @@ -1362,7 +1364,7 @@ function methods(@nospecialize(f), @nospecialize(t), world = get_world_counter() world == typemax(UInt) && error("code reflection cannot be used from generated functions") ms = _methods(f, t, -1, world)::Vector{Any} - return matches_to_methods(ms, typeof(f).name.mt, mod) + return matches_to_methods(ms, typeof(f).name, mod) end methods(@nospecialize(f), @nospecialize(t), mod::Module) = methods(f, t, (mod,)) @@ -1373,7 +1375,7 @@ function methods_including_ambiguous(@nospecialize(f), @nospecialize(t)) min = RefValue{UInt}(typemin(UInt)) max = RefValue{UInt}(typemax(UInt)) ms = _methods_by_ftype(tt, nothing, -1, world, true, min, max, Ptr{Int32}(C_NULL))::Vector{Any} - return matches_to_methods(ms, typeof(f).name.mt, nothing) + return matches_to_methods(ms, typeof(f).name, nothing) end function methods(@nospecialize(f), @@ -1562,10 +1564,8 @@ end function get_nospecializeinfer_sig(method::Method, @nospecialize(atype), sparams::SimpleVector) isa(atype, DataType) || return method.sig - mt = ccall(:jl_method_get_table, Any, (Any,), method) - mt === nothing && return method.sig - return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Any, Cint), - mt, atype, sparams, method, #=int return_if_compileable=#0) + return ccall(:jl_normalize_to_compilable_sig, Any, (Any, Any, Any, Cint), + atype, sparams, method, #=int return_if_compileable=#0) end is_nospecialized(method::Method) = method.nospecialize ≠ 0 diff --git a/base/ryu/shortest.jl b/base/ryu/shortest.jl index c1ec648bfacdd..3e2128e5730f3 100644 --- a/base/ryu/shortest.jl +++ b/base/ryu/shortest.jl @@ -196,6 +196,7 @@ integer. If a `maxsignif` argument is provided, then `b < maxsignif`. e10 = 0 if maxsignif !== nothing && b > maxsignif + roundup = false b_allzero = true # reduce to max significant digits while true diff --git a/base/show.jl b/base/show.jl index 3453c29956d59..8fcec0102c19d 100644 --- a/base/show.jl +++ b/base/show.jl @@ -32,16 +32,16 @@ end function _isself(ft::DataType) ftname = ft.name - isdefined(ftname, :mt) || return false - name = ftname.mt.name - mod = parentmodule(ft) # NOTE: not necessarily the same as ft.name.mt.module - return invokelatest(isdefinedglobal, mod, name) && ft == typeof(invokelatest(getglobal, mod, name)) + name = ftname.singletonname + ftname.name === name && return false + mod = parentmodule(ft) + return invokelatest(isdefinedglobal, mod, name) && ft === typeof(invokelatest(getglobal, mod, name)) end function show(io::IO, ::MIME"text/plain", f::Function) get(io, :compact, false)::Bool && return show(io, f) ft = typeof(f) - name = ft.name.mt.name + name = ft.name.singletonname if isa(f, Core.IntrinsicFunction) print(io, f) id = Core.Intrinsics.bitcast(Int32, f) @@ -531,26 +531,24 @@ function active_module() return invokelatest(active_module, active_repl)::Module end -module UsesCoreAndBaseOnly +module UsesBaseOnly end function show_function(io::IO, f::Function, compact::Bool, fallback::Function) - ft = typeof(f) - mt = ft.name.mt - if mt === Symbol.name.mt - # uses shared method table + fname = typeof(f).name + if fname.name === fname.singletonname fallback(io, f) elseif compact - print(io, mt.name) - elseif isdefined(mt, :module) && isdefinedglobal(mt.module, mt.name) && - getglobal(mt.module, mt.name) === f + print(io, fname.singletonname) + elseif isdefined(fname, :module) && isdefinedglobal(fname.module, fname.singletonname) && isconst(fname.module, fname.singletonname) && + getglobal(fname.module, fname.singletonname) === f # this used to call the removed internal function `is_exported_from_stdlib`, which effectively - # just checked for exports from Core and Base. - mod = get(io, :module, UsesCoreAndBaseOnly) - if !(isvisible(mt.name, mt.module, mod) || mt.module === mod) - print(io, mt.module, ".") + # just checked for exports from Base. + mod = get(io, :module, UsesBaseOnly) + if !(isvisible(fname.singletonname, fname.module, mod) || fname.module === mod) + print(io, fname.module, ".") end - show_sym(io, mt.name) + show_sym(io, fname.singletonname) else fallback(io, f) end @@ -820,7 +818,7 @@ function make_typealiases(@nospecialize(x::Type)) Any === x && return aliases, Union{} x <: Tuple && return aliases, Union{} mods = modulesof!(Set{Module}(), x) - Core in mods && push!(mods, Base) + replace!(mods, Core=>Base) vars = Dict{Symbol,TypeVar}() xenv = UnionAll[] each = Any[] @@ -838,7 +836,7 @@ function make_typealiases(@nospecialize(x::Type)) ti === Union{} && continue # make sure this alias wasn't from an unrelated part of the Union mod2 = modulesof!(Set{Module}(), alias) - mod in mod2 || (mod === Base && Core in mods) || continue + mod in mod2 || (mod === Base && Core in mod2) || continue env = env::SimpleVector applied = alias if !isempty(env) @@ -958,7 +956,7 @@ function show(io::IO, ::MIME"text/plain", @nospecialize(x::Type)) # give a helpful hint for function types if x isa DataType && x !== UnionAll && !(get(io, :compact, false)::Bool) tn = x.name::Core.TypeName - globname = isdefined(tn, :mt) ? tn.mt.name : nothing + globname = tn.singletonname if is_global_function(tn, globname) print(io, " (singleton type of function ") show_sym(io, globname) @@ -1041,11 +1039,11 @@ function isvisible(sym::Symbol, parent::Module, from::Module) end function is_global_function(tn::Core.TypeName, globname::Union{Symbol,Nothing}) - if globname !== nothing + if globname !== nothing && isconcretetype(tn.wrapper) && tn !== DataType.name # ignore that typeof(DataType)===DataType, since it is valid but not useful globname_str = string(globname::Symbol) - if ('#' ∉ globname_str && '@' ∉ globname_str && isdefined(tn, :module) && - isdefinedglobal(tn.module, globname) && - isconcretetype(tn.wrapper) && isa(getglobal(tn.module, globname), tn.wrapper)) + if '#' ∉ globname_str && '@' ∉ globname_str && isdefined(tn, :module) && + isdefinedglobal(tn.module, globname) && isconst(tn.module, globname) && + isa(getglobal(tn.module, globname), tn.wrapper) return true end end @@ -1076,7 +1074,7 @@ function show_type_name(io::IO, tn::Core.TypeName) # intercept this case and print `UnionAll` instead. return print(io, "UnionAll") end - globname = isdefined(tn, :mt) ? tn.mt.name : nothing + globname = tn.singletonname globfunc = is_global_function(tn, globname) sym = (globfunc ? globname : tn.name)::Symbol globfunc && print(io, "typeof(") @@ -2553,10 +2551,10 @@ function show_signature_function(io::IO, @nospecialize(ft), demangle=false, farg uw = unwrap_unionall(ft) if ft <: Function && isa(uw, DataType) && isempty(uw.parameters) && _isself(uw) uwmod = parentmodule(uw) - if qualified && !isexported(uwmod, uw.name.mt.name) && uwmod !== Main + if qualified && !isexported(uwmod, uw.name.singletonname) && uwmod !== Main print_within_stacktrace(io, uwmod, '.', bold=true) end - s = sprint(show_sym, (demangle ? demangle_function_name : identity)(uw.name.mt.name), context=io) + s = sprint(show_sym, (demangle ? demangle_function_name : identity)(uw.name.singletonname), context=io) print_within_stacktrace(io, s, bold=true) elseif isType(ft) && (f = ft.parameters[1]; !isa(f, TypeVar)) uwf = unwrap_unionall(f) diff --git a/base/staticdata.jl b/base/staticdata.jl index c9983c72064de..9f7ef67743906 100644 --- a/base/staticdata.jl +++ b/base/staticdata.jl @@ -26,20 +26,20 @@ function insert_backedges(edges::Vector{Any}, ext_ci_list::Union{Nothing,Vector{ # determine which CodeInstance objects are still valid in our image # to enable any applicable new codes backedges_only = unsafe_load(cglobal(:jl_first_image_replacement_world, UInt)) == typemax(UInt) - methods_with_invalidated_source = Base.scan_new_methods(extext_methods, internal_methods, backedges_only) + Base.scan_new_methods!(extext_methods, internal_methods, backedges_only) stack = CodeInstance[] visiting = IdDict{CodeInstance,Int}() - _insert_backedges(edges, stack, visiting, methods_with_invalidated_source) + _insert_backedges(edges, stack, visiting) if ext_ci_list !== nothing - _insert_backedges(ext_ci_list, stack, visiting, methods_with_invalidated_source, #=external=#true) + _insert_backedges(ext_ci_list, stack, visiting, #=external=#true) end end -function _insert_backedges(edges::Vector{Any}, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}, mwis::IdSet{Method}, external::Bool=false) +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 validation_world = get_world_counter() - verify_method_graph(codeinst, stack, visiting, mwis, validation_world) + verify_method_graph(codeinst, stack, visiting, validation_world) # After validation, under the world_counter_lock, set max_world to typemax(UInt) for all dependencies # (recursively). From that point onward the ordinary backedge mechanism is responsible for maintaining # validity. @@ -63,16 +63,14 @@ function _insert_backedges(edges::Vector{Any}, stack::Vector{CodeInstance}, visi end end -function verify_method_graph(codeinst::CodeInstance, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}, mwis::IdSet{Method}, validation_world::UInt) +function verify_method_graph(codeinst::CodeInstance, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}, validation_world::UInt) @assert isempty(stack); @assert isempty(visiting); - child_cycle, minworld, maxworld = verify_method(codeinst, stack, visiting, mwis, validation_world) + child_cycle, minworld, maxworld = verify_method(codeinst, stack, visiting, validation_world) @assert child_cycle == 0 @assert isempty(stack); @assert isempty(visiting); nothing end -get_require_world() = unsafe_load(cglobal(:jl_require_world, UInt)) - function gen_staged_sig(def::Method, mi::MethodInstance) isdefined(def, :generator) || return nothing isdispatchtuple(mi.specTypes) || return nothing @@ -122,7 +120,7 @@ end # - 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}, mwis::IdSet{Method}, validation_world::UInt) +function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visiting::IdDict{CodeInstance,Int}, validation_world::UInt) world = codeinst.min_world let max_valid2 = codeinst.max_world if max_valid2 ≠ WORLD_AGE_REVALIDATION_SENTINEL @@ -136,13 +134,13 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi end # Implicitly referenced bindings in the current module do not get explicit edges. - # If they were invalidated, they'll be in `mwis`. If they weren't, they imply a minworld + # If they were invalidated, they'll have the flag set in did_scan_source. If they weren't, they imply a minworld # of `get_require_world`. In principle, this is only required for methods that do reference # an implicit globalref. However, we already don't perform this validation for methods that # don't have any (implicit or explicit) edges at all. The remaining corner case (some explicit, # but no implicit edges) is rare and there would be little benefit to lower the minworld for it # in any case, so we just always use `get_require_world` here. - local minworld::UInt, maxworld::UInt = get_require_world(), validation_world + local minworld::UInt, maxworld::UInt = Base.get_require_world(), validation_world if haskey(visiting, codeinst) return visiting[codeinst], minworld, maxworld end @@ -152,7 +150,11 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi # TODO JL_TIMING(VERIFY_IMAGE, VERIFY_Methods) callees = codeinst.edges # Check for invalidation of the implicit edges from GlobalRef in the Method source - if def in mwis + if (def.did_scan_source & 0x1) == 0x0 + backedges_only = unsafe_load(cglobal(:jl_first_image_replacement_world, UInt)) == typemax(UInt) + Base.scan_new_method!(def, backedges_only) + end + if (def.did_scan_source & 0x4) != 0x0 maxworld = 0 invalidations = _jl_debug_method_invalidation[] if invalidations !== nothing @@ -162,7 +164,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi # 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 == get_require_world() + elseif maxworld == Base.get_require_world() # if no new worlds were allocated since serializing the base module, then no new validation is worth doing right now either else j = 1 @@ -175,12 +177,15 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi end if edge isa MethodInstance sig = edge.specTypes - min_valid2, max_valid2, matches = verify_call(sig, callees, j, 1, world) + min_valid2, max_valid2, matches = verify_call(sig, callees, j, 1, world, true) 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 + # Handle negative counts (fully_covers=false) + nmatches = abs(edge) + fully_covers = edge > 0 + min_valid2, max_valid2, matches = verify_call(sig, callees, j+2, nmatches, world, fully_covers) + j += 2 + nmatches edge = sig elseif edge isa Core.Binding j += 1 @@ -240,7 +245,7 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi end callee = edge local min_valid2::UInt, max_valid2::UInt - child_cycle, min_valid2, max_valid2 = verify_method(callee, stack, visiting, mwis, validation_world) + child_cycle, min_valid2, max_valid2 = verify_method(callee, stack, visiting, validation_world) if minworld < min_valid2 minworld = min_valid2 end @@ -286,8 +291,9 @@ function verify_method(codeinst::CodeInstance, stack::Vector{CodeInstance}, visi return 0, minworld, maxworld end -function verify_call(@nospecialize(sig), expecteds::Core.SimpleVector, i::Int, n::Int, world::UInt) +function verify_call(@nospecialize(sig), expecteds::Core.SimpleVector, i::Int, n::Int, world::UInt, fully_covers::Bool) # verify that these edges intersect with the same methods as before + mi = nothing if n == 1 # first, fast-path a check if the expected method simply dominates its sig anyways # so the result of ml_matches is already simply known @@ -296,18 +302,30 @@ function verify_call(@nospecialize(sig), expecteds::Core.SimpleVector, i::Int, n meth = t else if t isa CodeInstance - t = get_ci_mi(t) + mi = get_ci_mi(t)::MethodInstance else - t = t::MethodInstance + mi = t::MethodInstance + end + meth = mi.def::Method + # Fast path is legal when fully_covers=true OR when METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC is unset + if (fully_covers || iszero(meth.dispatch_status & METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC)) && + !iszero(mi.dispatch_status & METHOD_SIG_LATEST_ONLY) + minworld = meth.primary_world + @assert minworld ≤ world + maxworld = typemax(UInt) + result = Any[] # result is unused + return minworld, maxworld, result end - meth = t.def::Method end - if !iszero(meth.dispatch_status & METHOD_SIG_LATEST_ONLY) - minworld = meth.primary_world - @assert minworld ≤ world - maxworld = typemax(UInt) - result = Any[] # result is unused - return minworld, maxworld, result + # Fast path is legal when fully_covers=true OR when METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC is unset + if fully_covers || iszero(meth.dispatch_status & METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC) + if !iszero(meth.dispatch_status & METHOD_SIG_LATEST_ONLY) + minworld = meth.primary_world + @assert minworld ≤ world + maxworld = typemax(UInt) + result = Any[] # result is unused + return minworld, maxworld, result + end end end end @@ -334,7 +352,7 @@ function verify_call(@nospecialize(sig), expecteds::Core.SimpleVector, i::Int, n meth = t else if t isa CodeInstance - t = get_ci_mi(t) + t = get_ci_mi(t)::MethodInstance else t = t::MethodInstance end @@ -361,6 +379,9 @@ function verify_call(@nospecialize(sig), expecteds::Core.SimpleVector, i::Int, n resize!(result, ins) end end + if maxworld[] == typemax(UInt) && mi isa MethodInstance + ccall(:jl_promote_mi_to_current, Cvoid, (Any, UInt, UInt), mi, minworld[], world) + end return minworld[], maxworld[], result end @@ -369,6 +390,8 @@ end const METHOD_SIG_LATEST_WHICH = 0x1 # true indicates this method would be returned as the only result from `methods` when calling `method.sig` in the current latest world const METHOD_SIG_LATEST_ONLY = 0x2 +# true indicates there exists some other method that is not more specific than this one in the current latest world (which might be more fully covering) +const METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC = 0x8 function verify_invokesig(@nospecialize(invokesig), expected::Method, world::UInt) @assert invokesig isa Type diff --git a/base/strings/basic.jl b/base/strings/basic.jl index c40deb0656ced..50b0d419b9101 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -810,6 +810,8 @@ write(io::IO, s::CodeUnits) = write(io, s.s) cconvert(::Type{Ptr{T}}, s::CodeUnits{T}) where {T} = cconvert(Ptr{T}, s.s) cconvert(::Type{Ptr{Int8}}, s::CodeUnits{UInt8}) = cconvert(Ptr{Int8}, s.s) +similar(::Type{<:CodeUnits{T}}, dims::Dims) where {T} = similar(Array{T}, dims) + """ codeunits(s::AbstractString) diff --git a/base/strings/io.jl b/base/strings/io.jl index b27a6049f0b0e..9db196161997a 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -51,7 +51,7 @@ function print(io::IO, xs...) return nothing end -setfield!(typeof(print).name.mt, :max_args, 10, :monotonic) +setfield!(typeof(print).name, :max_args, Int32(10), :monotonic) """ println([io::IO], xs...) @@ -76,7 +76,7 @@ julia> String(take!(io)) """ println(io::IO, xs...) = print(io, xs..., "\n") -setfield!(typeof(println).name.mt, :max_args, 10, :monotonic) +setfield!(typeof(println).name, :max_args, Int32(10), :monotonic) ## conversion of general objects to strings ## """ @@ -152,7 +152,7 @@ function print_to_string(xs...) end String(_unsafe_take!(s)) end -setfield!(typeof(print_to_string).name.mt, :max_args, 10, :monotonic) +setfield!(typeof(print_to_string).name, :max_args, Int32(10), :monotonic) function string_with_env(env, xs...) if isempty(xs) diff --git a/base/strings/unicode.jl b/base/strings/unicode.jl index f2938ba6021f2..7e0feed1c5bd5 100644 --- a/base/strings/unicode.jl +++ b/base/strings/unicode.jl @@ -6,7 +6,7 @@ module Unicode import Base: show, ==, hash, string, Symbol, isless, length, eltype, convert, isvalid, ismalformed, isoverlong, iterate, AnnotatedString, AnnotatedChar, annotated_chartransform, - @assume_effects, annotations + @assume_effects, annotations, is_overlong_enc # whether codepoints are valid Unicode scalar values, i.e. 0-0xd7ff, 0xe000-0x10ffff @@ -262,17 +262,15 @@ julia> textwidth('⛵') 2 ``` """ -function textwidth(c::AbstractChar) - ismalformed(c) && return 1 - i = codepoint(c) - i < 0x7f && return Int(i >= 0x20) # ASCII fast path - Int(ccall(:utf8proc_charwidth, Cint, (UInt32,), i)) -end +textwidth(c::AbstractChar) = textwidth(Char(c)::Char) function textwidth(c::Char) - b = bswap(reinterpret(UInt32, c)) # from isascii(c) + u = reinterpret(UInt32, c) + b = bswap(u) # from isascii(c) b < 0x7f && return Int(b >= 0x20) # ASCII fast path - ismalformed(c) && return 1 + # We can't know a priori how terminals will render invalid UTF8 chars, + # so we conservatively decide a width of 1. + (ismalformed(c) || is_overlong_enc(u)) && return 1 Int(ccall(:utf8proc_charwidth, Cint, (UInt32,), c)) end @@ -800,7 +798,7 @@ isgraphemebreak(c1::AbstractChar, c2::AbstractChar) = # Stateful grapheme break required by Unicode-9 rules: the string # must be processed in sequence, with state initialized to Ref{Int32}(0). # Requires utf8proc v2.0 or later. -function isgraphemebreak!(state::Ref{Int32}, c1::AbstractChar, c2::AbstractChar) +@inline function isgraphemebreak!(state::Ref{Int32}, c1::AbstractChar, c2::AbstractChar) if ismalformed(c1) || ismalformed(c2) state[] = 0 return true diff --git a/base/summarysize.jl b/base/summarysize.jl index 62b0ad0849778..55fc72efad314 100644 --- a/base/summarysize.jl +++ b/base/summarysize.jl @@ -139,7 +139,7 @@ end function (ss::SummarySize)(obj::Core.TypeName) key = pointer_from_objref(obj) haskey(ss.seen, key) ? (return 0) : (ss.seen[key] = true) - return Core.sizeof(obj) + (isdefined(obj, :mt) ? ss(obj.mt) : 0) + return Core.sizeof(obj) end function (ss::SummarySize)(obj::GenericMemory) diff --git a/base/sysimg.jl b/base/sysimg.jl index 4a99f7a9f337e..7e205ca955409 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -15,8 +15,8 @@ ccall(:jl_init_restored_module, Cvoid, (Any,), Base) include([mapexpr::Function,] path::AbstractString) Evaluate the contents of the input source file in the global scope of the containing module. -Every module (except those defined with `baremodule`) has its own -definition of `include`, which evaluates the file in that module. +Every `Module` (except those defined with `baremodule`) has a private 1-argument definition +of `include`, which evaluates the file in that module, for use inside that module. Returns the result of the last evaluated expression of the input file. During including, a task-local include path is set to the directory containing the file. Nested calls to `include` will search relative to that path. This function is typically used to load source @@ -40,15 +40,18 @@ Use [`Base.include`](@ref) to evaluate a file into another module. !!! compat "Julia 1.5" Julia 1.5 is required for passing the `mapexpr` argument. """ -const include = Base.IncludeInto(Main) +Base.IncludeInto """ eval(expr) Evaluate an expression in the global scope of the containing module. -Every `Module` (except those defined with `baremodule`) has its own 1-argument -definition of `eval`, which evaluates expressions in that module. +Every `Module` (except those defined with `baremodule`) has a private 1-argument definition +of `eval`, which evaluates expressions in that module, for use inside that module. """ +Core.EvalInto + +const include = Base.IncludeInto(Main) const eval = Core.EvalInto(Main) # Ensure this file is also tracked diff --git a/base/task.jl b/base/task.jl index e33a7e4efddf6..951e980ee903c 100644 --- a/base/task.jl +++ b/base/task.jl @@ -1145,16 +1145,6 @@ function throwto(t::Task, @nospecialize exc) return try_yieldto(identity) end -@inline function wait_forever() - while true - wait() - end -end - -const get_sched_task = OncePerThread{Task}() do - Task(wait_forever) -end - function ensure_rescheduled(othertask::Task) ct = current_task() W = workqueue_for(Threads.threadid()) @@ -1191,39 +1181,25 @@ end checktaskempty = Partr.multiq_check_empty +@noinline function poptask(W::StickyWorkqueue) + task = trypoptask(W) + if !(task isa Task) + task = ccall(:jl_task_get_next, Ref{Task}, (Any, Any, Any), trypoptask, W, checktaskempty) + end + set_next_task(task) + nothing +end + function wait() ct = current_task() # [task] user_time -yield-or-done-> wait_time record_running_time!(ct) - # let GC run GC.safepoint() - # check for libuv events - process_events() - - # get the next task to run - result = nothing - have_result = false W = workqueue_for(Threads.threadid()) - task = trypoptask(W) - if !(task isa Task) - # No tasks to run; switch to the scheduler task to run the - # thread sleep logic. - sched_task = get_sched_task() - if ct !== sched_task - result = yieldto(sched_task) - have_result = true - else - task = ccall(:jl_task_get_next, Ref{Task}, (Any, Any, Any), - trypoptask, W, checktaskempty) - end - end - # We may have already switched tasks (via the scheduler task), so - # only switch if we haven't. - if !have_result - @assert task isa Task - set_next_task(task) - result = try_yieldto(ensure_rescheduled) - end + poptask(W) + result = try_yieldto(ensure_rescheduled) + process_events() + # return when we come out of the queue return result end diff --git a/contrib/juliac/Artifacts.toml b/contrib/juliac/Artifacts.toml new file mode 100644 index 0000000000000..54771b41b21f7 --- /dev/null +++ b/contrib/juliac/Artifacts.toml @@ -0,0 +1,19 @@ +[[mingw-w64]] +arch = "x86_64" +git-tree-sha1 = "b17bda08a19173572926f43a48aad5ef3d845e7c" +os = "windows" +lazy = true + + [[mingw-w64.download]] + sha256 = "53645e06775a55733580426341395c67dda20a664af83bcda76a1d052b618b59" + url = "https://github.com/JuliaLang/PackageCompiler.jl/releases/download/v2.1.24/x86_64-14.2.0-release-posix-seh-msvcrt-rt_v12-rev0.tar.gz" + +[[mingw-w64]] +arch = "i686" +git-tree-sha1 = "76b9f278e7de1d7dfdfe3a786afbe9c1e29003ea" +os = "windows" +lazy = true + + [[mingw-w64.download]] + sha256 = "d049bd771e01b02f2ca9274435f0e6f9f4f295bf2af72a8059dd851c52144910" + url = "https://github.com/JuliaLang/PackageCompiler.jl/releases/download/v2.1.24/i686-14.2.0-release-posix-dwarf-msvcrt-rt_v12-rev0.tar.gz" diff --git a/contrib/juliac/juliac-buildscript.jl b/contrib/juliac/juliac-buildscript.jl new file mode 100644 index 0000000000000..40b35c66a829f --- /dev/null +++ b/contrib/juliac/juliac-buildscript.jl @@ -0,0 +1,95 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# Script to run in the process that generates juliac's object file output + +# Run the verifier in the current world (before modifications), so that error +# messages and types print in their usual way. +Core.Compiler._verify_trim_world_age[] = Base.get_world_counter() + +# Initialize some things not usually initialized when output is requested +Sys.__init__() +Base.init_depot_path() +Base.init_load_path() +Base.init_active_project() +task = current_task() +task.rngState0 = 0x5156087469e170ab +task.rngState1 = 0x7431eaead385992c +task.rngState2 = 0x503e1d32781c2608 +task.rngState3 = 0x3a77f7189200c20b +task.rngState4 = 0x5502376d099035ae +uuid_tuple = (UInt64(0), UInt64(0)) +ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, uuid_tuple) +if Base.get_bool_env("JULIA_USE_FLISP_PARSER", false) === false + Base.JuliaSyntax.enable_in_core!() +end + +if Base.JLOptions().trim != 0 + include(joinpath(@__DIR__, "juliac-trim-base.jl")) +end + +# Load user code + +import Base.Experimental.entrypoint + +# for use as C main if needed +function _main(argc::Cint, argv::Ptr{Ptr{Cchar}})::Cint + args = ccall(:jl_set_ARGS, Any, (Cint, Ptr{Ptr{Cchar}}), argc, argv)::Vector{String} + return Main.main(args) +end + +let mod = Base.include(Main, ARGS[1]) + Core.@latestworld + if ARGS[2] == "--output-exe" + have_cmain = false + if isdefined(Main, :main) + for m in methods(Main.main) + if isdefined(m, :ccallable) + # TODO: possibly check signature and return type + have_cmain = true + break + end + end + end + if !have_cmain + if Base.should_use_main_entrypoint() + if hasmethod(Main.main, Tuple{Vector{String}}) + entrypoint(_main, (Cint, Ptr{Ptr{Cchar}})) + Base._ccallable("main", Cint, Tuple{typeof(_main), Cint, Ptr{Ptr{Cchar}}}) + else + error("`@main` must accept a `Vector{String}` argument.") + end + else + error("To generate an executable a `@main` function must be defined.") + end + end + end + #entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{Base.SubString{String}, 1}, String)) + #entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{String, 1}, Char)) + entrypoint(Base.task_done_hook, (Task,)) + entrypoint(Base.wait, ()) + entrypoint(Base.poptask, (Base.StickyWorkqueue,)) + entrypoint(Base.trypoptask, (Base.StickyWorkqueue,)) + entrypoint(Base.checktaskempty, ()) + if ARGS[3] == "true" + ccall(:jl_add_ccallable_entrypoints, Cvoid, ()) + end +end + +if Base.JLOptions().trim != 0 + include(joinpath(@__DIR__, "juliac-trim-stdlib.jl")) +end + +empty!(Core.ARGS) +empty!(Base.ARGS) +empty!(LOAD_PATH) +empty!(DEPOT_PATH) +empty!(Base.TOML_CACHE.d) +Base.TOML.reinit!(Base.TOML_CACHE.p, "") +Base.ACTIVE_PROJECT[] = nothing +@eval Base begin + PROGRAM_FILE = "" +end +@eval Sys begin + BINDIR = "" + STDLIB = "" +end diff --git a/contrib/juliac-buildscript.jl b/contrib/juliac/juliac-trim-base.jl similarity index 54% rename from contrib/juliac-buildscript.jl rename to contrib/juliac/juliac-trim-base.jl index 4bfbfd2272220..96fed77969c97 100644 --- a/contrib/juliac-buildscript.jl +++ b/contrib/juliac/juliac-trim-base.jl @@ -1,31 +1,6 @@ -# Script to run in the process that generates juliac's object file output +# This file is a part of Julia. License is MIT: https://julialang.org/license -inputfile = ARGS[1] -output_type = ARGS[2] -add_ccallables = ARGS[3] == "true" - -# Run the verifier in the current world (before modifications), so that error -# messages and types print in their usual way. -Core.Compiler._verify_trim_world_age[] = Base.get_world_counter() - -# Initialize some things not usually initialized when output is requested -Sys.__init__() -Base.init_depot_path() -Base.init_load_path() -Base.init_active_project() -task = current_task() -task.rngState0 = 0x5156087469e170ab -task.rngState1 = 0x7431eaead385992c -task.rngState2 = 0x503e1d32781c2608 -task.rngState3 = 0x3a77f7189200c20b -task.rngState4 = 0x5502376d099035ae -uuid_tuple = (UInt64(0), UInt64(0)) -ccall(:jl_set_module_uuid, Cvoid, (Any, NTuple{2, UInt64}), Base.__toplevel__, uuid_tuple) -if Base.get_bool_env("JULIA_USE_FLISP_PARSER", false) === false - Base.JuliaSyntax.enable_in_core!() -end - -# Patch methods in Core and Base +# Patches to Base needed for trimming @eval Core begin DomainError(@nospecialize(val), @nospecialize(msg::AbstractString)) = (@noinline; $(Expr(:new, :DomainError, :val, :msg))) @@ -184,123 +159,3 @@ end return Time(h, m, s, ms) end end - -# Load user code - -import Base.Experimental.entrypoint - -let mod = Base.include(Base.__toplevel__, inputfile) - if !isa(mod, Module) - mod = Main - end - Core.@latestworld - if output_type == "--output-exe" && isdefined(mod, :main) && !add_ccallables - entrypoint(mod.main, ()) - end - #entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{Base.SubString{String}, 1}, String)) - #entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{String, 1}, Char)) - entrypoint(Base.task_done_hook, (Task,)) - entrypoint(Base.wait, ()) - entrypoint(Base.wait_forever, ()) - entrypoint(Base.trypoptask, (Base.StickyWorkqueue,)) - entrypoint(Base.checktaskempty, ()) - if add_ccallables - ccall(:jl_add_ccallable_entrypoints, Cvoid, ()) - end -end - -# Additional method patches depending on whether user code loads certain stdlibs -let - find_loaded_root_module(key::Base.PkgId) = Base.maybe_root_module(key) - - SparseArrays = find_loaded_root_module(Base.PkgId( - Base.UUID("2f01184e-e22b-5df5-ae63-d93ebab69eaf"), "SparseArrays")) - if SparseArrays !== nothing - @eval SparseArrays.CHOLMOD begin - function __init__() - ccall((:SuiteSparse_config_malloc_func_set, :libsuitesparseconfig), - Cvoid, (Ptr{Cvoid},), cglobal(:jl_malloc, Ptr{Cvoid})) - ccall((:SuiteSparse_config_calloc_func_set, :libsuitesparseconfig), - Cvoid, (Ptr{Cvoid},), cglobal(:jl_calloc, Ptr{Cvoid})) - ccall((:SuiteSparse_config_realloc_func_set, :libsuitesparseconfig), - Cvoid, (Ptr{Cvoid},), cglobal(:jl_realloc, Ptr{Cvoid})) - ccall((:SuiteSparse_config_free_func_set, :libsuitesparseconfig), - Cvoid, (Ptr{Cvoid},), cglobal(:jl_free, Ptr{Cvoid})) - end - end - end - - Artifacts = find_loaded_root_module(Base.PkgId( - Base.UUID("56f22d72-fd6d-98f1-02f0-08ddc0907c33"), "Artifacts")) - if Artifacts !== nothing - @eval Artifacts begin - function _artifact_str( - __module__, - artifacts_toml, - name, - path_tail, - artifact_dict, - hash, - platform, - _::Val{LazyArtifacts} - ) where LazyArtifacts - # If the artifact exists, we're in the happy path and we can immediately - # return the path to the artifact: - dirs = artifacts_dirs(bytes2hex(hash.bytes)) - for dir in dirs - if isdir(dir) - return jointail(dir, path_tail) - end - end - error("Artifact not found") - end - end - end - - Pkg = find_loaded_root_module(Base.PkgId( - Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg")) - if Pkg !== nothing - @eval Pkg begin - __init__() = rand() #TODO, methods that do nothing don't get codegened - end - end - - StyledStrings = find_loaded_root_module(Base.PkgId( - Base.UUID("f489334b-da3d-4c2e-b8f0-e476e12c162b"), "StyledStrings")) - if StyledStrings !== nothing - @eval StyledStrings begin - __init__() = rand() - end - end - - Markdown = find_loaded_root_module(Base.PkgId( - Base.UUID("d6f4376e-aef5-505a-96c1-9c027394607a"), "Markdown")) - if Markdown !== nothing - @eval Markdown begin - __init__() = rand() - end - end - - JuliaSyntaxHighlighting = find_loaded_root_module(Base.PkgId( - Base.UUID("ac6e5ff7-fb65-4e79-a425-ec3bc9c03011"), "JuliaSyntaxHighlighting")) - if JuliaSyntaxHighlighting !== nothing - @eval JuliaSyntaxHighlighting begin - __init__() = rand() - end - end -end - -empty!(Core.ARGS) -empty!(Base.ARGS) -empty!(LOAD_PATH) -empty!(DEPOT_PATH) -empty!(Base.TOML_CACHE.d) -Base.TOML.reinit!(Base.TOML_CACHE.p, "") -Base.ACTIVE_PROJECT[] = nothing -@eval Base begin - PROGRAM_FILE = "" -end -@eval Sys begin - BINDIR = "" - STDLIB = "" -end diff --git a/contrib/juliac/juliac-trim-stdlib.jl b/contrib/juliac/juliac-trim-stdlib.jl new file mode 100644 index 0000000000000..3e2501c2c3e50 --- /dev/null +++ b/contrib/juliac/juliac-trim-stdlib.jl @@ -0,0 +1,83 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# Patches to stdlib needed for trimming + +let + find_loaded_root_module(key::Base.PkgId) = Base.maybe_root_module(key) + + SparseArrays = find_loaded_root_module(Base.PkgId( + Base.UUID("2f01184e-e22b-5df5-ae63-d93ebab69eaf"), "SparseArrays")) + if SparseArrays !== nothing + @eval SparseArrays.CHOLMOD begin + function __init__() + ccall((:SuiteSparse_config_malloc_func_set, :libsuitesparseconfig), + Cvoid, (Ptr{Cvoid},), cglobal(:jl_malloc, Ptr{Cvoid})) + ccall((:SuiteSparse_config_calloc_func_set, :libsuitesparseconfig), + Cvoid, (Ptr{Cvoid},), cglobal(:jl_calloc, Ptr{Cvoid})) + ccall((:SuiteSparse_config_realloc_func_set, :libsuitesparseconfig), + Cvoid, (Ptr{Cvoid},), cglobal(:jl_realloc, Ptr{Cvoid})) + ccall((:SuiteSparse_config_free_func_set, :libsuitesparseconfig), + Cvoid, (Ptr{Cvoid},), cglobal(:jl_free, Ptr{Cvoid})) + end + end + end + + Artifacts = find_loaded_root_module(Base.PkgId( + Base.UUID("56f22d72-fd6d-98f1-02f0-08ddc0907c33"), "Artifacts")) + if Artifacts !== nothing + @eval Artifacts begin + function _artifact_str( + __module__, + artifacts_toml, + name, + path_tail, + artifact_dict, + hash, + platform, + _::Val{LazyArtifacts} + ) where LazyArtifacts + # If the artifact exists, we're in the happy path and we can immediately + # return the path to the artifact: + dirs = artifacts_dirs(bytes2hex(hash.bytes)) + for dir in dirs + if isdir(dir) + return jointail(dir, path_tail) + end + end + error("Artifact not found") + end + end + end + + Pkg = find_loaded_root_module(Base.PkgId( + Base.UUID("44cfe95a-1eb2-52ea-b672-e2afdf69b78f"), "Pkg")) + if Pkg !== nothing + @eval Pkg begin + __init__() = rand() #TODO, methods that do nothing don't get codegened + end + end + + StyledStrings = find_loaded_root_module(Base.PkgId( + Base.UUID("f489334b-da3d-4c2e-b8f0-e476e12c162b"), "StyledStrings")) + if StyledStrings !== nothing + @eval StyledStrings begin + __init__() = rand() + end + end + + Markdown = find_loaded_root_module(Base.PkgId( + Base.UUID("d6f4376e-aef5-505a-96c1-9c027394607a"), "Markdown")) + if Markdown !== nothing + @eval Markdown begin + __init__() = rand() + end + end + + JuliaSyntaxHighlighting = find_loaded_root_module(Base.PkgId( + Base.UUID("ac6e5ff7-fb65-4e79-a425-ec3bc9c03011"), "JuliaSyntaxHighlighting")) + if JuliaSyntaxHighlighting !== nothing + @eval JuliaSyntaxHighlighting begin + __init__() = rand() + end + end +end diff --git a/contrib/juliac.jl b/contrib/juliac/juliac.jl similarity index 65% rename from contrib/juliac.jl rename to contrib/juliac/juliac.jl index b110f1d233690..ed80d88444639 100644 --- a/contrib/juliac.jl +++ b/contrib/juliac/juliac.jl @@ -1,8 +1,12 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + # Julia compiler wrapper script # NOTE: The interface and location of this script are considered unstable/experimental +using LazyArtifacts + module JuliaConfig - include(joinpath(@__DIR__, "julia-config.jl")) + include(joinpath(@__DIR__, "..", "julia-config.jl")) end julia_cmd = `$(Base.julia_cmd()) --startup-file=no --history-file=no` @@ -28,6 +32,57 @@ if help !== nothing exit(0) end +# Copied from PackageCompiler +# https://github.com/JuliaLang/PackageCompiler.jl/blob/1c35331d8ef81494f054bbc71214811253101993/src/PackageCompiler.jl#L147-L190 +function get_compiler_cmd(; cplusplus::Bool=false) + cc = get(ENV, "JULIA_CC", nothing) + path = nothing + @static if Sys.iswindows() + path = joinpath(LazyArtifacts.artifact"mingw-w64", + "extracted_files", + (Int==Int64 ? "mingw64" : "mingw32"), + "bin", + cplusplus ? "g++.exe" : "gcc.exe") + compiler_cmd = `$path` + end + if cc !== nothing + compiler_cmd = Cmd(Base.shell_split(cc)) + path = nothing + elseif !Sys.iswindows() + compilers_cpp = ("g++", "clang++") + compilers_c = ("gcc", "clang") + found_compiler = false + if cplusplus + for compiler in compilers_cpp + if Sys.which(compiler) !== nothing + compiler_cmd = `$compiler` + found_compiler = true + break + end + end + end + if !found_compiler + for compiler in compilers_c + if Sys.which(compiler) !== nothing + compiler_cmd = `$compiler` + found_compiler = true + if cplusplus && !WARNED_CPP_COMPILER[] + @warn "could not find a c++ compiler (g++ or clang++), falling back to $compiler, this might cause link errors" + WARNED_CPP_COMPILER[] = true + end + break + end + end + end + found_compiler || error("could not find a compiler, looked for ", + join(((cplusplus ? compilers_cpp : ())..., compilers_c...), ", ", " and ")) + end + if path !== nothing + compiler_cmd = addenv(compiler_cmd, "PATH" => string(ENV["PATH"], ";", dirname(path))) + end + return compiler_cmd +end + # arguments to forward to julia compilation process julia_args = [] enable_trim::Bool = false @@ -80,6 +135,7 @@ function get_rpath(; relative::Bool = false) end end +cc = get_compiler_cmd() absfile = abspath(file) cflags = JuliaConfig.cflags(; framework=false) cflags = Base.shell_split(cflags) @@ -91,7 +147,6 @@ tmpdir = mktempdir(cleanup=false) img_path = joinpath(tmpdir, "img.a") bc_path = joinpath(tmpdir, "img-bc.a") - function precompile_env() # Pre-compile the environment # (otherwise obscure error messages will occur) @@ -119,7 +174,6 @@ function compile_products(enable_trim::Bool) println(stderr, "\nFailed to compile $file") exit(1) end - end function link_products() @@ -135,11 +189,11 @@ function link_products() julia_libs = Base.shell_split(Base.isdebugbuild() ? "-ljulia-debug -ljulia-internal-debug" : "-ljulia -ljulia-internal") try if output_type == "--output-lib" - cmd2 = `cc $(allflags) $(rpath) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)` + cmd2 = `$(cc) $(allflags) $(rpath) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)` elseif output_type == "--output-sysimage" - cmd2 = `cc $(allflags) $(rpath) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)` + cmd2 = `$(cc) $(allflags) $(rpath) -o $outname -shared -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)` else - cmd2 = `cc $(allflags) $(rpath) -o $outname -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)` + cmd2 = `$(cc) $(allflags) $(rpath) -o $outname -Wl,$(Base.Linking.WHOLE_ARCHIVE) $img_path -Wl,$(Base.Linking.NO_WHOLE_ARCHIVE) $(julia_libs)` end verbose && println("Running: $cmd2") run(cmd2) diff --git a/contrib/mac/app/startup.applescript b/contrib/mac/app/startup.applescript index 9964049f34ed6..d7b46cec1a89d 100644 --- a/contrib/mac/app/startup.applescript +++ b/contrib/mac/app/startup.applescript @@ -1,4 +1,3 @@ set RootPath to (path to me) set JuliaPath to POSIX path of ((RootPath as text) & "Contents:Resources:julia:bin:julia") -set JuliaFile to POSIX file JuliaPath -tell application id "com.apple.finder" to open JuliaFile +do shell script "open -a Terminal '" & JuliaPath & "'" diff --git a/deps/blastrampoline.version b/deps/blastrampoline.version index 1e4a75305a4dd..bb711cfcd67ec 100644 --- a/deps/blastrampoline.version +++ b/deps/blastrampoline.version @@ -4,6 +4,6 @@ BLASTRAMPOLINE_JLL_NAME := libblastrampoline ## source build -BLASTRAMPOLINE_VER := 5.12.0 -BLASTRAMPOLINE_BRANCH=v5.12.0 -BLASTRAMPOLINE_SHA1=b127bc8dd4758ffc064340fff2aef4ead552f386 +BLASTRAMPOLINE_VER := 5.13.1 +BLASTRAMPOLINE_BRANCH=v5.13.1 +BLASTRAMPOLINE_SHA1=f26278e83ddc9035ae7695da597f1a5b26a4c62b diff --git a/deps/checksums/Distributed-3679026d7b510befdedfa8c6497e3cb032f9cea1.tar.gz/md5 b/deps/checksums/Distributed-3679026d7b510befdedfa8c6497e3cb032f9cea1.tar.gz/md5 new file mode 100644 index 0000000000000..ca3d9730181f4 --- /dev/null +++ b/deps/checksums/Distributed-3679026d7b510befdedfa8c6497e3cb032f9cea1.tar.gz/md5 @@ -0,0 +1 @@ +fdf2e62fcaed6aa5ad69bca405329675 diff --git a/deps/checksums/Distributed-3679026d7b510befdedfa8c6497e3cb032f9cea1.tar.gz/sha512 b/deps/checksums/Distributed-3679026d7b510befdedfa8c6497e3cb032f9cea1.tar.gz/sha512 new file mode 100644 index 0000000000000..186dfb34221b6 --- /dev/null +++ b/deps/checksums/Distributed-3679026d7b510befdedfa8c6497e3cb032f9cea1.tar.gz/sha512 @@ -0,0 +1 @@ +2361fc4ccad83139cf728f14fa38466f075fbf93dddfac533af8f5c0c35d6b86511881b7b97a95ee59f858ba9a33428d3514ac3bd605b745b002a673acfc3190 diff --git a/deps/checksums/Distributed-51e52978481835413d15b589919aba80dd85f890.tar.gz/md5 b/deps/checksums/Distributed-51e52978481835413d15b589919aba80dd85f890.tar.gz/md5 deleted file mode 100644 index cdf885890db7c..0000000000000 --- a/deps/checksums/Distributed-51e52978481835413d15b589919aba80dd85f890.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -bf358a22ed4aa0d57b8672ef81fb2b44 diff --git a/deps/checksums/Distributed-51e52978481835413d15b589919aba80dd85f890.tar.gz/sha512 b/deps/checksums/Distributed-51e52978481835413d15b589919aba80dd85f890.tar.gz/sha512 deleted file mode 100644 index 171fd2fdbf512..0000000000000 --- a/deps/checksums/Distributed-51e52978481835413d15b589919aba80dd85f890.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -399ab073d8c8cd1404e2e89ce2753486c782aa18646d56d8508c0a929c6a312e8bac2c791eddc01966f99cec1af34e56bbdccd8d75196b26f0b1bbb1fa8bd9ac diff --git a/deps/checksums/LinearAlgebra-6cc040592fd509ee048658e9afb8a99a2dc20e1b.tar.gz/md5 b/deps/checksums/LinearAlgebra-6cc040592fd509ee048658e9afb8a99a2dc20e1b.tar.gz/md5 new file mode 100644 index 0000000000000..585185b3c2983 --- /dev/null +++ b/deps/checksums/LinearAlgebra-6cc040592fd509ee048658e9afb8a99a2dc20e1b.tar.gz/md5 @@ -0,0 +1 @@ +39c0cb64a6c4226f8cb07518f592a8bc diff --git a/deps/checksums/LinearAlgebra-6cc040592fd509ee048658e9afb8a99a2dc20e1b.tar.gz/sha512 b/deps/checksums/LinearAlgebra-6cc040592fd509ee048658e9afb8a99a2dc20e1b.tar.gz/sha512 new file mode 100644 index 0000000000000..41693dd5c7625 --- /dev/null +++ b/deps/checksums/LinearAlgebra-6cc040592fd509ee048658e9afb8a99a2dc20e1b.tar.gz/sha512 @@ -0,0 +1 @@ +31563375775a85fa5ae1f6584f0ebc1ffef8b66a2c76ea74111b21c5d6d171189768d40cf6a4decc203845c8d0c789da6688ad9a15ec9d5ee8e7700e1e08715b diff --git a/deps/checksums/LinearAlgebra-7264a497869f2232eaa3d740ba3b145ade3fc9f4.tar.gz/md5 b/deps/checksums/LinearAlgebra-7264a497869f2232eaa3d740ba3b145ade3fc9f4.tar.gz/md5 deleted file mode 100644 index 809e00b6e137d..0000000000000 --- a/deps/checksums/LinearAlgebra-7264a497869f2232eaa3d740ba3b145ade3fc9f4.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -1e348930bff6c7075dd4a5a29a24ab60 diff --git a/deps/checksums/LinearAlgebra-7264a497869f2232eaa3d740ba3b145ade3fc9f4.tar.gz/sha512 b/deps/checksums/LinearAlgebra-7264a497869f2232eaa3d740ba3b145ade3fc9f4.tar.gz/sha512 deleted file mode 100644 index 411324a140622..0000000000000 --- a/deps/checksums/LinearAlgebra-7264a497869f2232eaa3d740ba3b145ade3fc9f4.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -f362aa184dcfa71dbca347ae91784a83ec8317bef6b5a31ee9be9318f1d2a6cbc89283421661f916fc8478d9143f4d7f1a0ce3e54fbb64d7e98156050b80a333 diff --git a/deps/checksums/Pkg-7aeec766cf637e2bc2af161eba8abd3a4b68d025.tar.gz/md5 b/deps/checksums/Pkg-7aeec766cf637e2bc2af161eba8abd3a4b68d025.tar.gz/md5 deleted file mode 100644 index 2574fca7dbe2b..0000000000000 --- a/deps/checksums/Pkg-7aeec766cf637e2bc2af161eba8abd3a4b68d025.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -d3e705f029ba3d81bd0725c2cb0b2e46 diff --git a/deps/checksums/Pkg-7aeec766cf637e2bc2af161eba8abd3a4b68d025.tar.gz/sha512 b/deps/checksums/Pkg-7aeec766cf637e2bc2af161eba8abd3a4b68d025.tar.gz/sha512 deleted file mode 100644 index 54276d232add9..0000000000000 --- a/deps/checksums/Pkg-7aeec766cf637e2bc2af161eba8abd3a4b68d025.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -ef8c37b056fb6dfc3c8b1b542d65d6ffdfdc1f41a08da5307ad1c3e7ce9fe0030ac4132c9d30af0e850964842d9b330e2f950bb49dd6dd0fd5b30592f8173477 diff --git a/deps/checksums/Pkg-e7a2dfecbfe43cf1c32f1ccd1e98a4dca52726ee.tar.gz/md5 b/deps/checksums/Pkg-e7a2dfecbfe43cf1c32f1ccd1e98a4dca52726ee.tar.gz/md5 new file mode 100644 index 0000000000000..afba373e163a4 --- /dev/null +++ b/deps/checksums/Pkg-e7a2dfecbfe43cf1c32f1ccd1e98a4dca52726ee.tar.gz/md5 @@ -0,0 +1 @@ +748d62ff0edc36821fbd739d5bc58bad diff --git a/deps/checksums/Pkg-e7a2dfecbfe43cf1c32f1ccd1e98a4dca52726ee.tar.gz/sha512 b/deps/checksums/Pkg-e7a2dfecbfe43cf1c32f1ccd1e98a4dca52726ee.tar.gz/sha512 new file mode 100644 index 0000000000000..17170e00be6ef --- /dev/null +++ b/deps/checksums/Pkg-e7a2dfecbfe43cf1c32f1ccd1e98a4dca52726ee.tar.gz/sha512 @@ -0,0 +1 @@ +c1dee8e8f0273897a8cdf29661f05dfb0e8025ddbf06b86d6b03bd5d499290c11694a6d089145c3698d100a49d0489337b770b23b54f49143498a28a74b87b6d diff --git a/deps/checksums/SparseArrays-72c7cac6bbf21367a3c2fbc5c50e908aea5984bb.tar.gz/md5 b/deps/checksums/SparseArrays-72c7cac6bbf21367a3c2fbc5c50e908aea5984bb.tar.gz/md5 deleted file mode 100644 index 12c4f2ff97697..0000000000000 --- a/deps/checksums/SparseArrays-72c7cac6bbf21367a3c2fbc5c50e908aea5984bb.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -3f25f8a47a7945b55c9cc53ef489a55f diff --git a/deps/checksums/SparseArrays-72c7cac6bbf21367a3c2fbc5c50e908aea5984bb.tar.gz/sha512 b/deps/checksums/SparseArrays-72c7cac6bbf21367a3c2fbc5c50e908aea5984bb.tar.gz/sha512 deleted file mode 100644 index 5daf7514ff4ed..0000000000000 --- a/deps/checksums/SparseArrays-72c7cac6bbf21367a3c2fbc5c50e908aea5984bb.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -5fd827602430e79846d974661b039902a5ab6495f94af8292a3d66c3c3a07a0c59858bfa5bfa941bf8bf6418af98d1dd41b88aad4cc7c7355a8e56cad7f1f3ac diff --git a/deps/checksums/SparseArrays-cdbad55530fba0c7aa27d4bcc64dde2204ff133f.tar.gz/md5 b/deps/checksums/SparseArrays-cdbad55530fba0c7aa27d4bcc64dde2204ff133f.tar.gz/md5 new file mode 100644 index 0000000000000..0cd5ebfb0fd87 --- /dev/null +++ b/deps/checksums/SparseArrays-cdbad55530fba0c7aa27d4bcc64dde2204ff133f.tar.gz/md5 @@ -0,0 +1 @@ +9f4376c0de171f481c153442dee250a4 diff --git a/deps/checksums/SparseArrays-cdbad55530fba0c7aa27d4bcc64dde2204ff133f.tar.gz/sha512 b/deps/checksums/SparseArrays-cdbad55530fba0c7aa27d4bcc64dde2204ff133f.tar.gz/sha512 new file mode 100644 index 0000000000000..207b0685cc2a5 --- /dev/null +++ b/deps/checksums/SparseArrays-cdbad55530fba0c7aa27d4bcc64dde2204ff133f.tar.gz/sha512 @@ -0,0 +1 @@ +ee756aa32d95849f728f7cfae8ba9cfce8ad51701cee6430e547f6b80b1f420e78d7d74471afc25ffc8cf6699cd5ae4e63cf38c32f3e8279179630074fda1830 diff --git a/deps/checksums/UnicodeData-13.0.0.txt/md5 b/deps/checksums/UnicodeData-13.0.0.txt/md5 deleted file mode 100644 index 2b3ffc179ce01..0000000000000 --- a/deps/checksums/UnicodeData-13.0.0.txt/md5 +++ /dev/null @@ -1 +0,0 @@ -85879f1976cc8eb739ee5585a93938e2 diff --git a/deps/checksums/UnicodeData-13.0.0.txt/sha512 b/deps/checksums/UnicodeData-13.0.0.txt/sha512 deleted file mode 100644 index a93ba01e7ddda..0000000000000 --- a/deps/checksums/UnicodeData-13.0.0.txt/sha512 +++ /dev/null @@ -1 +0,0 @@ -1a4a662e2ab33469976bf5f91aa6933ed9b73f6d4179a2daffb349e1869d7d6cfa885b164e82d15dcdad7458cd451c81add58d875eb0c70de854589dc97b2055 diff --git a/deps/checksums/UnicodeData-16.0.0.txt/md5 b/deps/checksums/UnicodeData-16.0.0.txt/md5 new file mode 100644 index 0000000000000..79ae5d27eff0e --- /dev/null +++ b/deps/checksums/UnicodeData-16.0.0.txt/md5 @@ -0,0 +1 @@ +f50a0495d2000b7d6dd979cb40e00ba2 diff --git a/deps/checksums/UnicodeData-16.0.0.txt/sha512 b/deps/checksums/UnicodeData-16.0.0.txt/sha512 new file mode 100644 index 0000000000000..05b998b3724ba --- /dev/null +++ b/deps/checksums/UnicodeData-16.0.0.txt/sha512 @@ -0,0 +1 @@ +963e5a1e7a480873c6e66d53e9288232b5029942477a694a0bfafa7e994c55189cb9c2f8d00255de84b82b72ff6066932e5531e3664fb422eeef9c69ea25d80e diff --git a/deps/checksums/blastrampoline b/deps/checksums/blastrampoline index 9e007f6055cf9..7870242560f34 100644 --- a/deps/checksums/blastrampoline +++ b/deps/checksums/blastrampoline @@ -1,38 +1,38 @@ -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 +blastrampoline-f26278e83ddc9035ae7695da597f1a5b26a4c62b.tar.gz/md5/855b7723a6e9eb8885876eb675d48329 +blastrampoline-f26278e83ddc9035ae7695da597f1a5b26a4c62b.tar.gz/sha512/29cbd060c8f5eb17ef486d0a10ee4b221eeceec3a2ab0f9f98f60880f3d19a2247d93ac0dc0d32ec568ef876acd30f6c0642aaf704757580c2e17884e425607f +libblastrampoline.v5.13.1+0.aarch64-apple-darwin.tar.gz/md5/d8dc0f092f86b379b2fb9da97382be70 +libblastrampoline.v5.13.1+0.aarch64-apple-darwin.tar.gz/sha512/d9fc0439565afaabe53f56f64c20aeddb846c991dafeafdef6c2369bd7a359c1a6b49cdf8d63eaae2730a336509854b5c306e630eb520445712efc4e41c0263e +libblastrampoline.v5.13.1+0.aarch64-linux-gnu.tar.gz/md5/c181e51a6ca4cde0da3d036d561e24dc +libblastrampoline.v5.13.1+0.aarch64-linux-gnu.tar.gz/sha512/fe4a86bb4c94ef86c2307adad528bb58d0508a33c194c64190fffe7902f5b915592567d9e0cc35414633c5ab9067def2fa20cf669a2f4309265744180a5ec51a +libblastrampoline.v5.13.1+0.aarch64-linux-musl.tar.gz/md5/6f9eb8d73a0e61f3a2b97dba7105086e +libblastrampoline.v5.13.1+0.aarch64-linux-musl.tar.gz/sha512/9c3db080155729a91b5dd47df91d3852539aefc331d4dc51167fccaf3b01e601b36911ec259c53e211fe192c108e839a1f14b837009fa4f7d88ed82d658f80ff +libblastrampoline.v5.13.1+0.aarch64-unknown-freebsd.tar.gz/md5/68f65db9da9938929d510eea3540335b +libblastrampoline.v5.13.1+0.aarch64-unknown-freebsd.tar.gz/sha512/2fc7b375a751f3bb201504e0417828602fe014a2c8626137779c09ca7264ac6d39d44db0d1d32e0dc506284f56b49e23791922b0cc1237021473fb505fbf06bd +libblastrampoline.v5.13.1+0.armv6l-linux-gnueabihf.tar.gz/md5/a377fa4e5751fbeb3c42f319cb6341de +libblastrampoline.v5.13.1+0.armv6l-linux-gnueabihf.tar.gz/sha512/9ddb1e2f4daab45d65b66dafc00df6ca7f788cb919cd6699c4aa0deca3e99a86d9ced10c3741610a6e480093d483e8a02c1d9165f91a7179632c1e2ae1abcfb7 +libblastrampoline.v5.13.1+0.armv6l-linux-musleabihf.tar.gz/md5/42c841baa05f80f17ea1b1d4f3405bef +libblastrampoline.v5.13.1+0.armv6l-linux-musleabihf.tar.gz/sha512/0c3ed42bd48f8f1ee9b1dc18faa7afa6e2fb27cffc59b9a420e29b5e6cdf8fb3bde36b82f3086075f8f7f329614aeb91ca5f173b1683e30e9530076f341ea2e0 +libblastrampoline.v5.13.1+0.armv7l-linux-gnueabihf.tar.gz/md5/61e515ec1223c99705175a26e6fbaf87 +libblastrampoline.v5.13.1+0.armv7l-linux-gnueabihf.tar.gz/sha512/92260dcc563ece74719f21921a7cb51266884ed01b50c97fa997b4a98737e900ec9eaa8012d2c4c67ab479c4080bd1cf2708612eaaaddbba28e4f9147f3708ea +libblastrampoline.v5.13.1+0.armv7l-linux-musleabihf.tar.gz/md5/d45816d705dd46572d85105567bc060e +libblastrampoline.v5.13.1+0.armv7l-linux-musleabihf.tar.gz/sha512/45cba07050b818cd85c67acdfc29515e1fe416eb4e0c219171f2c0c026f7412903c3a9367d48258259a16e89f36c1e8f9fa054e455759720f1c6c5e8e27be476 +libblastrampoline.v5.13.1+0.i686-linux-gnu.tar.gz/md5/c8d3fd5f314353133934396361857c92 +libblastrampoline.v5.13.1+0.i686-linux-gnu.tar.gz/sha512/a949b3c0655ad9d6f8d53fd8a3f0b4ab504046e49a373039defc94e832b7faf90c77520f3912c4d6db8b0829951d85b4fc2a4021b3d8bb2c399d1ad04ce77ab0 +libblastrampoline.v5.13.1+0.i686-linux-musl.tar.gz/md5/a7bbd2233366d180ce8aa61fd3568c11 +libblastrampoline.v5.13.1+0.i686-linux-musl.tar.gz/sha512/e78cbef5b3bcfa93a86e14eebf0d704a94ac7b1f5c7030706d1f4a960de888c42e3daddb65395c7102e08dfd444efbfb40273e58a5f1de199d44ad55fd3ae658 +libblastrampoline.v5.13.1+0.i686-w64-mingw32.tar.gz/md5/4ca5cf3f855d04d3e8bdbd15321944ad +libblastrampoline.v5.13.1+0.i686-w64-mingw32.tar.gz/sha512/33160caa000c6c44cedd594195e1f2efefb950459653ee12ad2be4cedf0b833874772512f1812948d753f075ee7b8fe5629e5f9bd753a3da7804c4a6e1b0e0a8 +libblastrampoline.v5.13.1+0.powerpc64le-linux-gnu.tar.gz/md5/8be947c20f7d35ec22247f9a11ccce43 +libblastrampoline.v5.13.1+0.powerpc64le-linux-gnu.tar.gz/sha512/56f4246f96d2f49b03f5e5f3b996660a48d50b3784f89df7cd1dc52bab6efea0c120a65015040041a51d18fc6f361f89486f77317d771fbf588a1ba7565d77a2 +libblastrampoline.v5.13.1+0.riscv64-linux-gnu.tar.gz/md5/85e1f70a3235097158b4884a58a58154 +libblastrampoline.v5.13.1+0.riscv64-linux-gnu.tar.gz/sha512/11f1f5c2a409dbdab11d6bc968610b5700e9b0cb95094e348fe43ddca5586eda47bda1c382fb1f4b5a15aa741a6fc2b31f58f9b08bfe46631b5471e864bc009b +libblastrampoline.v5.13.1+0.x86_64-apple-darwin.tar.gz/md5/c6756ca8b6778ce2a4a440f63355c32e +libblastrampoline.v5.13.1+0.x86_64-apple-darwin.tar.gz/sha512/895d9bba75a9a0861809dca48b3dae7b5ffc5d866a518729ffd52f70fa1742a41a4b8b4e03bb354cba12d9ad11a33f3f112fa69a30ab3f945a9dede0d59d92b3 +libblastrampoline.v5.13.1+0.x86_64-linux-gnu.tar.gz/md5/1326a406aa98b6045f7459d7fb237894 +libblastrampoline.v5.13.1+0.x86_64-linux-gnu.tar.gz/sha512/4965baa1de5532425ea57b8100e369cf44b55963340cd144c0359f845560f27a1bea1597e4c72ec541917f71aaff8a4863f47d01a095c2e761a68212bfb08d1e +libblastrampoline.v5.13.1+0.x86_64-linux-musl.tar.gz/md5/5103983b7fecc7b87f495cd3b6c4d7a5 +libblastrampoline.v5.13.1+0.x86_64-linux-musl.tar.gz/sha512/f3243d84a0a0a191abad9e3850c37be78892eb5905b63b47bfb3e5a4148e0dae672ee72d311c5c764ad0fffe57d39c10dfd2086466efd76b5030118941d36a00 +libblastrampoline.v5.13.1+0.x86_64-unknown-freebsd.tar.gz/md5/a001ecd07b5178ce724a4f78996dc43e +libblastrampoline.v5.13.1+0.x86_64-unknown-freebsd.tar.gz/sha512/508866d54a9a49df2ef7eaa5d807173016c6dfaec59c4c89d5b37cd3faa7384302d2d4d39aca1975d79a948414657b7ec048a3ebdf6bf5c938037aa89303013a +libblastrampoline.v5.13.1+0.x86_64-w64-mingw32.tar.gz/md5/14fc4ec99e72e5bb646f5e6e8410fe01 +libblastrampoline.v5.13.1+0.x86_64-w64-mingw32.tar.gz/sha512/b7d07218047917fe217736b3c97d2b0565f6c904cd9cf6de96e38c66552aeec13b3cde714775fce1eb5a230db0ec0f2822572de8f0e166cb042552a16beb2b79 diff --git a/deps/checksums/clang b/deps/checksums/clang index 2158589b5cef5..aad235644dfb1 100644 --- a/deps/checksums/clang +++ b/deps/checksums/clang @@ -1,112 +1,112 @@ -Clang.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/1dfebd0db436a282c2ccb01375e48419 -Clang.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/d5a8fc8be8bdcfb98c3f868c1a08cb18bffaca0c9fc6efbb11beaadf40ed5ca7e2a70c3be783a7cc93b23f39e06167784f63e91abe726240ad62d11210337794 -Clang.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/f82250af13bd879486677cbf1ae0b7dd -Clang.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/c4f67a59e30ea7bfb9ac83f07b1e07c856113dbc674d3a7d01cc7bbc326a1529f97d0e1a08a3aa60e110f901dba6d4888bae7060e24065444baaf633482108d7 -Clang.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/2817b0eeb83eff4e1f580729e02564ab -Clang.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/88242559299836c7a7b7d3a216353fc6880a587a839793ed71d6d053318d6e2071ff218587a082f2b5dd9fb2b0952b4c60e62030d707435607303708bb1e6d81 -Clang.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/d3f92998b7cc35a507cb1071baae8b02 -Clang.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/be22296623f604927e2e815a1cc149addda6d567270a50b2cdf77fe5b09f74313210a1ca7b1b3194592da23490ba1ccfdab9f520ce7219989e646f12208e418a -Clang.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/716300acfdee4415f1afa3b5571b102b -Clang.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/b97efb3c461ea7d2736a3a8bb6b6b5c99f02df9a095f11291319c629d44f1fb934b124d38af6be3e5cc7103c6f85793d7f185c607383461de5d0c846560a1d1b -Clang.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/034f44b2fc61791234d9580402002fb2 -Clang.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/0b4ff55afcec0b1e8fbd09fab57de8b44d5ded360d3b53132c7a7df8d3a3b83a495bf6e0c706784e678c6de46be3a72e8bfe562c7f8dfad90b82880849625e35 -Clang.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/54211070d63a2afac6350d06442cb145 -Clang.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/a58f8afe9a20f202cf3956f758dc13a10be240d78877a02cd006d7e972751ed65623eef7e92a7256d9ed9157d6e277302f93b58f583d86d386ed4945f3c7d875 -Clang.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/7084567b3637fe64088fdce357a255de -Clang.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/77ae83e159a814a7117cc859a0b2aa7a5d41f983d45b7eb1ce2fd2e93f8733ee067ac8c9fad9d5af90f852b8802043ef39c29b44430b2594892e57b61ccb680b -Clang.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/9e294d16a6e1c2c76c03f32cbbbfbe23 -Clang.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/b8f83542b51f5cf953f6baed185550394744a8466307ee08525bf18a651fcecd7daafb98e75a0866b0e9a95a524e8940be7ae1878ba80d856182dcb7f7d2254e -Clang.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/70a41c2ffd55d2d87a7b8728287eb9fd -Clang.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/44bb3dea7227ee991b2666c43a88613d5b5d382eb560b5ad1f1184d38680c85a2ef961bac6ad71c2b920702c1ec6e09296198e7ff5e2929f4ba7839e55896e3f -Clang.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/1f673de0cc2ec59cc62dee6040b2d6b7 -Clang.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/9b2e64cd2cd510677375f3d07d434f46066adb7464751dfeaebb057129f6b092d8425b0728f60dd9a2ec4cb29625ffc5cda57acf1d5465d5f82765369954c58a -Clang.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/0d91f5a19060c6a1b1dadb3befa0fe6a -Clang.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/9f9aaa36e1dab2d98a17602ed0b27163729928bfe4ac0f7b565cff1e0a653855b0f3e404830cb77ff35d93c0d5c42ed11d2506aecb5ec8d3752fbdfeb0ff5b4c -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/95ee1406f8575898eb52e2c86ae18992 -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/4da66e4d397491836b3e539258844346fe50bff41e6c0628cbb5c0eac76147bd91d1720cec1523452efdb063adf6ef8792dc278244e1f8e194ef60a180442c56 -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/6c4e4e892b54ce81d73a8598728083e3 -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/53d08fd8b6782867cfa6ce001b14a2fde38bc9ffc85c7e148aebf59dd9c1c535b54eaea816c39fcff42abc456c1047ed13d688917302bcc5a281abe368bd29bb -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/5acc5853111bcd529eeb06ea31b329e5 -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/b1794f7cdfba838a7e43de8f66700ae44fd16d8f06300e8ab955044ae9bc96110c5ea72691841cd3787cdc93dfb91c6b257702c20390689a8d1b45a994db2fd8 -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/c4de50252e557fb126360001ddae6a97 -Clang.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/9343a7272c76d5341bb49273ff8d43bed09ad99b2879ec51cfb8946174181b286af82d85e2d3a13a375c7e7859e51e4a4f06031a6a3fe7e540700cfc6a795741 -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/af301478b20e56cb7fa1160cda2573a2 -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/8822c58df101c239221fead6fb523e677da04a065b42849a2e6ffff03dfd81e07f162a9bbdd29490ad9c0e0a33d362eec46608b9e6e42dfb4889da1c22191c91 -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/901d2808599d5ac5ac7b5ca4bc39833d -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/820756cad00b1fe927801a253bd3077709c2b067ae79f9e1812f3cc9e85a0b7ac2ce1534031b7c6f7bda3364b7173c1c508e7c7d316920fb9bb901c16c1b18c7 -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/d1f368604084e907c382aaf00efe452c -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/523b25f6b79e222eb65b5f4cd8f23b0d2c8b25b29af0df88efe45546ea57c7dabd88baef454fa0b76342d8d364739107271f25d3504380fdec5c9d225fcc2521 -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/e57c116b2ad1cf32307eb4e600ac80be -Clang.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/63366b983c7aac9fe1246b25432b2200c8316f569f6930eb12de3c867f448ffccb8756d418f92eae7751d4c9ce6c42cee38237e429b81530819684fd5150c93a -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/645929ce42276db10ab79184a60cd6e3 -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/65555ed26d9bd670b8363e5dad949822c2bf0e141a5418e1dc30c3f8a4733dd050620e40be2e7552c2551ecb30d4ef3e8f74cb240f1d441a9720a25f5a3bcaa7 -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/8424c6c6318dfa7bebeac33917b29453 -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/6cf90c253f6b22358c2389a2347af2febd010117b22de0cc91ad713b8c8224627398004567c96b673650212eb5bd40bb97b9a637d46ddfeb3c72388d83445017 -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/ea8151dc1dc32befe579c7f9d7f13898 -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/ed518423e9ec35afd7983471cf9ff1e971b840f637f34e0f62a1f6c7379ea59d4dafbeb9a311d39761733ecc98c0318ce3d8883298f8998e9c741441c7c9616b -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/70ed39b13bcb0435fee63bc30ae25a39 -Clang.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/b2afa383346875514c62129c2991b3604c4fd3d507ecf4fc4244dec81d08b30218f5aa03dc4977185c2c9fb2d08848ddd373e448883ab472e5221ae5bf285c99 -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/e6798835128f663f0c837aed4463e34b -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c99856e16bd42ff967479e2c89690ea41268f1d1f868e2628482eafdfa53a0d69ed7c21ecc68ff0859eef07d9fe02f4844fad5f13df26cee6cea3a4254446096 -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/92c1bd54b0474244e35c51952966a55b -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/2d7c3b60ba8b11cf903bc5ea720193852027cbe61ea0c8d6fac70be8f97691da3d36663aac6e61b68185dd83b42d09ad61dea973d9390271210d690295e4902c -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/c495d594f8ce1f701d1bab54d0b60521 -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/0261bf45403daccf236723383341dc791e9cb3b291bde97812378d85aed785f083d5deea3bf806480a04ef1b972b00dccfd0537e43532a066c64733b817c3d77 -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/41541de24d625271bdd5fad867b8eb0c -Clang.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/595226ad7ef75ab8ae03adb456b4ee9e884e9554c720b6c4ecbc38c75d446ddba7898be94630673074f09f40c6dc3e18fea9cee5a91b8b0e4727d20a180f670c -Clang.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/8bd8ca0436611e78882939067f6277f7 -Clang.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/27c7b06e93fb0fb516b1b240e0df6c95e8bad6aea04d637ba065c6fafd087bfa94d9136afd39273c8d82d9c467395dcbd7b16f6a4b829acb0c0d4a5677676a5b -Clang.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/424bfbd7b69ddf7b1199afaacde3e028 -Clang.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/9c48d949309aef6ee39371ff39a4f12c31bf3f25ddd288b317b2a17a803db73850cba2886598a1d10c4c154d511a4b79958d1acc012e92491a63f3925c522873 -Clang.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/6b0b3e045ad64ecdc9848898f30d5f34 -Clang.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/6c0f4bdabbbc94fc9e1fedc138b0bce99d383e380ae7222fb70f5935f17701d549f6486956c8a21731061e4bf60bbc52794f6ce6858b4d2adb89bf80f88795c0 -Clang.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/3b7a461ebf957756aeb2a2455b0a298c -Clang.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/74641a3636dd58c69415b19f0cb1de444215e22cfa9f0268fd549b5c53b206811d8beecdeb9692285613468d9a0569e836d225fb8361218438346914f6282839 -Clang.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/7533ca14f2932c35881ec05a5fb1e550 -Clang.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/a1e55212b92c6b6dffc7e7b316c98e421e8384f65d4339455694c53643a3509b817d2ecb4e8dcd5f147dcf1be3920bcf82c1cb1732b23657bc7e36abb800d21e -Clang.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/5525f1e02315a128195cacb7f6cf7d44 -Clang.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/9ee9fe4b1f52dc6533f177256e60b0579943e8bb5ba34118e5a02d25b6a4419133f3f819aae1e02d916cc17edd09330facdc6625d66564ad3cbd97ebfc439e32 -Clang.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/9f442a545e9c3fbb0898b7a233e5079f -Clang.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/99cf06a5cda26001ed8d8bb4915a6a5993d4c9c5a7a038ccff99a3fa752f207b02095bdf1689f5cb9a2584a7e3ef26436b840896fe9a5b9b626980ebc7d85751 -Clang.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/9910ade7fdfc95ac2db3113fbfde42e0 -Clang.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/6267f1b3dbbf7900bd72cd5700756e1e2c783157b87b1829af552f7dac36f749d9c7d2662235892105c959e1425914e944fbdd2f9521d2da7de321efe6c793a1 -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/a6c7d64ede931fb19e066a1c191e2f6d -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/1a085a4ea1efb910f2b529f3c0e51be4a5e31debbefd00ceefeddc352b36bea6d0de5a06ea7d509098d16416b536ffed3da8485feefad7a2f11b1bc148a0c8c2 -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/692af94ca3e5c3d229cbb459e266aadf -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/b27f05cfb0ada89cefc5a6f6527583b6b43d03525954d5b1ad1c807712efdb8750ea558a230b587a0c0d9e77c54d9f8978cc2f3884653808c7409eab1b32a055 -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/3b59b6aa4b18b5dbbc632811f2ffa270 -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/f8c4b593f969c723ff1931c4875ed52497d83d74b94121890e10c9fcca5f6bddc5067555dee9949e61e426586ae3e568375fc44f318a07b70571ee34fdf7032c -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/bc4be32ad57b13c3dabc80684a176ba7 -Clang.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/19a8346547b6c6adc2a9156e4b913b20137593752efa3648ad532b08de67cf015bba1eb023204755f48904c3381a3665c6c54fc8233c50e887a22ceebc652303 -Clang.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/13436ae410728f67c914fa7aed304736 -Clang.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/3f83f1659580f4c5085b2da1c1a90581dcb3c45f5da1cf4d1801e230bb56fdb78a98cfe41b755949b34316ae08c55f5b2d558bb4026503ef2afa895b59dc861c -Clang.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/fa79485d88d173e15fb99b2f7fd793bc -Clang.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/4886be75294979cdb55030747c664bd4cc2a2fa1489790d744e918a39fddcc5c214d4f39755d58206fd1bfd077774302b2be506ee80e4d0a2e2e2de642dbf124 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/4e5d1064d90f24d57d63f08b61baaab5 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/cbfbe8b6f2be80e59b69d25d6af901ccb4807b12180208b69afa7223dd7d5249255265bc319c9402a1b0d1f0995940e3e72d7ecf1009f60d83021f8d35626a46 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/22fead15b4c45398ca869821d04ce015 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/2ee7a7d3f293f7b63c89bbe3b541722c502a840883804ffe272848f4ac99b7a8ed350ebe92ec434dfdf03d1f4a5531c1367859f4a4603c98325abe5a0ad71177 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/46dd01b10377cc3d45c6a42cac0a07e5 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/957677ce4251938d0c5e066448762b38a21bcce5ed424072ccd58085167d61b7e45a88fe32375f6bbd43dfb579b65a9afc09a886a650fc634a8fb9c81f27c9e3 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/bd9a61ea186a39162201341f0739fe84 -Clang.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/7a06d2a9ef20e88daa00d627d482ebbb6bf7223219d8b2a24aa60ac9eda24649d206b093d5bdb88b65c1e2b0d1ba0ad7dd927697e2bbac65bc9b42f9d14ad0d9 -Clang.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/60c98c6cc7d4446fb52b7585bc8709f3 -Clang.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/4d55464b4499a45f774e1000a8b015326d114103a3d348fb263367e5506ca6659444ea6ee2767712903757e83939cd446aff6fe2351438b644f0057053422b58 -Clang.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/90a512d1881c4af1f1abfd5e90e37356 -Clang.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/62d6d855aebd49f132d6470c7b0d5a0b965c6489b025046c1ea73fc53336030d6c5b4c867523a9206821f7fcf62fdb37ef0b7ff4b5eb04d07f40b65edd2c8e0f -Clang.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/c9eb9acb605d774db9636b82bf2e5f41 -Clang.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/96e1440b3b0378edf8907d4cf779b1c53d63f6d00fa798efe1b6aaa289135aba8fd00a8d6f55d9678136e9e07d0c189293aec64f46e66788b938e1f8e1fc2199 -Clang.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/5837070450c81d44395468d8e3671dc7 -Clang.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/0e8b674c0360f9586f03c7f5d0ffd5bc73dcde1e88eddf7d6360c1461adb8efffb104d8f454116a6a6cdc909973d0876745590b21009a9de56e12ce6e1c2e8fc -Clang.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/f94431ce7b8a12774925348a076e39e9 -Clang.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/cdbcf5bd32a9fa4d5204e77f12d60b1fde540fc93243236f26896106d21f3b2106b0c3fcd93b1a7bbd6a9c4688200837f309b216ec9f334f8c8f28144b36d4ca -Clang.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/4ca4824a441d51cd4d1fe3516d7841fb -Clang.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/ac0a046ede4b3c9bc75bbf7d1189e4679df6c35ca50e97fd6dadf437aba00816f66038db5dfddcfe2c49140c8416c79cfa4b67db371b4185ee897e0585b96301 -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/844031bd67137863f8e7dcd65aa6e45b -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/56efe56f02f0d13e03ba029cc2ccf2aaf2d50479d8153b7922392ff90327e3cded2c1e7fc8cd799737cd988e64bb9c74f2c0ea6156a04fc08f22a4dbe6156cba -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/cc2705c3a856574835383aac7185ab32 -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/eb037e996168d6d8987ff50c45e879f5e9779b044075f91cd8bbfe096260cd155b36f80bad840e88e1ab7970517e692875d5e84adc447153f167dfed886e0442 -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/2103b507b6aec55f8cb58a0c86aa461c -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/d9a4d6eeec2aac1bc41a0be40526842e782d0796a306d3c1b5e53f7f146628ed974c8a4c4dce8baff5734d973966b4f3e1310be40b90ced9981ace4c4369a257 -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/daf3d83095fbad33bbb120314d6b53f7 -Clang.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/e68a71d0d89d16e0c5c9182b8a3336c67179f37e247c8eef3f21e362a3258ff4815f258d2430ca3883a52a95bc26c8e2c42e3dd081f4998ed309813f3d0a4aa6 +Clang.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/d33fc7b8dad6ec4e7c3d407554004649 +Clang.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/d2f9c58df58b520a955f2f3b867efbc0bc5acfbe4bb92b7fbd2ad88a7779b610c9afdef55bb9f29610fbcd08502a2cfe3170566fe28d24e78ba290c0e07bc3bf +Clang.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/be335c7b781138f1bf1716a57fb1a36f +Clang.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/578caf4c00aa96328064424688bce976a29561886ff45634b44f0c17b952e825ad5136f3da3b76b59c73308e66efa7adeae0d463a091a41b23f247557881df8e +Clang.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/bc2291806d2f778a26eb0d9bbbfb69df +Clang.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/682a39517d53ff1139d52cce12d08a687e37d57a0f02cabfbde901662ca6039a52f30a5d640a2bd85d3a08b8eb3d10f596e6fe6ced559527c02c2715948b04d6 +Clang.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/cb0bf998272b6c21c3ca347a1405d5d2 +Clang.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/02f6c518e3a817b35459bd37de871b31f59fe05deb29a6cf969d2123b3c40a3b40f4fdf6f8b6e5476a705ee29308148777386e7edf07a300e0ba9726e04a955a +Clang.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/d24dd31a7ce66e13abc0df85d371292c +Clang.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/d18712f49d5599397b8309c08aa133abd6cc31b4e44a7ee318afce345074f2e021a03287e7acd0394d3da1aa751f100b29510292073dd3503146f15a5dff7f4b +Clang.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/dbdaa23478a49beb5e337dd8a0d18380 +Clang.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/9b4fc902bd433a4deba1ae80dbc6c5b0af9fb55ad2369c0155078c19905ad56bc703649f347e3ca5168a3e0f47252db5b24fca27e2e49d9a9300640dca33411e +Clang.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/883656cd00f127c9fe67cf52e1c0c6eb +Clang.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/f78473efe02df6ec498a1c8046d6ff4f6a28df8681cb46887897566f10678cbe4b6d8da5bf566b32cc3a3ada12119efbe891d77645a9e57a32a7cf126859747f +Clang.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/ded96c4bc5ced9c54ad54ed1913aca8d +Clang.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/b8bc33601c2db3b9b4fe1409dab5663d20ce0f0ff9a3c1177b2ab40309eec8c846e155c81d110cbe78c96f10cc95b38b06fa0558278342dcc36181d9f5ce3b89 +Clang.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/f6d3e2f0760e1669fd099902d80c8eb7 +Clang.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/a4295c4bbfa7541bec11d51a797595405fbe6f7dd27f5feb9f5aba44a43343b1ec07dade9647c117e3cc822f6c16878e7cf4ec53838976456847958ff2c4fa0b +Clang.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/efea50a7bcfcfd479c56dfb5719f0182 +Clang.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/eb8e78e25cfb52c4f035ee7880896827c48b900d8d5d6d6800295c9aced66d52974218a885139746f13da43e68408d44fd7da88071f26c21407226fb501baafd +Clang.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/3138f99666b75ef5304776263b19ee71 +Clang.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/a6b9cd8874588024c7c5a28d2cd02ecc08a91617bcc98079078611c88b3821b053f3ed05b64a3129871778300544f51262cb80842ad1f56d0d7ef4bce8f311ce +Clang.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/65ea4e4b49ad2e131d897a7e3fef9a50 +Clang.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/329da8a6cc14a4f4365cc98c97d19c0e0b79f994f279e279af20e92c12f482258f378007e3e8bb9542e2b4be352a5639e863cda2b03c9a6e6a35ebc979d4e613 +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/57a3cb518d3b97d78752d0e58c758f2c +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/0359d1283c0bcec1932e40c00faa4571df6676af7c0ac1c7044da395b6240ae1d96e8566a15bc695339b1646910fc1edc9b60fb1c5339e8772b87ff0b38e7aa4 +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/135f3526951dcf3453a8f368dc203753 +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/804fe6b5393d551a3278b3a8c17c06f23e8457225f0040a5179864bd814acdb4dd285203d2bd9c4a991d9ca45eb6ddc4e2a6ecf3d37cad5819f67dcc65057197 +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/48eee8f53f4cba55d7c178ff93c0bb97 +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/944f03b54a8c4d185406f3d492aa6dbe6d2c6ea85e55fc8bdd9b1099f32478242e567175d587750d74ee9dc0cf88018ac07911e53e86c38eaa22e145ecb4f928 +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/b0887d9a754fcb9d69d57326e6bbadef +Clang.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/ab01a41f0ef3444618e61d4e4a4a79236147026efc2909fda1c11bb622cb43178fc60ed494d4d480a1cad947d0b703fb8d6f39c5e3b503e246f2fea1c6a6fb24 +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/86d8d2608c949d81eafdafe5566e5dea +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/d7b5c8c6d296883237bcdb7e1b3c14f486a689ecfbc323e9f21a3037f8349f67f8cc69ac842722544f0a51c589e970abbdcee4f7d6f62b624b8ff36c1810c739 +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/3cbd719a2d2d9a5a221234acc259ae3d +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/3e6587a89880a4fa46e2488a2d825afb58fc747c17d854b71da15113d37f6d23213a8026a50fb3b7173a7cac6d8edd51837782971abc2a1b19c18645e97b1599 +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/6f8373c6a149020f96abdbb55bc464e2 +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/a8e655239e436892250ca329ce682a924eed4dd85eb03cf29716f4606f8ade05e6e5808e2bdd69e3e0dc7f648b7ee318e1c966f9793cfd09099283ff58ff0a40 +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/ad3f423db87f59f7dae16011e1d7e749 +Clang.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/613e5f4a5f00f67471cdf59df2ec8748301d781edb9a4122cb48a89805930ac681dc6962d629fca272b204751e8cdc3d4026d14f5209a85f007de458719d7b44 +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/8f62a3e5ee232df367ae24ef441262a7 +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/fe058fca8c840f09acf853811c4b1c3360826150ad2b8c331e005fd7a3eee2967dcf59cbccd72e32e906490b208f48c91e9e0bd6d20e31f0fb9e002b964215d6 +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/a15a3f2724dc4f50de9b5471194b1b51 +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/74a798b2c87ba66c049f25f25d14cd3682a4a3e515baa59c8c0207cef7f5496bbd98a5e3b292560c15fa8816569296bf82d5bde4c7e030308f9011a0c69c1840 +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/d4dd462dde96aabc2fd58dc142e8e37a +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/a6e3816306d333e0ae01da09569fa7bf9c6af2b04e9f43be922ec6b70deab7607c928acf4bf64f27dd2d0a8811ac40c0334c432a2862895c2e34230592c66dde +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/a48d2577f84929236a41dbcedcfaa9d5 +Clang.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/dc87739dc39864372cab02e4d6bbdda3fb7f10f51c2bc05a45e9debf58b81c80cebe95300d116f85b3838eabd8d157f7dd325f797147fb17d1578d0e27ee12d3 +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/1f48da1003bb100eb7646ac587802dcb +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/9a5132ffbaa315ea03c220646886ac6775d07ed62cd94fa72b49a5eb64705ec701459a0894dfab13f895f39f12db740c2bfef61b23e5ef5d6879188f76c05f6f +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/7904719daabee715eb119aabe407d821 +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/7060e68295d2c3709bc02ad369616323771d12c62dd58fb95cda09007dcb4983bde68150cc7190fa3d96cb8be96f6fe3cbf4d88178e847aef7406d7db3639d58 +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/44f02b2fdfd7714b9eb4d9f2a3120994 +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/e71c06c472b5e5f08479c48d8520c4eccd44265b8f200b12268739da8c3c387a25bf5b7dd556da27cc5063fce5627d4507b6f5dc73781e21a16d59954979b4bf +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/3654e21fd175679b200eed03ef251023 +Clang.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/6ec7478869b94b20e4069ff465253c6f8e66c8254a855423d43f288fcdaf3b283761660a395dac3227fd9eb3f10ffb7592ab709d15ee554d5ce35ec841a7a2a5 +Clang.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/a22748f90259dcbb30bb95d6c468b93c +Clang.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/1a4728e6a43fb4e527ef3a1ce791f9c0f90f351bddc2b3e0a58b7ae68eeefd0007429e49e8d3b2f606acf1d75cdd74c7c17b7b2124d6d524bed46d800f3a3be6 +Clang.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/a82d206cec9e650916da80480c7cb475 +Clang.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/ac15d4f641cb8410af7e66cbfa22a90d6772926f4a918f6a36dd80f30e3f5f226fcd13019b68891d7569cde1902b872e9e8426ee753bc64e7d3360b362bdb4d1 +Clang.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/0a7fc5a1150c3f6890b6b445c577a737 +Clang.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/a1ab1a9fd500d2e97f95f01c9580c454e94f93c4e7cef3aa667c14e98465797b4d2f172ff2534f7eb0c05a94f03d8a4bfde0f0f56a46d2199163ff25f55cfae3 +Clang.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/df70c6d93254aa1680138ec8a0758410 +Clang.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/49a297bc347ef68ef1fd1c331c1c91526ac618459d132f2404e62e42d6a31f9485be6500d41d332b740261b64a704ffa373ab2d9f455f637185e96d7345090b5 +Clang.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/613a1fd0ddbf4ef27848ddaef2525f9b +Clang.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/6c5e544e400cdcd301515f7aaee5d24e46fe33ba8961795ac1e81a30403848ac23429903b999c32d0ac654ed6a4727cdddf3245f786cc26de54e437c721902ef +Clang.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/bb28c582b879422fee920ba57821b2f9 +Clang.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/3b7efc14099222759c45f3ebe8289e5781c0ff92ec38da476100eb57c69be491e4536025ae8f4c427182628143422e0dbe2d16bc0bada70db69a466aa08412c8 +Clang.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/b291718251843b0141b72095953151d0 +Clang.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/c2b631aac4f113c1fa8b2141d574abd6508eaaf1ed04037949cc731681c659f3a4150aa621225bbcdef32cafcea7cc756188cccc61a89f9f425d57a00cb823ba +Clang.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/e970211376c779e878cf378563f7325c +Clang.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/9672440cd03ebf3b7a049c977c0391483095de69f641eded0979d6fbc67b7befb6a24176b0878efbf0c8856f0470c951d00a50355511378b5f6793387b42d7a4 +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/860aa7dff4119e0b488bfe30be3255cc +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/92a40626eb48b70b89b53c81114bb8c022ce38d4582049e3a3520d396c22028e34229bf7d8a4cd6c840f979a4edf424c458ba33da15db5a4cf34b038ffae9389 +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/892cd95401702eaa30d0b81b0b1921b7 +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/ebc9a819d352137b23338801c59df02afef86a780394397711a36291fc86e2e3128bde5386ced54142b297116b03af27bb9a5e6b890ba49d32a2e4a07730ad55 +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/3dc49fdfb7a900f9ca0593eee6b2ab6e +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/a8970cf6f091833ab2dcc07711e2d6ca31c6ee71fc8487a24a88048db991c0beb5f175da676a3031e982357030cfe359e996af9da7e8ea88359d7314a114a304 +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/52a9bd4fa31f79a4b3fafc32c087e7a2 +Clang.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/5befeb640f0d0200389c78f8c01835ea421d7705bd589f138acc2ae0b08d4f01614dfa4b165ea40dd6bd50c4f11c9252e507bcaf9767bb00c099d246770a9704 +Clang.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/229dd91f636793cc2d9cf940d2abd3a4 +Clang.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/1ce5692bcb8ef1547479dbf9bf6d2abd5ec8f86ff28d3f7a9c79a314a0847437b18cc4f6a3b280c3dd01339130acd39f31cf21dc0911d5104ff1b465af05ddb7 +Clang.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/25b1b7a73c93e02879c4bfe665c1ad44 +Clang.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/6f919c7b3c79046a1ec079334e827191a051f926e2385acb019e47a418002b1702a8b6e50cbb3d7a2be480dd942f93a740f5a34a878dd291ca1f27f59867d04f +Clang.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/7b378124b57c43c59737adb0c25215bf +Clang.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/87597c30161ebaebcfd22ac8d032cedd35765e2d15e909857940ecd441430d9a47b9186b509390d1ceeace3d6701bc7dbd56bbc103ca568cc89bef20522af70f +Clang.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/6224e76523b9a3c05ceb404452aa2a73 +Clang.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/8b99badd21d9931abad9ceae3036b7a4bd6a140440d4a9e550f5e7212fe5278fbf3e51018883423fa9b8b7d907067bf03045708272fae4ae252f37543775ce44 +Clang.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/2b2eaf5af3f56281be586cdab0a75631 +Clang.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/7065cc65c9626a745a06d22b5a0bf7672be50caf9761953b3c631a5d20d3792a37090d106b967b4f74c4c4a7309bd7647487db6953ecdcd5dd2080fe81f9e93a +Clang.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/073bbdd2a26d53c2a14c36a7fdfe739a +Clang.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/0dfbfe35be2775baa5737a7fb1bff55c5cb4158edb735d7191c1e2a9b08124f5a7949696371a2d1b3ea0cb1a0ce593e74a53ead86680675e2d54c9e16733dd90 +Clang.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/8b6e067d0b1cd9882207334269568a36 +Clang.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/98f779e75614ba8ae2ae16d3d740ebbdc1428109d5716b51e53e8cf22bc4844bad47ac37a62b23c769dd0897581acd1e4e8c6f6f70db0043d73b2c5bd44216cc +Clang.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/b3a23a539915b32d2de6ad5ed073ea20 +Clang.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/6cc5c7de57018ed61b7661965480b1e3e52c357e8a18c70aa17350613dc74df5cecfadc329536b8ce61e784eb3f327c0739f36c614af100c3b1550982b5b03fa +Clang.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/c269baae05161d61d6346dea052787be +Clang.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/7a245fe24db9b9dfdf18e83fcdc1224329c6836bf02f6b21e6b8573e6d7fdcbc597300bb396ed71cbab6a8430a75e8e58be8b1130d01e476f5ab19969baf2551 +Clang.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/0c26d80c0202baadd22d18750bf83546 +Clang.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/32ff9b8b395fa5b760b909331a4ef845b234d42ad37a5869a4a6e150ff74e1129588a38ce143ce08c5c326ba85b9bac6bd6dc3b763b72a609f65174e02a774b6 +Clang.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/8643b8eb284d1bc30ac7ee5395f98c58 +Clang.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/35d4e724706395bc05ff02c5eabb938941e2b14fb7029b6cc170f3fa59af4d7f372eea23d3b43f899a109aefdf5689eabbe0a3dd2e5d8d9e74994f56115e08fa +Clang.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/f51d045b21cc4073fe6f4a1abf80f21e +Clang.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/4d7d4222eca7dddb3c0804866dd7420742238b92369bea2c28f0e18c583ee22f2588724a5ea152ab7865399b5427cced9ad1ea58aa8c30e255b43a6c1e63c551 +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/670ac3b79ae1ac2285ee6f553338078b +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/498cd3ba565f697a70a33a14bd56eaa492d9cc4f3451c1bf4a987c00fcf53b6a7542f321869ac35a0f42ebd6e261103e9cd6a60bcac9c15932accaf972f28b80 +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/7a8e855d96e33c53fb9e5940aca39763 +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/d4e0c4efc943606092b98fd8718a6a27efb034a14a03c489c12de1abee6ad9c5567a3fa952ae183ba2b60221d70c401d658d3b6d236b28e7751ba2d3439cf81a +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/340fb259209e11bcb6ec15e0561b566d +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/b4d173c20a85363c8f10170419ef59c1a23734c19a594bd5c0232f77d64947d9559ad124cad37024fb04c37f043115777d719e96521cfb27ecdbd9d193c76897 +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/9595c42011ce0c8156d6e8c2467304ab +Clang.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/0c660e25f479ab0d01a607d1d1f59006b1504fea8b515b67726d1f4f2f4255cd9bfd5b8ae0c97d51f9bf57b619a2b1c5e9136f4a74927c55dfa127fa710108d8 diff --git a/deps/checksums/lld b/deps/checksums/lld index fff3140025e8d..660ec90c3a458 100644 --- a/deps/checksums/lld +++ b/deps/checksums/lld @@ -1,112 +1,112 @@ -LLD.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/229323a0b31c29b4221d79ace1a76820 -LLD.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/c00fb8bf309f0cc6c8cb4465cc0062a8b1a848d9460c53241be654d88c598847b4590b4afa4b71c4859cfc67490942eddd79ae9ac4d75a9b0e392fbf67389a92 -LLD.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/ce7804a6a846d0d951aae34607c43bdc -LLD.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/164adec7649a36b2967872884866de1c57f6f54e1c24f955593f9f6a10cd89c69493a64a37bf9f001ce3576baed867423d138dfb1df0139b4c1312e81001b167 -LLD.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/cea134f347bae257cf5f55b6388cef81 -LLD.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/16b59143e929791b0c3e56cfb4970d8b3c87adf6e847fa9e2aac17c4ff2aa311ba2c7511c1b0ae2f39d9aa92f87ad4d99c042fe35bec391ac865fedb72bd3b1e -LLD.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/5f903bab0e38fa608e8965acce6f020e -LLD.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/01e5f6a32958e04174c545f57c6c3b1bc88ccfd5ab18dcb9d67b92b55ebc7655a03bf963c4eaf7e5c3792d4691427a89db372e7534c6c8f965f8a715a32d9284 -LLD.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/241a55374fd067f3736a2bb929e47015 -LLD.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/f1fedea4e6b5f6f3bbf4d705034d6c51b06f011c2ecec1ae49c5b7bd123891eee8b991462d60be7fffd58f7c773afe910a06ec0b55b37eed9b4d09b9fdbd5068 -LLD.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/ff018c7448a7589935333e46739ee2c4 -LLD.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/b646c6a945b8f42b396164a8e87fc2e54b1ad05681f438dfba83fdd3712a60167aaffcb0300bc42d904eb4bd34c002a71642b59540ca01e64d6fecc6daaacdd8 -LLD.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/e6ee9423a82322b9233cafb1c92eed2d -LLD.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/c915582a9ce2dfa8721741fb1ed19b719ba40f0092c2d29ebd68829ee558cef0b044a5e40985cff88e89129cbeed052d85fa5c6b6d87f9b3a68a6e89079ab4f3 -LLD.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/cc55112e2db358cf26d7bae3211d8e4f -LLD.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/0ecb43045419020eea911f1767dae23a6b1e81bb155ec493e911a9412e45f7ec71461aea2e6fe346e641747139cae43d9435ccecaa7fd6a234e4d69bb06606ed -LLD.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/498b2909f80b20588135466d5211bc80 -LLD.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/120fff24e85cf970670b20b5f4509475a3ae0d7621f8f67d018f3a7625548d736a3abc89f015966b1329c6b0a08a1db832e035ee3bae384e2c5864b73a856600 -LLD.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/1bcd298d5292f8e51f19b97fa4b27ab0 -LLD.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/695c42557f9ee53b2e10bbf74653fbad4d02124b962a1f50cf719d2821607dfbb9c1bf638dbbc9e0e544f3020a9ef4a82decd13f886cc41ddf47c07a5e40eaa1 -LLD.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/f0e0668d29253cd834418c88ad63df31 -LLD.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/f910fd8ca972b1cbe0704d4d73273e2d6911d31ae5fe842250802cd33453e4fa2ed03ae4b4df43ea4df13711cf2409c16b1c44832b44cb05f7681488c4402681 -LLD.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/84f79f1ce1fcd57ec4bd499a684da120 -LLD.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/d0e4a7ecff0e3f499dc22a9409ab8bff9099d4fdf191916426be917695c7fd55043b41cb0fa21541c3d6a6c202736b5c7b8fce53244e3ac713560a47a0ed6588 -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/2323ff933feaf3754b442bee48a63607 -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/47b8e490b89e04fb8886dae438e3ddcd53c4e98045de2b0def3988671827528c8e9ae296411464c0f17cc64bd3956644673f47a3817237f27e1c3ed16ac8ef01 -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/37cf8528666064a434296f2e0039e9c6 -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/ea1504a859509f8a16030db7a65f42f0e78d67adf5946497f2178bf25456c0f2583af72c636881a4bdd1210dc0d377bdf300ef55aef5db8c56995424a1886059 -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/1c341f2b161e2320d3d1a74685887f54 -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/4f6fc099293deb1a2cf729ea7edd6e17fea0dc8b9fae9acfe34e00b1f5c798933df9538c805c8d28c6279eb38f9ebae2a1aeb1a2f23087352c6eeb3b27b63ddc -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/e306d59c71b0958c77108e650fac2612 -LLD.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/79fd7cec0e169a9555ec9b0acc3248991e2e37a1d5bb422808ffcfd4f47e79321560b7985c82dfe070fb0b5ded5c160d83e358399c6e7608eeb62cd4a1406f88 -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/c1d080f1aebb58778d730578fb113290 -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/1f420da1897bd0a61413321aaaf032e8ed38d59e6dfe3313ca3a6ee6582ae6c566e3761ca8fcd1f5a964337ba8a9b3e73dc55ad68aca139beeb45e43d51e862b -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/6f4e0c7d2fe9ac254650dcd2842dafa8 -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/bbc71b334250e5e6429766d88595adbb671a206630987ec2a27e05711ff0f844487dffc1c136052ec11394e9d5c51c70d1b75d5348f97d3bf7fab463291e9dc8 -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/76925b9a7bc249b2227390c479c54f8d -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/20643ecb79732e3ae9666116dbd0763c18b808afa78e6a14998aadc7265cccd6efd28670592db61d3d27b8d3023be4c5f3df41fff9e1b38d61abf76829090b4f -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/399b9aac140d9050088fdb187ed4645f -LLD.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/8bab65965670fe392e78d0b9dc78c92cdcf202898f6d5a3174eb89ca5cb95b995675c8a7d81bbc4e95e490ad1a43d9d29d7907b7006789c0143a1d8f24cccaeb -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/026a4f5ae9eb3ac05e5e8fa894d77a5b -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/4bca8bd558619260cddf4e2f4593cbb2a0691b5ccc6d1dea6dfcc5a2b5f51d7d1a76c35e481244e211e2eacf32bd628df5ad0e6c75e5185bb1d9b569f6acbfd3 -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/f898ceabcba052b7e6713a2b2c208a92 -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/92be1910f795390be5f15ba5b2c220a3209a5f7ac04fca3f5229486628bcf5d2f20cf6e4dda8b41d6beaaff42a68a9ddb95fdacc6eae33b9183b581e9a194895 -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/e366058cf69a4367945bdba9523f2a0b -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/45a786e8d0162bd5bd01c029691d2928d3744ef4a7a1efc2e39755dee2f9a9ae23ee725f0454ca601cb9c082a342209e9129df851314b5757c74767b13508fc4 -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/665a8502170729c86ea95a7ea2fcce0f -LLD.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/c1a2a85c9ce14af8c91bc9a599393c52c0b8a585057366b1ceeed34c5db44641ecd0c9b377bee80cb4951fc7102fbb4f21fd050126bfa5bb4e582ffefee17035 -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/b90b2130262f63f5189cc8e4a65e4433 -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c1cbfd38c82d676c3fdbec486691334cf7bf4115d9ef2665012b71725c28545a49f34edf5689ea0352822c811c24c89cc152d1fccd1586b17ae8e6b2503641df -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/2d5360da4b2c9ffcea5d0a646a7c114b -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/73323e0937fe4423883480294c8df44744acde4f47380e35535cbe69c855c0e35e86a1eced3085ae0285f284f47af5ef237f4650bf2b6a8b9d5308efce88fa02 -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/a9b9a65938a7701aaac6fa706481c867 -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/fe8243aa131ad8be54f0fca5754c2e68ec39049004ec8feed499731c5228a7a46e303ba866b9f9a55e5318c73d8a46d964673e111f6c60e5ae1628c568d7d894 -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/0d9592a287c9231ae2db65000be2cea2 -LLD.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/4ee192dd33f518d2735a829ac8f822b5672b39e8c2254987aea6e5f2f0056213bd85d84c4050d52ba9ac8c35762521c324fe2d6e18db0396e7142af9cb61a561 -LLD.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/d487598dec9969485dcf785fc0968bd4 -LLD.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/8d3117739919696b9b0c9ae398f1b1e9db8bd3e2e27839f62b3551c22ae2517f8abb69e57e23d125002bb466889b7352e69c1e9dfd9abf1c5433f274e928b341 -LLD.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/943434b08dffb54e8cf04ae7bee34923 -LLD.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/77b7bbc5d988cf36ecd10609e091cf24dea134cd32c7ee96dec7bfe1a4942553b6205653edc16c8454261f621966daeb267f42562172bab4cec9693ad733d867 -LLD.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/cb9e371947ad415de048636ed78ca48f -LLD.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/c00b696fa146e8c29b37f15f78ab3325db9b3f5b3514e615f145b4eb7c9c8788662cfb6255b7dead596cad8c576b378f7459c2c85d462b597ba5e21adbac0536 -LLD.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/485f061ee8425f042e4dd3042388bf8a -LLD.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/845a47a36c61b305bb70b1249f6fb7c4e8f740acff90d3e850ab2e887f7d959ae263431a02305bf7587e4194463f9932769d500a19709bc479eb6e6168325421 -LLD.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/e4f97e8334e1f29ad9083d051a50eab9 -LLD.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/13ff037881da8a2333129bb702f515a0eb1afb3e4f27298c035c133ce5c512fa643b2a90df38d6f61b1dd5e86e32998b9061241358b61be794caba2b989efb70 -LLD.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/570f50ef6523cb8133b160af8fa2057e -LLD.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/69ec402469b2b2c85aabca1c8b36edd0c53b7e678e4c56fd96062b62a57b7ff1008f328d71e6aee36d4270a41a7bf84f62f934007398618b5426202d9614305d -LLD.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/0503dc3e4e69ca6fd7e2a5dac9c4ef3a -LLD.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/9b6c851341c2642d5ed9169326b4de9eda50ea06b1270a721d2e85bce8ffe4c595cd491e0a218c3a418aed526f881737fbb44cb417cd5ba7db972bcbaa6ad0d1 -LLD.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/08b22e98c514d48ddb1039b44f64f480 -LLD.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/5e5b7c66d5fec3ff1a9cb7989d62887699cc3e70ab36a94e6f157cb0b9adbe8d63f5f1a74cfb6765cf46851087019b12ccf09ea848ed6456d17cdc796a5bf2e8 -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/7962fc6f08531f0dcfa44bd667f31582 -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/2c936064685f12ed6764c187192023118e97dcbff6ca1656f0304a40772b4ecf55ee0296b3c2a00760f5bb437162e2b737635fdd59b889d35756d697fc7e6b72 -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/3eb4d78af670d446f696449a5e71e3ba -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/315dc76799f3e443fdb5ebbecf96a08070f8251930a26995de892b8e67bd35bbb365f2cc5fd93bc7cbcbc9edd08280ee8d2a36b28a704866dd3fdddae4969455 -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/e73cadd0354897bd5bb611cc1c027858 -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/6f444a4ea22e7108ab75686ce9cd78c0db0a677e39e8434896fb1ec90b9dc013abf7de1024d329a9726dabf229a8a68c27a11f211092e676715d282efb7b8504 -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/aeb310f106f31126dbe53459e36d33bd -LLD.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/cd18c115415dd92bc7fbb5c29cacc5848b1f3851c3a526ff9c0813ad46824df0a4f13a66b1e6641ed11b44b5b937390619f01666fe6d5a047f1772f0ad03c941 -LLD.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/9493a58ed62367b45a055c8880de0924 -LLD.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/5a448c87ad627235d7d2c8f8f8866af0f6872c3f7775123edb09b23b772f165fa020fe0c592ad100f8c777213fe1346b642a556df66ed003771eb0e76345215a -LLD.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/d397b37abf0026ca69fa6657dd791e27 -LLD.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/9e9fc915389bfa09cbe8b977f22a3466ccda052f415b3b5fdfc97a15e089d4f887fba97d6bfe6e17104f09bebe48c859bad25e9f2cabc179000247292eafca1b -LLD.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/5dc96eef71dc28611bc998ef966371c6 -LLD.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/781993c75bb07db96d02b5a7e779116864730a9bb941b64420a435956a7ecd501b5b2673f1854c09ece5f0c73559d5723c271d6352be57ddae6801a695629362 -LLD.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/8a1fe0ccf7699ab7a7a514b620112a70 -LLD.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/d002083045d3eb7c749f2e97527c1228cd317a8138ff254228e43594a6cabee47fa363785466ebc2874cc438457640ff08a836eec7334afac451506ea7bbed03 -LLD.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/331be92bd3d76bb8e86991b7832ad41a -LLD.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/7b1c6df53311a17a92a41cb67ec476f947949c4ca5d15a643badaf9f01e76a186abbb6e156f95ad1605d83250df4e081164986a6b7fcb3238076b0ec5a3bb565 -LLD.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/97c7f5267ad6927f699a25ce44f55a70 -LLD.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/7b847c6026fd7daeb17a4459b852562ce6664b2f406664be672bcc384dd5a79b9505561fc61dd8fb78a903a2ed4978f322cccad19f5a3966bac856e877c11ef7 -LLD.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/c86da6a396fcdddbd26cfd71c0f70458 -LLD.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/8d5b75b43167080b8ea456e516c9ace02ee6066ce715a56f0b42cb8045b965b1cf8d4ebc0786c23be4544693ff858816a6257b0638ec11e077df32ead62f7efb -LLD.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/d72e175272ed893688d18e868120c575 -LLD.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/9a46eeca8c7a8be65ed487a74227534e08a257e404814c44730f12a5bebc8cd160998cfd5ed30189aa606ddbe602e1b1788e465e4a210103c6726a7fd230abc3 -LLD.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/0206fdaa9582ae3bddaed1b6fd7a8cb5 -LLD.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/584a67f603f656ca5d27aa0ef2e425ad385612aff06cdc1d534b5944939a09246c93954fc153b8a89acff721e657a8903af9a640abc252d4e452f348781bca98 -LLD.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/0dd14af342467eac2e13cad4acbc881f -LLD.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/918f2c66898f828414009fa6ee273da5bd654e4b787ebb4d703f0be27e388b46870d68bd58c4f45638d276c61c1bfe2f3c67fbf34dfb5578158d072f82d927de -LLD.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/d1862068a670d4c04887513b914e11a8 -LLD.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/c5a91657667394e468e71d9c07df0c71918d63d094d2598875f75cf3830d8502e70f59fba59b07a2d1e0551f58d0487521c856e68e4122fd6a6f7ebd1c7c0f58 -LLD.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/8dc0ec01029765dbfdd28d63bea8cfca -LLD.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/234e9db1177003a074c6ca7236c589424b4617d1a359f5f9e2ba6095a7f317d62ac731319b4b4513c523e80c15b82c99ff0fc9df5f76fad452955492e9935b1d -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/7beb510d766ac1e16017aa6924e88659 -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/bd18b733a6b2fbbeef7f8af2f13dade0330a525c83b4faed5a5d2507007be2f2f7be70f99d05524fa94ae1dca524be64adbb9dc87485477f62109f44cbae95fe -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/9ecca76cea81cd1d0fd3470778145371 -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/d1548402dfcb4aa0cf3c9e445a9810e5d8bc2411de9943b57e892ec82af29e214f6d93c58af9cd0de9b4fa5a0438e4c1fe0b9591a9582143d470e7a42e685f4a -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/b1de7acc21fe51c1486854cd46b71bae -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/9f8457c12801584340b3fbf846920299756359016d151018562f8c14e0a03f657fdb6eb1d7418fdfbf586c59e670d866384e822de9bde15b2dbd031ce5e6af8d -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/373a7007eb8b526811604fb0161f73af -LLD.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/b586815621f698c7d6ff995c93e11ea1ec55e7e7c0e34ad874f64b942ecd73685cce150d51804bdd371ec42671e7814e364944276ec91282b9b8b8226a6d5786 +LLD.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/229323a0b31c29b4221d79ace1a76820 +LLD.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/c00fb8bf309f0cc6c8cb4465cc0062a8b1a848d9460c53241be654d88c598847b4590b4afa4b71c4859cfc67490942eddd79ae9ac4d75a9b0e392fbf67389a92 +LLD.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/ce7804a6a846d0d951aae34607c43bdc +LLD.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/164adec7649a36b2967872884866de1c57f6f54e1c24f955593f9f6a10cd89c69493a64a37bf9f001ce3576baed867423d138dfb1df0139b4c1312e81001b167 +LLD.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/cea134f347bae257cf5f55b6388cef81 +LLD.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/16b59143e929791b0c3e56cfb4970d8b3c87adf6e847fa9e2aac17c4ff2aa311ba2c7511c1b0ae2f39d9aa92f87ad4d99c042fe35bec391ac865fedb72bd3b1e +LLD.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/5f903bab0e38fa608e8965acce6f020e +LLD.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/01e5f6a32958e04174c545f57c6c3b1bc88ccfd5ab18dcb9d67b92b55ebc7655a03bf963c4eaf7e5c3792d4691427a89db372e7534c6c8f965f8a715a32d9284 +LLD.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/241a55374fd067f3736a2bb929e47015 +LLD.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/f1fedea4e6b5f6f3bbf4d705034d6c51b06f011c2ecec1ae49c5b7bd123891eee8b991462d60be7fffd58f7c773afe910a06ec0b55b37eed9b4d09b9fdbd5068 +LLD.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/ff018c7448a7589935333e46739ee2c4 +LLD.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/b646c6a945b8f42b396164a8e87fc2e54b1ad05681f438dfba83fdd3712a60167aaffcb0300bc42d904eb4bd34c002a71642b59540ca01e64d6fecc6daaacdd8 +LLD.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/e6ee9423a82322b9233cafb1c92eed2d +LLD.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/c915582a9ce2dfa8721741fb1ed19b719ba40f0092c2d29ebd68829ee558cef0b044a5e40985cff88e89129cbeed052d85fa5c6b6d87f9b3a68a6e89079ab4f3 +LLD.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/cc55112e2db358cf26d7bae3211d8e4f +LLD.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/0ecb43045419020eea911f1767dae23a6b1e81bb155ec493e911a9412e45f7ec71461aea2e6fe346e641747139cae43d9435ccecaa7fd6a234e4d69bb06606ed +LLD.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/498b2909f80b20588135466d5211bc80 +LLD.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/120fff24e85cf970670b20b5f4509475a3ae0d7621f8f67d018f3a7625548d736a3abc89f015966b1329c6b0a08a1db832e035ee3bae384e2c5864b73a856600 +LLD.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/1bcd298d5292f8e51f19b97fa4b27ab0 +LLD.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/695c42557f9ee53b2e10bbf74653fbad4d02124b962a1f50cf719d2821607dfbb9c1bf638dbbc9e0e544f3020a9ef4a82decd13f886cc41ddf47c07a5e40eaa1 +LLD.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/5e0c29963d8f132b57cc5f7440b0a6a5 +LLD.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/7521d79bb1bb993fc088fc72cddc468c10b9c07f8732f2de12debd9f1454e8f8f6a330957b3285473dc7c5d2379ac46ddf279174f6cef04a8bb549490caa6599 +LLD.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/8255acef157147cfdf3fc94b9cc2bda0 +LLD.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/98dbf592022f7eb2db42a2349d1cc0cf3cf07f40f5ba37dfe6e1622dc86e6bd1080a860f018636401a88ab0b5098dbb863bcfc6cbb3f0213423ebcc0abd3311f +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/2323ff933feaf3754b442bee48a63607 +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/47b8e490b89e04fb8886dae438e3ddcd53c4e98045de2b0def3988671827528c8e9ae296411464c0f17cc64bd3956644673f47a3817237f27e1c3ed16ac8ef01 +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/37cf8528666064a434296f2e0039e9c6 +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/ea1504a859509f8a16030db7a65f42f0e78d67adf5946497f2178bf25456c0f2583af72c636881a4bdd1210dc0d377bdf300ef55aef5db8c56995424a1886059 +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/1c341f2b161e2320d3d1a74685887f54 +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/4f6fc099293deb1a2cf729ea7edd6e17fea0dc8b9fae9acfe34e00b1f5c798933df9538c805c8d28c6279eb38f9ebae2a1aeb1a2f23087352c6eeb3b27b63ddc +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/e306d59c71b0958c77108e650fac2612 +LLD.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/79fd7cec0e169a9555ec9b0acc3248991e2e37a1d5bb422808ffcfd4f47e79321560b7985c82dfe070fb0b5ded5c160d83e358399c6e7608eeb62cd4a1406f88 +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/c1d080f1aebb58778d730578fb113290 +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/1f420da1897bd0a61413321aaaf032e8ed38d59e6dfe3313ca3a6ee6582ae6c566e3761ca8fcd1f5a964337ba8a9b3e73dc55ad68aca139beeb45e43d51e862b +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/6f4e0c7d2fe9ac254650dcd2842dafa8 +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/bbc71b334250e5e6429766d88595adbb671a206630987ec2a27e05711ff0f844487dffc1c136052ec11394e9d5c51c70d1b75d5348f97d3bf7fab463291e9dc8 +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/76925b9a7bc249b2227390c479c54f8d +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/20643ecb79732e3ae9666116dbd0763c18b808afa78e6a14998aadc7265cccd6efd28670592db61d3d27b8d3023be4c5f3df41fff9e1b38d61abf76829090b4f +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/399b9aac140d9050088fdb187ed4645f +LLD.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/8bab65965670fe392e78d0b9dc78c92cdcf202898f6d5a3174eb89ca5cb95b995675c8a7d81bbc4e95e490ad1a43d9d29d7907b7006789c0143a1d8f24cccaeb +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/026a4f5ae9eb3ac05e5e8fa894d77a5b +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/4bca8bd558619260cddf4e2f4593cbb2a0691b5ccc6d1dea6dfcc5a2b5f51d7d1a76c35e481244e211e2eacf32bd628df5ad0e6c75e5185bb1d9b569f6acbfd3 +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/f898ceabcba052b7e6713a2b2c208a92 +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/92be1910f795390be5f15ba5b2c220a3209a5f7ac04fca3f5229486628bcf5d2f20cf6e4dda8b41d6beaaff42a68a9ddb95fdacc6eae33b9183b581e9a194895 +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/e366058cf69a4367945bdba9523f2a0b +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/45a786e8d0162bd5bd01c029691d2928d3744ef4a7a1efc2e39755dee2f9a9ae23ee725f0454ca601cb9c082a342209e9129df851314b5757c74767b13508fc4 +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/665a8502170729c86ea95a7ea2fcce0f +LLD.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/c1a2a85c9ce14af8c91bc9a599393c52c0b8a585057366b1ceeed34c5db44641ecd0c9b377bee80cb4951fc7102fbb4f21fd050126bfa5bb4e582ffefee17035 +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/b90b2130262f63f5189cc8e4a65e4433 +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c1cbfd38c82d676c3fdbec486691334cf7bf4115d9ef2665012b71725c28545a49f34edf5689ea0352822c811c24c89cc152d1fccd1586b17ae8e6b2503641df +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/2d5360da4b2c9ffcea5d0a646a7c114b +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/73323e0937fe4423883480294c8df44744acde4f47380e35535cbe69c855c0e35e86a1eced3085ae0285f284f47af5ef237f4650bf2b6a8b9d5308efce88fa02 +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/a9b9a65938a7701aaac6fa706481c867 +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/fe8243aa131ad8be54f0fca5754c2e68ec39049004ec8feed499731c5228a7a46e303ba866b9f9a55e5318c73d8a46d964673e111f6c60e5ae1628c568d7d894 +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/0d9592a287c9231ae2db65000be2cea2 +LLD.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/4ee192dd33f518d2735a829ac8f822b5672b39e8c2254987aea6e5f2f0056213bd85d84c4050d52ba9ac8c35762521c324fe2d6e18db0396e7142af9cb61a561 +LLD.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/d487598dec9969485dcf785fc0968bd4 +LLD.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/8d3117739919696b9b0c9ae398f1b1e9db8bd3e2e27839f62b3551c22ae2517f8abb69e57e23d125002bb466889b7352e69c1e9dfd9abf1c5433f274e928b341 +LLD.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/943434b08dffb54e8cf04ae7bee34923 +LLD.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/77b7bbc5d988cf36ecd10609e091cf24dea134cd32c7ee96dec7bfe1a4942553b6205653edc16c8454261f621966daeb267f42562172bab4cec9693ad733d867 +LLD.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/cb9e371947ad415de048636ed78ca48f +LLD.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/c00b696fa146e8c29b37f15f78ab3325db9b3f5b3514e615f145b4eb7c9c8788662cfb6255b7dead596cad8c576b378f7459c2c85d462b597ba5e21adbac0536 +LLD.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/485f061ee8425f042e4dd3042388bf8a +LLD.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/845a47a36c61b305bb70b1249f6fb7c4e8f740acff90d3e850ab2e887f7d959ae263431a02305bf7587e4194463f9932769d500a19709bc479eb6e6168325421 +LLD.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/91ff693c2af0f7621b2f9060df25b2f6 +LLD.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/f15f7979db0b0f575cd6f8d9c052cd4faab663cb184ed3fb74f68734bc7c2e41c251ad893c3a0abe8c546a9ccfe73e177c92d28a892e5a3887ab8d8ef27327e7 +LLD.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/32d0692c49e490481a6feb672dcc6516 +LLD.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/f336b14dc27bb0db25e1af267d9b6c21580f9b01a610d08d15cfed47c77a5be0664d473e21b910754d82a2e7b3b68607c50a227b4c40b48a5f6ea6d23fe12638 +LLD.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/1d9612a61214b47d466a97e929ff5b20 +LLD.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/d38f71363ba0274f32221e42e655f27a1c40ee9e22c3cbf1c478e58fdbad040dca529bc6d74fff82c171825aa091ed39a8c043f9291fbe66a6c3ad4c6032a1d0 +LLD.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/21f4b3cbf1bd87843f73ccfe053d75b2 +LLD.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/fe730959877ad78e6c5d5ce72d52fc5639357436ff396bc2dfe0488c1a8a5da512fe418705741bd6868b4e497cfd4fbaa024f9a2d49034d6801170db09081872 +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/7962fc6f08531f0dcfa44bd667f31582 +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/2c936064685f12ed6764c187192023118e97dcbff6ca1656f0304a40772b4ecf55ee0296b3c2a00760f5bb437162e2b737635fdd59b889d35756d697fc7e6b72 +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/3eb4d78af670d446f696449a5e71e3ba +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/315dc76799f3e443fdb5ebbecf96a08070f8251930a26995de892b8e67bd35bbb365f2cc5fd93bc7cbcbc9edd08280ee8d2a36b28a704866dd3fdddae4969455 +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/e73cadd0354897bd5bb611cc1c027858 +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/6f444a4ea22e7108ab75686ce9cd78c0db0a677e39e8434896fb1ec90b9dc013abf7de1024d329a9726dabf229a8a68c27a11f211092e676715d282efb7b8504 +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/aeb310f106f31126dbe53459e36d33bd +LLD.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/cd18c115415dd92bc7fbb5c29cacc5848b1f3851c3a526ff9c0813ad46824df0a4f13a66b1e6641ed11b44b5b937390619f01666fe6d5a047f1772f0ad03c941 +LLD.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/9493a58ed62367b45a055c8880de0924 +LLD.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/5a448c87ad627235d7d2c8f8f8866af0f6872c3f7775123edb09b23b772f165fa020fe0c592ad100f8c777213fe1346b642a556df66ed003771eb0e76345215a +LLD.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/d397b37abf0026ca69fa6657dd791e27 +LLD.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/9e9fc915389bfa09cbe8b977f22a3466ccda052f415b3b5fdfc97a15e089d4f887fba97d6bfe6e17104f09bebe48c859bad25e9f2cabc179000247292eafca1b +LLD.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/5dc96eef71dc28611bc998ef966371c6 +LLD.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/781993c75bb07db96d02b5a7e779116864730a9bb941b64420a435956a7ecd501b5b2673f1854c09ece5f0c73559d5723c271d6352be57ddae6801a695629362 +LLD.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/8a1fe0ccf7699ab7a7a514b620112a70 +LLD.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/d002083045d3eb7c749f2e97527c1228cd317a8138ff254228e43594a6cabee47fa363785466ebc2874cc438457640ff08a836eec7334afac451506ea7bbed03 +LLD.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/331be92bd3d76bb8e86991b7832ad41a +LLD.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/7b1c6df53311a17a92a41cb67ec476f947949c4ca5d15a643badaf9f01e76a186abbb6e156f95ad1605d83250df4e081164986a6b7fcb3238076b0ec5a3bb565 +LLD.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/97c7f5267ad6927f699a25ce44f55a70 +LLD.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/7b847c6026fd7daeb17a4459b852562ce6664b2f406664be672bcc384dd5a79b9505561fc61dd8fb78a903a2ed4978f322cccad19f5a3966bac856e877c11ef7 +LLD.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/c86da6a396fcdddbd26cfd71c0f70458 +LLD.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/8d5b75b43167080b8ea456e516c9ace02ee6066ce715a56f0b42cb8045b965b1cf8d4ebc0786c23be4544693ff858816a6257b0638ec11e077df32ead62f7efb +LLD.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/d72e175272ed893688d18e868120c575 +LLD.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/9a46eeca8c7a8be65ed487a74227534e08a257e404814c44730f12a5bebc8cd160998cfd5ed30189aa606ddbe602e1b1788e465e4a210103c6726a7fd230abc3 +LLD.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/0206fdaa9582ae3bddaed1b6fd7a8cb5 +LLD.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/584a67f603f656ca5d27aa0ef2e425ad385612aff06cdc1d534b5944939a09246c93954fc153b8a89acff721e657a8903af9a640abc252d4e452f348781bca98 +LLD.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/0dd14af342467eac2e13cad4acbc881f +LLD.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/918f2c66898f828414009fa6ee273da5bd654e4b787ebb4d703f0be27e388b46870d68bd58c4f45638d276c61c1bfe2f3c67fbf34dfb5578158d072f82d927de +LLD.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/d209b46c3919a674da300effa7fb2c8e +LLD.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/d56ec5a6e4cbcfd3ba4c4c9549fa9f39fca262c5ef238fb338548d4df35f277f3e266ed5112f8ad056a6ad18eb0258afe79ba1b9d391468059f9c40b9981dddf +LLD.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/e22a96444d1b00a86b592b30dbf925eb +LLD.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/acfef951e6e0d0bbd343eeb4bd9c5485696916780c73d5eb81a76ea440ff97e2577205c85c789d0e92e6048a1595670b31e47d56caf5d02c5d423990246d8840 +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/312c816be2aa7f123a387905f580eae4 +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/7778a5efe3edc1faba62236f9a940c1c3c2ed1743fd89b6f18162dbebd4a25a04dc9ddf25788d9a47292f44ede44a06d31a9194b79df873967b1fb6f5fef23f3 +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/e50cd7ea46f14f2237455c5b015c16e1 +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/03b4612e4a1f9449598f0de0c526bf82e7d1aa25a41800263c5dc78edb7d71dd5a46694ad164f6ede66bdb887fa821bba20b2b04e6af8f228451243928f54842 +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/3a7f1029c8dcb80486174f24e29a097a +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/df217f008e81142a5cab4a9a2f51164d14f2021a8847136317b6ed7fb2b354f194407e2320843758c76d5e178f7bce92f7ca3e7cfec482908ac102b6dffe3fe9 +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/9467b4c03398cecc20cd1d60068e415d +LLD.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/a49068058becde369c83f1a42bcd77db9dfc62744b43abd4ab1be66a47e127dde78446501ed5f4b74e8ea6bbf3c72a2c251dfd5103118253694d48ce82d1e617 diff --git a/deps/checksums/llvm b/deps/checksums/llvm index ac8c678bdf653..a408ffa8d9664 100644 --- a/deps/checksums/llvm +++ b/deps/checksums/llvm @@ -1,115 +1,115 @@ -LLVM.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/f8c2d285a6db7c3b89d295b32b78f07b -LLVM.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/99d923fff09b70093962cb32d2a12a2d2355824c1c3404900d593cfd0e95a4b52744e7d3fcd22407651916adc2e1534637437630843762c3f2c0c650881aa0e6 -LLVM.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/2ad6bf2ab91cb75bc3bb627b1859997b -LLVM.v18.1.7+3.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/bd06a3adcae64700f4051a18705e7937539b3cdfa61dda38260398a8896401a267b718594631d71afc68a3b273b0d05f6018927c3a08c070bd6c45d53b19c78a -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/7bc3125dd810bcc44ea2d454b6caa683 -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/86742a4476481b14145855ead8a5acc6397782f6d3445f900ac2de0570f1fcf53563cf5e1f3cb59886282083ce63756604f1ca2434e9e427cdc1bd1f68373581 -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/4eae06d9e6272aef23afc191501810fd -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/fb75927982b1428b05b765bd5ac017b2c15d89990b7e6cb582b9e1a3ec04d09801d25d5cc6c037a12c205edb7c0f7a2d33832a2d1de7920711e9720dc3ca3655 -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/cd86e18a63cd6e84a1493acf0df4e267 -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/1dfefc4600368467ab90ccb527a9fdb012b9b7f485d932a0db8c4b1b81985fad931b74494b76ef2162e46280447d39a055b5681b33a17c564c50094de29aeb13 -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/c7cf7daa7c11827ae4f9fb2e16f3cce3 -LLVM.v18.1.7+3.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/dabe2940606a671a8e3b4f28bb9e813d000650203c382372142457020f2ccd498534903aa99320afb7ff960a62d752ee6cb724e74745bc1bad1051e12cf78ab4 -LLVM.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/62e575b89fd92d9206abebc19b084abf -LLVM.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/7ac029567fd68fee82b7096e2fe278ee5cd2935494433b1faace036469c54bc471d614d0bb339750429dd88f3e723165d2dacaa627f73c3647c6f3b51a4a3034 -LLVM.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/5d39ef811bc78204ebfc7e98111469cf -LLVM.v18.1.7+3.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/10fc9a64d63351e168bc79fa63bcaa6fd49c8483e5ecc40a66216192588367e9b47ec3ea2c047e88f39ea8f1caf8052726f4bc8858223f7744606156b4133970 -LLVM.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/f072fe487e5d1b717aec49a6244adf05 -LLVM.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/42b03a2562728ac86e751abab2e8233d583baf006e69b107d002a9258844ad53f62e6332eab3790364940d478c7ebab6d3e0e2194220e8436f40e6b75063d1a2 -LLVM.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/eabf0239298f13ff4893011e75828bdf -LLVM.v18.1.7+3.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/34724d9c9a550c85d406021d7265e1848b002b8f212427eebff6e8f03ec6acc336efb0c2cd9d9e1c76329e7c84a84a9d852b8de5897550d957e0e9385129033d -LLVM.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/8b736710b2c749fccf0a782f3b887ec2 -LLVM.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/d7458ead5a604781a117e54a03dc6f3fc47e932298c68af425a6725ef4767bb512c910316818081d5e27d9d08b4ce1792d684c0014271fd492eedaf47acc5eb3 -LLVM.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/ed0487ad3494352ffebfac51ef947168 -LLVM.v18.1.7+3.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/e13082056be94335b1f4253afe3c4a25555b6bd10c5d68052f01117415dab344a3f883a9f25ff4ac630262756dd15825e74395650d80181c85c0663d7028a9f5 -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/1910b5daa31db6542f0c762901ab7d43 -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c43e8091e9946ba1d8849734a25b258df95b4759a79676565b624930d4a19805a78b66b1d193e528f95174d909d7895d4a4e49fe8ca298a24dc40d25c95900b1 -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/a5198b13dc75ad3454e05aa6cdaca48f -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/9ec8078a1a7246f1545fe074783d6b88ce9b50f62b0438ff5637f6dedf5bcac427cc252c350354b7063f79f4e31a19f699c168c15bc6547a207da497026c2827 -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/f569654ecdd8ec2a50986ccac8388c69 -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/9b50e3be1577a753f0ce42704846bd126229d8dd9f28bfcbda58c4f18e4b9ca4ec6bb9b57de61b3b9af8157a2983aeffb8af782a073e5e19a8ccc261cbea9601 -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/496de8c9e2361f44ac6933480620d07f -LLVM.v18.1.7+3.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/02a8ecfb6e81e0fe07fb0d616a84a590e23e944588c18348c32265bf6bf19196beec189a0bc40514e379e97a9c8bef83557260839800fabe9f8e39e96689713d -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/05bc7406fd0a703edbc912bb3230eb37 -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/898dd4c19dd0f22dcd1bd44264daa8dc64340c890c3368fac7451da1ac872a687d55b5eb50ae4e156c2dc4ece226ec05775daebafe9d8b53eb83b72d2986ff92 -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/d6ca30fc3a2796ebda2451f80846883d -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/d7dc96e1bbca38272b1ca78b3ff995fc30434937a58815c63d0a9b4a017964cfb269a1f3203ad8374870257152229941d420f098644375b5f4d1b88fe39e0dff -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/6eb1a197150ad6c165b82c5e0e0db102 -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/a159598c2bf351ea79d01e8a454a82bbd9823c080399520af3182e57259957ad07834b03c336e6225857da365e8ec1aa9f65b0ddd0821883ae817cb81f8e6dab -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/116d849cb2fb4b1c8c517397b2b04192 -LLVM.v18.1.7+3.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/7b2596c76d2814fc30992ba78e5c8f93519442fa76004187de9830732b80bfc6c77f5d7aca042c20d8f868cd682bb6f71e3fa32940bc8c7b401753dc4ac2f331 -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/27837dc854a173bd37a20f92383f6913 -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/1719205cba6de969e8724a99444bf958d5a7943ae90ee2dd11193f56ddfd4f0edf6d9af6da2e67787a64b91d994fee76bd8ffde36486c5229a980c2c4ef07e29 -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/f0016c21c045e205131ea22dc711acaf -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/6d192b7e21c7ee3327d288b890f4c5dd03e5f53dcba6905a34cab96b7ad0ab6364f5271af88d95e60aab8f569a8840d17e16f27f6fcdafcaf537d5d4a651dca7 -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/9a2bad4518966db29e37e7c88388e779 -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/b9a10af9dcbacf1f129d4e9b4cf562a6a4687252cc8a0fcd78f52d75c0c20be0ff32e67413a7902a628b04e7fac1091d35b64b145e33814899796009b6ed2853 -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/77c4e24c1e44ce14bc6476954f294a15 -LLVM.v18.1.7+3.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/d9d90a4ac788dbbc1b532623a380d4cca8813ecdf8b7b4a8cfff769499e50a1433bac618234bd0765d8a4f50aafb3fa724d16ac71baf75ae5a2b4396fa2bd017 -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/b29e36dcf5a0aa05734f1d6a0afd6944 -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/ab46a835f9843c5b3427101bcd0c5d2b8acf79693aa9b8d4282d499f25df4ca248a81fc94ddd96c75d69d3c6b3814b225eed81bec32fbe9199bffdd605f7fec8 -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/a411269f925cc968a0438562262e6d97 -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/04f275603134b0ea0f23da377e4983765885f2b1954d5c617134af9f103470a5e50dfda18bcddb836852db2382f1c134db40df00b36c8bd00e7a9e6ff1a9e684 -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/841921e33407e15eeeaa76354aa2b737 -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/e1fb8b75e141cc90916c5c81c31ee91336911983c525f38eab86682ba69679dfbe1f10c9b673323632fc75f38cacc2af47a3d5d5d1031ec9a2a60cebd68d501b -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/7342a1d7b1d2c0fed7f5edf1c331ffa8 -LLVM.v18.1.7+3.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/dae8ca11fa8d34f99ee19a95bcd108a65b9e6a6ddf2e5a9b126f2ba1b1cdff6b7ec21e9590d70b3785593435bb71e47703d9765811db814a90aa8a47940421ff -LLVM.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/10aac489dfa10a77427a82958f525da2 -LLVM.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/a87f721df4fc5f6e929a54d8e41e55fb366a051a610836923213bfa42a7f1593de880391131619653cc3571bb76a4c82e011852ee5a6005523957c9f0937e6ba -LLVM.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/7f231fd359f9297261c22f95d8f738c8 -LLVM.v18.1.7+3.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/fdd6441011609ef341108ff2d108c6f320d415b621a69922aeacc555c3d1ae6090a0f600f24e229a609b88ba9c1868900791a6590033b7dad333ad11f8a6365b -LLVM.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/c4523a485082044553e1a89049dc4734 -LLVM.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/db365e63bbb5189f7f348e2fd51e627ddfebf838ca9dfc6c0f8a7bbf6b8a2a03d78ea3ccdf08b0c2674f4cf5a0979506efa643554091ba751f16051bdf42ca9f -LLVM.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/bcd10e4f3e5a4b00d52441e0094de1c9 -LLVM.v18.1.7+3.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/b17fae89a3dfaa9428cf48c9c0866477cc75edda6aa3800702227cc9e3d6ebaacbd60cccc96acb4ccde56a2de531dea5a436bac8e6c450a4674daae23b878037 -LLVM.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/6bb986b1c9b66ca24c976e6534726b00 -LLVM.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/1fd7cf1c80594561a8b83cf993192299e8a96046bd1e2f6eb330898c5e2dd0fc7c6ee0e3115d4e4049b83c71e724fab19a5d468e72fd141d8a2c4c02d831b71a -LLVM.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/c44aad21aef3b92fa0b1543ab9e4b93a -LLVM.v18.1.7+3.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/1aed6fb716a576b132d13397c927b36f00d78a42e5273168f1eacd208e366c55328286c56bae0abaf2c7ee424e7f19f4e096cd53f7d7caf863a0d58de1a2386e -LLVM.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/c3494f146906e178c5e5e32c10f6fec6 -LLVM.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/a0fe26f88492ce8416257e76a5938a65b4911822c9c3e3bd0e3455adae1beaa952a769d616e8f8525c3bac64a6e3cd7f1dfd68800b5e7db94ad63320a2716e2b -LLVM.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/4644616c2e8937169500c200fb56322a -LLVM.v18.1.7+3.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/1250c5c9541782dabb5f0063bb2a18ee15a5dcd0e8b675e78474fa7dce2d51dd97e1bc4eee0a526a73f7812c57e41faa85e021fea4de74d33c62ae67ca555d73 -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/b39ce0b0f143c3bef4dade99251003bc -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/62148e1e0a31d6b28effda0a5016d9335005b27ffdc5be1d184efcbb13f13e29eca52eca19cc6800d1d0421c0e67a36027e05d5fdc967dae686b5bfd112fb2b6 -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/9475748210eb5b1947fe3aa6673b6c29 -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/54320295e59e5903db558b6be0220442dbaf7ea78e1612d54a35cbe014541b354ea708679da00851b962140b6da77301e27b656fd478666d3f0f710382c13a85 -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/6a533054ccfc3d1b0920eabcfb45ee03 -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/3871620aeea2ccaf6e4b17a675c5504624fc6d8ed57bf4e5b66e0372b7124e4f3d1e0f10baa1018d5a1ac5bc4bf0e9d2143e84827712fda1f512fed24829f1b9 -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/3fc6d1b7d59b98823d6016f97835b7c5 -LLVM.v18.1.7+3.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/745942235e40f2ab71a5eaef2768842823620d4a4dc7454a7512fb2bd95bc8a74323eec6a4b33edf1ef935151c18a20172f60fcca2fca1ff3a37b1e019ea4640 -LLVM.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/4bf72195bb2b3fafd98bd3f1966dfd0a -LLVM.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/6554fd0374875428d0479e192ac3c70823a1143ac9acf0fafb3332f6c03e7fc8d14513512152bc995c186024bc36de77c5e7895ac1382f962b22b1089c3cf176 -LLVM.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/5631a8736cab900c3fcfeb559abc54a2 -LLVM.v18.1.7+3.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/55d93ffcc0125720f7db379396c5a79e98408225aebebc72fdd05b38605e73481eef46c219f59088b3bdea6257a7a7e369e6e0110019164374ac35bb49897738 -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/28ae362155ce224cef605cee53e36d0b -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/d90f25e57f92a9da68245ceb15316e3868bf657d7e744f37cce5ccb4945777ec82fc5d470ba4fc104fe7aaabfff7b0dc260838a45331e4360b0fd14c59a55666 -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/d10ec63510dc1a043ee0a4e37b49eacd -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/54c393208d1f51661e631cba62a21c0685fb58827067d5ea7c42fb3d6dd8c8db99d8ee1b3c304abc25510bcb0265d86ca03e1ce19be4faa252d97cfc8a1b52cb -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/2c1e000206c9e7c6c8e7515eb8115e3e -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/12c0ead798e43448a30699b5386b3d88aac49aaef9bae283ea6d089a1c66df7293f4f220a2b5c3d96e73e556e37e745f38d81f5c68e09a86a2b19a6695eff460 -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/21d6c5d5e422412b88ffce50862efb29 -LLVM.v18.1.7+3.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/5e8e17ba79134e9752c7fbd28b62e4616574a5e1dfcb0980160a3aad28a2f6cec4e48ed1acf73ca1f94d74397f7ee3eba53cb1280699e40c451295590ede3fe3 -LLVM.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/293fdc43431493f915a3e0a5b3c6d587 -LLVM.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/27e13a4334a3bfb3c91fd06abcc4eca7a347f4bffcbce40834302d153ef29756295121b42ac433c266668af1428ffa08ed12ce75f21fef44cd7ac1d8bdfd155a -LLVM.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/2825dac8280d0563b7f521a9eb8c0563 -LLVM.v18.1.7+3.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/7f4549ac7b63e58d8c149f6b22bd997545713477a1df3b32adf640f3951580df1645f08756d9ba80c479160cf5759e3f9372396655a35cdca14f4be4afc4ae22 -LLVM.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/0c0da0eccec4a092fc0e9a915716ed6f -LLVM.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/e538e29c4d52d9aaf151670619702541fed8231ae4c7fb9431a425d10eea95433087034a37da8fe468bd27a1c882f6f8eb9549ef71964124db10e99f4b402ba5 -LLVM.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/6b4fd19277c978306441da3b58ab86a1 -LLVM.v18.1.7+3.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/6216b3e1dc6aea979d8b5abc4cc0faf510e4e64441b1d18b4b36c45d65e874e9046e14eea67efb88f3219449ef048d34fcb751b15c59f8a299aa822b426d50ae -LLVM.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/689ce55ca1eb1be8090a7dad2e5f1a86 -LLVM.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/a2ebd80e71375abafdaa45d4d104c1822d2205bd680b8c8541aa90dbc54d530e348a64a18acfba14cb66c078f0386d54375bf26cddef935a348e874b99609312 -LLVM.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/dbb26e6bd19d71607248446d38ea0a42 -LLVM.v18.1.7+3.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/eecaafa95e1df14f57f93e44732a23b1fb734af73bb533c8b4662dd0ddcfe696271571b97e2a5346581c000336f9fa0b28bf1c92535490e5174649a7e01b6019 -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/51981c5aac875046101670896de92c2d -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/466da0868068d27dfa8284a3431925c9cfed9314f681bbadd0c331ae67a1acb975015a739abfea239e7f93a2fd7d439601f5d8421d7fa4fcceec5730649686a7 -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/65da06ac7ef16d3e3ea6137cb9a943f4 -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/6c70bcd54d1cbe502b7d9db50a59a62a8a10e4e90d7d607d61ed7737a70474aba2db5f5151b1dc03f965a84d8770d4be6f248ed1f4bc6c9e63298abecb936f1e -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/0a4cefbd15c37cb418cfaac56b789146 -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/7fd5c69bfde6264ae4e548ec9c399dd09b1a5fe4b9cced23d6bc4257f0f67874b838d53ee8d6eef7fc01ee9d086758e06f00bb0a0388b97de2eb85143a47192a -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/da2430483844823d31bcc5f302252ac2 -LLVM.v18.1.7+3.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/19e9168b44d40acdc0d924e16f93c315237207a4441ae78997c511135872e557f654236bc859453069671145e81e961ac93c9dfa601d1b6631b9ccfa09b929b3 +LLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/d2ff48876c4d883f430b27328c8c7520 +LLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/327b6651dbf039638fdf4920832ebfe19a6448226e1afed2f9052a338f7c71264616efad32843fa9372bde03db6b61964d814319e2c495381a4f024fef7ae7c5 +LLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/4763334eeb55148f50415c2fb41c56d6 +LLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/5cee3c928743d319eeb767e5b581b17c36e9daa5787970ebcce41a83575b1db67012513fb51f4c877022d732a6893dd3fb8f6912698a215d833ebc0d246c5f1b +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/1909f5e4d3f8ba6f2350f500e2610d01 +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/a9883aaac56058c29e4b67c202b53da7b9ab28cdec6a8c3aa75952bd327b6712c743f4db039985f6584a7537f8d8c8a8f183ff4453f6674af19ae685274eee54 +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/1a2804d3db38017049530614ee4b4c2a +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/b969f83495f808888b20f0eb53b5ef5a2b921abf64153f0dee7ae1133b9c974f226846c30f28d9db9512c18753ced7ec8ba104bd4512f3d92e789f4e2732c712 +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/b0e3dabffe2e4f2691520163cab614e0 +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/eb7bf45feb60b2845b08beaeef53db8af7cf7a2f4358cbacd26ec4df67ca2f929150dbba67d0214190cd415f89780916a8c1d6dfa1ffcae682afce7ef5754d0c +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/3ccfcca025dda5415548edb605a5915f +LLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/6b7bc5e2dce6c06006968b5a4c1aeca6241800dc2c457989c4ce4e4078b811ea9d73ad35b8b28798bc423124d05da5cadb62dcea70ee8040852140d109f06cad +LLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/3df8f5dac037a7a0a13e8ddccc43c09f +LLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/06b977792c934a611ac1a1631ca531aeb567dd9bbcf7b7d7d70ac39c079ee4e635840b09dc7e99702122ed467adcf653192987ee6f7b120dac020cdde2d4fa86 +LLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/3c158389fc53e608a768390df871295f +LLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/d4cd188dff4a7eecbd9a885e711f6ed399d89e7420d6eb4b8dc7d5fd1c7aa5caed38eac2f986f0fb992d6881bd7a1fde3f62c1b8dcbb4ae505ecd33a1ea56d0e +LLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/8c6dd5e1fe5eb9548c27ac28a0293eaf +LLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/5d2d7681661af8c592dba3330aab7cefde4a3220e6f18a0fc75f582c8f3025ff8a65fe6e8bf547f81a7d937b3a18bc1392c5dd3198cdde7f06bd12d85e5c090e +LLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/a5d4ba849d0607fbd73139b16bc16c5d +LLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/f2e1fbc104b63e8ef5632c02274eebfea6b1dc14c6919f0e066dfee4c1f3687ee451694ac11c74b1f57f3987e0553edbccd1efb2615ab179ff6ea342a7ae481b +LLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/da8f2ac10baf2f5792efac8f396d958e +LLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/b99138074e41dc534ed64cec0ad3337640bcbdf68b8738c9d5cfd5eba3574388c5a47fe76b967212a6e013bd7c09c3c0ceefc2c18a66302e2be7ffcc719e9cc0 +LLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/f69bedc9c68b53e45684a81067c684e9 +LLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/fc5a01f36ed0aee53a3d90f6b07b7dbbc73f40bc2613faacdee7f3b0e86f0f449502de6a47949245a85869b7c1415ab49193f346c496d034a33090445d83b5a0 +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/86190d010c3bf5a4a940a24d59a22cc0 +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/1c29ae7322f7e7c0ea47c165e239833d815482919322e9d8ea217dd6dc304884e844d82523d75e34964d1fbaff1106bac1008a4330f35ad00ca84676f4ab9907 +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/49e37626fd1a23eb2edf130db61433c9 +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/16fb2104375c06f6a69b1bce4f63f04d4989982ace593e3539966a19e23156f0a01ab375c2f060225a76de3496ec84a8d5bb129789ccbc38c7e69402f313e2c5 +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/dfa42f2505a81f71e8c96bb1ae8c040a +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/1de7804eb2d8cec8283cdca49fea44dcad73a5e1578ed6923a4534d84d0c4c34d6662141e68dbc045e9a06448e30c5c9096b0c149bae351f51e3d6c2111c0690 +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/ec4c23a7c635588d0f6b622a23ad7b60 +LLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/77e6af72ada7ff6d5622eb71b7b899bd3a15e8dab09bc1d996aee68d1e7794781a628643d823a69e61bfac272ef4ece5f01f92f77892d680da457e9a42aa5a68 +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/4be5d6998e7b9e365ece12a89eab85d7 +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/5846110206146899ada791c0accbb65ab5c167998a46533423ca31cb581cfa5765459455710f4fd8e918b1836d3eda4950a862ea4482179e960cac4bd997668a +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/c2b4455d8d7148d375db2cf31bfa8972 +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/1105d8dd5535db5401cfb644532563486e4a06191e9c440b4a64282b7288f20feafa90ae01be0311b9947fffdad17483b38c74bd513406cc0dfa3d5390da7d2b +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/20cbd4764f1641ac36ef4e91bb0a3443 +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/19ad90604d5af3579fc826d9061e327ad9c073642092d5d00f54d93e35b7888a55a64bf3a23f069ed4526bcfc6d0e0ba394f9f7cc982a49be1c41d2076b2f119 +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/42ab86133333da71b036d2aea0ab7e7f +LLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/a31ba5a95f4e1abeaf4ff86d07777716658ae79e1ab6cefbbe42c85beb66e39fa7627c8d794fd8d8e595ad6d20a3200b54c16e946166da50e41e78d51ba3f3b4 +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/9a5df42c54a585fe87c6ad00460e8c26 +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/297c717f00735b7d6daedd364695c657330645b803a29701b6331acc9558494896448e0529118e2b571bf137a7ad539fa33d707928c913d132a5ee086f3f93a3 +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/5c0c5d27b4055ede2c2c366c5cd37401 +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/6dfedc56c7a46f233e689c80740e6222242c595fc7030fdb853855c8e0be333351cc2db784eab43bb0a83bb42b06bcdae907af2f66815763461895d9395bc70c +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/64a5039fa3870fe66938167ba37719b4 +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/ddb6ee3e97c6cdb2c1f05d0ca05ad9720b964a0ebd5344f395b23f6e20aeff15cd7ef1bae38f067f3dadb26624498de9256167e2407d73737e39be09a77d7a36 +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/130e4ca797e14dad6aa0bc6a9d1f8f10 +LLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/d0b0725df6bf6e1ba530fa8844d45787c76608f11a9a16822825186df5f9d62021f9640ec9d6a5c4220a9efefb687e612e4f6400430d2de9888e93bdc2c53ffd +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/f0301ea8d84567ebc5caed562b277e74 +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/3adefc0b7e15cfd18f86531984bf677f19617b52716028c05351e00ad60a88096ea958d4889e98e12e87f1f869df9614092764ba819611d5aafaeec24001c906 +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/25a12d9e28753979d282212e6e31906a +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/9cccaf08dedec278ab71f1f910be41daeb6bfcc23ba629503b2ecdb4667de080fa237da046295e2d219f48e7639f7a923db65c1f1e0a07211bcb6614f767880e +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/66afe4276ab27fab5b782af20c7de1e9 +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/2dc373dc06969a7e3b52265341f93ad8ca4a8c80676fb6155405a18ab6577ab03ed39ccae28220497b78b133dce2ca65f0d3b68278f350c217cdb396287fc09a +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/df2bb1a9461190a8def39f77c827c615 +LLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/d9d2093fc52ce7b016d9e392cd068b12ea820467fa0c31c7e9da18baf3d736b7c7b49050957c202232cc6a6fe4fac5aba23c1c5d8ae2d1e21bededa525ae791f +LLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/6c2b730a3056f9fc4e48ba9caa0959bb +LLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/9c71497c6480b66f1bc2d77f72b12a7120746f35b823af6b999e0e8576d2371097b76d87d927b8eae00090ea9553f822b78548768fbb73c1c895d4ac8709c75f +LLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/81c3bf18dac5f9a6e1670f62f044dba2 +LLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/074beb7a543407168b2f42b3c29063cf0a43d0b98e2919a7826f200cd7082a734c96304d0dfc604803f187980d79bf4501eb291f66d92b7e2f9fa9a2dcc7e4a4 +LLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/14b99a0abc5b26b0cdd8bee2fc66f5d5 +LLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/1397a732b1a55f39033930add4357e894da5a3f8fdf8e71afb7ad05d74a2d3fe895aabae2de8d14588fe01d0fe676fd3d4f8a8777645fc13c49672d5493bb4ca +LLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/d1e0b91f6d3dbcf94be3ff8f8e83f761 +LLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/249fa874921f1b3088afb01667863a2a5de5a8d26ad5b439c09484472492c607c98df2b52556399d3319e7add198446aa871dd00fed1843b966bdbfbb35acb71 +LLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/a2f5c38be76b35ca02c6b1ce87f873f9 +LLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/c83665cf6a25f675b45b54a7346dd8ff6ad0cdaa197a68ac3cb1eb73afd7e75ebffe9aa31047ca7f36d50f0d9187865ba872c7ad7f705823400bbbcf4ac7bbbb +LLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/6fa91c4a862b114926118cd1992c36f5 +LLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/319fe078adaf3101d7c8e4502bf4f30617c858f254af4fab40913e4d8aacca54fbacf121ec43fcdb07f8f92d788c92ceda89d8fbc50d033c6b1fdfef7b8b3d3f +LLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/fac4b602f1658964a3157d7870e391a8 +LLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/07c4b9cc5c4843025fc8da3f9db80253933fd6e05d9f781539025a922de2bcb62250c893f551fba1676785a53faf768d767080a7a59e80b051d4c61cd9a697b9 +LLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/faeeee316451a553e499a850f4927153 +LLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/b6d9a425907260293e0fb9a7e38e1cebbb8176452f5754bd226736e711056452b6da8b7584ddd13219f088c59f8acfebb0f05ab2966e662936b45027d8248ad1 +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/b4b66836f9156fc61ecb296ba09339ef +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/b310dc8d8863c0da72d5c1e0b094542b1d8a8b2696999eba38a13a8962c5972e2cc682e62c627de8b2c0565624e0c283aa877473f803d4ea25e2a69d1895e369 +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/ad15a8c23753c91a4cddd15504d077b0 +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/24560043f2de1baeaf3343814ec9cca1c3c9de514586f2449e1f1766f4ebda11dd7bb49bf95959c027d3ce845124bd38ed41907cf1cb31f1e02851d6a85f23da +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/7b6e45ef10fe03a30186ce84b2900b55 +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/f193a596a4bdc4b0d4656b2dac4a16e08d1274f1ca3ac1400f7ae19c045876c0cdfeaf7f853c2dec89931274bdce8d1a59aa31125c266ca2e66ef739ff2012c8 +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/1710dc4978f1c66ca1ece6415942f2f2 +LLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/eeab3db272f72626c3f5aeb2ae9917fe0837dffa0d35f2c66ac2befbca0544f22ebc639de79f2b27ea9ac0354855867febcad700a60c9a6d26a463cdebafdeef +LLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/f939452c4251f79bf798c043cf18579d +LLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/3799a37feec6845240b7ffac3006c82f7206315b6bee52e35f7d5001c7658b552e951e3c82118bc9c31eb414f148a1d2f94aa39bc0fd8c7e3d474bb660b50e3f +LLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/daa29a91e0bb0a5217277b549754f5ab +LLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/77ee4bb3df16e7e8b09da71811c9e333131b2bb6202b247383b7eed129d51e643a83359cb4b34ee27eda4a0c61235661d01a5b8362292e3fb82feca7e0bc1aae +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/e9acc5388bb91de5bd5677d0261e64a9 +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/3bf168ecb2163b896dcd6eeec06aafc9f072b6ffc2cb458ee16f44fb0a3b8aff8f7a9a78c7d8e56133c108820f01ccf747c800205cd17bd220037109b0085758 +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/5bbd2421abcb5aee53bb9dfe349f85b4 +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/5e172445793d0f02bed170f58473bae10fb6dac3734d7e5a362ea03a607b918636b688990c33b6a9392e50da3a90f0fa1f82fa5bfd3d00f9ac032244b72b10f4 +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/79188f344f825f0d25ea43221757788e +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/264010b23484c5fed36557c8a2abe49c4628d24230265487f64a5a3318d53845439796c6f4cb231712dd92f5ea210ce2362e6d69135df6b1566e9670aa51843d +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/5e45fd8bff4f0f60ad5acdb929d422e3 +LLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/1faedb56a9cf919e53270fdeb0417a27345cedcd9974c82a0edaa4de5e99e2592faf02522952353b1f2bedd8c03a4f38466ede7f829d6555526665a66141017f +LLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/4723d91f315cd44b4d53e4790f20831b +LLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/92b10a8729fa0cdc10690ca743d41f6c2bb7cec7b134b1b0ed216e75360f59d461af51d86212967e86bcd9473d561916a27d8da281d5e446d05ef92582ad152a +LLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/468c76c8a239aef2a85f99ce53a3a9e7 +LLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/e1cadb25b5c06d5f3807251adbf5d8f9d34c8f7bcda229e8a4d01f76fd820a71c7e472fb1c7877941b2ba9b4b17a3d227ca28ad71e51e2ca6d71c6d124d640c0 +LLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/cbbbdd8781c5bac3b43b5736c26f5142 +LLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/621f81114ac516516f7cd7f43480285f70780202a29baafff4b883b5df3e293ab5a5788951dc3b2dc29bc8fd6fa66a07637833ace4eacba6162648d1987505fe +LLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/46bb4ce575cf0b640bb6b5a2a606b327 +LLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/385218b95dba66d9bf1448c5e6e75678b4537083d13f4457e127f460abf14836fa5711159a3e12c61c93dd81fdc5cf6f1ca855b56ff968b697818b639b7a32be +LLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/6e6e79c0ac1afc889cd46eade345154e +LLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/d01b62f114afc49c7cc69a27aa454e8940d224609995ff2ae7731f34a2652ff37b8ff203eee4a0966ff4c86e1fba4d2f699d9c510b83b1f2775451a174ed3bc8 +LLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/f3c87420e35c24b50161adb7aa111670 +LLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/64aca33f22ff15f236f5b3514208477b3eafddf309f21bf29c634430bed4b1aa27e22a1798e4e1a33364db7a36e80c89dde4605db9d62f686d4a5d008091b382 +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/4228a2ce55a4beb2c3609d0703f87bc1 +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/7d412e51499f2cf864f5c0e668aa8b4faaf3ee2b79f362d54e612147b9be9ff642280b3a59363ded48be685c5f0c3e322e38fe9e15b1595961d3ed9c872e0326 +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/6b7bf112cacd833d79904b31ebb17d7e +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/49487f7f8baf310e13c4269c1fa2e90c8227902ce4b4578e5695e11bceae2ed626e49a944a4e50d23ab7309fae96f347a2cb7530f2074b4119d1cf7c825efd87 +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/71b6dfae49fb6abba57bb2ea5f5ced10 +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/b152aa0be9814d733b892b9d316aee8e47b8fc034fd3190251e45a1ace828b893614a2735d2d71dccb1edd56c47bc9cacfa2044fb67927beb0daa20054dc6dcf +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/e8f344f933ea61d6a75028c735a625e0 +LLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/9fc38dc52b007ac71c826856ebb88a4700c23ac5d70510bde62ea41ee90eee100c20abf1ff488fc0091eb59a2c5a5191e304b723b45042a6497a93b57a8bcbc3 LLVMLibUnwind.v19.1.4+0.aarch64-apple-darwin.tar.gz/md5/aace388fc1ece82ea524c582506ae931 LLVMLibUnwind.v19.1.4+0.aarch64-apple-darwin.tar.gz/sha512/c0211340a05630bcfcf9e3bab97da3e9f07e596e8d391427fa919c99502ab0a09878eda379254f379511884347f7e742872e8589f9b6ccbc2d126a5dfe0a350f LLVMLibUnwind.v19.1.4+0.aarch64-linux-gnu.tar.gz/md5/942d0b4ffb8bfd743cdafebf5bdfdbb3 @@ -144,119 +144,119 @@ LLVMLibUnwind.v19.1.4+0.x86_64-unknown-freebsd.tar.gz/md5/05f5b916fa639a68096cc7 LLVMLibUnwind.v19.1.4+0.x86_64-unknown-freebsd.tar.gz/sha512/0a137168c466861fdbdbef86dec96ece0d4c10f87fdc2dd729b445deb0fd59b214241b62644da77581a0100826e07dacf81fa060e67e35ff38df0d6807cb618b LLVMLibUnwind.v19.1.4+0.x86_64-w64-mingw32.tar.gz/md5/bb073cb86c821a70b845bd5de0edc2d9 LLVMLibUnwind.v19.1.4+0.x86_64-w64-mingw32.tar.gz/sha512/24d206c65c7be34485a1492250a9ca958e70be7057b981940bc24c4822e50e3963c9f88f42892ba2ea6df17fedb2783ace1693aeac74f200a5ca6033a14d6cb9 -libLLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/9f0f5961fd1b7459b7cc6b535c49b9cc -libLLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/5a72510ab3b0b56ad478aaa49deffb809f0f1f3939cb6b7a899110249c95391fcf77108e3c60295c26d87c75ccd0fd548b9cbd5a528b4371eddd4b2f428d2af1 -libLLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/6f4c4802055e49efb045a18b3a18c3c1 -libLLVM.v18.1.7+4.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/c5d17d6c8782b2de3c69942bab8a972e29bd7f262662d41475202ca6436202b01c9dcc2cde9b09f39473159c9da8cbb1b4db7717f0f701469dfe6f363ef62d45 -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/4cd6ea39664d09051d12767ea53e14b1 -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/6cc3b443c5e4ac71d81bce312af48b663b5b20e10a874a171faf9f7cee65f37a0ddba41a13b6eb61e07a84d8bd2058e5748969bbfa8a59b01a94867dadf6f5c2 -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/1ae79bb7cba1fd6a898f3cb86563337c -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/c4b714b4aeea418c988bbc91911ae226fc8e2301bcc00efa34d703ff91f28b20b2a15647612651cc346ef2508280492497035a43ebd2f62b062800216bd023ef -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/29804b49dceb444d71c4b9110b3b9141 -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/bb15cdcb3aa10067d52bccfc89a1bf0141501c6f54eea4e2bfe094f463d5041dead84ab5d613a0250a86258d33df530b9b2b8636e5335963c8874ac00b5191c1 -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/d37118f2ebf692b2b48995fa7567f3ec -libLLVM.v18.1.7+4.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/3f4f88c82137c11f70cfee1998ebd8d7b8507d8164ca61a425b0bdd9d724ac0476eb61582408171ac104aa4692f38da4b8522182ac50c6d4c239dce7e5116d7e -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/da62e799a788ef941b60c474c80fbc16 -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/b2b87955bb0628fff800245ba8785ff1c57fa6b82263094c8207aba1cfe8b3c60d8816700c722606feed7db50635fca0ecb7e2f7f3cdaa2bcbee0cb7995f960c -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/07dcc3b96e32f4c845b8bd6d4bb3f6be -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/7e785c1f1ccef610b5129985a4250102f3d3592848404fcd0e07293e7fc4836189165deec650286be82f4a14a719720580bc2c80168a0648c26cbbe99734ebae -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/fe4dba386d61114ab035009f5d973534 -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/8fa0a8027f64f382735757eed2b66b4be20a065c6f9714c7ffb10d643d491a8682927f5113a2e3e2cfc151101d3b48f4c3905a8ab6cde58d76fa1c2af7cabe36 -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/3c0deeb5750ccc5e74904eb4cdb1059d -libLLVM.v18.1.7+4.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/2956cd529e2bbec075bdf398ed44fd9e31861e08803beae454f9d8f1a85cc38aa41e36535f1f02940abf48f6f8a31f6663470e057065827ed174edd1f063a999 -libLLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/840ddff37d9b3fb591052882a2f3daaf -libLLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/73b1ee831c455f447a3e603d5c9c333e89fd367c2692f1aa1d3063b8dd60a514565b3abbd79902e4ed5ee800146dd3e92b5dedb5092ad9520b325dca8da77b1f -libLLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/73608188562e1e315a489d0772ccb2d6 -libLLVM.v18.1.7+4.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/08c10107a22f4bba18b6bd108a8821e81699f6be0495356f69b6c53d1f2033b4e37a7d9bcba01d28586ccd067028baeb549e671794cc7dd4d3791026690ff721 -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/d6821537e94a38482271ff68c8e3f992 -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/2616e190c2765b43e4c3304029e849e5360555e5e1dc0059f6c3294d2797bef102a1c1ecdaf1eb9ff78aaf62e23525e0a3bac998ed92a4d14774dbe8923c50b6 -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/ebc37e019458e57824d3868a5caadb05 -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/f835fd254c746621d5e9e12fee0a2bbb4c1954fd357a140208912552701d0e17005a4b5bbe5675f9526778c6b3bd3e5fae510e312dd48e07fe376da0c5d40899 -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/7f3d5b242f875bd2da988fd8e83cafb6 -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/e763e99ff7356d03564215b5b3ff747a6e78a91dc62fa9d6c09cdb091efa4dad7cf8f88565f0d01dc35f6485aa3c2d513fcc91dd93051f3233b7dd551f8474ac -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/e4045d26a8878a4e7f51a31e761a537d -libLLVM.v18.1.7+4.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/025045a9491aa9ffce618f191d9c3d87310a956b6e23abd32f64116eccc52df6958e3135720a05ddcc37231e707fde541d1715f212eec0cadbce14397098d6b6 -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/2bf265fcf032fb1dcd670a535c36a57f -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/7c77257585829e4022767ca3f4ace0dfb56e60179d2ddaed76ed9df329b8a5f227507f8565dbf8d5df8869bec2677089ec1565c5a0f94238a6ba01b2a696d8c3 -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/6c8ecc36f4b34045bf7750a8ce8893b4 -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/cdf31871986baebfc11437743f15f133fb987784bc6a98ae0a6fff30c2e954cc6affc0c7a513b364c458c4279f7ed80486eacc0d1a5950a935bcc7158a176660 -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/ce67eeb02f9b12bfd89b6bc6b2079969 -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/8c7feb74068f6a5df9d7f4d4fe719779ba9d4682606fcd170c1fdc2be1fdd963882d7092a42a00ab84a91e71962428964334db90de45adee9e4ba93c14fe1174 -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/4e1faf56780903a64e88cdda15b8bf5b -libLLVM.v18.1.7+4.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/9bbf6fba0f6a236d68dd228b933cf0cf1687b02397d8959a93ad59f0cc72f5a769670efd4aa48c2374e1368d900f2ed5a2ba0a5b795cf16f457a33b5162a9136 -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/85451952680acb73bd57c6093211443d -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/b8e4180a312e68538af2057582c409387684ccd7320514def933df8dd7c1258f08a18dca339c9b6eb78c4c2a14eb11c2fb25e6f96da83515f465eed5c500d1c7 -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/c02f109693eb630d20b9c2aba03ff07b -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/4162bc3aeadca88f81816b1ad84582dbe680f54d88d76285caab686c2c00d0a30346f1d6d0958fd1b5f8a296679605560ec37569e399574f2ab3110656fad74f -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/01fcecf3adb17ed0358d854eece4b79a -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/eb140c0c7a18de4a58b2467dc359cb2c1ffe34264ca358573ba90cfa8651f9d770fa8c067b618d045699f1420e3b29489b71aae087c47eb4114039b4979fbc8a -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/861c096f87bbc516a8cfdca2bd8f9cc0 -libLLVM.v18.1.7+4.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/fc65b7b5206ee9e5f579bd0a34cbff93f47b93ad7ae6c2ee14a7b446dd9489db8b02df85587b5d4867ac82a30823633d52e2b0cadf94e4ae4d1cef7c33ccce48 -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/9b6639379b74e4c3d0aa288abd433e53 -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/261ec83cdbf2b2a75926a632a748c0db14b0be37175bdaa610997df8e3611f08689509b93ca483c8b8b6a11c90a2fdaa5dee6cc9c2245672cb83922ce650b725 -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/5b9687dbe8576a9881c24bb2541edbd2 -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/39cf2b39e20fbc63dd4746be92b09aef91e9386c94d3e0b0100bced398eb071953f103f55f3668e48801fa8ef0af14c5184a75eceb10f840982591fa8c6c2f59 -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/fbcac757c4b5d86446e70ff3e0b6c2ff -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/1285e54eb0973eb97f457667fa92365fd3775a9691ea949a966f56d29f5770c88b6912d286d4ab3ccabe6a8bfb2e1b87e22b636323110d69994ff65e6504896b -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/b77f996fbc03bfdb944c7ea630867cdc -libLLVM.v18.1.7+4.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/b40dff6e56f9e3bcee67e8e65bd79685f63475fe21f2760a7cb79604268cd97f9eb602c2aa163a7ecc3ba2645a088e1911d2719d18cdd8daf6643db8f54352f0 -libLLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/afcfc9e4d4a04abc0c69361f8ba43598 -libLLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/5d5137f1c4e7ae998629c5bb076051683f88e62688683d76ca2742aa723a80edd2c63b1ae6ff0bce81602c96b69ff99d804857f60939bfa59393e6d250ab07a2 -libLLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/0bf97c7ac35c1a68c69ed2bba861924b -libLLVM.v18.1.7+4.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/e6cc1d6294fdbb0dbd424d60c459cdb497e0118b1da1144ddbed64f7e5dd58fb01911eb6a9ffec24e0e27cc4c593b0c4bbfa38497ed446a8040e6f85b2911b8b -libLLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/64bf5c29c94d8ba4577e2d73e99d2a94 -libLLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/eb0690538cc1aa0b321f95117cd61426c47b6bc31117216b1daea6bbc691dd9ed68cb3aa41485ae1925358849e749110f273338a515822765557df2f3d258348 -libLLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/5a7e644087ff78651ce07160f5a98f91 -libLLVM.v18.1.7+4.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/de9c8be69fcf6dc6f564e0440f5e2c08deb9da2b75b5a702e936b988e9c9ac8a9392f540c752f163ce80f80870b236a421f79229b148f460498b779f963b1d54 -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/ee33a06fda2bf953b255ddbffde1284e -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/45d41cb2018f37c1ce8f28b9a81b8a9bd2b7282e70c9f5be4246d7fe6b44a439340485ad472c8eb837b6c80653dfda3cbb5c2d35fce13e9046431fe0271290a8 -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/f26af4c3ac08df8eea7c9856a7583ddd -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/b3fbd17c5aac722620da44cb1c6f84fe1220d07997e028c21f0360f5f7844b953d9e4a500b2e743adac1f9d2ad61a522b0e44621845ad9fc4c7587456a1de278 -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/5149f99d2b29dcfb70e845c4810b64ea -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/7cf494ae8cfd7ce780f7fc000c910af441a19c7633682655c30633e9131ff2be710851e3f1c582ca4898378749fcfb6a678ecfc1b35d97797e9832e1ea2e4ff4 -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/46fbebdccad778e953c02c82ae77de7c -libLLVM.v18.1.7+4.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/46735b1dabd675440591a44e8ddb94cec066b9f90c7579e9b8327e3079d94709aa14a6cc9f523f5ab14296e9d04ec38e2b3265b91c39d8115f43cd2e43af4436 -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/7aa31bd01782ee5a3e8ead1983cdb9fa -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/8411ef4fb32344f9c511b77963953e117fa3424b9e4c27640c97861612c3e465f0508b762ea5dd70a0e453f71d1070e5d88a169b357c8d6aab4e04ba5cff268d -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/68d8ad81493ff8951b752a4bbe7d7050 -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/1e4ccd4ef2f2784a7cfeb2721f2e13db52365b8af3bbdb552c72474f18fa5681e6aa0188f69dc2bce218f9e395a4873b61f73f35d10b5f21c9acea1f3e461c77 -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/1b50987bd4fa05f020c3795c60c0b1cc -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/7271b5e17e759deb7d0f75c4c01c28b9fe83adb9564b389b6e44d131570f8d0eb942e9c645042b8ea6a07dc49d537c38035e176ff9ab08c92cfd1a44338a8a48 -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/0f485d054050e1dcdfb8f01b4efef86a -libLLVM.v18.1.7+4.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/153e77cdb946b545247cbd8c682e07226a85c092dd415deb6f4cce6a3d4a731b42a20cb88dbbb8220b7d8c298a3b3fddf1dec3ad5ccdc87dc286e10cd54a052f -libLLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/4fbb5ecb088a636d7f3979cdc0d19508 -libLLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/6c64e28c867ce9d0bb5f19235b51c537de38907ac2e84d16bce1b2f18e5c1d02760e9ed8bab73fd78b551267e31872bf2ca59df164de6bc7cb8fcc5f05ba5989 -libLLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/cdc1786080c6dcd3b29251d92e110aae -libLLVM.v18.1.7+4.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/1ee211fe903577c351c5bd84461b47b2570209960b8f218f92503b1e2a9c95a8b74ce083ac4da5ee66000f3da0f7804a07ef655f5560b396baf291f5f5fe8b1c -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/50f41cd5d8f789175d10498f7762bbbf -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/31095dcc4b29cb840a8429a97e8ee916fe95802419d94d26dd6cbd7693a66af881cc82615ff71350bb4e24a5ce42156ee086fbc044c51e83b41b54a86004d985 -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/8355ee35aab8205ce83d62b57bc1c8f9 -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/3704ca4bbcba6123f20943dc35194e4a666fae1822279dbe2851ccf620683bebd8f92fa98e84e302c54cd23546b1521ee37f900645e1427e2700e2d928211cae -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/745b55591cd0c0530ab36b3b6303de86 -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/7701289fc8ad175f4f264eea07e19f8f19cc8263876f14dc5d2cf35e3170b0bbea54558eec07e9cf175f9127029aac13754eae45e42ab1e1f31f2e5287857296 -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/c5784fdc403b8002b88482e5dac9c910 -libLLVM.v18.1.7+4.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/710376e2f13461e6c629bf53185f834d16f1854c9fb284eaa5b55249d9289b23fccc8a9f7f8fc00e74d93fa13b86782a360a3394d247942bff72bdcf6f926781 -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/f50abc149a6e7bae03a0a568d2915b4a -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/206bb3db48bd5408f227c48e9282f8f215988c17f498f41768c1f1659ce81f6ab1c26229079bb78326e9640266b94e5e1337dfc06e6e2c6c406e6b3b55089fa0 -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/e9ebabbef45e39a344b84284b0e62c96 -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/dc986a3e55990d6b885bef493a9526bfb16b8ceb1e3dc62b00a7e6d6aa8fd749cbb2690f061559d6b0b7fc74fc58b7eb289bee6e528d3add90f4db94d1218c60 -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/9c1e44db7c2e259529982336e29e7de1 -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/ea8ab32de84ff2c1e37bf17cab026d331c4d5c065d2ad52fede1fd9bc8138b4b9532011e57d52e5dae2455363dbbe196310529a4090a834c1bed354e8032971b -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/dee60d75932b1327118b4115ff2d710d -libLLVM.v18.1.7+4.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/b1b46fa9fa16c8822a06ae116376f7d60846b67756066ae716f20cc2fe22c0976726bd1efeb4ea0a9fd52e9a7c7b3f24944ccbebc155fbe4480790e22b140d67 -libLLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/5c670329435e934957e3025b9dc7325d -libLLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/b51bd90a1f175e7b5c8f24f63daac8075b41134a5b5477610f433bf3d7ffa144b6ba0684540014967bd9021cb4d0c95c5dd7bc22d54da7a79f73e0326c0e65c5 -libLLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/0d6f6974a8a82d224669e1f5c2a45d99 -libLLVM.v18.1.7+4.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/9bb7fee05f0fb449316f746b27a06fbd14579eef70a2bf39332e5a406a35aa1b1bc362d74a41774d65781cfcb49743f940c25fc734a531db5d94c03869626de0 -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/83aef3200c39e359b805d9200b5fe4df -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/5648cd248851af495ab4548b01adfa71826aa41353ee1a6199c55e20d406d0bca8aef29482668a2f7a6ed5e2e2d3c2241c5e8cd4022692de813f2a615296df86 -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/9539f763d6ca37b9930ddee290a32cb2 -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/0831d52bc9c134a666151ed2743e2b9471b58cf51dd2cc67c8f30fde1a142cfd4bf52cbf3845dc86fe7184457ff7adb1c2c31fdf5a9f15cdf55691580dde5f3c -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/fa169a8fb12a8ab69e08abaa7ba71c86 -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/7554a970b31140a57f625df23cee8d3653c4f24fae020197c9e777f92d9c60b268dfa6bc60d3d895dc9ecb9a182269ea4b512d7bafa9218a72c81c8b39f83f6b -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/c8883304bc0f8defbd8117ebb9b6721b -libLLVM.v18.1.7+4.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/01abcc346cdd6f4a09ec4954b2b47e7e506e7aa51f69060389e3426101acef46e6d84c049b62b933d52cea3cc859b03de09843091c441f0a4091c962d59b4a30 -llvm-julia-18.1.7-3.tar.gz/md5/82e931476ec0e953022d3958bd3b1f8a -llvm-julia-18.1.7-3.tar.gz/sha512/683c28e68d354b3200d451004201a16737d8e52b20cee0f1e2fb8621301de34f23444c60636a79056d865dbcc6a59422458596d52797b0fa67c90620f864bd9d +libLLVM.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/614c4f2cf80128a345a1d3632f2adfa5 +libLLVM.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/a8c5169dda4394c1cdab569ae6132ae3e69aacf281cb7a52e59dd930f08b6a32a3957314386d073ee7ede877732861e3359b59a322f875d237a22a5ed458d665 +libLLVM.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.tar.gz/md5/702923c46893d9d1394a4520d94acee2 +libLLVM.v18.1.7+5.aarch64-apple-darwin-llvm_version+18.tar.gz/sha512/8ae620e1cc1cfddecd1d1230f509072ddcaf8fc1258addc1ff51d788b66b5e709d05093a29c45ac413ba61ca1c437d2408f481e2bb4d926cbeb433b1d23098e3 +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/0f94779b455b80f60c8e8380f94519b9 +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/7611f7970885bb1a7e57afc3d571025ed9c344ab4045a9febcd50a026a6473d35676eb8eee06fe7a6a4828f7f9654d3c6d36aea7b609a6af88eb15d8306232d1 +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/4e9b7af9743d73adaf235ed0f4695947 +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/d02e260109727686cc06005a4cc57a513ac27498c302e3fc2a656dda1e38f51a818ae58fe817c22bc797bf3dac6f9e915f5e6229320b867262188763652a82cd +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/1407e50419e476d0f8ff16367a13f306 +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/c03e30bca892d2eba104ca525aa4524b5014367771a53caf0a276b075e109fee4e4b237d0689474c2aff26acac01dc096663449a9d64df23579b1552797ff997 +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/7f5c127f0ac374801c67afd9efc91de4 +libLLVM.v18.1.7+5.aarch64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/e53e0f9d7225eface37bc04dd03ef0d8d760e12470cfb4d744387979bb28731511d979bccb69e61f8d8e88a7885113070827a947c13029b05b674274bd64e573 +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/b6862585ea1bda09a1221bea8041662b +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/72e1a8d0a06f24b30057e403519c6f6ad64d2955b809a142bcc31f5960fd62455b01f10c4aff8e0fb05d93f720b54bed8240040954ca46d0df647cc130160018 +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/f0cc1309cfa700f8dde09979d7262606 +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/238ff54b91ed8e21e73cfa06dd0cc406d64d263d3df0cfa20fec0b6fe7ab5106d3c9a7faebdc8ccc9cd9e5ee74cfdafeba410ff7ea03337b67fa052d38499413 +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/baf59bf8e5ecfc7b042d71829fd4b6f3 +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/c34e7ba26ada00bf727e84e15fad4e2cfcf90f86880a458686f44cc127c49c00de1e3f78bd71b480b4c6cfc6a6516d495cba46f1f675f9487132c150fca419dd +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/6864ba9219b57cee5c4adfa34408542f +libLLVM.v18.1.7+5.aarch64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/4308479ebd399eb9fd5cc82c0b4a3cb4f9de047b66575284b148e0fa9b71d8c0ed838aa08ff518c75c4f0df81a23604705e69f9b8f455b1cc0d9bec5309f39e5 +libLLVM.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/846c59a5a4eec694c094beb3701fbafb +libLLVM.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/33ebff717bb0c0b2a918fafab6d3a7485ee9cd2c6624281154f8d116e1b65dec955bab1fdb7491535641f0306444278f4b2d19c2852f920c2a01610dc52c4581 +libLLVM.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.tar.gz/md5/236c2c016eacd64b6278e67057aa8a62 +libLLVM.v18.1.7+5.aarch64-unknown-freebsd-llvm_version+18.tar.gz/sha512/4baec6cebb6975bc76fa55f785c1edc1cd6b51f284d0205aeaf22a453e52df728eb7a5bbc4d6ed55ee256ce65474b3faae961dac0208256c1eca57cdc7ffb470 +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/5de4e3558dc54696172405efb55f832a +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/38941739db5d1d49f87fe402c4caa2ddc1139569f97a4ed858d2d29c91acb4d208e2223af8495ac243087ab459a168279d988a8a6957bcf2c535c4d79f301037 +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/9bb7aca392fe906aa7b70cd6d8a0611a +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/d12cd2b0d2e918a5c9102e650a563918051feab012993066df9a0eb4e6abb3587090b82c4621bafd618ebc477c2db2f55f647a7092103a3c539e503494443fd7 +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/617c8996fa61ab17a8b3a2280b20e910 +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/4d96846c0766187e08663bf7aaf15673f2b05180f59069008d974f1b81be90c4652588781942f65e31d5c4ce24d84792a490369d2d521e1463625e587a1af414 +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/52c10f854291b4574e0d3f39af6e87cb +libLLVM.v18.1.7+5.armv6l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/4f4449f555023ec8706cdfd48ae9cfdcbf06dd034c42de9db76addf31f507330baf366c411caab1c5ead811c89b1aff51973bfa220b00af9166570a34d870549 +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/2c50c1857373b4caa6e8d6a1dff2adf3 +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/693f74f6f8b3d9c264298f9725d9fd5704304a7d3fb7ae010db4f4a60d2d3ca951e83e9eaf1ea34f3c4a1aa5250657d3bfa2367fe11164a7401623bffa39848f +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/06da4e466c5cc3518bb8396d304d86e9 +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/edc7717bfcf55e0e828c5c1cfe57f82f925dc3a29d8d2c0829688b554c2e8a3ae7a60de35fec7e93bf9ba47dc64265a91753c25ebdadb18bf31cdd63dacf4f3e +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/e6adb4e03d54249d7148fcd5f0d2ab65 +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/02e41826135a7ae279cdb7169f7969942e5142a8e77a99f0e590a87b8a4633fcaeda2590e23b1598449672b3f00650cd69526f20dd1be2ad98595a27ae359a64 +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/714db0b44c5d2e31a3fefada500af4d3 +libLLVM.v18.1.7+5.armv6l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/933c84e79d15c13b4becbf6ae3c5cd3b5ab3d29fe678c40e7e8e6a7581658e24263cb901381795443072cac382e4c75c90f34a7b8ef2c7aa53f675e4fe2a957c +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/ff39f8e44e85beed03d3c1561e12feb5 +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/dd25a5f962960577c9e18dd7bc1c61b8ba252cb1f3ec2b06f82aee3a75bcc37b0f337ac6aa8c04d3fd5bb1689889881b8ac1e7a2cbeb974dbeb30dd14b4952bc +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/md5/887d1219e2d850752647ea6930393659 +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx03-llvm_version+18.tar.gz/sha512/b90031987fd32cdbba488dc579fed6bec2ad0ebe22c7fce99115214cee9bfcf17f0a71b2bdd940983c4f47fd4ffd8d16d2cc0749f7c42307960fb8a2c5a6e0d9 +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/51674de63294e1644acd6d76863f4a03 +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/949763f9f28ea1f807bb3f89a5a919e1c62ffc57f80a1c60e998f3840400e1ebdc521e884a378f6a104cd6911a6aa74075338baf8f246057fd2b465a865652b0 +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/md5/494e0b31ac708167ea1c3e7424d2a939 +libLLVM.v18.1.7+5.armv7l-linux-gnueabihf-cxx11-llvm_version+18.tar.gz/sha512/881dc6767cb0ecf6e13eb5102f5cbd69aea1bcc005097151ad38ba4ebfefe7ea399338ccd36b0755b443a96364d9ee7305a9d82616271490346269dbb076081c +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/md5/c50ec7ed8ea740e59a9a9b854c62e551 +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.asserts.tar.gz/sha512/c8fcb46aa12c7624ac929b58e1b9041ce0c66151912e15889ed1f35d8f5b5a021ef62d22142d1b46e7ae219d38980106a4efdf2863261dcb64bd2d75b2bd3d60 +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/md5/8f770e875820d320bb838375f4a76ed8 +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx03-llvm_version+18.tar.gz/sha512/22d3e1e5026c770438642b6fd2e58550fc58d59caa546fc8dfb72ee91b16f713160fcb928988a2229a2960327c1088bef32f09a9525ad30b6dc1de51567c691b +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/md5/6f4ea685a2f61365a4584dfd7ed1d48f +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.asserts.tar.gz/sha512/3046c2e05e57b0255a7afafafafed4cf60a6231882541ea2b0d4ecfe959e43adf792bf02dd0eaa18b395b6dea6e85c5118fbc1c3a24432a73257e7fd0c4d3b7e +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/md5/97585c0a6be92891a9bf0b2abf8498e9 +libLLVM.v18.1.7+5.armv7l-linux-musleabihf-cxx11-llvm_version+18.tar.gz/sha512/be31a9d03a6cebde2319593a14572b906c37113d46b4d74c869581ee7bb04855ae12c5f381c77eb78be9e019ab45d42da29a649f0799771b55d29cfda4037441 +libLLVM.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/27e80a7f447540261234fa7682f640d6 +libLLVM.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/065ea890b83b5e7be1e053018a3578a298e8b2552608f4d5e0cf2f127bfe25fcbfe588642b08e7891a57265043d6b8c0d35d4c3da49d320db103d7eb80ab9ff0 +libLLVM.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/7f04972f69e6d18fc33c683ab9c04f7d +libLLVM.v18.1.7+5.i686-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/22a5edd6ea35385e2535c1a3f4ef5044e5a84cc2a0185e7e46289418f424955a3ae2e35c22628b52ab5ca12fbb21b77d924e170eb56968ee946a6b5f2d0a33b4 +libLLVM.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/fec8498206f1d9a42be6359c5cd95466 +libLLVM.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/eda50e64c2219e73a7d3565d6ab90b6102da3c2c4168b2e5218cdea5e51573b5dbdc121eb2189dc3c7775f77c6bc340c5c004af27699f94317b52a98c95cc51d +libLLVM.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/7a347dceefa924dbe36de2a50050abe0 +libLLVM.v18.1.7+5.i686-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/6e4d9b097efc5a63562bc11a23e93d385379ce4baac77c65677e610d1824cc8fe9019048e2dd8e25caf976f2023df8f7b85ca7c8a9c3d2b6c1ac9b2a5dfa3845 +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/6cf0604857ce7dbebe4e805ab13f2ebc +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/8d257fa81af8418ecd1f7f0cea88b969b970b1973c8764422f211ea183fc7f6fc177e2c2189892a19d2289ef026c6ec3f74059d6edddca0b3846b9a2c126ad84 +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/850f0a17f7ae56d693c66d032801d97e +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/e42b12097d002306d734b49983261c7b9dadd7273862aeba09f6994832db9da65835ab86294e57265028fd4a8b7a544f8a3dd48bf3c23e45b2de4eec87d44160 +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/221e2a112359ed954ad721fc76f5b13c +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/a94d68718254da9043aa45f22f49a3bb6cd768e32cdc14402f2ee12ed7c48c8c8ede9163808bffa451d7d1e7d4a6c1390956ff9d6f4461fea5a83e7187a82698 +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/264057f43126283102b00def81b17ea3 +libLLVM.v18.1.7+5.i686-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/5de5d22f1685ac3183568f9c2f330c1de9912d81e5f4cc58a03d430960fbbccb812c17730c3782a00ff7327500fc4a501a7cf999de93932338fe93f68c7680f3 +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/45d2a5957d1aca883046e5c95cd1c494 +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/354407da4e50d15340abd8f3ae5ef029314cc4be78777a14e2e89bacf9014562e423b1ccb595794cdcc608a01420595dbbf3f1c6ab284969a3588cd972a40fa8 +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/4fe886695db26d9360df8e76508cda88 +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/0978223ab4fcd157ddadd9c0656748e5ce011ab7d07b980c1f09dcbc2fbf67b21055f18be623e498265c305817dfd5cde057b71b046e88871a1523484ad489a4 +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/d96ed9650675ccb49e52aead0482a49c +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/6bd83eb1f636bc294c0e6088d215054dc896779f93d1e3df2fc32835778db2f02a75264ef274ec054fd3f604386f97746ba20ab1187296a5445f5647a4a13604 +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/ac6fd6d5a07084e4cae2314a2cd9adfb +libLLVM.v18.1.7+5.powerpc64le-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/852f613fc8b78511d9f53484b2bf544230939750e659da7aa5179dccb8662fd61a4f36086104a20b367dee74990980fff0a4f7bcb8b0ea8ad987f309337c42b1 +libLLVM.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/md5/3f7fb351702456f897486cc02540184c +libLLVM.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.asserts.tar.gz/sha512/7b3951189c2f1f9b8d3d60dc7fda46537ed6d7c06b6be698d6df37157c39d8294d1048d7cdec5fd4ad54cc9b597268cd802c2bc8e5a5c6f3b6461d50c2a9f773 +libLLVM.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.tar.gz/md5/ed26db445a214d2570f732933a0c8e51 +libLLVM.v18.1.7+5.x86_64-apple-darwin-llvm_version+18.tar.gz/sha512/ff7dce53822518132608d1ae6e454c99fbe88a7108b7ac676f57cd3832df2761de460e2f2c4f4ff32bc4279f01bb4c1d0a4b67ebd24fc4551c955677eae91303 +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/md5/c2037083649784ac685aae6be5d643be +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.asserts.tar.gz/sha512/82787adcb833510fa0f2dc89dc8bc8721d4d4d28c1b753a669be2fcd23db1789ae77e6c774b4d8101fa07e8e0018fe12b1022b40d6226e831035abfcaa2243cf +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/md5/194a410598ae3c6fd2f94ece77613e29 +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx03-llvm_version+18.tar.gz/sha512/a224855c0bad5cd9c86373f2e5cbc1c6c12efa2b7fa897d75e1401dae2eea1dcb75004e423b771346fbed083846fe57ce9349c79e1e871bf0ca7fbb1cf0d4c83 +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/md5/6aef022fe6057e71d84a469de39f1df6 +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.asserts.tar.gz/sha512/646aa726e2d745ca8d01cc24265d73ac7e8b0e8a818dfdf7ba17984f82ca3ba697e237eb685c36e2fd29f6a649316e5769cd677f15d861b0f66ca848ca7b3619 +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/md5/b3c4d1bd69eb0ef24e244a2c53d4482e +libLLVM.v18.1.7+5.x86_64-linux-gnu-cxx11-llvm_version+18.tar.gz/sha512/4814a550f6d7fb5cb975c403b0b06e910aec4ae13d007428ad507c3a9e69a628e1e6d09ec4b933909fbb59cfb8f4755003527584afce813625cf56f432873a87 +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/md5/3558bdf495c90df4666324927b25fb7c +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.asserts.tar.gz/sha512/a746ab1c229d9fe995258915757dd4b2f05f23b34710f9e198ad25e2202216ced254978376f7a1bd05196da5f1b893f1b86143d7107ef1885349950ed7fdcedf +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/md5/de1ec2406a8f5642157ed8a01a3c10ab +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx03-llvm_version+18.tar.gz/sha512/d937ebaa5780b7d9a404055d991456e6d5de3c56f133f4c8377acea98f033fca5a836b661da18bb58b0122e9702ad7969456b9695594bfee9ce8eb9e77a6b1b0 +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/md5/5ebeb59d5398edd3a53b976ead0500e3 +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.asserts.tar.gz/sha512/a3c5cc63d1972970b3d03a4b58298f33ec66ed739564862223987947287e97a85342ac5f70d0c197086dad74b69eeaba47baf15dbb49f6f2744318c430bc6dc5 +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/md5/8862f2f7ee02f39339811c1b0741d7c0 +libLLVM.v18.1.7+5.x86_64-linux-musl-cxx11-llvm_version+18.tar.gz/sha512/f1866e04a290e69d0e3fcf906f2053aa8ed2c51ac0ba6fc621799a75984a9cd38d763126b9f8ca726cdbb7d2a2b686ed0df9780caa3276ed02ec889da3f37f31 +libLLVM.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/md5/7977ab6cb209a4b8569ee13f9462c24c +libLLVM.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.asserts.tar.gz/sha512/5f2f6a9588704fa0870f51a609938f4a26fb6bdae5158285b5d222a0649b7e2086bd4fbb3892914b0322ef7ee1848164f0e5e39fb2c5d8ba2febbd903a49dad4 +libLLVM.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.tar.gz/md5/7b5d194d4747f1a1b4e348ed2bc0f8a9 +libLLVM.v18.1.7+5.x86_64-unknown-freebsd-llvm_version+18.tar.gz/sha512/d0e9b608c8bf914b3e7cac3d75cd340e703695cad113604e9bd6a6ad9fc40db2d5eae7ae7287f726ace098fec92253c551366b5294728aa28ab96c55faeda3d5 +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/md5/7807e53cfb230f22c52fd0bdf3c204c5 +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.asserts.tar.gz/sha512/c601e229f16e848362d22653cf56228d34a94be2d713d403daeae8a57e86ead6d02e1bd8d7e015e4a1431823f029d2d3502c703d1cd43b09cff093b35f65dc16 +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/md5/0a6ce9706165364620ca3285c5a028ff +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx03-llvm_version+18.tar.gz/sha512/cc1a13c043b79c047097b0c9179e24e793448eb46929860a97e37287e32733b9bdc77cf35de4b0617da8228c4321eca747bbc9c2bfd3d0a14de7de301f81bb3f +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/md5/78a1ae46a856d695314e2d1c5ec32648 +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.asserts.tar.gz/sha512/46eb78cf06070003d3db9468dd0f7eb7182ab0e2aab5382c084a50c998f1f88feac4b6b7865c0a3ac68789749580f6363cc4658d89e97a67a1980b5632501aa0 +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/md5/2fa953aa26fb40a38e0e22b23d93c0e7 +libLLVM.v18.1.7+5.x86_64-w64-mingw32-cxx11-llvm_version+18.tar.gz/sha512/a6aacd7bb74424ba5bc84b3201f9e6965a929090a60ed61b19fd516d8073fee259cde368201ba2d6296fac6fa805c3ec7aa94f6434cc35c3457c7b3aa0e57744 +llvm-julia-18.1.7-4.tar.gz/md5/ddd227220baeac9ac36ee2fcbb098905 +llvm-julia-18.1.7-4.tar.gz/sha512/a356c3189b30c0fd9c7a527f2b55ef7b95584355f5bbbf284fd59ddbe91af1bcfa57c30303e15884e80ace4792e7899f89d9dae25b97c40ae2cd3618a7ff024a llvm-project-19.1.4.tar.xz/md5/1e13043b18558e4346ea3769094c9737 llvm-project-19.1.4.tar.xz/sha512/a586f8a41dde5e0d9ca6d8c58e9ef2a2e59b70a86d2e2c46106dc31b5c096bb80af0cdbdb486179e9cc676a540099f49a1c2db9e5e84c50362db1f72e9af6906 diff --git a/deps/checksums/openssl b/deps/checksums/openssl index 3b41bfa69231d..cca21ccd8c5a5 100644 --- a/deps/checksums/openssl +++ b/deps/checksums/openssl @@ -1,38 +1,38 @@ -OpenSSL.v3.5.0+0.aarch64-apple-darwin.tar.gz/md5/b8dc9909528f769bd9ac56cf2681f387 -OpenSSL.v3.5.0+0.aarch64-apple-darwin.tar.gz/sha512/0d9ea24d8f856c31c8b88afa1de317d13aff1f1f60b309e06e77eea91d195526ec91ed2d077f0dbb75370c17b8875c24d3066e6872bbef04312616e99d0aff3d -OpenSSL.v3.5.0+0.aarch64-linux-gnu.tar.gz/md5/7cf5baeacf4d882b547c229758a9fa9b -OpenSSL.v3.5.0+0.aarch64-linux-gnu.tar.gz/sha512/726ceee82379e667a65abe27c482d3b57e611c630d82b1314f6d385f0f2e8256835ef707c2e015f9204d563d7ee469bed2dee88d245af81dcde2af3b8331b19c -OpenSSL.v3.5.0+0.aarch64-linux-musl.tar.gz/md5/4601e56eaed365548203752a19f4f8e8 -OpenSSL.v3.5.0+0.aarch64-linux-musl.tar.gz/sha512/da349081850d47b9393665c4365787c26f61471362475c2acd3c8205063d09a785f7b6c836ba6793e880440115b19e85821b4d1938e57dafea0cabb45048a70b -OpenSSL.v3.5.0+0.aarch64-unknown-freebsd.tar.gz/md5/6a9e78436727e67af2f537170e18445e -OpenSSL.v3.5.0+0.aarch64-unknown-freebsd.tar.gz/sha512/4dc2f7a39f17255871773d10ed1b74de5c908af0f7a4bd3f94fd71bc12480fd4cdee0bd859a154328218935f004eee20359dacc353e366c47ed890229a579fc4 -OpenSSL.v3.5.0+0.armv6l-linux-gnueabihf.tar.gz/md5/5c751092c27910a48cab31f87700fe19 -OpenSSL.v3.5.0+0.armv6l-linux-gnueabihf.tar.gz/sha512/b44e2356f719549dd831745963b8c74346be173d176ca15ab2ee6f4a1ec7e105086d89115cb76831a3251eb67bf7c5ff5cba3a03fd4614a3501af235a8e03beb -OpenSSL.v3.5.0+0.armv6l-linux-musleabihf.tar.gz/md5/fc05f9645ff000b21e46951f16833fb0 -OpenSSL.v3.5.0+0.armv6l-linux-musleabihf.tar.gz/sha512/8c960294fe542ab9d9ae7dc283c0c30621f348ff8011a9a47f38c1460234b3b128011426c3e5d0cb6c9b02fbee261b7b264d0b0c55bdf3be2a2cd5bdd210d71d -OpenSSL.v3.5.0+0.armv7l-linux-gnueabihf.tar.gz/md5/8928d47a0f549d15240eb934caddf599 -OpenSSL.v3.5.0+0.armv7l-linux-gnueabihf.tar.gz/sha512/4b5dbfb3a4ea4ebe6510cbe63da2de0bb3762a0fc98946acbb059e9a92791ac65a3519577250dcb571fa07f29be182f165a5d4fa05fc96b60270441adab30e74 -OpenSSL.v3.5.0+0.armv7l-linux-musleabihf.tar.gz/md5/1e4c11043d05bea0fcdbf92525152c51 -OpenSSL.v3.5.0+0.armv7l-linux-musleabihf.tar.gz/sha512/e9514cd0c3a8c3659ff87d505490ca3011a65800222b21e4f932bc2a80fb38bb11de1d13925c3a6313f6bea1c2baf35b38b3db18193ac11ec42eb434edee3418 -OpenSSL.v3.5.0+0.i686-linux-gnu.tar.gz/md5/ee699f302edd1f7677baa565ae631c74 -OpenSSL.v3.5.0+0.i686-linux-gnu.tar.gz/sha512/16dd396b192b4ca23d1fad54d130a92ef43a36259482cd3b276001d084711ef8674dcd167c9f832f5989d6197889af69d2ae6bcef3e6b9f538066bf347c89584 -OpenSSL.v3.5.0+0.i686-linux-musl.tar.gz/md5/e6ffea118acb68d39ccb13df51e15125 -OpenSSL.v3.5.0+0.i686-linux-musl.tar.gz/sha512/44335dcaf144d388bd47dd80db08862f4cff1d5a90861f34001127df74d0d16babedbe0ffd02ab398bddd17ecda605f433a940b3cc5159947cb54810a564b0df -OpenSSL.v3.5.0+0.i686-w64-mingw32.tar.gz/md5/8ef4284ac47a6b45f8c5b01d203ae668 -OpenSSL.v3.5.0+0.i686-w64-mingw32.tar.gz/sha512/d7ea8c94d54a139631f2710cb2c47c0387b694e60dc7afddbca3c6705e17d25ec8958a84b4424edd1ea27d6d1c78457fbacd92f7634345f4ccc1a81cf242c28f -OpenSSL.v3.5.0+0.powerpc64le-linux-gnu.tar.gz/md5/21674471f2a3352ede9aef3454381edd -OpenSSL.v3.5.0+0.powerpc64le-linux-gnu.tar.gz/sha512/5615d438db7c3e97dc422b260b3152cd89a2412b7b9b5d7cea36b0ce471fbd3f1a2e8a9d77f399e257f5c38b8b5dfc256acfbdbe2645ba47b89c177dadd066e9 -OpenSSL.v3.5.0+0.riscv64-linux-gnu.tar.gz/md5/7761384fd5991eb56286f24c9a0fbdba -OpenSSL.v3.5.0+0.riscv64-linux-gnu.tar.gz/sha512/e63d5f7ddc368f4cdb03c299361faef7274930c622404907c3560eb04e6110f851b9a201b402bb6e52fdafe64988f909c209f659f84ba77957eb45a933c8baf1 -OpenSSL.v3.5.0+0.x86_64-apple-darwin.tar.gz/md5/a970728a9aa6f25d56db7e43e7b0cae2 -OpenSSL.v3.5.0+0.x86_64-apple-darwin.tar.gz/sha512/8ab5b2dd90914e193d1f7689c8560228d03cb6ee79fd43a48ae9339b61274fea0557a2bf3a7ae4ce4d4b51630aede55d6d6e860f263e1ffc0bfd6141367a9514 -OpenSSL.v3.5.0+0.x86_64-linux-gnu.tar.gz/md5/4530c0e1791b0eaec99b68f2967a3c2f -OpenSSL.v3.5.0+0.x86_64-linux-gnu.tar.gz/sha512/ba952738be38f52ebc23f48c52c12c1bec9c8b81416264612da21ca21f23604c8e59bf49f73d4b80256ea17b6b662179620deadb8660be98d8ad5ed57e346394 -OpenSSL.v3.5.0+0.x86_64-linux-musl.tar.gz/md5/eb49cefbb938d80198dbab90e1ad9108 -OpenSSL.v3.5.0+0.x86_64-linux-musl.tar.gz/sha512/f038e9bd950e4472cdd82b0c39aebbfd60e75cdf24fd8408d39e4db0793813c9d30471d1ca8d112b0bb4049f18f8fb36b4c3069dfce61032dc73cb6568852b77 -OpenSSL.v3.5.0+0.x86_64-unknown-freebsd.tar.gz/md5/25023844dae8c7d326620b1f9e730a07 -OpenSSL.v3.5.0+0.x86_64-unknown-freebsd.tar.gz/sha512/e38f1f7c452903a09b3f0127e377d5e46e538903f9a58076e53dfc53883b2423463d3fdcf13dc961516965b6dbc2d289bfbfa1027f8c3110a61bdee060bccf73 -OpenSSL.v3.5.0+0.x86_64-w64-mingw32.tar.gz/md5/a73f5220598dfc5e71e1eee6b26f7a27 -OpenSSL.v3.5.0+0.x86_64-w64-mingw32.tar.gz/sha512/c028527230b6e9e675b7e22a21997e5d032e1099dd1f3437c6e764b7967fd0196d4cb46d66b36f2f6ddeb8200f445aa8d6a7a61f7be61288ee5e0e510b5800f8 -openssl-3.5.0.tar.gz/md5/51da7d2bdf7f4f508cb024f562eb9b03 -openssl-3.5.0.tar.gz/sha512/39cc80e2843a2ee30f3f5de25cd9d0f759ad8de71b0b39f5a679afaaa74f4eb58d285ae50e29e4a27b139b49343ac91d1f05478f96fb0c6b150f16d7b634676f +OpenSSL.v3.5.1+0.aarch64-apple-darwin.tar.gz/md5/b19522093c25c50685002ad48933a835 +OpenSSL.v3.5.1+0.aarch64-apple-darwin.tar.gz/sha512/afa6363f8396deac5131f5efbe92d5b60f4d6982d279d63b5847e80ac4717d89e32edcc9bc7a5fbaab95e03908a6e3e9b386a3931effb0a7163b947b38ed2cd5 +OpenSSL.v3.5.1+0.aarch64-linux-gnu.tar.gz/md5/60af2cb22b7d5f4fddd94bd196f86ad2 +OpenSSL.v3.5.1+0.aarch64-linux-gnu.tar.gz/sha512/3d384f5da4be3af848b47f48f2438dbda8cdb228b8569d01bd4fbd6feea9f494ecafd3cab6e7b0bbed596746aa2614826971133a2b6dea02836c0904ce870760 +OpenSSL.v3.5.1+0.aarch64-linux-musl.tar.gz/md5/5f96641ec5256a547e03cd6028892a50 +OpenSSL.v3.5.1+0.aarch64-linux-musl.tar.gz/sha512/668c08f2a08f9d65b2e5c1ca4db8f74932995d0fa97c4737a2d9cedb3548482f85fddd478fad37325e2d48f76259fd8f7e003d31fc2a9ecfdb88c4748f90e1d6 +OpenSSL.v3.5.1+0.aarch64-unknown-freebsd.tar.gz/md5/377bd17ae448f4394b3100b290602f35 +OpenSSL.v3.5.1+0.aarch64-unknown-freebsd.tar.gz/sha512/f989a15062b47f059086d4dc8fd53af00717ca622ef8c475a11f6e62a29d8ec4a80159d93a683e8729da66c4bda4c46b7647754dc996ed2ff5635cbbdaf702aa +OpenSSL.v3.5.1+0.armv6l-linux-gnueabihf.tar.gz/md5/83bcc0b545bea092a0a5de9e64cbcbf1 +OpenSSL.v3.5.1+0.armv6l-linux-gnueabihf.tar.gz/sha512/c589119945ff6c1341bc229a2e61096c630288f7d483ea9538202915f8ee1a9e26cd53efc479f1e92a83a75aa6c7453ceba446832678ffed340a4bec13fefbfc +OpenSSL.v3.5.1+0.armv6l-linux-musleabihf.tar.gz/md5/3b2e34e506960259dbb40a36fed26ffe +OpenSSL.v3.5.1+0.armv6l-linux-musleabihf.tar.gz/sha512/735f22fe1202818f64f369471292bb8fdf8cf1f3395d01e70ddf8f65efc5430aec54a63fe950e52625f2c8a5dbd59ed0175f088144af8d99c7db1967ed0e5aeb +OpenSSL.v3.5.1+0.armv7l-linux-gnueabihf.tar.gz/md5/aedb37bde1b3fad428987745dc1dd095 +OpenSSL.v3.5.1+0.armv7l-linux-gnueabihf.tar.gz/sha512/1919823df3c0de01c59a5f9cf42b912a1d56fe7de903c4e7cbcd54603760783a99fe34cd1c108e954d5fe41502c1791b803d67742d70abae64d316c3656b7280 +OpenSSL.v3.5.1+0.armv7l-linux-musleabihf.tar.gz/md5/573a752ca28fd62644208a4c0b32eaa4 +OpenSSL.v3.5.1+0.armv7l-linux-musleabihf.tar.gz/sha512/3385b170973a9e50919981e66e591077479ae7561368941f018aca6f42c86b3d01aa1d9896d4d5f6deb69760fa42f535f6aaa076b75a15f207328ba6f0a32660 +OpenSSL.v3.5.1+0.i686-linux-gnu.tar.gz/md5/fcdb2ab108900c412abf154a6cbd46e7 +OpenSSL.v3.5.1+0.i686-linux-gnu.tar.gz/sha512/b558e6c23809f702a7388dba7031a9df577e1a2eb1ca86b7cf0dcd9809973dff1c9b56d4a09c315b17dcc9860e7f89604513a2d022117d9145f2bc81befa094b +OpenSSL.v3.5.1+0.i686-linux-musl.tar.gz/md5/0192e44a52d9518d712db58019ace62c +OpenSSL.v3.5.1+0.i686-linux-musl.tar.gz/sha512/fe9740850e6eb32eb539d16303b39d9ad1d3e8cc2e5a742304013890a0e1e8af93e131a5393c3c817b5723680425947d6954455dd715cc83589fd097c517b5c2 +OpenSSL.v3.5.1+0.i686-w64-mingw32.tar.gz/md5/51b5546301f8c474bcc9c97b625df2c1 +OpenSSL.v3.5.1+0.i686-w64-mingw32.tar.gz/sha512/47874ce005e6944f3a4d482f3edf44bcaa3724338230d68fff22c484c0620fe857a11bdc515ef9154522a2884f64bacadfd1fddb1430a45c7722a6a4799107f6 +OpenSSL.v3.5.1+0.powerpc64le-linux-gnu.tar.gz/md5/1aeaa0660006b4b8c13cd1cb45b2acfc +OpenSSL.v3.5.1+0.powerpc64le-linux-gnu.tar.gz/sha512/dff025feb0d1ae96a7c33f1beff5e6f76d5a85833314470f59d75bf791e90363145ae79f3ed82c5c40e36416b75fa9deb5807911c8133fe11f31b4705737f0bc +OpenSSL.v3.5.1+0.riscv64-linux-gnu.tar.gz/md5/160065eb12650c504fd40a25e4bae2ba +OpenSSL.v3.5.1+0.riscv64-linux-gnu.tar.gz/sha512/68951cf98c4eb778d372e239d14497405e6161461a623135a5254c3fd65bc3a12fe3df1ecce88909cb05dc29104b5b18caafea115799c5abf2505afe75be3207 +OpenSSL.v3.5.1+0.x86_64-apple-darwin.tar.gz/md5/7e5903d1d051de70a93a9b801ce274db +OpenSSL.v3.5.1+0.x86_64-apple-darwin.tar.gz/sha512/729b33cc208b8646394bcf0029a276ad41cf2e9d44737dbc1e15dca794cc55a52e2b782b0c72ef57b5580b84a93b25133788424f1b16ef2b784d409bca598150 +OpenSSL.v3.5.1+0.x86_64-linux-gnu.tar.gz/md5/9cee745524f41dc21af2f460ac2f1293 +OpenSSL.v3.5.1+0.x86_64-linux-gnu.tar.gz/sha512/6949c7f19b7919073542af903019ec0d8fd5172450141a3f69f0c325f0c5cc19618f1959b96380719538c5a1a5a388165a0db8e6eab041d0a5874a627820212b +OpenSSL.v3.5.1+0.x86_64-linux-musl.tar.gz/md5/e55565c84e5cff597ea490e02c559d1a +OpenSSL.v3.5.1+0.x86_64-linux-musl.tar.gz/sha512/c27930401c72b6be94ba7717f7b3be0025b09138e146f3d2a761e805308ee51f4ca871459941448e102f64b0e3c1aa479f39ee77f3234321890fa7105418ed44 +OpenSSL.v3.5.1+0.x86_64-unknown-freebsd.tar.gz/md5/276d97e2d573977727ca8d2113335fac +OpenSSL.v3.5.1+0.x86_64-unknown-freebsd.tar.gz/sha512/71f72a82c590542928660f004f38f84ea335b303e7da53578d712994fff9e84a3b69fc836c08d03dd8310d17c9edc63e5f6975e6d26e67124124763633ab1b59 +OpenSSL.v3.5.1+0.x86_64-w64-mingw32.tar.gz/md5/cebdbbf8a8a301e332d75c46dcdb1af0 +OpenSSL.v3.5.1+0.x86_64-w64-mingw32.tar.gz/sha512/0e141d7317ac8f5c43d1ecc9d161b00345f99145af785d7554f750b5787ea69969f785e7a1305059137271d26450835c25dd126bf9e5aef2cdf7dcbbdebb6911 +openssl-3.5.1.tar.gz/md5/562a4e8d14ee5272f677a754b9c1ca5c +openssl-3.5.1.tar.gz/sha512/0fa152ae59ab5ea066319de039dfb1d24cbb247172d7512feb5dd920db3740f219d76b0195ea562f84fe5eae36c23772302eddfbb3509df13761452b4dafb9d3 diff --git a/deps/clang.version b/deps/clang.version index 0f49ecdd649f0..f8531d0d96286 100644 --- a/deps/clang.version +++ b/deps/clang.version @@ -3,4 +3,4 @@ ## jll artifact # Clang (paired with LLVM, only here as a JLL download) CLANG_JLL_NAME := Clang -CLANG_JLL_VER := 18.1.7+3 +CLANG_JLL_VER := 18.1.7+4 diff --git a/deps/lld.version b/deps/lld.version index 8c7008fc93d7d..84ebd52bfd273 100644 --- a/deps/lld.version +++ b/deps/lld.version @@ -2,4 +2,4 @@ ## jll artifact LLD_JLL_NAME := LLD -LLD_JLL_VER := 18.1.7+3 +LLD_JLL_VER := 18.1.7+5 diff --git a/deps/llvm-tools.version b/deps/llvm-tools.version index 8a1159fd69174..a25a9eb42512c 100644 --- a/deps/llvm-tools.version +++ b/deps/llvm-tools.version @@ -3,5 +3,5 @@ ## jll artifact # LLVM_tools (downloads LLVM_jll to get things like `lit` and `opt`) LLVM_TOOLS_JLL_NAME := LLVM -LLVM_TOOLS_JLL_VER := 18.1.7+3 -LLVM_TOOLS_ASSERT_JLL_VER := 18.1.7+3 +LLVM_TOOLS_JLL_VER := 18.1.7+4 +LLVM_TOOLS_ASSERT_JLL_VER := 18.1.7+4 diff --git a/deps/llvm.version b/deps/llvm.version index 27250f008cd8e..75f8120444ce1 100644 --- a/deps/llvm.version +++ b/deps/llvm.version @@ -2,14 +2,14 @@ ## jll artifact LLVM_JLL_NAME := libLLVM -LLVM_ASSERT_JLL_VER := 18.1.7+4 +LLVM_ASSERT_JLL_VER := 18.1.7+5 ## source build # Version number of LLVM LLVM_VER := 18.1.7 # Git branch name in `LLVM_GIT_URL` repository -LLVM_BRANCH=julia-18.1.7-3 +LLVM_BRANCH=julia-18.1.7-4 # Git ref in `LLVM_GIT_URL` repository -LLVM_SHA1=julia-18.1.7-3 +LLVM_SHA1=julia-18.1.7-4 ## Following options are used to automatically fetch patchset from Julia's fork. This is ## useful if you want to build an external LLVM while still applying Julia's patches. @@ -20,4 +20,4 @@ LLVM_JULIA_DIFF_GITHUB_REPO := https://github.com/llvm/llvm-project # Base GitHub ref for generating the diff. LLVM_BASE_REF := llvm:llvmorg-18.1.7 # Julia fork's GitHub ref for generating the diff. -LLVM_JULIA_REF := JuliaLang:julia-18.1.7-3 +LLVM_JULIA_REF := JuliaLang:julia-18.1.7-4 diff --git a/deps/openssl.version b/deps/openssl.version index 49c463aad1565..2313ae5ffe116 100644 --- a/deps/openssl.version +++ b/deps/openssl.version @@ -3,4 +3,4 @@ OPENSSL_JLL_NAME := OpenSSL ## source build -OPENSSL_VER := 3.5.0 +OPENSSL_VER := 3.5.1 diff --git a/doc/Makefile b/doc/Makefile index 4469a40f74248..13bc0e2b61599 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -25,7 +25,7 @@ help: DOCUMENTER_OPTIONS := linkcheck=$(linkcheck) doctest=$(doctest) buildroot=$(call cygpath_w,$(BUILDROOT)) \ texplatform=$(texplatform) revise=$(revise) -UNICODE_DATA_VERSION=13.0.0 +UNICODE_DATA_VERSION=16.0.0 $(SRCCACHE)/UnicodeData-$(UNICODE_DATA_VERSION).txt: @mkdir -p "$(SRCCACHE)" $(JLDOWNLOAD) "$@" https://www.unicode.org/Public/$(UNICODE_DATA_VERSION)/ucd/UnicodeData.txt diff --git a/doc/src/devdocs/functions.md b/doc/src/devdocs/functions.md index 777afaa56348d..0cbbb4623e9fa 100644 --- a/doc/src/devdocs/functions.md +++ b/doc/src/devdocs/functions.md @@ -1,25 +1,22 @@ # Julia Functions + This document will explain how functions, method definitions, and method tables work. ## Method Tables Every function in Julia is a generic function. A generic function is conceptually a single function, -but consists of many definitions, or methods. The methods of a generic function are stored in -a method table. Method tables (type `MethodTable`) are associated with `TypeName`s. A `TypeName` -describes a family of parameterized types. For example `Complex{Float32}` and `Complex{Float64}` -share the same `Complex` type name object. - -All objects in Julia are potentially callable, because every object has a type, which in turn -has a `TypeName`. +but consists of many definitions, or methods. The methods of a generic function are stored in a +method table. There is one global method table (type `MethodTable`) named `Core.GlobalMethods`. Any +default operation on methods (such as calls) uses that table. ## [Function calls](@id Function-calls) -Given the call `f(x, y)`, the following steps are performed: first, the method table to use is -accessed as `typeof(f).name.mt`. Second, an argument tuple type is formed, `Tuple{typeof(f), typeof(x), typeof(y)}`. -Note that the type of the function itself is the first element. This is because the type might -have parameters, and so needs to take part in dispatch. This tuple type is looked up in the method -table. +Given the call `f(x, y)`, the following steps are performed: First, a tuple type is formed, +`Tuple{typeof(f), typeof(x), typeof(y)}`. Note that the type of the function itself is the first +element. This is because the function itself participates symmetrically in method lookup with the +other arguments. This tuple type is looked up in the global method table. However, the system can +then cache the results, so these steps can be skipped later for similar lookups. This dispatch process is performed by `jl_apply_generic`, which takes two arguments: a pointer to an array of the values `f`, `x`, and `y`, and the number of values (in this case 3). @@ -48,15 +45,6 @@ jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs); Given the above dispatch process, conceptually all that is needed to add a new method is (1) a tuple type, and (2) code for the body of the method. `jl_method_def` implements this operation. -`jl_method_table_for` is called to extract the relevant method table from what would be -the type of the first argument. This is much more complicated than the corresponding procedure -during dispatch, since the argument tuple type might be abstract. For example, we can define: - -```julia -(::Union{Foo{Int},Foo{Int8}})(x) = 0 -``` - -which works since all possible matching methods would belong to the same method table. ## Creating generic functions @@ -93,9 +81,7 @@ end ## Constructors -A constructor call is just a call to a type. The method table for `Type` contains all -constructor definitions. All subtypes of `Type` (`Type`, `UnionAll`, `Union`, and `DataType`) -currently share a method table via special arrangement. +A constructor call is just a call to a type, to a method defined on `Type{T}`. ## Builtins @@ -127,18 +113,14 @@ import Markdown Markdown.parse ``` -These are all singleton objects whose types are subtypes of `Builtin`, which is a subtype of -`Function`. Their purpose is to expose entry points in the run time that use the "jlcall" calling -convention: +These are mostly singleton objects all of whose types are subtypes of `Builtin`, which is a +subtype of `Function`. Their purpose is to expose entry points in the run time that use the +"jlcall" calling convention: ```c jl_value_t *(jl_value_t*, jl_value_t**, uint32_t) ``` -The method tables of builtins are empty. Instead, they have a single catch-all method cache entry -(`Tuple{Vararg{Any}}`) whose jlcall fptr points to the correct function. This is kind of a hack -but works reasonably well. - ## Keyword arguments Keyword arguments work by adding methods to the kwcall function. This function @@ -187,7 +169,7 @@ is absent. Finally there is the kwsorter definition: ``` -function (::Core.kwftype(typeof(circle)))(kws, circle, center, radius) +function (::Core.kwcall)(kws, circle, center, radius) if haskey(kws, :color) color = kws.color else @@ -205,30 +187,6 @@ function (::Core.kwftype(typeof(circle)))(kws, circle, center, radius) end ``` -The function `Core.kwftype(t)` creates the field `t.name.mt.kwsorter` (if it hasn't been created -yet), and returns the type of that function. - -This design has the feature that call sites that don't use keyword arguments require no special -handling; everything works as if they were not part of the language at all. Call sites that do -use keyword arguments are dispatched directly to the called function's kwsorter. For example the -call: - -```julia -circle((0, 0), 1.0, color = red; other...) -``` - -is lowered to: - -```julia -kwcall(merge((color = red,), other), circle, (0, 0), 1.0) -``` - -`kwcall` (also in`Core`) denotes a kwcall signature and dispatch. -The keyword splatting operation (written as `other...`) calls the named tuple `merge` function. -This function further unpacks each *element* of `other`, expecting each one to contain two values -(a symbol and a value). -Naturally, a more efficient implementation is available if all splatted arguments are named tuples. -Notice that the original `circle` function is passed through, to handle closures. ## [Compiler efficiency issues](@id compiler-efficiency-issues) @@ -251,18 +209,13 @@ sees an argument in the `Function` type hierarchy passed to a slot declared as ` it behaves as if the `@nospecialize` annotation were applied. This heuristic seems to be extremely effective in practice. -The next issue concerns the structure of method cache hash tables. Empirical studies show that -the vast majority of dynamically-dispatched calls involve one or two arguments. In turn, many -of these cases can be resolved by considering only the first argument. (Aside: proponents of single -dispatch would not be surprised by this at all. However, this argument means "multiple dispatch -is easy to optimize in practice", and that we should therefore use it, *not* "we should use single -dispatch"!) So the method cache uses the type of the first argument as its primary key. Note, -however, that this corresponds to the *second* element of the tuple type for a function call (the -first element being the type of the function itself). Typically, type variation in head position -is extremely low -- indeed, the majority of functions belong to singleton types with no parameters. -However, this is not the case for constructors, where a single method table holds constructors -for every type. Therefore the `Type` method table is special-cased to use the *first* tuple type -element instead of the second. +The next issue concerns the structure of method tables. Empirical studies show that the vast +majority of dynamically-dispatched calls involve one or two arguments. In turn, many of these cases +can be resolved by considering only the first argument. (Aside: proponents of single dispatch would +not be surprised by this at all. However, this argument means "multiple dispatch is easy to optimize +in practice", and that we should therefore use it, *not* "we should use single dispatch"!). So the +method table and cache splits up on the structure based on a left-to-right decision tree so allow +efficient nearest-neighbor searches. The front end generates type declarations for all closures. Initially, this was implemented by generating normal type declarations. However, this produced an extremely large number of constructors, diff --git a/doc/src/devdocs/locks.md b/doc/src/devdocs/locks.md index 8d6672842c3c8..c89499a4162a9 100644 --- a/doc/src/devdocs/locks.md +++ b/doc/src/devdocs/locks.md @@ -85,6 +85,10 @@ may result in pernicious and hard-to-find deadlocks. BE VERY CAREFUL! > > * Libdl.LazyLibrary lock +The following is a level 7 lock, which can only be acquired when not holding any other locks: + +> * world_counter_lock + The following is the root lock, meaning no other lock shall be held when trying to acquire it: diff --git a/doc/src/devdocs/sysimg.md b/doc/src/devdocs/sysimg.md index 2cbba2744d4a1..e8202736e57e1 100644 --- a/doc/src/devdocs/sysimg.md +++ b/doc/src/devdocs/sysimg.md @@ -176,7 +176,7 @@ debug info, respectively, and so will make debugging more difficult. We have identified many small changes to Base that significantly increase the set of programs that can be reliably trimmed. Unfortunately some of those changes would be considered breaking, and so are only applied when trimming is requested (this is done by an external build script, -currently maintained inside the test suite as `contrib/juliac-buildscript.jl`). +currently maintained inside the test suite as `contrib/juliac/juliac-buildscript.jl`). Therefore in many cases trimming will require you to opt in to new variants of Base and some standard libraries. diff --git a/doc/src/devdocs/types.md b/doc/src/devdocs/types.md index a09df61e4881d..fc4a93b94ca3c 100644 --- a/doc/src/devdocs/types.md +++ b/doc/src/devdocs/types.md @@ -176,7 +176,12 @@ julia> dump(Array{Int,1}.name) TypeName name: Symbol Array module: Module Core - names: empty SimpleVector + singletonname: Symbol Array + names: SimpleVector + 1: Symbol ref + 2: Symbol size + atomicfields: Ptr{Nothing}(0x0000000000000000) + constfields: Ptr{Nothing}(0x0000000000000000) wrapper: UnionAll var: TypeVar name: Symbol T @@ -188,21 +193,20 @@ TypeName lb: Union{} ub: abstract type Any body: mutable struct Array{T, N} <: DenseArray{T, N} + Typeofwrapper: abstract type Type{Array} <: Any cache: SimpleVector ... - linearcache: SimpleVector ... - - hash: Int64 -7900426068641098781 - mt: MethodTable - name: Symbol Array - defs: Nothing nothing - cache: Nothing nothing - max_args: Int64 0 - module: Module Core - : Int64 0 - : Int64 0 + hash: Int64 2594190783455944385 + backedges: #undef + partial: #undef + max_args: Int32 0 + n_uninitialized: Int32 0 + flags: UInt8 0x02 + cache_entry_count: UInt8 0x00 + max_methods: UInt8 0x00 + constprop_heuristic: UInt8 0x00 ``` In this case, the relevant field is `wrapper`, which holds a reference to the top-level type used diff --git a/doc/src/manual/multi-threading.md b/doc/src/manual/multi-threading.md index ec470f867cc47..401169e9c2132 100644 --- a/doc/src/manual/multi-threading.md +++ b/doc/src/manual/multi-threading.md @@ -8,7 +8,7 @@ of Julia multi-threading features. By default, Julia starts up with 2 threads of execution; 1 worker thread and 1 interactive thread. This can be verified by using the command [`Threads.nthreads()`](@ref): -```jldoctest +```julia julia> Threads.nthreads(:default) 1 julia> Threads.nthreads(:interactive) @@ -37,6 +37,7 @@ each threadpool. !!! compat "Julia 1.12" Starting by default with 1 interactive thread, as well as the 1 worker thread, was made as such in Julia 1.12 + If the number of threads is set to 1 by either doing `-t1` or `JULIA_NUM_THREADS=1` an interactive thread will not be spawned. Lets start Julia with 4 threads: @@ -144,6 +145,8 @@ julia> nthreads(:interactive) julia> nthreads() 3 ``` +!!! note + Explicitly asking for 1 thread by doing `-t1` or `JULIA_NUM_THREADS=1` does not add an interactive thread. !!! note The zero-argument version of `nthreads` returns the number of threads diff --git a/src/aotcompile.cpp b/src/aotcompile.cpp index 8c5d9e678a166..4393a99c73380 100644 --- a/src/aotcompile.cpp +++ b/src/aotcompile.cpp @@ -620,7 +620,7 @@ static void generate_cfunc_thunks(jl_codegen_params_t ¶ms, jl_compiled_funct } } Function *f = codeinst ? aot_abi_converter(params, M, declrt, sigt, cfunc.nargs, cfunc.specsig, codeinst, defM, func, "", false) : unspec; - return assign_fptr(f); + assign_fptr(f); } } @@ -661,7 +661,7 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm 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] = jl_box_long(trim); + fargs[3] = jl_box_uint8(trim); size_t last_age = ct->world_age; ct->world_age = jl_typeinf_world; codeinfos = (jl_array_t*)jl_apply(fargs, 4); @@ -2387,7 +2387,7 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t *dump, jl_method_instance_t *mi, jl_ jl_method_instance_t *mi = jl_get_specialization1((jl_tupletype_t*)sigt, latestworld, 0); if (mi == nullptr) continue; - jl_code_instance_t *codeinst = jl_type_infer(mi, latestworld, SOURCE_MODE_NOT_REQUIRED); + jl_code_instance_t *codeinst = jl_type_infer(mi, latestworld, SOURCE_MODE_NOT_REQUIRED, jl_options.trim); if (codeinst == nullptr || compiled_functions.count(codeinst)) continue; orc::ThreadSafeModule decl_m = jl_create_ts_module("extern", ctx); diff --git a/src/builtin_proto.h b/src/builtin_proto.h index c82ec77414129..586d948f722c1 100644 --- a/src/builtin_proto.h +++ b/src/builtin_proto.h @@ -8,82 +8,88 @@ extern "C" { #endif // declarations for julia-callable builtin functions +#define JL_BUILTIN_FUNCTIONS(XX) \ + XX(_abstracttype,"_abstracttype") \ + XX(_apply_iterate,"_apply_iterate") \ + XX(_call_in_world_total,"_call_in_world_total") \ + XX(_compute_sparams,"_compute_sparams") \ + XX(_defaultctors,"_defaultctors") \ + XX(_equiv_typedef,"_equiv_typedef") \ + XX(_expr,"_expr") \ + XX(_primitivetype,"_primitivetype") \ + XX(_setsuper,"_setsuper!") \ + XX(_structtype,"_structtype") \ + XX(_svec_ref,"_svec_ref") \ + XX(_typebody,"_typebody!") \ + XX(_typevar,"_typevar") \ + XX(applicable,"applicable") \ + XX(apply_type,"apply_type") \ + XX(compilerbarrier,"compilerbarrier") \ + XX(current_scope,"current_scope") \ + XX(donotdelete,"donotdelete") \ + XX(fieldtype,"fieldtype") \ + XX(finalizer,"finalizer") \ + XX(get_binding_type,"get_binding_type") \ + XX(getfield,"getfield") \ + XX(getglobal,"getglobal") \ + XX(ifelse,"ifelse") \ + XX(intrinsic_call,"intrinsic_call") \ + XX(invoke,"invoke") \ + XX(invoke_in_world,"invoke_in_world") \ + XX(invokelatest,"invokelatest") \ + XX(is,"===") \ + XX(isa,"isa") \ + XX(isdefined,"isdefined") \ + XX(isdefinedglobal,"isdefinedglobal") \ + XX(issubtype,"<:") \ + XX(memorynew,"memorynew") \ + XX(memoryrefnew,"memoryrefnew") \ + XX(memoryref_isassigned,"memoryref_isassigned") \ + XX(memoryrefget,"memoryrefget") \ + XX(memoryrefmodify,"memoryrefmodify!") \ + XX(memoryrefoffset,"memoryrefoffset") \ + XX(memoryrefreplace,"memoryrefreplace!") \ + XX(memoryrefset,"memoryrefset!") \ + XX(memoryrefsetonce,"memoryrefsetonce!") \ + XX(memoryrefswap,"memoryrefswap!") \ + XX(modifyfield,"modifyfield!") \ + XX(modifyglobal,"modifyglobal!") \ + XX(nfields,"nfields") \ + XX(opaque_closure_call,"opaque_closure_call") \ + XX(replacefield,"replacefield!") \ + XX(replaceglobal,"replaceglobal!") \ + XX(setfield,"setfield!") \ + XX(setfieldonce,"setfieldonce!") \ + XX(setglobal,"setglobal!") \ + XX(setglobalonce,"setglobalonce!") \ + XX(sizeof,"sizeof") \ + XX(svec,"svec") \ + XX(swapfield,"swapfield!") \ + XX(swapglobal,"swapglobal!") \ + XX(throw,"throw") \ + XX(throw_methoderror,"throw_methoderror") \ + XX(tuple,"tuple") \ + XX(typeassert,"typeassert") \ + XX(typeof,"typeof") \ -#ifdef DEFINE_BUILTIN_GLOBALS -#define DECLARE_BUILTIN(name) \ - JL_CALLABLE(jl_f_##name); \ - JL_DLLEXPORT jl_value_t *jl_builtin_##name; \ - JL_DLLEXPORT jl_fptr_args_t jl_f_##name##_addr = &jl_f_##name -#else -#define DECLARE_BUILTIN(name) \ - JL_CALLABLE(jl_f_##name); \ - JL_DLLEXPORT extern jl_value_t *jl_builtin_##name; \ - JL_DLLEXPORT extern jl_fptr_args_t jl_f_##name##_addr -#endif +#define DECLARE_BUILTIN(cname,jlname) \ + JL_CALLABLE(jl_f_##cname); +JL_BUILTIN_FUNCTIONS(DECLARE_BUILTIN) +#undef DECLARE_BUILTIN + +#define BUILTIN(cname) (jl_builtin_instances[jl_builtin_id_##cname]) + +enum jl_builtin_ids { +#define BUILTIN_IDS(cname,jlname) jl_builtin_id_##cname, +JL_BUILTIN_FUNCTIONS(BUILTIN_IDS) +#undef BUILTIN_IDS + jl_n_builtins +}; -DECLARE_BUILTIN(_apply_iterate); -DECLARE_BUILTIN(invoke_in_world); -DECLARE_BUILTIN(_call_in_world_total); -DECLARE_BUILTIN(invokelatest); -DECLARE_BUILTIN(_compute_sparams); -DECLARE_BUILTIN(_expr); -DECLARE_BUILTIN(_svec_ref); -DECLARE_BUILTIN(_typebody); -DECLARE_BUILTIN(_typevar); -DECLARE_BUILTIN(applicable); -DECLARE_BUILTIN(apply_type); -DECLARE_BUILTIN(compilerbarrier); -DECLARE_BUILTIN(current_scope); -DECLARE_BUILTIN(donotdelete); -DECLARE_BUILTIN(fieldtype); -DECLARE_BUILTIN(finalizer); -DECLARE_BUILTIN(getfield); -DECLARE_BUILTIN(getglobal); -DECLARE_BUILTIN(ifelse); -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); -DECLARE_BUILTIN(memoryrefmodify); -DECLARE_BUILTIN(memoryrefoffset); -DECLARE_BUILTIN(memoryrefreplace); -DECLARE_BUILTIN(memoryrefset); -DECLARE_BUILTIN(memoryrefsetonce); -DECLARE_BUILTIN(memoryrefswap); -DECLARE_BUILTIN(modifyfield); -DECLARE_BUILTIN(modifyglobal); -DECLARE_BUILTIN(nfields); -DECLARE_BUILTIN(replacefield); -DECLARE_BUILTIN(replaceglobal); -DECLARE_BUILTIN(setfield); -DECLARE_BUILTIN(setfieldonce); -DECLARE_BUILTIN(setglobal); -DECLARE_BUILTIN(setglobalonce); -DECLARE_BUILTIN(sizeof); -DECLARE_BUILTIN(svec); -DECLARE_BUILTIN(swapfield); -DECLARE_BUILTIN(swapglobal); -DECLARE_BUILTIN(throw); -DECLARE_BUILTIN(throw_methoderror); -DECLARE_BUILTIN(tuple); -DECLARE_BUILTIN(typeassert); -DECLARE_BUILTIN(typeof); +JL_DLLEXPORT extern jl_fptr_args_t const jl_builtin_f_addrs[]; +JL_DLLEXPORT extern const char *const jl_builtin_f_names[]; +JL_DLLEXPORT extern jl_value_t *jl_builtin_instances[]; -JL_CALLABLE(jl_f__structtype); -JL_CALLABLE(jl_f__abstracttype); -JL_CALLABLE(jl_f__primitivetype); -JL_CALLABLE(jl_f__setsuper); -JL_CALLABLE(jl_f__defaultctors); -JL_CALLABLE(jl_f__equiv_typedef); -JL_CALLABLE(jl_f_get_binding_type); -JL_CALLABLE(jl_f__compute_sparams); -JL_CALLABLE(jl_f__svec_ref); #ifdef __cplusplus } #endif diff --git a/src/builtins.c b/src/builtins.c index a2cae857f26b4..d68c7fc21ec40 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -30,6 +30,27 @@ extern "C" { #endif +jl_fptr_args_t const jl_builtin_f_addrs[jl_n_builtins] = { +#define BUILTIN_ADDRS(cname,jlname) &jl_f_##cname, +JL_BUILTIN_FUNCTIONS(BUILTIN_ADDRS) +#undef BUILTIN_ADDRS +}; + +const char *const jl_builtin_f_names[jl_n_builtins] = { +#define BUILTIN_F_NAMES(cname,jlname) XSTR(jl_f_##cname), +JL_BUILTIN_FUNCTIONS(BUILTIN_F_NAMES) +#undef BUILTIN_F_NAMES +}; + +jl_value_t *jl_builtin_instances[jl_n_builtins]; + +static const char *const jl_builtin_names[jl_n_builtins] = { +#define BUILTIN_NAMES(cname,jlname) jlname, +JL_BUILTIN_FUNCTIONS(BUILTIN_NAMES) +#undef BUILTIN_NAMES +}; + + // egal and object_id --------------------------------------------------------- static int bits_equal(const void *a, const void *b, int sz) JL_NOTSAFEPOINT @@ -647,7 +668,7 @@ JL_CALLABLE(jl_f__apply_iterate) nargs -= 1; if (nargs == 2) { // some common simple cases - if (f == jl_builtin_svec) { + if (f == BUILTIN(svec)) { if (jl_is_svec(args[1])) return args[1]; if (jl_is_genericmemory(args[1])) { @@ -672,7 +693,7 @@ JL_CALLABLE(jl_f__apply_iterate) return (jl_value_t*)t; } } - else if (f == jl_builtin_tuple && jl_is_tuple(args[1])) { + else if (f == BUILTIN(tuple) && jl_is_tuple(args[1])) { return args[1]; } } @@ -1317,7 +1338,7 @@ JL_CALLABLE(jl_f_getglobal) jl_atomic_error("getglobal: module binding cannot be read non-atomically"); else if (order >= jl_memory_order_seq_cst) jl_fence(); - jl_value_t *v = jl_eval_global_var(mod, sym); // relaxed load + jl_value_t *v = jl_eval_global_var(mod, sym, jl_current_task->world_age); // relaxed load if (order >= jl_memory_order_acquire) jl_fence(); return v; @@ -1691,11 +1712,11 @@ JL_CALLABLE(jl_f_memorynew) return (jl_value_t*)jl_alloc_genericmemory(args[0], nel); } -JL_CALLABLE(jl_f_memoryref) +JL_CALLABLE(jl_f_memoryrefnew) { - JL_NARGS(memoryref, 1, 3); + JL_NARGS(memoryrefnew, 1, 3); if (nargs == 1) { - JL_TYPECHK(memoryref, genericmemory, args[0]); + JL_TYPECHK(memoryrefnew, genericmemory, args[0]); jl_genericmemory_t *m = (jl_genericmemory_t*)args[0]; jl_value_t *typ = jl_apply_type((jl_value_t*)jl_genericmemoryref_type, jl_svec_data(((jl_datatype_t*)jl_typetagof(m))->parameters), 3); JL_GC_PROMISE_ROOTED(typ); // it is a concrete type @@ -1705,10 +1726,10 @@ JL_CALLABLE(jl_f_memoryref) return (jl_value_t*)jl_new_memoryref(typ, m, m->ptr); } else { - JL_TYPECHK(memoryref, genericmemoryref, args[0]); - JL_TYPECHK(memoryref, long, args[1]); + JL_TYPECHK(memoryrefnew, genericmemoryref, args[0]); + JL_TYPECHK(memoryrefnew, long, args[1]); if (nargs == 3) - JL_TYPECHK(memoryref, bool, args[2]); + JL_TYPECHK(memoryrefnew, bool, args[2]); jl_genericmemoryref_t *m = (jl_genericmemoryref_t*)args[0]; size_t i = jl_unbox_long(args[1]) - 1; const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(m->mem))->layout; @@ -1735,7 +1756,7 @@ JL_CALLABLE(jl_f_memoryref) JL_CALLABLE(jl_f_memoryrefoffset) { JL_NARGS(memoryrefoffset, 1, 1); - JL_TYPECHK(memoryref, genericmemoryref, args[0]); + JL_TYPECHK(memoryrefoffest, genericmemoryref, args[0]); jl_genericmemoryref_t m = *(jl_genericmemoryref_t*)args[0]; const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(m.mem))->layout; size_t offset; @@ -2415,15 +2436,12 @@ void jl_init_intrinsic_functions(void) JL_GC_DISABLED { jl_module_t *inm = jl_new_module_(jl_symbol("Intrinsics"), jl_core_module, 0, 1); jl_set_initial_const(jl_core_module, jl_symbol("Intrinsics"), (jl_value_t*)inm, 0); - jl_mk_builtin_func(jl_intrinsic_type, "IntrinsicFunction", jl_f_intrinsic_call); - jl_mk_builtin_func( - (jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_opaque_closure_type), - "OpaqueClosure", jl_f_opaque_closure_call); + jl_mk_builtin_func(jl_intrinsic_type, jl_symbol("IntrinsicFunction"), jl_f_intrinsic_call); + jl_datatype_t *oc = (jl_datatype_t*)jl_unwrap_unionall((jl_value_t*)jl_opaque_closure_type); // Save a reference to the just created OpaqueClosure method, so we can provide special // codegen for it later. - jl_opaque_closure_method = (jl_method_t*)jl_methtable_lookup(jl_opaque_closure_typename->mt, - (jl_value_t*)jl_anytuple_type, 1); + jl_opaque_closure_method = jl_mk_builtin_func(oc, jl_symbol("OpaqueClosure"), jl_f_opaque_closure_call); // TODO: awkwardly not actually declared a Builtin, even though it relies on being handled by the special cases for Builtin everywhere else #define ADD_I(name, nargs) add_intrinsic(inm, #name, name); #define ADD_HIDDEN(name, nargs) @@ -2439,93 +2457,21 @@ static void add_builtin(const char *name, jl_value_t *v) jl_set_initial_const(jl_core_module, jl_symbol(name), v, 0); } -jl_fptr_args_t jl_get_builtin_fptr(jl_datatype_t *dt) -{ - assert(jl_subtype((jl_value_t*)dt, (jl_value_t*)jl_builtin_type)); - jl_typemap_entry_t *entry = (jl_typemap_entry_t*)jl_atomic_load_relaxed(&dt->name->mt->defs); - jl_method_instance_t *mi = jl_atomic_load_relaxed(&entry->func.method->unspecialized); - jl_code_instance_t *ci = jl_atomic_load_relaxed(&mi->cache); - assert(ci->owner == jl_nothing); - return jl_atomic_load_relaxed(&ci->specptr.fptr1); -} - -static jl_value_t *add_builtin_func(const char *name, jl_fptr_args_t fptr) -{ - return jl_mk_builtin_func(NULL, name, fptr)->instance; -} - void jl_init_primitives(void) JL_GC_DISABLED { - jl_builtin_is = add_builtin_func("===", jl_f_is); - jl_builtin_typeof = add_builtin_func("typeof", jl_f_typeof); - jl_builtin_sizeof = add_builtin_func("sizeof", jl_f_sizeof); - jl_builtin_issubtype = add_builtin_func("<:", jl_f_issubtype); - jl_builtin_isa = add_builtin_func("isa", jl_f_isa); - jl_builtin_typeassert = add_builtin_func("typeassert", jl_f_typeassert); - jl_builtin_throw = add_builtin_func("throw", jl_f_throw); - jl_builtin_tuple = add_builtin_func("tuple", jl_f_tuple); - jl_builtin_ifelse = add_builtin_func("ifelse", jl_f_ifelse); - - // field access - jl_builtin_getfield = add_builtin_func("getfield", jl_f_getfield); - jl_builtin_setfield = add_builtin_func("setfield!", jl_f_setfield); - jl_builtin_setfieldonce = add_builtin_func("setfieldonce!", jl_f_setfieldonce); - jl_builtin_swapfield = add_builtin_func("swapfield!", jl_f_swapfield); - jl_builtin_modifyfield = add_builtin_func("modifyfield!", jl_f_modifyfield); - jl_builtin_replacefield = add_builtin_func("replacefield!", jl_f_replacefield); - jl_builtin_fieldtype = add_builtin_func("fieldtype", jl_f_fieldtype); - jl_builtin_nfields = add_builtin_func("nfields", jl_f_nfields); - jl_builtin_isdefined = add_builtin_func("isdefined", jl_f_isdefined); - - // 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); - jl_builtin_modifyglobal = add_builtin_func("modifyglobal!", jl_f_modifyglobal); - 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); - jl_builtin_memoryrefset = add_builtin_func("memoryrefset!", jl_f_memoryrefset); - jl_builtin_memoryref_isassigned = add_builtin_func("memoryref_isassigned", jl_f_memoryref_isassigned); - jl_builtin_memoryrefswap = add_builtin_func("memoryrefswap!", jl_f_memoryrefswap); - jl_builtin_memoryrefreplace = add_builtin_func("memoryrefreplace!", jl_f_memoryrefreplace); - jl_builtin_memoryrefmodify = add_builtin_func("memoryrefmodify!", jl_f_memoryrefmodify); - jl_builtin_memoryrefsetonce = add_builtin_func("memoryrefsetonce!", jl_f_memoryrefsetonce); - - // method table utils - jl_builtin_applicable = add_builtin_func("applicable", jl_f_applicable); - jl_builtin_invoke = add_builtin_func("invoke", jl_f_invoke); - - // internal functions - jl_builtin_apply_type = add_builtin_func("apply_type", jl_f_apply_type); - jl_builtin__apply_iterate = add_builtin_func("_apply_iterate", jl_f__apply_iterate); - jl_builtin__expr = add_builtin_func("_expr", jl_f__expr); - jl_builtin_svec = add_builtin_func("svec", jl_f_svec); - add_builtin_func("invokelatest", jl_f_invokelatest); - add_builtin_func("invoke_in_world", jl_f_invoke_in_world); - add_builtin_func("_call_in_world_total", jl_f__call_in_world_total); - add_builtin_func("_typevar", jl_f__typevar); - add_builtin_func("_structtype", jl_f__structtype); - add_builtin_func("_abstracttype", jl_f__abstracttype); - add_builtin_func("_primitivetype", jl_f__primitivetype); - add_builtin_func("_setsuper!", jl_f__setsuper); - add_builtin_func("_defaultctors", jl_f__defaultctors); - jl_builtin__typebody = add_builtin_func("_typebody!", jl_f__typebody); - add_builtin_func("_equiv_typedef", jl_f__equiv_typedef); - jl_builtin_donotdelete = add_builtin_func("donotdelete", jl_f_donotdelete); - jl_builtin_compilerbarrier = add_builtin_func("compilerbarrier", jl_f_compilerbarrier); - add_builtin_func("finalizer", jl_f_finalizer); - add_builtin_func("_compute_sparams", jl_f__compute_sparams); - add_builtin_func("_svec_ref", jl_f__svec_ref); - jl_builtin_current_scope = add_builtin_func("current_scope", jl_f_current_scope); - add_builtin_func("throw_methoderror", jl_f_throw_methoderror); + // Builtins are specially considered available from world 0 + for (int i = 0; i < jl_n_builtins; i++) { + if (i == jl_builtin_id_intrinsic_call || + i == jl_builtin_id_opaque_closure_call) + continue; + jl_sym_t *sname = jl_symbol(jl_builtin_names[i]); + jl_value_t *builtin = jl_new_generic_function_with_supertype(sname, jl_core_module, jl_builtin_type, 0); + jl_set_initial_const(jl_core_module, sname, builtin, 0); + jl_mk_builtin_func((jl_datatype_t*)jl_typeof(builtin), sname, jl_builtin_f_addrs[i]); + jl_builtin_instances[i] = builtin; + } + add_builtin("OpaqueClosure", (jl_value_t*)jl_opaque_closure_type); + add_builtin("IntrinsicFunction", (jl_value_t*)jl_intrinsic_type); // builtin types add_builtin("Any", (jl_value_t*)jl_any_type); @@ -2545,6 +2491,8 @@ void jl_init_primitives(void) JL_GC_DISABLED add_builtin("Module", (jl_value_t*)jl_module_type); add_builtin("MethodTable", (jl_value_t*)jl_methtable_type); + add_builtin("GlobalMethods", (jl_value_t*)jl_method_table); + add_builtin("MethodCache", (jl_value_t*)jl_methcache_type); add_builtin("Method", (jl_value_t*)jl_method_type); add_builtin("CodeInstance", (jl_value_t*)jl_code_instance_type); add_builtin("TypeMapEntry", (jl_value_t*)jl_typemap_entry_type); @@ -2558,14 +2506,12 @@ void jl_init_primitives(void) JL_GC_DISABLED add_builtin("PartialOpaque", (jl_value_t*)jl_partial_opaque_type); add_builtin("InterConditional", (jl_value_t*)jl_interconditional_type); add_builtin("MethodMatch", (jl_value_t*)jl_method_match_type); - add_builtin("IntrinsicFunction", (jl_value_t*)jl_intrinsic_type); add_builtin("Function", (jl_value_t*)jl_function_type); add_builtin("Builtin", (jl_value_t*)jl_builtin_type); add_builtin("MethodInstance", (jl_value_t*)jl_method_instance_type); add_builtin("CodeInfo", (jl_value_t*)jl_code_info_type); add_builtin("LLVMPtr", (jl_value_t*)jl_llvmpointer_type); add_builtin("Task", (jl_value_t*)jl_task_type); - add_builtin("OpaqueClosure", (jl_value_t*)jl_opaque_closure_type); add_builtin("AddrSpace", (jl_value_t*)jl_addrspace_type); add_builtin("Ref", (jl_value_t*)jl_ref_type); @@ -2611,6 +2557,26 @@ void jl_init_primitives(void) JL_GC_DISABLED add_builtin("AbstractString", (jl_value_t*)jl_abstractstring_type); add_builtin("String", (jl_value_t*)jl_string_type); + + // ensure that primitive types are fully allocated (since jl_init_types is incomplete) + assert(jl_atomic_load_relaxed(&jl_world_counter) == 1); + jl_module_t *core = jl_core_module; + jl_svec_t *bindings = jl_atomic_load_relaxed(&core->bindings); + jl_value_t **table = jl_svec_data(bindings); + for (size_t i = 0; i < jl_svec_len(bindings); i++) { + if (table[i] != jl_nothing) { + jl_binding_t *b = (jl_binding_t*)table[i]; + jl_value_t *v = jl_get_binding_value_in_world(b, 1); + if (v) { + if (jl_is_unionall(v)) + v = jl_unwrap_unionall(v); + if (jl_is_datatype(v)) { + jl_datatype_t *tt = (jl_datatype_t*)v; + tt->name->module = core; + } + } + } + } } #ifdef __cplusplus diff --git a/src/cgutils.cpp b/src/cgutils.cpp index beaad5f85fec3..945e125c71be2 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1601,10 +1601,17 @@ static void undef_var_error_ifnot(jl_codectx_t &ctx, Value *ok, jl_sym_t *name, ctx.builder.SetInsertPoint(ifok); } +// ctx.builder.CreateIsNotNull(v) lowers incorrectly in non-standard +// address spaces where null is not zero +// TODO: adapt to https://github.com/llvm/llvm-project/pull/131557 once merged static Value *null_pointer_cmp(jl_codectx_t &ctx, Value *v) { ++EmittedNullchecks; - return ctx.builder.CreateIsNotNull(v); + Type *T = v->getType(); + return ctx.builder.CreateICmpNE( + v, + ctx.builder.CreateAddrSpaceCast( + Constant::getNullValue(ctx.builder.getPtrTy(0)), T)); } @@ -2641,6 +2648,11 @@ static jl_cgval_t typed_store(jl_codectx_t &ctx, ctx.builder.CreateStore(r, intcast); r = ctx.builder.CreateLoad(intcast_eltyp, intcast); } + else if (!isboxed && intcast_eltyp) { + assert(issetfield); + // issetfield doesn't use intcast, so need to reload rhs with the correct type + r = emit_unbox(ctx, intcast_eltyp, rhs, jltype); + } if (!isboxed) emit_write_multibarrier(ctx, parent, r, rhs.typ); else @@ -4638,7 +4650,7 @@ static Value *emit_memoryref_FCA(jl_codectx_t &ctx, const jl_cgval_t &ref, const static jl_cgval_t emit_memoryref(jl_codectx_t &ctx, const jl_cgval_t &ref, jl_cgval_t idx, jl_value_t *inbounds, const jl_datatype_layout_t *layout) { ++EmittedArrayNdIndex; - emit_typecheck(ctx, idx, (jl_value_t*)jl_long_type, "memoryref"); + emit_typecheck(ctx, idx, (jl_value_t*)jl_long_type, "memoryrefnew"); idx = update_julia_type(ctx, idx, (jl_value_t*)jl_long_type); if (idx.typ == jl_bottom_type) return jl_cgval_t(); diff --git a/src/clangsa/GCChecker.cpp b/src/clangsa/GCChecker.cpp index af07ca2227839..09a034a9549d8 100644 --- a/src/clangsa/GCChecker.cpp +++ b/src/clangsa/GCChecker.cpp @@ -836,6 +836,7 @@ bool GCChecker::isGCTrackedType(QualType QT) { Name.ends_with_insensitive("jl_typemap_t") || Name.ends_with_insensitive("jl_unionall_t") || Name.ends_with_insensitive("jl_methtable_t") || + Name.ends_with_insensitive("jl_methcache_t") || Name.ends_with_insensitive("jl_cgval_t") || Name.ends_with_insensitive("jl_codectx_t") || Name.ends_with_insensitive("jl_ast_context_t") || diff --git a/src/codegen.cpp b/src/codegen.cpp index 6f6328c2a5758..2dfcdd39aa665 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -354,7 +354,7 @@ struct jl_tbaacache_t { MDNode *tbaa_ptrarraybuf; // Data in an array of boxed values MDNode *tbaa_arraybuf; // Data in an array of POD MDNode *tbaa_array; // jl_array_t or jl_genericmemory_t - MDNode *tbaa_arrayptr; // The pointer inside a jl_array_t (to memoryref) + MDNode *tbaa_arrayptr; // The pointer inside a jl_array_t (to a memoryref) MDNode *tbaa_arraysize; // A size in a jl_array_t MDNode *tbaa_arrayselbyte; // a selector byte in a isbits Union jl_genericmemory_t MDNode *tbaa_memoryptr; // The pointer inside a jl_genericmemory_t @@ -568,7 +568,14 @@ FunctionType *invoke_type(TypeFnContextAndTriple f, Module &M) template struct JuliaFunction { public: - llvm::StringLiteral name; + template + constexpr JuliaFunction(const char (&cname)[N], TypeFn_t _type, llvm::AttributeList (*_attrs)(llvm::LLVMContext &C)) + : name(StringRef(cname, N-1)), _type(_type), _attrs(_attrs) {} + JuliaFunction(StringRef cname, TypeFn_t _type, llvm::AttributeList (*_attrs)(llvm::LLVMContext &C)) + : name(cname), _type(_type), _attrs(_attrs) {} + JuliaFunction(char *cname, TypeFn_t _type, llvm::AttributeList (*_attrs)(llvm::LLVMContext &C)) = delete; + + llvm::StringRef name; TypeFn_t _type; llvm::AttributeList (*_attrs)(llvm::LLVMContext &C); @@ -617,10 +624,6 @@ static FunctionType *get_func_sig(LLVMContext &C) { return JuliaType::get_jlfunc static FunctionType *get_func2_sig(LLVMContext &C) { return JuliaType::get_jlfunc2_ty(C); } static FunctionType *get_func3_sig(LLVMContext &C) { return JuliaType::get_jlfunc3_ty(C); } -static FunctionType *get_donotdelete_sig(LLVMContext &C) { - return FunctionType::get(getVoidTy(C), true); -} - static AttributeList get_func_attrs(LLVMContext &C) { return AttributeList::get(C, @@ -630,18 +633,6 @@ static AttributeList get_func_attrs(LLVMContext &C) Attributes(C, {Attribute::NoAlias, Attribute::ReadOnly, Attribute::NoCapture, Attribute::NoUndef})}); } -static AttributeList get_donotdelete_func_attrs(LLVMContext &C) -{ - AttrBuilder FnAttrs(C); - FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); - FnAttrs.addAttribute(Attribute::WillReturn); - FnAttrs.addAttribute(Attribute::NoUnwind); - return AttributeList::get(C, - AttributeSet::get(C, FnAttrs), - Attributes(C, {}), - None); -} - static AttributeList get_attrs_noreturn(LLVMContext &C) { return AttributeList::get(C, @@ -663,7 +654,7 @@ static AttributeList get_attrs_box_float(LLVMContext &C, unsigned nbytes) auto FnAttrs = AttrBuilder(C); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); - FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); + FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly() | MemoryEffects::readOnly()); auto RetAttrs = AttrBuilder(C); RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addDereferenceableAttr(nbytes); @@ -679,7 +670,7 @@ static AttributeList get_attrs_box_sext(LLVMContext &C, unsigned nbytes) auto FnAttrs = AttrBuilder(C); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); - FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); + FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly() | MemoryEffects::readOnly()); auto RetAttrs = AttrBuilder(C); RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addAttribute(Attribute::getWithDereferenceableBytes(C, nbytes)); @@ -696,7 +687,7 @@ static AttributeList get_attrs_box_zext(LLVMContext &C, unsigned nbytes) auto FnAttrs = AttrBuilder(C); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); - FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly()); + FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly() | MemoryEffects::readOnly()); auto RetAttrs = AttrBuilder(C); RetAttrs.addAttribute(Attribute::NonNull); RetAttrs.addDereferenceableAttr(nbytes); @@ -1147,7 +1138,7 @@ static const auto jl_alloc_obj_func = new JuliaFunction{ auto FnAttrs = AttrBuilder(C); FnAttrs.addAllocSizeAttr(1, None); // returns %1 bytes FnAttrs.addAllocKindAttr(AllocFnKind::Alloc); - FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef)); + FnAttrs.addMemoryAttr(MemoryEffects::argMemOnly(ModRefInfo::Ref) | MemoryEffects::inaccessibleMemOnly()); FnAttrs.addAttribute(Attribute::WillReturn); FnAttrs.addAttribute(Attribute::NoUnwind); auto RetAttrs = AttrBuilder(C); @@ -1171,7 +1162,7 @@ static const auto jl_alloc_genericmemory_unchecked_func = new JuliaFunction{ }, get_attrs_basic, }; -static const auto jlgetbuiltinfptr_func = new JuliaFunction<>{ - XSTR(jl_get_builtin_fptr), - [](LLVMContext &C) { return FunctionType::get(get_func_sig(C)->getPointerTo(), - {JuliaType::get_prjlvalue_ty(C)}, false); }, - nullptr, +static const auto jldnd_func = new JuliaFunction<>{ + XSTR(jl_f_donotdelete), + [](LLVMContext &C) { + return FunctionType::get(getVoidTy(C), true); + }, + [](LLVMContext &C) { + AttrBuilder FnAttrs(C); + FnAttrs.addMemoryAttr(MemoryEffects::inaccessibleMemOnly() | MemoryEffects::readOnly()); + FnAttrs.addAttribute(Attribute::WillReturn); + FnAttrs.addAttribute(Attribute::NoUnwind); + return AttributeList::get(C, + AttributeSet::get(C, FnAttrs), + Attributes(C, {}), + None); + }, }; // placeholder functions @@ -1583,56 +1584,23 @@ static const auto julia_call3 = new JuliaFunction<>{ static const auto jltuple_func = new JuliaFunction<>{XSTR(jl_f_tuple), get_func_sig, get_func_attrs}; static const auto jlintrinsic_func = new JuliaFunction<>{XSTR(jl_f_intrinsic_call), get_func3_sig, get_func_attrs}; +static const auto jl_new_opaque_closure_jlcall_func = new JuliaFunction<>{XSTR(jl_new_opaque_closure_jlcall), get_func_sig, get_func_attrs}; + +static const auto mk_builtin_func_map() { + auto builtin_addrs = new DenseMap*>(); + for (int i = 0; i < jl_n_builtins; i++) { + jl_value_t *builtin = jl_builtin_instances[i]; + if (builtin) // a couple do not have instances (e.g. IntrinsicFunction) + (*builtin_addrs)[builtin] = new JuliaFunction<>{StringRef(jl_builtin_f_names[i]), get_func_sig, get_func_attrs}; + } + return builtin_addrs; +} static const auto &builtin_func_map() { - static auto builtins = new DenseMap*> { - { jl_f_is_addr, new JuliaFunction<>{XSTR(jl_f_is), get_func_sig, get_func_attrs} }, - { jl_f_typeof_addr, new JuliaFunction<>{XSTR(jl_f_typeof), get_func_sig, get_func_attrs} }, - { jl_f_sizeof_addr, new JuliaFunction<>{XSTR(jl_f_sizeof), get_func_sig, get_func_attrs} }, - { jl_f_issubtype_addr, new JuliaFunction<>{XSTR(jl_f_issubtype), get_func_sig, get_func_attrs} }, - { jl_f_isa_addr, new JuliaFunction<>{XSTR(jl_f_isa), get_func_sig, get_func_attrs} }, - { jl_f_typeassert_addr, new JuliaFunction<>{XSTR(jl_f_typeassert), get_func_sig, get_func_attrs} }, - { jl_f_ifelse_addr, new JuliaFunction<>{XSTR(jl_f_ifelse), get_func_sig, get_func_attrs} }, - { jl_f__apply_iterate_addr, new JuliaFunction<>{XSTR(jl_f__apply_iterate), get_func_sig, get_func_attrs} }, - { jl_f_invokelatest_addr, new JuliaFunction<>{XSTR(jl_f_invokelatest), get_func_sig, get_func_attrs} }, - { jl_f_invoke_in_world_addr, new JuliaFunction<>{XSTR(jl_f_invoke_in_world), get_func_sig, get_func_attrs} }, - { jl_f__call_in_world_total_addr, new JuliaFunction<>{XSTR(jl_f__call_in_world_total), get_func_sig, get_func_attrs} }, - { jl_f_throw_addr, new JuliaFunction<>{XSTR(jl_f_throw), get_func_sig, get_func_attrs} }, - { jl_f_throw_methoderror_addr, new JuliaFunction<>{XSTR(jl_f_throw_methoderror), get_func_sig, get_func_attrs} }, - { jl_f_tuple_addr, jltuple_func }, - { jl_f_svec_addr, new JuliaFunction<>{XSTR(jl_f_svec), get_func_sig, get_func_attrs} }, - { jl_f_applicable_addr, new JuliaFunction<>{XSTR(jl_f_applicable), get_func_sig, get_func_attrs} }, - { jl_f_invoke_addr, new JuliaFunction<>{XSTR(jl_f_invoke), get_func_sig, get_func_attrs} }, - { jl_f_isdefined_addr, new JuliaFunction<>{XSTR(jl_f_isdefined), get_func_sig, get_func_attrs} }, - { jl_f_getfield_addr, new JuliaFunction<>{XSTR(jl_f_getfield), get_func_sig, get_func_attrs} }, - { jl_f_setfield_addr, new JuliaFunction<>{XSTR(jl_f_setfield), get_func_sig, get_func_attrs} }, - { jl_f_swapfield_addr, new JuliaFunction<>{XSTR(jl_f_swapfield), get_func_sig, get_func_attrs} }, - { jl_f_modifyfield_addr, new JuliaFunction<>{XSTR(jl_f_modifyfield), get_func_sig, get_func_attrs} }, - { jl_f_fieldtype_addr, new JuliaFunction<>{XSTR(jl_f_fieldtype), get_func_sig, get_func_attrs} }, - { 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} }, - { jl_f_memoryrefswap_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefswap), get_func_sig, get_func_attrs} }, - { jl_f_memoryrefreplace_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefreplace), get_func_sig, get_func_attrs} }, - { jl_f_memoryrefmodify_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefmodify), get_func_sig, get_func_attrs} }, - { jl_f_memoryrefsetonce_addr, new JuliaFunction<>{XSTR(jl_f_memoryrefsetonce), get_func_sig, get_func_attrs} }, - { jl_f_memoryref_isassigned_addr,new JuliaFunction<>{XSTR(jl_f_memoryref_isassigned), get_func_sig, get_func_attrs} }, - { jl_f_apply_type_addr, new JuliaFunction<>{XSTR(jl_f_apply_type), get_func_sig, get_func_attrs} }, - { jl_f_donotdelete_addr, new JuliaFunction<>{XSTR(jl_f_donotdelete), get_donotdelete_sig, get_donotdelete_func_attrs} }, - { jl_f_compilerbarrier_addr, new JuliaFunction<>{XSTR(jl_f_compilerbarrier), get_func_sig, get_func_attrs} }, - { jl_f_finalizer_addr, new JuliaFunction<>{XSTR(jl_f_finalizer), get_func_sig, get_func_attrs} }, - { jl_f__svec_ref_addr, new JuliaFunction<>{XSTR(jl_f__svec_ref), get_func_sig, get_func_attrs} }, - { jl_f_current_scope_addr, new JuliaFunction<>{XSTR(jl_f_current_scope), get_func_sig, get_func_attrs} }, - }; + static auto builtins = mk_builtin_func_map(); return *builtins; } -static const auto jl_new_opaque_closure_jlcall_func = new JuliaFunction<>{XSTR(jl_new_opaque_closure_jlcall), get_func_sig, get_func_attrs}; - static _Atomic(uint64_t) globalUniqueGeneratedNames{1}; // --- code generation --- @@ -2912,7 +2880,7 @@ static jl_value_t *static_apply_type(jl_codectx_t &ctx, ArrayRef arg return NULL; v[i] = args[i].constant; } - assert(v[0] == jl_builtin_apply_type); + assert(v[0] == BUILTIN(apply_type)); size_t last_age = jl_current_task->world_age; // call apply_type, but ignore errors. we know that will work in world 1. jl_current_task->world_age = 1; @@ -2982,7 +2950,7 @@ static jl_value_t *static_eval(jl_codectx_t &ctx, jl_value_t *ex) if (e->head == jl_call_sym) { jl_value_t *f = static_eval(ctx, jl_exprarg(e, 0)); if (f) { - if (jl_array_dim0(e->args) == 3 && (f == jl_builtin_getfield || f == jl_builtin_getglobal)) { + if (jl_array_dim0(e->args) == 3 && (f == BUILTIN(getfield) || f == BUILTIN(getglobal))) { m = (jl_module_t*)static_eval(ctx, jl_exprarg(e, 1)); // Check the tag before evaluating `s` so that a value of random // type won't be corrupted. @@ -3001,10 +2969,11 @@ static jl_value_t *static_eval(jl_codectx_t &ctx, jl_value_t *ex) } } } - else if (f==jl_builtin_tuple || f==jl_builtin_apply_type) { + else if (f==BUILTIN(tuple) || f==BUILTIN(apply_type)) { size_t i; size_t n = jl_array_dim0(e->args)-1; - if (n==0 && f==jl_builtin_tuple) return (jl_value_t*)jl_emptytuple; + if (n==0 && f==BUILTIN(tuple)) + return (jl_value_t*)jl_emptytuple; jl_value_t **v; JL_GC_PUSHARGS(v, n+1); v[0] = f; @@ -3631,11 +3600,11 @@ static Value *emit_f_is(jl_codectx_t &ctx, const jl_cgval_t &arg1, const jl_cgva static bool emit_f_opglobal(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, ArrayRef argv, size_t nargs, const jl_cgval_t *modifyop) { - bool issetglobal = f == jl_builtin_setglobal; - bool isreplaceglobal = f == jl_builtin_replaceglobal; - bool isswapglobal = f == jl_builtin_swapglobal; - bool ismodifyglobal = f == jl_builtin_modifyglobal; - bool issetglobalonce = f == jl_builtin_setglobalonce; + bool issetglobal = f == BUILTIN(setglobal); + bool isreplaceglobal = f == BUILTIN(replaceglobal); + bool isswapglobal = f == BUILTIN(swapglobal); + bool ismodifyglobal = f == BUILTIN(modifyglobal); + bool issetglobalonce = f == BUILTIN(setglobalonce); const jl_cgval_t undefval; const jl_cgval_t &mod = argv[1]; const jl_cgval_t &sym = argv[2]; @@ -3704,11 +3673,11 @@ static bool emit_f_opfield(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, ArrayRef argv, size_t nargs, const jl_cgval_t *modifyop) { ++EmittedOpfields; - bool issetfield = f == jl_builtin_setfield; - bool isreplacefield = f == jl_builtin_replacefield; - bool isswapfield = f == jl_builtin_swapfield; - bool ismodifyfield = f == jl_builtin_modifyfield; - bool issetfieldonce = f == jl_builtin_setfieldonce; + bool issetfield = f == BUILTIN(setfield); + bool isreplacefield = f == BUILTIN(replacefield); + bool isswapfield = f == BUILTIN(swapfield); + bool ismodifyfield = f == BUILTIN(modifyfield); + bool issetfieldonce = f == BUILTIN(setfieldonce); const jl_cgval_t undefval; const jl_cgval_t &obj = argv[1]; const jl_cgval_t &fld = argv[2]; @@ -3851,11 +3820,11 @@ static jl_cgval_t emit_isdefinedglobal(jl_codectx_t &ctx, jl_module_t *modu, jl_ 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) { - bool issetmemory = f == jl_builtin_memoryrefset; - bool isreplacememory = f == jl_builtin_memoryrefreplace; - bool isswapmemory = f == jl_builtin_memoryrefswap; - bool ismodifymemory = f == jl_builtin_memoryrefmodify; - bool issetmemoryonce = f == jl_builtin_memoryrefsetonce; + bool issetmemory = f == BUILTIN(memoryrefset); + bool isreplacememory = f == BUILTIN(memoryrefreplace); + bool isswapmemory = f == BUILTIN(memoryrefswap); + bool ismodifymemory = f == BUILTIN(memoryrefmodify); + bool issetmemoryonce = f == BUILTIN(memoryrefsetonce); const jl_cgval_t undefval; const jl_cgval_t &ref = argv[1]; @@ -4041,14 +4010,19 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, // returns true if the call has been handled { ++EmittedBuiltinCalls; - if (f == jl_builtin_is && nargs == 2) { + if (f == BUILTIN(is) && nargs == 2) { // emit comparison test Value *ans = emit_f_is(ctx, argv[1], argv[2]); *ret = mark_julia_type(ctx, ans, false, jl_bool_type); return true; } - else if (f == jl_builtin_typeof && nargs == 1) { + else if (f == BUILTIN(ifelse) && nargs == 3) { + *ret = emit_ifelse(ctx, argv[1], argv[2], argv[3], rt); + return true; + } + + else if (f == BUILTIN(typeof) && nargs == 1) { const jl_cgval_t &p = argv[1]; if (p.constant) *ret = mark_julia_const(ctx, jl_typeof(p.constant)); @@ -4059,7 +4033,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } - else if (f == jl_builtin_typeassert && nargs == 2) { + else if (f == BUILTIN(typeassert) && nargs == 2) { const jl_cgval_t &arg = argv[1]; const jl_cgval_t &ty = argv[2]; if (jl_is_type_type(ty.typ) && !jl_has_free_typevars(ty.typ)) { @@ -4077,7 +4051,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_isa && nargs == 2) { + else if (f == BUILTIN(isa) && nargs == 2) { const jl_cgval_t &arg = argv[1]; const jl_cgval_t &ty = argv[2]; if (jl_is_type_type(ty.typ) && !jl_has_free_typevars(ty.typ)) { @@ -4088,7 +4062,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_issubtype && nargs == 2) { + else if (f == BUILTIN(issubtype) && nargs == 2) { const jl_cgval_t &ta = argv[1]; const jl_cgval_t &tb = argv[2]; if (jl_is_type_type(ta.typ) && !jl_has_free_typevars(ta.typ) && @@ -4099,7 +4073,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if ((f == jl_builtin__apply_iterate && nargs == 3) && ctx.vaSlot > 0) { + else if ((f == BUILTIN(_apply_iterate) && nargs == 3) && ctx.vaSlot > 0) { // turn Core._apply_iterate(iter, f, Tuple) ==> f(Tuple...) using the jlcall calling convention if Tuple is the va allocation if (LoadInst *load = dyn_cast_or_null(argv[3].V)) { if (load->getPointerOperand() == ctx.slots[ctx.vaSlot].boxroot && ctx.argArray) { @@ -4116,7 +4090,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_tuple) { + else if (f == BUILTIN(tuple)) { if (nargs == 0) { *ret = ghostValue(ctx, jl_emptytuple_type); return true; @@ -4127,14 +4101,14 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_throw && nargs == 1) { + else if (f == BUILTIN(throw) && nargs == 1) { Value *arg1 = boxed(ctx, argv[1]); raise_exception(ctx, arg1); *ret = jl_cgval_t(); return true; } - else if (f == jl_builtin_memorynew && (nargs == 2)) { + else if (f == BUILTIN(memorynew) && (nargs == 2)) { const jl_cgval_t &memty = argv[1]; if (!memty.constant) return false; @@ -4158,7 +4132,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } - else if (f == jl_builtin_memoryref && nargs == 1) { + else if (f == BUILTIN(memoryrefnew) && nargs == 1) { const jl_cgval_t &mem = argv[1]; jl_datatype_t *mty_dt = (jl_datatype_t*)jl_unwrap_unionall(mem.typ); if (jl_is_genericmemory_type(mty_dt) && jl_is_concrete_type((jl_value_t*)mty_dt)) { @@ -4169,7 +4143,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_memoryref && (nargs == 2 || nargs == 3)) { + else if (f == BUILTIN(memoryrefnew) && (nargs == 2 || nargs == 3)) { const jl_cgval_t &ref = argv[1]; jl_value_t *mty_dt = jl_unwrap_unionall(ref.typ); if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type(mty_dt)) { @@ -4177,13 +4151,13 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, const jl_datatype_layout_t *layout = ((jl_datatype_t*)mty_dt)->layout; jl_value_t *boundscheck = nargs == 3 ? argv[3].constant : nullptr; if (nargs == 3) - emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryref"); + emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryrefnew"); *ret = emit_memoryref(ctx, ref, argv[2], boundscheck, layout); return true; } } - else if (f == jl_builtin_memoryrefoffset && nargs == 1) { + else if (f == BUILTIN(memoryrefoffset) && nargs == 1) { const jl_cgval_t &ref = argv[1]; jl_value_t *mty_dt = jl_unwrap_unionall(ref.typ); if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type(mty_dt)) { @@ -4194,7 +4168,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_memoryrefget && nargs == 3) { + else if (f == BUILTIN(memoryrefget) && nargs == 3) { const jl_cgval_t &ref = argv[1]; jl_value_t *mty_dt = jl_unwrap_unionall(ref.typ); if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type(mty_dt)) { @@ -4233,7 +4207,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, order = isatomic ? jl_memory_order_unordered : jl_memory_order_notatomic; } jl_value_t *boundscheck = argv[3].constant; - emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryref"); + emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryrefget"); const jl_datatype_layout_t *layout = ((jl_datatype_t*)mty_dt)->layout; Value *mem = emit_memoryref_mem(ctx, ref, layout); Value *mlen = emit_genericmemorylen(ctx, mem, ref.typ); @@ -4310,16 +4284,16 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if ((f == jl_builtin_memoryrefset && nargs == 4) || - (f == jl_builtin_memoryrefswap && nargs == 4) || - (f == jl_builtin_memoryrefreplace && nargs == 6) || - (f == jl_builtin_memoryrefmodify && nargs == 5) || - (f == jl_builtin_memoryrefsetonce && nargs == 5)) { + else if ((f == BUILTIN(memoryrefset) && nargs == 4) || + (f == BUILTIN(memoryrefswap) && nargs == 4) || + (f == BUILTIN(memoryrefreplace) && nargs == 6) || + (f == BUILTIN(memoryrefmodify) && nargs == 5) || + (f == BUILTIN(memoryrefsetonce) && nargs == 5)) { return emit_f_opmemory(ctx, ret, f, argv, nargs, nullptr); } - else if (f == jl_builtin_memoryref_isassigned && nargs == 3) { + else if (f == BUILTIN(memoryref_isassigned) && nargs == 3) { const jl_cgval_t &ref = argv[1]; jl_value_t *mty_dt = jl_unwrap_unionall(ref.typ); if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type(mty_dt)) { @@ -4390,7 +4364,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } if (!isboxed) elem = emit_ptrgep(ctx, elem, layout->first_ptr * sizeof(void*)); - // emit this using the same type as jl_builtin_memoryrefget + // emit this using the same type as BUILTIN(memoryrefget) // so that LLVM may be able to load-load forward them and fold the result auto tbaa = isboxed ? ctx.tbaa().tbaa_ptrarraybuf : ctx.tbaa().tbaa_arraybuf; jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, tbaa); @@ -4419,7 +4393,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } - else if (f == jl_builtin_getfield && (nargs == 2 || nargs == 3 || nargs == 4)) { + else if (f == BUILTIN(getfield) && (nargs == 2 || nargs == 3 || nargs == 4)) { const jl_cgval_t &obj = argv[1]; const jl_cgval_t &fld = argv[2]; enum jl_memory_order order = jl_memory_order_unspecified; @@ -4579,7 +4553,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return false; } - else if (f == jl_builtin_getglobal && (nargs == 2 || nargs == 3)) { + else if (f == BUILTIN(getglobal) && (nargs == 2 || nargs == 3)) { const jl_cgval_t &mod = argv[1]; const jl_cgval_t &sym = argv[2]; enum jl_memory_order order = jl_memory_order_unspecified; @@ -4611,23 +4585,23 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return false; } - else if ((f == jl_builtin_setglobal && (nargs == 3 || nargs == 4)) || - (f == jl_builtin_swapglobal && (nargs == 3 || nargs == 4)) || - (f == jl_builtin_replaceglobal && (nargs == 4 || nargs == 5 || nargs == 6)) || - (f == jl_builtin_modifyglobal && (nargs == 4 || nargs == 5)) || - (f == jl_builtin_setglobalonce && (nargs == 3 || nargs == 4 || nargs == 5))) { + else if ((f == BUILTIN(setglobal) && (nargs == 3 || nargs == 4)) || + (f == BUILTIN(swapglobal) && (nargs == 3 || nargs == 4)) || + (f == BUILTIN(replaceglobal) && (nargs == 4 || nargs == 5 || nargs == 6)) || + (f == BUILTIN(modifyglobal) && (nargs == 4 || nargs == 5)) || + (f == BUILTIN(setglobalonce) && (nargs == 3 || nargs == 4 || nargs == 5))) { return emit_f_opglobal(ctx, ret, f, argv, nargs, nullptr); } - else if ((f == jl_builtin_setfield && (nargs == 3 || nargs == 4)) || - (f == jl_builtin_swapfield && (nargs == 3 || nargs == 4)) || - (f == jl_builtin_replacefield && (nargs == 4 || nargs == 5 || nargs == 6)) || - (f == jl_builtin_modifyfield && (nargs == 4 || nargs == 5)) || - (f == jl_builtin_setfieldonce && (nargs == 3 || nargs == 4 || nargs == 5))) { + else if ((f == BUILTIN(setfield) && (nargs == 3 || nargs == 4)) || + (f == BUILTIN(swapfield) && (nargs == 3 || nargs == 4)) || + (f == BUILTIN(replacefield) && (nargs == 4 || nargs == 5 || nargs == 6)) || + (f == BUILTIN(modifyfield) && (nargs == 4 || nargs == 5)) || + (f == BUILTIN(setfieldonce) && (nargs == 3 || nargs == 4 || nargs == 5))) { return emit_f_opfield(ctx, ret, f, argv, nargs, nullptr); } - else if (f == jl_builtin_nfields && nargs == 1) { + else if (f == BUILTIN(nfields) && nargs == 1) { const jl_cgval_t &obj = argv[1]; if (ctx.vaSlot > 0) { // optimize VA tuple @@ -4659,7 +4633,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } - else if (f == jl_builtin_fieldtype && (nargs == 2 || nargs == 3)) { + else if (f == BUILTIN(fieldtype) && (nargs == 2 || nargs == 3)) { const jl_cgval_t &typ = argv[1]; const jl_cgval_t &fld = argv[2]; if ((jl_is_type_type(typ.typ) && jl_is_concrete_type(jl_tparam0(typ.typ))) || @@ -4684,7 +4658,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_sizeof && nargs == 1) { + else if (f == BUILTIN(sizeof) && nargs == 1) { const jl_cgval_t &obj = argv[1]; jl_datatype_t *sty = (jl_datatype_t*)jl_unwrap_unionall(obj.typ); assert(jl_string_type->name->mutabl); @@ -4729,7 +4703,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, } } - else if (f == jl_builtin_apply_type && nargs > 0) { + else if (f == BUILTIN(apply_type) && nargs > 0) { if (jl_is_method(ctx.linfo->def.method)) { // don't bother codegen constant-folding for toplevel. jl_value_t *ty = static_apply_type(ctx, argv, nargs + 1); @@ -4743,7 +4717,7 @@ 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)) { + else if (f == 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; @@ -4779,7 +4753,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } - else if (f == jl_builtin_isdefined && (nargs == 2 || nargs == 3)) { + else if (f == BUILTIN(isdefined) && (nargs == 2 || nargs == 3)) { const jl_cgval_t &obj = argv[1]; const jl_cgval_t &fld = argv[2]; jl_datatype_t *stt = (jl_datatype_t*)obj.typ; @@ -4895,7 +4869,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } - else if (f == jl_builtin_current_scope && (nargs == 0)) { + else if (f == BUILTIN(current_scope) && (nargs == 0)) { jl_aliasinfo_t scope_ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_gcframe); Instruction *v = scope_ai.decorateInst( ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, get_scope_field(ctx), ctx.types().alignof_ptr)); @@ -4903,18 +4877,13 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } - else if (f == jl_builtin_donotdelete) { + else if (f == BUILTIN(donotdelete)) { // For now we emit this as a vararg call to the builtin // (which doesn't look at the arguments). In the future, // this should be an LLVM builtin. - auto it = builtin_func_map().find(jl_f_donotdelete_addr); - if (it == builtin_func_map().end()) { - return false; - } - *ret = mark_julia_const(ctx, jl_nothing); FunctionType *Fty = FunctionType::get(getVoidTy(ctx.builder.getContext()), true); - Function *dnd = prepare_call(it->second); + Function *dnd = prepare_call(jldnd_func); SmallVector call_args; for (size_t i = 1; i <= nargs; ++i) { @@ -4933,7 +4902,7 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f, return true; } - else if (f == jl_builtin_compilerbarrier && (nargs == 2)) { + else if (f == BUILTIN(compilerbarrier) && (nargs == 2)) { emit_typecheck(ctx, argv[1], (jl_value_t*)jl_symbol_type, "compilerbarrier"); *ret = argv[2]; return true; @@ -5356,22 +5325,22 @@ static jl_cgval_t emit_invoke_modify(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_ if (f.constant) { jl_cgval_t ret; auto it = builtin_func_map().end(); - if (f.constant == jl_builtin_modifyfield) { - if (emit_f_opfield(ctx, &ret, jl_builtin_modifyfield, argv, nargs - 1, &lival)) + if (f.constant == BUILTIN(modifyfield)) { + if (emit_f_opfield(ctx, &ret, BUILTIN(modifyfield), argv, nargs - 1, &lival)) return ret; - it = builtin_func_map().find(jl_f_modifyfield_addr); + it = builtin_func_map().find(f.constant); assert(it != builtin_func_map().end()); } - else if (f.constant == jl_builtin_modifyglobal) { - if (emit_f_opglobal(ctx, &ret, jl_builtin_modifyglobal, argv, nargs - 1, &lival)) + else if (f.constant == BUILTIN(modifyglobal)) { + if (emit_f_opglobal(ctx, &ret, BUILTIN(modifyglobal), argv, nargs - 1, &lival)) return ret; - it = builtin_func_map().find(jl_f_modifyglobal_addr); + it = builtin_func_map().find(f.constant); assert(it != builtin_func_map().end()); } - else if (f.constant == jl_builtin_memoryrefmodify) { - if (emit_f_opmemory(ctx, &ret, jl_builtin_memoryrefmodify, argv, nargs - 1, &lival)) + else if (f.constant == BUILTIN(memoryrefmodify)) { + if (emit_f_opmemory(ctx, &ret, BUILTIN(memoryrefmodify), argv, nargs - 1, &lival)) return ret; - it = builtin_func_map().find(jl_f_memoryrefmodify_addr); + it = builtin_func_map().find(f.constant); assert(it != builtin_func_map().end()); } else if (jl_typetagis(f.constant, jl_intrinsic_type)) { @@ -5431,15 +5400,15 @@ static jl_cgval_t emit_call(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt, bo return jl_cgval_t(); } + // a couple intrinsics (really just llvmcall, though partly cglobal too) + // have non-standard (aka invalid) evaluation semantics, so we must handle these first if (f.constant && jl_typetagis(f.constant, jl_intrinsic_type)) { JL_I::intrinsic fi = (intrinsic)*(uint32_t*)jl_data_ptr(f.constant); return emit_intrinsic(ctx, fi, args, nargs - 1); } size_t n_generic_args = nargs; - SmallVector argv(n_generic_args); - argv[0] = f; for (size_t i = 1; i < nargs; ++i) { argv[i] = emit_expr(ctx, args[i]); @@ -5447,37 +5416,23 @@ static jl_cgval_t emit_call(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt, bo return jl_cgval_t(); // anything past here is unreachable } - if (jl_subtype(f.typ, (jl_value_t*)jl_builtin_type)) { - if (f.constant) { - if (f.constant == jl_builtin_ifelse && nargs == 4) - return emit_ifelse(ctx, argv[1], argv[2], argv[3], rt); - jl_cgval_t result; - bool handled = emit_builtin_call(ctx, &result, f.constant, argv, nargs - 1, rt, ex, is_promotable); - if (handled) - return result; - jl_fptr_args_t builtin_fptr = jl_get_builtin_fptr((jl_datatype_t*)jl_typeof(f.constant)); - // special case for some known builtin not handled by emit_builtin_call - auto it = builtin_func_map().find(builtin_fptr); - if (it != builtin_func_map().end()) { - Value *ret = emit_jlcall(ctx, it->second, Constant::getNullValue(ctx.types().T_prjlvalue), ArrayRef(argv).drop_front(), nargs - 1, julia_call); - setName(ctx.emission_context, ret, it->second->name + "_ret"); - return mark_julia_type(ctx, ret, true, rt); - } - } - Value *fptr; - JuliaFunction<> *cc; - if (f.typ == (jl_value_t*)jl_intrinsic_type) { - fptr = prepare_call(jlintrinsic_func); - cc = julia_call3; - } - else { - fptr = ctx.builder.CreateCall(prepare_call(jlgetbuiltinfptr_func), {emit_typeof(ctx, f)}); - cc = julia_call; - } - Value *ret = emit_jlcall(ctx, fptr, nullptr, argv, nargs, cc); + if (f.typ == (jl_value_t*)jl_intrinsic_type) { + Value *ret = emit_jlcall(ctx, prepare_call(jlintrinsic_func), nullptr, argv, nargs, julia_call3); setName(ctx.emission_context, ret, "Builtin_ret"); return mark_julia_type(ctx, ret, true, rt); } + else if (f.constant && jl_isa(f.constant, (jl_value_t*)jl_builtin_type)) { + jl_cgval_t result; + bool handled = emit_builtin_call(ctx, &result, f.constant, argv, nargs - 1, rt, ex, is_promotable); + if (handled) + return result; + auto it = builtin_func_map().find(f.constant); + if (it != builtin_func_map().end()) { + Value *ret = emit_jlcall(ctx, it->second, Constant::getNullValue(ctx.types().T_prjlvalue), ArrayRef(argv).drop_front(), nargs - 1, julia_call); + setName(ctx.emission_context, ret, it->second->name + "_ret"); + return mark_julia_type(ctx, ret, true, rt); + } + } // handle calling an OpaqueClosure if (jl_is_concrete_type(f.typ) && jl_subtype(f.typ, (jl_value_t*)jl_opaque_closure_type)) { @@ -6393,8 +6348,8 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr, ssize_t ssaidx_ } else if (head == jl_cfunction_sym) { assert(nargs == 5); - jl_cgval_t fexpr_rt = emit_expr(ctx, args[1]); - return emit_cfunction(ctx, args[0], fexpr_rt, args[2], (jl_svec_t*)args[3]); + jl_cgval_t fexpr_val = emit_expr(ctx, args[1]); + return emit_cfunction(ctx, args[0], fexpr_val, args[2], (jl_svec_t*)args[3]); } else if (head == jl_assign_sym) { assert(nargs == 2); @@ -7521,16 +7476,11 @@ static const char *derive_sigt_name(jl_value_t *jargty) jl_datatype_t *dt = (jl_datatype_t*)jl_argument_datatype(jargty); if ((jl_value_t*)dt == jl_nothing) return NULL; - jl_sym_t *name = dt->name->name; - // if we have a kwcall, use that as the name anyways - jl_methtable_t *mt = dt->name->mt; - if (mt == jl_type_type_mt || mt == jl_nonfunction_mt || mt == NULL) { - // our value for `name` from MethodTable is not good, try to come up with something better - if (jl_is_type_type((jl_value_t*)dt)) { - dt = (jl_datatype_t*)jl_argument_datatype(jl_tparam0(dt)); - if ((jl_value_t*)dt != jl_nothing) { - name = dt->name->name; - } + jl_sym_t *name = dt->name->singletonname; + if (jl_is_type_type((jl_value_t*)dt)) { + dt = (jl_datatype_t*)jl_argument_datatype(jl_tparam0(dt)); + if ((jl_value_t*)dt != jl_nothing) { + name = dt->name->singletonname; } } return jl_symbol_name(name); @@ -7539,7 +7489,7 @@ static const char *derive_sigt_name(jl_value_t *jargty) // Get the LLVM Function* for the C-callable entry point for a certain function // and argument types. // here argt does not include the leading function type argument -static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, const jl_cgval_t &fexpr_rt, jl_value_t *declrt, jl_svec_t *argt) +static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, const jl_cgval_t &fexpr_val, jl_value_t *declrt, jl_svec_t *argt) { jl_unionall_t *unionall_env = (jl_is_method(ctx.linfo->def.method) && jl_is_unionall(ctx.linfo->def.method->sig)) ? (jl_unionall_t*)ctx.linfo->def.method->sig @@ -7597,8 +7547,8 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con // compute+verify the dispatch signature, and see if it depends on the environment sparams bool approx = false; sigt = (jl_value_t*)jl_alloc_svec(nargt + 1); - jl_svecset(sigt, 0, fexpr_rt.typ); - if (!fexpr_rt.constant && (!jl_is_concrete_type(fexpr_rt.typ) || jl_is_kind(fexpr_rt.typ))) + jl_svecset(sigt, 0, fexpr_val.typ); + if (!fexpr_val.constant && (!jl_is_concrete_type(fexpr_val.typ) || jl_is_kind(fexpr_val.typ))) approx = true; for (size_t i = 0; i < nargt; i++) { jl_value_t *jargty = jl_svecref(argt, i); @@ -7627,7 +7577,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con unionall_env = NULL; } - bool nest = (!fexpr_rt.constant || unionall_env); + bool nest = (!fexpr_val.constant || unionall_env); if (ctx.emission_context.TargetTriple.isAArch64() || ctx.emission_context.TargetTriple.isARM() || ctx.emission_context.TargetTriple.isPPC64()) { if (nest) { emit_error(ctx, "cfunction: closures are not supported on this platform"); @@ -7635,17 +7585,17 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con return jl_cgval_t(); } } - const char *name = derive_sigt_name(fexpr_rt.typ); + const char *name = derive_sigt_name(fexpr_val.typ); Value *F = gen_cfun_wrapper( jl_Module, ctx.emission_context, - sig, fexpr_rt.constant, name, + sig, fexpr_val.constant, name, declrt, sigt, unionall_env, sparam_vals, &closure_types); bool outboxed; if (nest) { // F is actually an init_trampoline function that returns the real address // Now fill in the nest parameters - Value *fobj = boxed(ctx, fexpr_rt); + Value *fobj = boxed(ctx, fexpr_val); jl_svec_t *fill = jl_emptysvec; if (closure_types) { assert(ctx.spvals_ptr); @@ -7685,7 +7635,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, tbaa); ai.decorateInst(ctx.builder.CreateStore(F, derived_strct)); ai.decorateInst(ctx.builder.CreateStore( - ctx.builder.CreatePtrToInt(literal_pointer_val(ctx, fexpr_rt.constant), ctx.types().T_size), + ctx.builder.CreatePtrToInt(literal_pointer_val(ctx, fexpr_val.constant), ctx.types().T_size), ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_size, derived_strct, 1))); ai.decorateInst(ctx.builder.CreateStore(Constant::getNullValue(ctx.types().T_size), ctx.builder.CreateConstInBoundsGEP1_32(ctx.types().T_size, derived_strct, 2))); @@ -7707,7 +7657,7 @@ const char *jl_generate_ccallable(Module *llvmmod, jl_value_t *nameval, jl_value assert(jl_is_datatype(ft)); jl_value_t *ff = ft->instance; assert(ff); - const char *name = !jl_is_string(nameval) ? jl_symbol_name(ft->name->mt->name) : jl_string_data(nameval); + const char *name = !jl_is_string(nameval) ? jl_symbol_name(ft->name->singletonname) : jl_string_data(nameval); jl_value_t *crt = declrt; if (jl_is_abstract_ref_type(declrt)) { declrt = jl_tparam0(declrt); @@ -9818,7 +9768,6 @@ static void init_jit_functions(void) { add_named_global("jl_fptr_args", jl_fptr_args_addr); add_named_global("jl_fptr_sparam", jl_fptr_sparam_addr); - add_named_global("jl_f_opaque_closure_call", &jl_f_opaque_closure_call); add_named_global(jl_small_typeof_var, &jl_small_typeof); add_named_global(jlstack_chk_guard_var, &__stack_chk_guard); add_named_global(jlRTLD_DEFAULT_var, &jl_RTLD_DEFAULT_handle); @@ -9855,10 +9804,8 @@ static void init_jit_functions(void) add_named_global(jlcheckassign_func, &jl_checked_assignment); add_named_global(jlcheckbpwritable_func, &jl_check_binding_currently_writable); add_named_global(jlboundp_func, &jl_boundp); - for (auto it : builtin_func_map()) - add_named_global(it.second, it.first); - add_named_global(jlintrinsic_func, &jl_f_intrinsic_call); - add_named_global(jlgetbuiltinfptr_func, &jl_get_builtin_fptr); + for (int i = 0; i < jl_n_builtins; i++) + add_named_global(jl_builtin_f_names[i], jl_builtin_f_addrs[i]); add_named_global(jlapplygeneric_func, &jl_apply_generic); add_named_global(jlinvoke_func, &jl_invoke); add_named_global(jltopeval_func, &jl_toplevel_eval); diff --git a/src/common_symbols2.inc b/src/common_symbols2.inc index 2a6990bac52ff..e9c070ee8da6a 100644 --- a/src/common_symbols2.inc +++ b/src/common_symbols2.inc @@ -97,7 +97,7 @@ jl_symbol("pointerref"), jl_symbol("multidimensional.jl"), jl_symbol("Generator"), jl_symbol("leave"), -jl_symbol("memoryref"), +jl_symbol("memoryrefnew"), jl_symbol("show.jl"), jl_symbol("pointer_from_objref"), jl_symbol("memoryrefget"), diff --git a/src/datatype.c b/src/datatype.c index 677f0d0bff65b..0dbba03e30343 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -39,22 +39,31 @@ static jl_sym_t *jl_demangle_typename(jl_sym_t *s) JL_NOTSAFEPOINT return _jl_symbol(&n[1], len); } +JL_DLLEXPORT jl_methcache_t *jl_new_method_cache(void) +{ + jl_task_t *ct = jl_current_task; + jl_methcache_t *mc = + (jl_methcache_t*)jl_gc_alloc(ct->ptls, sizeof(jl_methcache_t), + jl_methcache_type); + jl_atomic_store_relaxed(&mc->leafcache, (jl_genericmemory_t*)jl_an_empty_memory_any); + jl_atomic_store_relaxed(&mc->cache, jl_nothing); + JL_MUTEX_INIT(&mc->writelock, "methodtable->writelock"); + return mc; +} + JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module) { + jl_methcache_t *mc = jl_new_method_cache(); + JL_GC_PUSH1(&mc); jl_task_t *ct = jl_current_task; jl_methtable_t *mt = - (jl_methtable_t*)jl_gc_alloc(ct->ptls, sizeof(jl_methtable_t), - jl_methtable_type); - mt->name = jl_demangle_typename(name); - mt->module = module; + (jl_methtable_t*)jl_gc_alloc(ct->ptls, sizeof(jl_methtable_t), jl_methtable_type); jl_atomic_store_relaxed(&mt->defs, jl_nothing); - jl_atomic_store_relaxed(&mt->leafcache, (jl_genericmemory_t*)jl_an_empty_memory_any); - jl_atomic_store_relaxed(&mt->cache, jl_nothing); - jl_atomic_store_relaxed(&mt->max_args, 0); - mt->backedges = NULL; - JL_MUTEX_INIT(&mt->writelock, "methodtable->writelock"); - mt->offs = 0; - mt->frozen = 0; + mt->cache = mc; + mt->name = name; + mt->module = module; + mt->backedges = (jl_genericmemory_t*)jl_an_empty_memory_any; + JL_GC_POP(); return mt; } @@ -67,21 +76,22 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu tn->name = name; tn->module = module; tn->wrapper = NULL; + tn->singletonname = jl_demangle_typename(name); jl_atomic_store_relaxed(&tn->Typeofwrapper, NULL); jl_atomic_store_relaxed(&tn->cache, jl_emptysvec); jl_atomic_store_relaxed(&tn->linearcache, jl_emptysvec); tn->names = NULL; tn->hash = bitmix(bitmix(module ? module->build_id.lo : 0, name->hash), 0xa1ada1da); - tn->_reserved = 0; + tn->_unused = 0; tn->abstract = abstract; tn->mutabl = mutabl; tn->mayinlinealloc = 0; - tn->mt = NULL; tn->partial = NULL; tn->atomicfields = NULL; tn->constfields = NULL; - jl_atomic_store_relaxed(&tn->cache_entry_count, 0); tn->max_methods = 0; + jl_atomic_store_relaxed(&tn->max_args, 0); + jl_atomic_store_relaxed(&tn->cache_entry_count, 0); tn->constprop_heustic = 0; return tn; } @@ -861,18 +871,6 @@ JL_DLLEXPORT jl_datatype_t *jl_new_datatype( } else { tn = jl_new_typename_in((jl_sym_t*)name, module, abstract, mutabl); - if (super == jl_function_type || super == jl_builtin_type || is_anonfn_typename(jl_symbol_name(name))) { - // Callable objects (including compiler-generated closures) get independent method tables - // as an optimization - tn->mt = jl_new_method_table(name, module); - jl_gc_wb(tn, tn->mt); - if (jl_svec_len(parameters) == 0 && !abstract) - tn->mt->offs = 1; - } - else { - // Everything else, gets to use the unified table - tn->mt = jl_nonfunction_mt; - } } t->name = tn; jl_gc_wb(t, t->name); diff --git a/src/debug-registry.h b/src/debug-registry.h index 72189c60d3d40..00e3445200361 100644 --- a/src/debug-registry.h +++ b/src/debug-registry.h @@ -12,7 +12,8 @@ typedef struct { const llvm::object::ObjectFile *obj; llvm::DIContext *ctx; int64_t slide; -} objfileentry_t; + std::map> *symbolmap; +} jl_object_file_entry_t; // Central registry for resolving function addresses to `jl_code_instance_t`s and // originating `ObjectFile`s (for the DWARF debug info). @@ -121,7 +122,7 @@ class JITDebugInfoRegistry using rev_map = std::map>; typedef rev_map objectmap_t; - typedef rev_map objfilemap_t; + typedef rev_map objfilemap_t; objectmap_t objectmap{}; rev_map> cimap{}; @@ -152,4 +153,6 @@ class JITDebugInfoRegistry void add_image_info(image_info_t info) JL_NOTSAFEPOINT; bool get_image_info(uint64_t base, image_info_t *info) const JL_NOTSAFEPOINT; Locked::LockT get_objfile_map() JL_NOTSAFEPOINT; + + std::shared_mutex symbol_mutex; }; diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 8625b82aedff8..4f6c399369c1b 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -706,7 +706,8 @@ static inline void ignoreError(T &err) JL_NOTSAFEPOINT #endif } -static void get_function_name_and_base(llvm::object::SectionRef Section, size_t pointer, int64_t slide, bool inimage, +static void get_function_name_and_base(llvm::object::SectionRef Section, std::map> *symbolmap, + size_t pointer, int64_t slide, bool inimage, void **saddr, char **name, bool untrusted_dladdr) JL_NOTSAFEPOINT { bool needs_saddr = saddr && (!*saddr || untrusted_dladdr); @@ -732,59 +733,73 @@ static void get_function_name_and_base(llvm::object::SectionRef Section, size_t #endif } if (Section.getObject() && (needs_saddr || needs_name)) { - size_t distance = (size_t)-1; - object::SymbolRef sym_found; - for (auto sym : Section.getObject()->symbols()) { - if (!Section.containsSymbol(sym)) - continue; - auto addr = sym.getAddress(); - if (!addr) - continue; - size_t symptr = addr.get(); - if (symptr > pointer + slide) - continue; - size_t new_dist = pointer + slide - symptr; - if (new_dist > distance) - continue; - distance = new_dist; - sym_found = sym; - } - if (distance != (size_t)-1) { - if (needs_saddr) { - uintptr_t addr = cantFail(sym_found.getAddress()); - *saddr = (void*)(addr - slide); - needs_saddr = false; + uintptr_t addr = 0; + StringRef nameref{}; + { + std::shared_lock read_lock(getJITDebugRegistry().symbol_mutex); + if (symbolmap->empty()) { + read_lock.unlock(); + { + // symbol map hasn't been generated yet, so fill it in now + std::unique_lock write_lock(getJITDebugRegistry().symbol_mutex); + if (symbolmap->empty()) { + for (auto sym : Section.getObject()->symbols()) { + if (!Section.containsSymbol(sym)) + continue; + + auto maybe_addr = sym.getAddress(); + if (!maybe_addr) + continue; + size_t addr = maybe_addr.get(); + + auto maybe_nameref = sym.getName(); + StringRef nameref{}; + if (maybe_nameref) + nameref = maybe_nameref.get(); + + symbolmap->emplace(addr, nameref); + } + } + } + read_lock.lock(); + } + auto fit = symbolmap->lower_bound(pointer + slide); + if (fit != symbolmap->end()) { + addr = fit->first; + nameref = fit->second; } - if (needs_name) { - if (auto name_or_err = sym_found.getName()) { - auto nameref = name_or_err.get(); - const char globalPrefix = // == DataLayout::getGlobalPrefix + } + std::string namerefstr = nameref.str(); + if (needs_saddr && addr != 0) { + *saddr = (void*)(addr - slide); + needs_saddr = false; + } + if (needs_name && !nameref.empty()) { + const char globalPrefix = // == DataLayout::getGlobalPrefix #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) - '_'; + '_'; #elif defined(_OS_DARWIN_) - '_'; + '_'; #else - '\0'; + '\0'; #endif - if (globalPrefix) { - if (nameref[0] == globalPrefix) - nameref = nameref.drop_front(); + if (globalPrefix) { + if (nameref[0] == globalPrefix) + nameref = nameref.drop_front(); #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) - else if (nameref[0] == '@') // X86_VectorCall - nameref = nameref.drop_front(); + else if (nameref[0] == '@') // X86_VectorCall + nameref = nameref.drop_front(); #endif - // else VectorCall, Assembly, Internal, etc. - } + // else VectorCall, Assembly, Internal, etc. + } #if defined(_OS_WINDOWS_) && !defined(_CPU_X86_64_) - nameref = nameref.split('@').first; + nameref = nameref.split('@').first; #endif - size_t len = nameref.size(); - *name = (char*)realloc_s(*name, len + 1); - memcpy(*name, nameref.data(), len); - (*name)[len] = 0; - needs_name = false; - } - } + size_t len = nameref.size(); + *name = (char*)realloc_s(*name, len + 1); + memcpy(*name, nameref.data(), len); + (*name)[len] = 0; + needs_name = false; } } #ifdef _OS_WINDOWS_ @@ -808,7 +823,7 @@ static void get_function_name_and_base(llvm::object::SectionRef Section, size_t #endif } -static objfileentry_t find_object_file(uint64_t fbase, StringRef fname) JL_NOTSAFEPOINT +static jl_object_file_entry_t find_object_file(uint64_t fbase, StringRef fname) JL_NOTSAFEPOINT { int isdarwin = 0, islinux = 0, iswindows = 0; #if defined(_OS_DARWIN_) @@ -821,7 +836,7 @@ static objfileentry_t find_object_file(uint64_t fbase, StringRef fname) JL_NOTSA (void)iswindows; // GOAL: Read debuginfo from file - objfileentry_t entry{nullptr, nullptr, 0}; + jl_object_file_entry_t entry{nullptr, nullptr, 0, nullptr}; auto success = getJITDebugRegistry().get_objfile_map()->emplace(fbase, entry); if (!success.second) // Return cached value @@ -995,7 +1010,8 @@ static objfileentry_t find_object_file(uint64_t fbase, StringRef fname) JL_NOTSA auto binary = errorobj->takeBinary(); binary.first.release(); binary.second.release(); - entry = {debugobj, context, slide}; + + entry = {debugobj, context, slide, new std::map>()}; // update cache (*getJITDebugRegistry().get_objfile_map())[fbase] = entry; } @@ -1125,7 +1141,7 @@ bool jl_dylib_DI_for_fptr(size_t pointer, object::SectionRef *Section, int64_t * jl_copy_str(filename, dlinfo.dli_fname); fname = dlinfo.dli_fname; #endif // ifdef _OS_WINDOWS_ - auto entry = find_object_file(fbase, fname); + jl_object_file_entry_t entry = find_object_file(fbase, fname); *slide = entry.slide; *context = entry.ctx; if (entry.obj) @@ -1133,7 +1149,7 @@ bool jl_dylib_DI_for_fptr(size_t pointer, object::SectionRef *Section, int64_t * // Assume we only need base address for sysimg for now if (!inimage || 0 == image_info.fptrs.nptrs) saddr = nullptr; - get_function_name_and_base(*Section, pointer, entry.slide, inimage, saddr, name, untrusted_dladdr); + get_function_name_and_base(*Section, entry.symbolmap, pointer, entry.slide, inimage, saddr, name, untrusted_dladdr); return true; } diff --git a/src/gc-stock.c b/src/gc-stock.c index 66a1724ecf4ce..55f31b26679ff 100644 --- a/src/gc-stock.c +++ b/src/gc-stock.c @@ -2845,6 +2845,8 @@ static void gc_mark_roots(jl_gc_markqueue_t *mq) gc_try_claim_and_push(mq, jl_main_module, NULL); gc_heap_snapshot_record_gc_roots((jl_value_t*)jl_main_module, "main_module"); // invisible builtin values + gc_try_claim_and_push(mq, jl_method_table, NULL); + gc_heap_snapshot_record_gc_roots((jl_value_t*)jl_method_table, "global_method_table"); gc_try_claim_and_push(mq, jl_an_empty_vec_any, NULL); gc_heap_snapshot_record_gc_roots((jl_value_t*)jl_an_empty_vec_any, "an_empty_vec_any"); gc_try_claim_and_push(mq, jl_module_init_order, NULL); diff --git a/src/gf.c b/src/gf.c index 7b2f996563dda..b0c7a65ea8f99 100644 --- a/src/gf.c +++ b/src/gf.c @@ -27,6 +27,8 @@ extern "C" { _Atomic(int) allow_new_worlds = 1; JL_DLLEXPORT _Atomic(size_t) jl_world_counter = 1; // uses atomic acquire/release jl_mutex_t world_counter_lock; +jl_methtable_t *jl_method_table; + JL_DLLEXPORT size_t jl_get_world_counter(void) JL_NOTSAFEPOINT { jl_task_t *ct = jl_current_task; @@ -41,31 +43,41 @@ JL_DLLEXPORT size_t jl_get_tls_world_age(void) JL_NOTSAFEPOINT } // Compute the maximum number of times to unroll Varargs{T}, based on -// m->max_varargs (if specified) or a heuristic based on the maximum -// number of non-varargs arguments in the provided method table. +// m->max_varargs (if specified) or a heuristic based on the maximum number of +// non-varargs arguments for the function type of the method signature. // // If provided, `may_increase` is set to 1 if the returned value is // heuristic-based and has a chance of increasing in the future. static size_t get_max_varargs( jl_method_t *m, - jl_methtable_t *kwmt, - jl_methtable_t *mt, uint8_t *may_increase) JL_NOTSAFEPOINT { size_t max_varargs = 1; if (may_increase != NULL) *may_increase = 0; - if (m->max_varargs != UINT8_MAX) + if (m->max_varargs != UINT8_MAX) { max_varargs = m->max_varargs; - else if (kwmt != NULL && kwmt != jl_type_type_mt && kwmt != jl_nonfunction_mt && kwmt != jl_kwcall_mt) { - if (may_increase != NULL) - *may_increase = 1; // `max_args` can increase as new methods are inserted - - max_varargs = jl_atomic_load_relaxed(&kwmt->max_args) + 2; - if (mt == jl_kwcall_mt) - max_varargs += 2; - max_varargs -= m->nargs; + } + else { + jl_datatype_t *dt1 = jl_nth_argument_datatype(m->sig, 1); + jl_datatype_t *dt; + if (jl_kwcall_type && dt1 == jl_kwcall_type) + dt = jl_nth_argument_datatype(m->sig, 3); + else + dt = dt1; + if (dt != NULL && !jl_is_type_type((jl_value_t*)dt) && dt != jl_kwcall_type) { + if (may_increase != NULL) + *may_increase = 1; // `max_args` can increase as new methods are inserted + + max_varargs = jl_atomic_load_relaxed(&dt->name->max_args) + 2; + if (jl_kwcall_type && dt1 == jl_kwcall_type) + max_varargs += 2; + if (max_varargs > m->nargs) + max_varargs -= m->nargs; + else + max_varargs = 0; + } } return max_varargs; } @@ -104,9 +116,9 @@ void jl_call_tracer(tracer_cb callback, jl_value_t *tracee) /// ----- Definitions for various internal TypeMaps ----- /// -static int8_t jl_cachearg_offset(jl_methtable_t *mt) +static int8_t jl_cachearg_offset(void) { - return mt->offs; + return 0; } /// ----- Insertion logic for special entries ----- /// @@ -274,13 +286,13 @@ JL_DLLEXPORT jl_value_t *jl_specializations_lookup(jl_method_t *m, jl_value_t *t return mi; } -JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_value_t *type, size_t world) +JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_value_t *type, size_t world) { // TODO: this is sort of an odd lookup strategy (and the only user of // jl_typemap_assoc_by_type with subtype=0), while normally jl_gf_invoke_lookup would be // expected to be used instead struct jl_typemap_assoc search = {type, world, NULL}; - jl_typemap_entry_t *sf = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&mt->defs), &search, jl_cachearg_offset(mt), /*subtype*/0); + jl_typemap_entry_t *sf = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&jl_method_table->defs), &search, 0, /*subtype*/0); if (!sf) return jl_nothing; return sf->func.value; @@ -288,54 +300,50 @@ JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt, jl_value_t *typ // ----- MethodInstance specialization instantiation ----- // -jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_args_t fptr) JL_GC_DISABLED +jl_method_t *jl_mk_builtin_func(jl_datatype_t *dt, jl_sym_t *sname, jl_fptr_args_t fptr) JL_GC_DISABLED { - jl_sym_t *sname = jl_symbol(name); - if (dt == NULL) { - // 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_initial_const(jl_core_module, sname, f, 0); - dt = (jl_datatype_t*)jl_typeof(f); - } - jl_method_t *m = jl_new_method_uninit(jl_core_module); m->name = sname; m->module = jl_core_module; m->isva = 1; m->nargs = 2; jl_atomic_store_relaxed(&m->primary_world, 1); - jl_atomic_store_relaxed(&m->dispatch_status, METHOD_SIG_LATEST_ONLY | METHOD_SIG_LATEST_ONLY); + jl_atomic_store_relaxed(&m->dispatch_status, METHOD_SIG_LATEST_ONLY | METHOD_SIG_LATEST_WHICH); m->sig = (jl_value_t*)jl_anytuple_type; m->slot_syms = jl_an_empty_string; m->nospecialize = 0; m->nospecialize = ~m->nospecialize; - jl_methtable_t *mt = dt->name->mt; jl_typemap_entry_t *newentry = NULL; - JL_GC_PUSH2(&m, &newentry); + jl_datatype_t *tuptyp = NULL; + JL_GC_PUSH3(&m, &newentry, &tuptyp); - newentry = jl_typemap_alloc(jl_anytuple_type, NULL, jl_emptysvec, - (jl_value_t*)m, 1, ~(size_t)0); - jl_typemap_insert(&mt->defs, (jl_value_t*)mt, newentry, jl_cachearg_offset(mt)); + jl_value_t *params[2]; + params[0] = dt->name->wrapper; + params[1] = jl_tparam0(jl_anytuple_type); + tuptyp = (jl_datatype_t*)jl_apply_tuple_type_v(params, 2); - jl_method_instance_t *mi = jl_get_specialized(m, (jl_value_t*)jl_anytuple_type, jl_emptysvec); + jl_method_instance_t *mi = jl_get_specialized(m, (jl_value_t*)tuptyp, jl_emptysvec); jl_atomic_store_relaxed(&m->unspecialized, mi); jl_gc_wb(m, mi); 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, 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); + jl_mi_cache_insert(mi, codeinst); - newentry = jl_typemap_alloc(jl_anytuple_type, NULL, jl_emptysvec, + newentry = jl_typemap_alloc(tuptyp, NULL, jl_emptysvec, + (jl_value_t*)m, 1, ~(size_t)0); + jl_typemap_insert(&jl_method_table->defs, (jl_value_t*)jl_method_table, newentry, 0); + + newentry = jl_typemap_alloc(tuptyp, NULL, jl_emptysvec, (jl_value_t*)mi, 1, ~(size_t)0); - jl_typemap_insert(&mt->cache, (jl_value_t*)mt, newentry, 0); + jl_typemap_insert(&jl_method_table->cache->cache, (jl_value_t*)jl_method_table->cache, newentry, 0); - mt->frozen = 1; JL_GC_POP(); - return dt; + return m; } // only relevant for bootstrapping. otherwise fairly broken. @@ -395,7 +403,7 @@ static jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi // 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) +jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_t source_mode, uint8_t trim_mode) { if (jl_typeinf_func == NULL) { if (source_mode == SOURCE_MODE_ABI) @@ -419,11 +427,12 @@ jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_ return NULL; JL_TIMING(INFERENCE, INFERENCE); jl_value_t **fargs; - JL_GC_PUSHARGS(fargs, 4); + JL_GC_PUSHARGS(fargs, 5); fargs[0] = (jl_value_t*)jl_typeinf_func; fargs[1] = (jl_value_t*)mi; fargs[2] = jl_box_ulong(world); fargs[3] = jl_box_uint8(source_mode); + fargs[4] = jl_box_uint8(trim_mode); int last_errno = errno; #ifdef _OS_WINDOWS_ DWORD last_error = GetLastError(); @@ -450,7 +459,7 @@ jl_code_instance_t *jl_type_infer(jl_method_instance_t *mi, size_t world, uint8_ // allocate another bit for the counter. ct->reentrant_timing += 0b10; JL_TRY { - ci = (jl_code_instance_t*)jl_apply(fargs, 4); + ci = (jl_code_instance_t*)jl_apply(fargs, 5); } JL_CATCH { jl_value_t *e = jl_current_exception(ct); @@ -504,12 +513,13 @@ JL_DLLEXPORT jl_code_info_t *jl_gdbcodetyped1(jl_method_instance_t *mi, size_t w ct->world_age = jl_typeinf_world; jl_value_t **fargs; JL_GC_PUSHARGS(fargs, 4); - jl_module_t *CC = (jl_module_t*)jl_get_global(jl_core_module, jl_symbol("Compiler")); + jl_module_t *CC = (jl_module_t*)jl_get_global_value(jl_core_module, jl_symbol("Compiler"), ct->world_age); if (CC != NULL && jl_is_module(CC)) { - fargs[0] = jl_get_global(CC, jl_symbol("NativeInterpreter"));; + JL_GC_PROMISE_ROOTED(CC); + fargs[0] = jl_get_global_value(CC, jl_symbol("NativeInterpreter"), ct->world_age); fargs[1] = jl_box_ulong(world); fargs[1] = jl_apply(fargs, 2); - fargs[0] = jl_get_global(CC, jl_symbol("typeinf_code")); + fargs[0] = jl_get_global_value(CC, jl_symbol("typeinf_code"), ct->world_age); fargs[2] = (jl_value_t*)mi; fargs[3] = jl_true; ci = (jl_code_info_t*)jl_apply(fargs, 4); @@ -546,7 +556,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( { jl_value_t *owner = jl_nothing; // TODO: owner should be arg jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache); - while (codeinst) { + for (; codeinst; codeinst = jl_atomic_load_relaxed(&codeinst->next)) { if (jl_atomic_load_relaxed(&codeinst->min_world) == min_world && jl_atomic_load_relaxed(&codeinst->max_world) == max_world && jl_egal(codeinst->owner, owner) && @@ -564,7 +574,6 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( if (e && jl_egal((jl_value_t*)e, (jl_value_t*)edges)) return codeinst; } - codeinst = jl_atomic_load_relaxed(&codeinst->next); } codeinst = jl_new_codeinst( mi, owner, rettype, (jl_value_t*)jl_any_type, NULL, NULL, @@ -769,7 +778,117 @@ JL_DLLEXPORT int jl_mi_try_insert(jl_method_instance_t *mi JL_ROOTING_ARGUMENT, return ret; } -int foreach_mtable_in_module( +enum top_typename_facts { + EXACTLY_ANY = 1 << 0, + HAVE_TYPE = 1 << 1, + EXACTLY_TYPE = 1 << 2, + HAVE_FUNCTION = 1 << 3, + EXACTLY_FUNCTION = 1 << 4, + HAVE_KWCALL = 1 << 5, + EXACTLY_KWCALL = 1 << 6, + SHORT_TUPLE = 1 << 7, +}; + +static void foreach_top_nth_typename(void (*f)(jl_typename_t*, int, void*), jl_value_t *a JL_PROPAGATES_ROOT, int n, unsigned *facts, void *env) +{ + if (jl_is_datatype(a)) { + if (n <= 0) { + jl_datatype_t *dt = ((jl_datatype_t*)a); + if (dt->name == jl_type_typename) { // key Type{T} on T instead of Type + *facts |= HAVE_TYPE; + foreach_top_nth_typename(f, jl_tparam0(a), -1, facts, env); + } + else if (dt == jl_function_type) { + if (n == -1) // key Type{>:Function} as Type instead of Function + *facts |= EXACTLY_TYPE; // HAVE_TYPE is already set + else + *facts |= HAVE_FUNCTION | EXACTLY_FUNCTION; + } + else if (dt == jl_any_type) { + if (n == -1) // key Type{>:Any} and kinds as Type instead of Any + *facts |= EXACTLY_TYPE; // HAVE_TYPE is already set + else + *facts |= EXACTLY_ANY; + } + else if (dt == jl_kwcall_type) { + if (n == -1) // key Type{>:typeof(kwcall)} as exactly kwcall + *facts |= EXACTLY_KWCALL; + else + *facts |= HAVE_KWCALL; + } + else { + while (1) { + jl_datatype_t *super = dt->super; + if (super == jl_function_type) { + *facts |= HAVE_FUNCTION; + break; + } + if (super == jl_any_type || super->super == dt) + break; + dt = super; + } + f(dt->name, 1, env); + } + } + else if (jl_is_tuple_type(a)) { + if (jl_nparams(a) >= n) + foreach_top_nth_typename(f, jl_tparam(a, n - 1), 0, facts, env); + else + *facts |= SHORT_TUPLE; + } + } + else if (jl_is_typevar(a)) { + foreach_top_nth_typename(f, ((jl_tvar_t*)a)->ub, n, facts, env); + } + else if (jl_is_unionall(a)) { + foreach_top_nth_typename(f, ((jl_unionall_t*)a)->body, n, facts, env); + } + else if (jl_is_uniontype(a)) { + jl_uniontype_t *u = (jl_uniontype_t*)a; + foreach_top_nth_typename(f, u->a, n, facts, env); + foreach_top_nth_typename(f, u->b, n, facts, env); + } +} + +// Inspect type `argtypes` for all backedge keys that might be relevant to it, splitting it +// up on some commonly observed patterns to make a better distribution. +// (It could do some of that balancing automatically, but for now just hard-codes kwcall.) +// Along the way, record some facts about what was encountered, so that those additional +// calls can be added later if needed for completeness. +// The `int explct` argument instructs the caller if the callback is due to an exactly +// encountered type or if it rather encountered a subtype. +// This is not capable of walking to all top-typenames for an explicitly encountered +// Function or Any, so the caller a fallback that can scan the entire in that case. +// We do not de-duplicate calls when encountering a Union. +static int jl_foreach_top_typename_for(void (*f)(jl_typename_t*, int, void*), jl_value_t *argtypes JL_PROPAGATES_ROOT, int all_subtypes, void *env) +{ + unsigned facts = 0; + foreach_top_nth_typename(f, argtypes, 1, &facts, env); + if (facts & HAVE_KWCALL) { + // split kwcall on the 3rd argument instead, using the same logic + unsigned kwfacts = 0; + foreach_top_nth_typename(f, argtypes, 3, &kwfacts, env); + // copy kwfacts to original facts + if (kwfacts & SHORT_TUPLE) + kwfacts |= (all_subtypes ? EXACTLY_ANY : EXACTLY_KWCALL); + facts |= kwfacts; + } + if (all_subtypes && (facts & (EXACTLY_FUNCTION | EXACTLY_TYPE | EXACTLY_ANY))) + // flag that we have an explct match than is necessitating a full table scan + return 0; + // or inform caller of only which supertypes are applicable + if (facts & HAVE_FUNCTION) + f(jl_function_type->name, facts & EXACTLY_FUNCTION ? 1 : 0, env); + if (facts & HAVE_TYPE) + f(jl_type_typename, facts & EXACTLY_TYPE ? 1 : 0, env); + if (facts & (HAVE_KWCALL | EXACTLY_KWCALL)) + f(jl_kwcall_type->name, facts & EXACTLY_KWCALL ? 1 : 0, env); + f(jl_any_type->name, facts & EXACTLY_ANY ? 1 : 0, env); + return 1; +} + + +static int foreach_mtable_in_module( jl_module_t *m, int (*visit)(jl_methtable_t *mt, void *env), void *env) @@ -782,20 +901,7 @@ int foreach_mtable_in_module( jl_sym_t *name = b->globalref->name; jl_value_t *v = jl_get_latest_binding_value_if_const(b); if (v) { - jl_value_t *uw = jl_unwrap_unionall(v); - if (jl_is_datatype(uw)) { - jl_typename_t *tn = ((jl_datatype_t*)uw)->name; - if (tn->module == m && tn->name == name && tn->wrapper == v) { - // this is the original/primary binding for the type (name/wrapper) - jl_methtable_t *mt = tn->mt; - if (mt != NULL && (jl_value_t*)mt != jl_nothing && mt != jl_type_type_mt && mt != jl_nonfunction_mt) { - assert(mt->module == m); - if (!visit(mt, env)) - return 0; - } - } - } - else if (jl_is_module(v)) { + if (jl_is_module(v)) { jl_module_t *child = (jl_module_t*)v; if (child != m && child->parent == m && child->name == name) { // this is the original/primary binding for the submodule @@ -805,9 +911,7 @@ int foreach_mtable_in_module( } else if (jl_is_mtable(v)) { jl_methtable_t *mt = (jl_methtable_t*)v; - if (mt->module == m && mt->name == name) { - // this is probably an external method table here, so let's - // assume so as there is no way to precisely distinguish them + if (mt && mt != jl_method_table) { if (!visit(mt, env)) return 0; } @@ -818,37 +922,23 @@ int foreach_mtable_in_module( return 1; } -int jl_foreach_reachable_mtable(int (*visit)(jl_methtable_t *mt, void *env), void *env) + +int jl_foreach_reachable_mtable(int (*visit)(jl_methtable_t *mt, void *env), jl_array_t *mod_array, void *env) { - if (!visit(jl_type_type_mt, env)) - return 0; - if (!visit(jl_nonfunction_mt, env)) + if (!visit(jl_method_table, env)) return 0; - jl_array_t *mod_array = jl_get_loaded_modules(); if (mod_array) { - JL_GC_PUSH1(&mod_array); - int i; - for (i = 0; i < jl_array_nrows(mod_array); i++) { + for (size_t i = 0; i < jl_array_nrows(mod_array); i++) { jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(mod_array, i); assert(jl_is_module(m)); if (m->parent == m) // some toplevel modules (really just Base) aren't actually - if (!foreach_mtable_in_module(m, visit, env)) { - JL_GC_POP(); + if (!foreach_mtable_in_module(m, visit, env)) return 0; - } } - JL_GC_POP(); - } - else { - if (!foreach_mtable_in_module(jl_main_module, visit, env)) - return 0; - if (!foreach_mtable_in_module(jl_core_module, visit, env)) - return 0; } return 1; } - jl_function_t *jl_typeinf_func JL_GLOBALLY_ROOTED = NULL; JL_DLLEXPORT size_t jl_typeinf_world = 1; @@ -932,7 +1022,7 @@ static jl_value_t *inst_varargp_in_env(jl_value_t *decl, jl_svec_t *sparams) return vm; } -static jl_value_t *ml_matches(jl_methtable_t *mt, +static jl_value_t *ml_matches(jl_methtable_t *mt, jl_methcache_t *mc, jl_tupletype_t *type, int lim, int include_ambiguous, int intersections, size_t world, int cache_result, size_t *min_valid, size_t *max_valid, int *ambig); @@ -1139,9 +1229,10 @@ static void jl_compilation_sig( // and the types we find should be bigger. if (np >= nspec && jl_va_tuple_kind((jl_datatype_t*)decl) == JL_VARARG_UNBOUND) { if (!*newparams) *newparams = tt->parameters; - if (max_varargs > 0) { + if (max_varargs > 0 && nspec >= 2) { type_i = jl_svecref(*newparams, nspec - 2); - } else { + } + else { // If max varargs is zero, always specialize to (Any...) since // there is no preceding parameter to use for `type_i` type_i = jl_bottom_type; @@ -1216,15 +1307,11 @@ JL_DLLEXPORT int jl_isa_compileable_sig( if (definition->isva) { unsigned nspec_min = nargs + 1; // min number of arg values (including tail vararg) unsigned nspec_max = INT32_MAX; // max number of arg values (including tail vararg) - jl_methtable_t *mt = jl_method_table_for(decl); - jl_methtable_t *kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for(decl) : mt; - if ((jl_value_t*)mt != jl_nothing) { - // try to refine estimate of min and max - uint8_t heuristic_used = 0; - nspec_max = nspec_min = nargs + get_max_varargs(definition, kwmt, mt, &heuristic_used); - if (heuristic_used) - nspec_max = INT32_MAX; // new methods may be added, increasing nspec_min later - } + // try to refine estimate of min and max + uint8_t heuristic_used = 0; + nspec_max = nspec_min = nargs + get_max_varargs(definition, &heuristic_used); + if (heuristic_used) + nspec_max = INT32_MAX; // new methods may be added, increasing nspec_min later int isunbound = (jl_va_tuple_kind((jl_datatype_t*)decl) == JL_VARARG_UNBOUND); if (jl_is_vararg(jl_tparam(type, np - 1))) { if (!isunbound || np < nspec_min || np > nspec_max) @@ -1413,34 +1500,52 @@ static inline jl_typemap_entry_t *lookup_leafcache(jl_genericmemory_t *leafcache return NULL; } jl_method_instance_t *cache_method( - jl_methtable_t *mt, _Atomic(jl_typemap_t*) *cache, jl_value_t *parent JL_PROPAGATES_ROOT, + jl_methtable_t *mt, jl_methcache_t *mc, _Atomic(jl_typemap_t*) *cache, jl_value_t *parent JL_PROPAGATES_ROOT, jl_tupletype_t *tt, // the original tupletype of the signature jl_method_t *definition, size_t world, size_t min_valid, size_t max_valid, jl_svec_t *sparams) { - // caller must hold the mt->writelock + // caller must hold the parent->writelock, which this releases // short-circuit (now that we hold the lock) if this entry is already present - int8_t offs = mt ? jl_cachearg_offset(mt) : 1; + int8_t offs = mc ? jl_cachearg_offset() : 1; { // scope block - if (mt) { - jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache); + if (mc) { + jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mc->leafcache); jl_typemap_entry_t *entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world); - if (entry) + if (entry) { + if (mc) JL_UNLOCK(&mc->writelock); return entry->func.linfo; + } } struct jl_typemap_assoc search = {(jl_value_t*)tt, world, NULL}; jl_typemap_t *cacheentry = jl_atomic_load_relaxed(cache); assert(cacheentry != NULL); jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(cacheentry, &search, offs, /*subtype*/1); - if (entry && entry->func.value) + if (entry && entry->func.value) { + if (mc) JL_UNLOCK(&mc->writelock); return entry->func.linfo; + } + } + + jl_method_instance_t *newmeth = NULL; + if (definition->sig == (jl_value_t*)jl_anytuple_type && definition != jl_opaque_closure_method && !definition->is_for_opaque_closure) { + newmeth = jl_atomic_load_relaxed(&definition->unspecialized); + if (newmeth != NULL) { // handle builtin methods de-specialization (for invoke, or if the global cache entry somehow gets lost) + jl_tupletype_t *cachett = (jl_tupletype_t*)newmeth->specTypes; + assert(cachett != jl_anytuple_type); + jl_typemap_entry_t *newentry = jl_typemap_alloc(cachett, NULL, jl_emptysvec, (jl_value_t*)newmeth, min_valid, max_valid); + JL_GC_PUSH1(&newentry); + jl_typemap_insert(cache, parent, newentry, offs); + JL_GC_POP(); + if (mc) JL_UNLOCK(&mc->writelock); + return newmeth; + } } jl_value_t *temp = NULL; jl_value_t *temp2 = NULL; jl_value_t *temp3 = NULL; - jl_method_instance_t *newmeth = NULL; jl_svec_t *newparams = NULL; JL_GC_PUSH5(&temp, &temp2, &temp3, &newmeth, &newparams); @@ -1448,8 +1553,7 @@ jl_method_instance_t *cache_method( // so that we can minimize the number of required cache entries. int cache_with_orig = 1; jl_tupletype_t *compilationsig = tt; - jl_methtable_t *kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for(definition->sig) : mt; - intptr_t max_varargs = get_max_varargs(definition, kwmt, mt, NULL); + intptr_t max_varargs = get_max_varargs(definition, NULL); jl_compilation_sig(tt, sparams, definition, max_varargs, &newparams); if (newparams) { temp2 = jl_apply_tuple_type(newparams, 1); @@ -1479,13 +1583,16 @@ jl_method_instance_t *cache_method( if (newmeth->cache_with_orig) cache_with_orig = 1; + // Capture world counter at start to detect races + size_t current_world = mc ? jl_atomic_load_acquire(&jl_world_counter) : ~(size_t)0; + jl_tupletype_t *cachett = tt; - jl_svec_t* guardsigs = jl_emptysvec; + jl_svec_t *guardsigs = jl_emptysvec; if (!cache_with_orig && mt) { // now examine what will happen if we chose to use this sig in the cache size_t min_valid2 = 1; size_t max_valid2 = ~(size_t)0; - temp = ml_matches(mt, compilationsig, MAX_UNSPECIALIZED_CONFLICTS, 1, 1, world, 0, &min_valid2, &max_valid2, NULL); + temp = ml_matches(mt, mc, compilationsig, MAX_UNSPECIALIZED_CONFLICTS, 1, 1, world, 0, &min_valid2, &max_valid2, NULL); int guards = 0; if (temp == jl_nothing) { cache_with_orig = 1; @@ -1533,7 +1640,7 @@ jl_method_instance_t *cache_method( guards++; // alternative approach: insert sentinel entry //jl_typemap_insert(cache, parent, (jl_tupletype_t*)matc->spec_types, - // NULL, jl_emptysvec, /*guard*/NULL, jl_cachearg_offset(mt), other->min_world, other->max_world); + // NULL, jl_emptysvec, /*guard*/NULL, jl_cachearg_offset(), other->min_world, other->max_world); } } assert(guards == jl_svec_len(guardsigs)); @@ -1550,6 +1657,10 @@ jl_method_instance_t *cache_method( } } + int unconstrained_max = max_valid == ~(size_t)0; + if (max_valid > current_world) + max_valid = current_world; + // now scan `cachett` and ensure that `Type{T}` in the cache will be matched exactly by `typeof(T)` // and also reduce the complexity of rejecting this entry in the cache // by replacing non-simple types with jl_any_type to build a new `type` @@ -1593,7 +1704,7 @@ jl_method_instance_t *cache_method( jl_typemap_entry_t *newentry = jl_typemap_alloc(cachett, simplett, guardsigs, (jl_value_t*)newmeth, min_valid, max_valid); temp = (jl_value_t*)newentry; - if (mt && cachett == tt && jl_svec_len(guardsigs) == 0 && tt->hash && !tt->hasfreetypevars) { + if (mc && cachett == tt && jl_svec_len(guardsigs) == 0 && tt->hash && !tt->hasfreetypevars) { // we check `tt->hash` exists, since otherwise the NamedTuple // constructor and `structdiff` method pollutes this lookup with a lot // of garbage in the linear table search @@ -1606,14 +1717,14 @@ jl_method_instance_t *cache_method( jl_cache_type_(tt); JL_UNLOCK(&typecache_lock); // Might GC } - jl_genericmemory_t *oldcache = jl_atomic_load_relaxed(&mt->leafcache); + jl_genericmemory_t *oldcache = jl_atomic_load_relaxed(&mc->leafcache); jl_typemap_entry_t *old = (jl_typemap_entry_t*)jl_eqtable_get(oldcache, (jl_value_t*)tt, jl_nothing); jl_atomic_store_relaxed(&newentry->next, old); jl_gc_wb(newentry, old); - jl_genericmemory_t *newcache = jl_eqtable_put(jl_atomic_load_relaxed(&mt->leafcache), (jl_value_t*)tt, (jl_value_t*)newentry, NULL); + jl_genericmemory_t *newcache = jl_eqtable_put(jl_atomic_load_relaxed(&mc->leafcache), (jl_value_t*)tt, (jl_value_t*)newentry, NULL); if (newcache != oldcache) { - jl_atomic_store_release(&mt->leafcache, newcache); - jl_gc_wb(mt, newcache); + jl_atomic_store_release(&mc->leafcache, newcache); + jl_gc_wb(mc, newcache); } } else { @@ -1628,55 +1739,138 @@ jl_method_instance_t *cache_method( } } } + if (mc) { + JL_UNLOCK(&mc->writelock); + + // Only set METHOD_SIG_LATEST_ONLY on method instance if method does NOT have the bit, no guards required, and min_valid == primary_world + int should_set_dispatch_status = !(jl_atomic_load_relaxed(&definition->dispatch_status) & METHOD_SIG_LATEST_ONLY) && + (!cache_with_orig && jl_svec_len(guardsigs) == 0) && + min_valid == jl_atomic_load_relaxed(&definition->primary_world) && + !(jl_atomic_load_relaxed(&newmeth->dispatch_status) & METHOD_SIG_LATEST_ONLY); + + // Combined trylock for both dispatch_status setting and max_world restoration + if ((should_set_dispatch_status || unconstrained_max) && + jl_atomic_load_relaxed(&jl_world_counter) == current_world) { + JL_LOCK(&world_counter_lock); + if (jl_atomic_load_relaxed(&jl_world_counter) == current_world) { + if (should_set_dispatch_status) { + jl_atomic_store_relaxed(&newmeth->dispatch_status, METHOD_SIG_LATEST_ONLY); + } + if (unconstrained_max) { + jl_atomic_store_relaxed(&newentry->max_world, ~(size_t)0); + } + } + JL_UNLOCK(&world_counter_lock); + } + } JL_GC_POP(); return newmeth; } -static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, jl_value_t *mt, size_t world, size_t *min_valid, size_t *max_valid); +static void _jl_promote_ci_to_current(jl_code_instance_t *ci, size_t validated_world) JL_NOTSAFEPOINT +{ + if (jl_atomic_load_relaxed(&ci->max_world) != validated_world) + return; + jl_atomic_store_relaxed(&ci->max_world, ~(size_t)0); + jl_svec_t *edges = jl_atomic_load_relaxed(&ci->edges); + for (size_t i = 0; i < jl_svec_len(edges); i++) { + jl_value_t *edge = jl_svecref(edges, i); + if (!jl_is_code_instance(edge)) + continue; + _jl_promote_ci_to_current((jl_code_instance_t *)edge, validated_world); + } +} -static jl_method_instance_t *jl_mt_assoc_by_type(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_datatype_t *tt JL_MAYBE_UNROOTED, size_t world) +JL_DLLEXPORT void jl_promote_cis_to_current(jl_code_instance_t **cis, size_t n, size_t validated_world) { - jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache); - jl_typemap_entry_t *entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world); + size_t current_world = jl_atomic_load_relaxed(&jl_world_counter); + // No need to acquire the lock if we've been invalidated anyway + if (current_world > validated_world) + return; + JL_LOCK(&world_counter_lock); + current_world = jl_atomic_load_relaxed(&jl_world_counter); + if (current_world == validated_world) { + for (size_t i = 0; i < n; i++) { + _jl_promote_ci_to_current(cis[i], validated_world); + } + } + JL_UNLOCK(&world_counter_lock); +} + +JL_DLLEXPORT void jl_promote_ci_to_current(jl_code_instance_t *ci, size_t validated_world) +{ + jl_promote_cis_to_current(&ci, 1, validated_world); +} + +JL_DLLEXPORT void jl_promote_mi_to_current(jl_method_instance_t *mi, size_t min_world, size_t validated_world) +{ + size_t current_world = jl_atomic_load_relaxed(&jl_world_counter); + // No need to acquire the lock if we've been invalidated anyway + if (current_world > validated_world) + return; + // Only set METHOD_SIG_LATEST_ONLY on method instance if method does NOT have the bit and min_valid == primary_world + jl_method_t *definition = mi->def.method; + if ((jl_atomic_load_relaxed(&definition->dispatch_status) & METHOD_SIG_LATEST_ONLY) || + min_world != jl_atomic_load_relaxed(&definition->primary_world) || + (jl_atomic_load_relaxed(&mi->dispatch_status) & METHOD_SIG_LATEST_ONLY)) + return; + JL_LOCK(&world_counter_lock); + current_world = jl_atomic_load_relaxed(&jl_world_counter); + if (current_world == validated_world) { + jl_atomic_store_relaxed(&mi->dispatch_status, METHOD_SIG_LATEST_ONLY); + } + JL_UNLOCK(&world_counter_lock); +} + +static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, jl_methtable_t *mt, size_t world, int cache, size_t *min_valid, size_t *max_valid); + +JL_DLLEXPORT jl_typemap_entry_t *jl_mt_find_cache_entry(jl_methcache_t *mc JL_PROPAGATES_ROOT, jl_datatype_t *tt JL_MAYBE_UNROOTED JL_ROOTS_TEMPORARILY, size_t world) +{ // exported only for debugging purposes, not for casual use + if (tt->isdispatchtuple) { + jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mc->leafcache); + jl_typemap_entry_t *entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world); + if (entry) + return entry; + } + JL_GC_PUSH1(&tt); + struct jl_typemap_assoc search = {(jl_value_t*)tt, world, NULL}; + jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&mc->cache), &search, jl_cachearg_offset(), /*subtype*/1); + JL_GC_POP(); + return entry; +} + +static jl_method_instance_t *jl_mt_assoc_by_type(jl_methcache_t *mc JL_PROPAGATES_ROOT, jl_datatype_t *tt JL_MAYBE_UNROOTED, size_t world) +{ + jl_typemap_entry_t *entry = jl_mt_find_cache_entry(mc, tt, world); if (entry) return entry->func.linfo; + assert(tt->isdispatchtuple || tt->hasfreetypevars); JL_TIMING(METHOD_LOOKUP_SLOW, METHOD_LOOKUP_SLOW); jl_method_match_t *matc = NULL; JL_GC_PUSH2(&tt, &matc); - JL_LOCK(&mt->writelock); - assert(tt->isdispatchtuple || tt->hasfreetypevars); + JL_LOCK(&mc->writelock); jl_method_instance_t *mi = NULL; - if (tt->isdispatchtuple) { - jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache); - jl_typemap_entry_t *entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world); - if (entry) - mi = entry->func.linfo; - } - - if (!mi) { - struct jl_typemap_assoc search = {(jl_value_t*)tt, world, NULL}; - jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&mt->cache), &search, jl_cachearg_offset(mt), /*subtype*/1); - if (entry) - mi = entry->func.linfo; - } - + entry = jl_mt_find_cache_entry(mc, tt, world); + if (entry) + mi = entry->func.linfo; if (!mi) { size_t min_valid = 0; size_t max_valid = ~(size_t)0; - matc = _gf_invoke_lookup((jl_value_t*)tt, jl_nothing, world, &min_valid, &max_valid); + matc = _gf_invoke_lookup((jl_value_t*)tt, jl_method_table, world, 0, &min_valid, &max_valid); if (matc) { jl_method_t *m = matc->method; jl_svec_t *env = matc->sparams; - mi = cache_method(mt, &mt->cache, (jl_value_t*)mt, tt, m, world, min_valid, max_valid, env); + mi = cache_method(jl_method_table, mc, &mc->cache, (jl_value_t*)mc, tt, m, world, min_valid, max_valid, env); + JL_GC_POP(); + return mi; } } - JL_UNLOCK(&mt->writelock); + JL_UNLOCK(&mc->writelock); JL_GC_POP(); return mi; } - struct matches_env { struct typemap_intersection_env match; jl_typemap_entry_t *newentry; @@ -1714,7 +1908,7 @@ static int get_intersect_visitor(jl_typemap_entry_t *oldentry, struct typemap_in return 1; } -static jl_value_t *get_intersect_matches(jl_typemap_t *defs, jl_typemap_entry_t *newentry, jl_typemap_entry_t **replaced, int8_t offs, size_t world) +static jl_value_t *get_intersect_matches(jl_typemap_t *defs, jl_typemap_entry_t *newentry, jl_typemap_entry_t **replaced, size_t world) { jl_tupletype_t *type = newentry->sig; jl_tupletype_t *ttypes = (jl_tupletype_t*)jl_unwrap_unionall((jl_value_t*)type); @@ -1733,7 +1927,7 @@ static jl_value_t *get_intersect_matches(jl_typemap_t *defs, jl_typemap_entry_t /* .ti = */ NULL, /* .env = */ jl_emptysvec, /* .issubty = */ 0}, /* .newentry = */ newentry, /* .shadowed */ NULL, /* .replaced */ NULL}; JL_GC_PUSH3(&env.match.env, &env.match.ti, &env.shadowed); - jl_typemap_intersection_visitor(defs, offs, &env.match); + jl_typemap_intersection_visitor(defs, 0, &env.match); env.match.env = NULL; env.match.ti = NULL; *replaced = env.replaced; @@ -1757,7 +1951,7 @@ static void method_overwrite(jl_typemap_entry_t *newentry, jl_method_t *oldvalue jl_module_t *newmod = method->module; jl_module_t *oldmod = oldvalue->module; jl_datatype_t *dt = jl_nth_argument_datatype(oldvalue->sig, 1); - if (dt == (jl_datatype_t*)jl_typeof(jl_kwcall_func)) + if (jl_kwcall_type && dt == jl_kwcall_type) dt = jl_nth_argument_datatype(oldvalue->sig, 3); int anon = dt && is_anonfn_typename(jl_symbol_name(dt->name->name)); if ((jl_options.warn_overwrite == JL_OPTIONS_WARN_OVERWRITE_ON) || @@ -1783,18 +1977,20 @@ static void method_overwrite(jl_typemap_entry_t *newentry, jl_method_t *oldvalue } } -static void update_max_args(jl_methtable_t *mt, jl_value_t *type) +static void update_max_args(jl_value_t *type) { - if (mt == jl_type_type_mt || mt == jl_nonfunction_mt || mt == jl_kwcall_mt) - return; type = jl_unwrap_unionall(type); + jl_datatype_t *dt = jl_nth_argument_datatype(type, 1); + if (dt == NULL || dt == jl_kwcall_type || jl_is_type_type((jl_value_t*)dt)) + return; + jl_typename_t *tn = dt->name; assert(jl_is_datatype(type)); size_t na = jl_nparams(type); if (jl_va_tuple_kind((jl_datatype_t*)type) == JL_VARARG_UNBOUND) na--; - // update occurs inside mt->writelock - if (na > jl_atomic_load_relaxed(&mt->max_args)) - jl_atomic_store_relaxed(&mt->max_args, na); + // update occurs inside global writelock + if (na > jl_atomic_load_relaxed(&tn->max_args)) + jl_atomic_store_relaxed(&tn->max_args, na); } jl_array_t *_jl_debug_method_invalidation JL_GLOBALLY_ROOTED = NULL; @@ -1838,7 +2034,9 @@ static void invalidate_code_instance(jl_code_instance_t *replaced, size_t max_wo jl_atomic_store_release(&replaced->max_world, max_world); // recurse to all backedges to update their valid range also _invalidate_backedges(replaced_mi, replaced, max_world, depth + 1); - } else { + // TODO: should we visit all forward edges now and delete ourself from all of those lists too? + } + else { assert(jl_atomic_load_relaxed(&replaced->max_world) <= max_world); } JL_UNLOCK(&replaced_mi->def.method->writelock); @@ -1849,6 +2047,19 @@ JL_DLLEXPORT void jl_invalidate_code_instance(jl_code_instance_t *replaced, size invalidate_code_instance(replaced, max_world, 1); } +JL_DLLEXPORT void jl_maybe_log_binding_invalidation(jl_value_t *replaced) +{ + if (_jl_debug_method_invalidation) { + if (replaced) { + jl_array_ptr_1d_push(_jl_debug_method_invalidation, replaced); + } + jl_value_t *loctag = jl_cstr_to_string("jl_maybe_log_binding_invalidation"); + JL_GC_PUSH1(&loctag); + jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); + JL_GC_POP(); + } +} + static void _invalidate_backedges(jl_method_instance_t *replaced_mi, jl_code_instance_t *replaced_ci, size_t max_world, int depth) { uint8_t recursion_flags = 0; jl_array_t *backedges = jl_mi_get_backedges_mutate(replaced_mi, &recursion_flags); @@ -1902,11 +2113,32 @@ static void _invalidate_backedges(jl_method_instance_t *replaced_mi, jl_code_ins JL_GC_POP(); } -enum morespec_options { - morespec_unknown, - morespec_isnot, - morespec_is -}; +static int jl_type_intersection2(jl_value_t *t1, jl_value_t *t2, jl_value_t **isect JL_REQUIRE_ROOTED_SLOT, jl_value_t **isect2 JL_REQUIRE_ROOTED_SLOT) +{ + *isect2 = NULL; + int is_subty = 0; + *isect = jl_type_intersection_env_s(t1, t2, NULL, &is_subty); + if (*isect == jl_bottom_type) + return 0; + if (is_subty) + return 1; + // TODO: sometimes type intersection returns types with free variables + if (jl_has_free_typevars(t1) || jl_has_free_typevars(t2)) + return 1; + // determine if type-intersection can be convinced to give a better, non-bad answer + // if the intersection was imprecise, see if we can do better by switching the types + *isect2 = jl_type_intersection(t2, t1); + if (*isect2 == jl_bottom_type) { + *isect = jl_bottom_type; + *isect2 = NULL; + return 0; + } + if (jl_types_egal(*isect2, *isect)) { + *isect2 = NULL; + } + return 1; +} + // check if `type` is replacing `m` with an ambiguity here, given other methods in `d` that already match it static int is_replacing(char ambig, jl_value_t *type, jl_method_t *m, jl_method_t *const *d, size_t n, jl_value_t *isect, jl_value_t *isect2, char *morespec) @@ -1917,9 +2149,7 @@ static int is_replacing(char ambig, jl_value_t *type, jl_method_t *m, jl_method_ // see if m2 also fully covered this intersection if (m == m2 || !(jl_subtype(isect, m2->sig) || (isect2 && jl_subtype(isect2, m2->sig)))) continue; - if (morespec[k] == (char)morespec_unknown) - morespec[k] = (char)(jl_type_morespecific(m2->sig, type) ? morespec_is : morespec_isnot); - if (morespec[k] == (char)morespec_is) + if (morespec[k]) // not actually shadowing this--m2 will still be better return 0; // if type is not more specific than m (thus now dominating it) @@ -1927,7 +2157,7 @@ static int is_replacing(char ambig, jl_value_t *type, jl_method_t *m, jl_method_ // since m2 was also a previous match over isect, // see if m was previously dominant over all m2 // or if this was already ambiguous before - if (ambig == morespec_is && !jl_type_morespecific(m->sig, m2->sig)) { + if (ambig && !jl_type_morespecific(m->sig, m2->sig)) { // m and m2 were previously ambiguous over the full intersection of mi with type, and will still be ambiguous with addition of type return 0; } @@ -1982,6 +2212,7 @@ static int _invalidate_dispatch_backedges(jl_method_instance_t *mi, jl_value_t * // invalidate cached methods that overlap this definition static void invalidate_backedges(jl_method_instance_t *replaced_mi, size_t max_world, const char *why) { + // Reset dispatch_status when method instance is replaced JL_LOCK(&replaced_mi->def.method->writelock); _invalidate_backedges(replaced_mi, NULL, max_world, 1); JL_UNLOCK(&replaced_mi->def.method->writelock); @@ -1992,6 +2223,7 @@ static void invalidate_backedges(jl_method_instance_t *replaced_mi, size_t max_w jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); JL_GC_POP(); } + jl_atomic_store_relaxed(&replaced_mi->dispatch_status, 0); } // add a backedge from callee to caller @@ -2006,7 +2238,6 @@ JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee, assert(invokesig == NULL || jl_is_type(invokesig)); JL_LOCK(&callee->def.method->writelock); if (jl_atomic_load_relaxed(&allow_new_worlds)) { - int found = 0; jl_array_t *backedges = jl_mi_get_backedges(callee); // TODO: use jl_cache_type_(invokesig) like cache_method does to save memory if (!backedges) { @@ -2015,70 +2246,151 @@ JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee, callee->backedges = backedges; jl_gc_wb(callee, backedges); } - else { - size_t i = 0, l = jl_array_nrows(backedges); - for (i = 0; i < l; i++) { - // optimized version of while (i < l) i = get_next_edge(callee->backedges, i, &invokeTypes, &mi); - jl_value_t *ciedge = jl_array_ptr_ref(backedges, i); - if (ciedge != (jl_value_t*)caller) - continue; - jl_value_t *invokeTypes = i > 0 ? jl_array_ptr_ref(backedges, i - 1) : NULL; - if (invokeTypes && jl_is_method_instance(invokeTypes)) - invokeTypes = NULL; - if ((invokesig == NULL && invokeTypes == NULL) || - (invokesig && invokeTypes && jl_types_equal(invokesig, invokeTypes))) { - found = 1; - break; - } + push_edge(backedges, invokesig, caller); + } + JL_UNLOCK(&callee->def.method->writelock); +} + + +static int jl_foreach_top_typename_for(void (*f)(jl_typename_t*, int, void*), jl_value_t *argtypes JL_PROPAGATES_ROOT, int all_subtypes, void *env); + +struct _typename_add_backedge { + jl_value_t *typ; + jl_value_t *caller; +}; + +static void _typename_add_backedge(jl_typename_t *tn, int explct, void *env0) +{ + struct _typename_add_backedge *env = (struct _typename_add_backedge*)env0; + JL_GC_PROMISE_ROOTED(env->typ); + JL_GC_PROMISE_ROOTED(env->caller); + if (!explct) + return; + jl_genericmemory_t *allbackedges = jl_method_table->backedges; + jl_array_t *backedges = (jl_array_t*)jl_eqtable_get(allbackedges, (jl_value_t*)tn, NULL); + if (backedges == NULL) { + backedges = jl_alloc_vec_any(2); + JL_GC_PUSH1(&backedges); + jl_array_del_end(backedges, 2); + jl_genericmemory_t *newtable = jl_eqtable_put(allbackedges, (jl_value_t*)tn, (jl_value_t*)backedges, NULL); + JL_GC_POP(); + if (newtable != allbackedges) { + jl_method_table->backedges = newtable; + jl_gc_wb(jl_method_table, newtable); + } + } + // check if the edge is already present and avoid adding a duplicate + size_t i, l = jl_array_nrows(backedges); + // reuse an already cached instance of this type, if possible + // TODO: use jl_cache_type_(tt) like cache_method does, instead of this linear scan? + // TODO: use as_global_root and de-dup edges array too + for (i = 1; i < l; i += 2) { + if (jl_array_ptr_ref(backedges, i) == env->caller) { + if (jl_types_equal(jl_array_ptr_ref(backedges, i - 1), env->typ)) { + env->typ = jl_array_ptr_ref(backedges, i - 1); + return; // this edge already recorded } } - if (!found) - push_edge(backedges, invokesig, caller); } - JL_UNLOCK(&callee->def.method->writelock); + for (i = 1; i < l; i += 2) { + if (jl_array_ptr_ref(backedges, i) != env->caller) { + if (jl_types_equal(jl_array_ptr_ref(backedges, i - 1), env->typ)) { + env->typ = jl_array_ptr_ref(backedges, i - 1); + break; + } + } + } + jl_array_ptr_1d_push(backedges, env->typ); + jl_array_ptr_1d_push(backedges, env->caller); } // add a backedge from a non-existent signature to caller -JL_DLLEXPORT void jl_method_table_add_backedge(jl_methtable_t *mt, jl_value_t *typ, jl_code_instance_t *caller) +JL_DLLEXPORT void jl_method_table_add_backedge(jl_value_t *typ, jl_code_instance_t *caller) { assert(jl_is_code_instance(caller)); if (!jl_atomic_load_relaxed(&allow_new_worlds)) return; - JL_LOCK(&mt->writelock); + // try to pick the best cache(s) for this typ edge + jl_methtable_t *mt = jl_method_table; + jl_methcache_t *mc = mt->cache; + JL_LOCK(&mc->writelock); if (jl_atomic_load_relaxed(&allow_new_worlds)) { - if (!mt->backedges) { - // lazy-init the backedges array - mt->backedges = jl_alloc_vec_any(2); - jl_gc_wb(mt, mt->backedges); - jl_array_ptr_set(mt->backedges, 0, typ); - jl_array_ptr_set(mt->backedges, 1, caller); - } - else { - // check if the edge is already present and avoid adding a duplicate - size_t i, l = jl_array_nrows(mt->backedges); - for (i = 1; i < l; i += 2) { - if (jl_array_ptr_ref(mt->backedges, i) == (jl_value_t*)caller) { - if (jl_types_equal(jl_array_ptr_ref(mt->backedges, i - 1), typ)) { - JL_UNLOCK(&mt->writelock); - return; - } - } - } - // reuse an already cached instance of this type, if possible - // TODO: use jl_cache_type_(tt) like cache_method does, instead of this linear scan? - for (i = 1; i < l; i += 2) { - if (jl_array_ptr_ref(mt->backedges, i) != (jl_value_t*)caller) { - if (jl_types_equal(jl_array_ptr_ref(mt->backedges, i - 1), typ)) { - typ = jl_array_ptr_ref(mt->backedges, i - 1); + struct _typename_add_backedge env = {typ, (jl_value_t*)caller}; + jl_foreach_top_typename_for(_typename_add_backedge, typ, 0, &env); + } + JL_UNLOCK(&mc->writelock); +} + +struct _typename_invalidate_backedge { + jl_value_t *type; + jl_value_t **isect; + jl_value_t **isect2; + jl_method_t *const *d; + size_t n; + size_t max_world; + int invalidated; +}; + +static void _typename_invalidate_backedges(jl_typename_t *tn, int explct, void *env0) +{ + struct _typename_invalidate_backedge *env = (struct _typename_invalidate_backedge*)env0; + JL_GC_PROMISE_ROOTED(env->type); + JL_GC_PROMISE_ROOTED(env->isect); // isJuliaType considers jl_value_t** to be a julia object too + JL_GC_PROMISE_ROOTED(env->isect2); // isJuliaType considers jl_value_t** to be a julia object too + jl_array_t *backedges = (jl_array_t*)jl_eqtable_get(jl_method_table->backedges, (jl_value_t*)tn, NULL); + if (backedges == NULL) + return; + jl_value_t **d = jl_array_ptr_data(backedges); + size_t i, na = jl_array_nrows(backedges); + size_t ins = 0; + for (i = 1; i < na; i += 2) { + jl_value_t *backedgetyp = d[i - 1]; + JL_GC_PROMISE_ROOTED(backedgetyp); + int missing = 0; + if (jl_type_intersection2(backedgetyp, (jl_value_t*)env->type, env->isect, env->isect2)) { + // See if the intersection was actually already fully + // covered, but that the new method is ambiguous. + // -> no previous method: now there is one, need to update the missing edge + // -> one+ previously matching method(s): + // -> more specific then all of them: need to update the missing edge + // -> some may have been ambiguous: now there is a replacement + // -> some may have been called: now there is a replacement (also will be detected in the loop later) + // -> less specific or ambiguous with any one of them: can ignore the missing edge (not missing) + // -> some may have been ambiguous: still are + // -> some may have been called: they may be partly replaced (will be detected in the loop later) + // c.f. `is_replacing`, which is a similar query, but with an existing method match to compare against + missing = 1; + for (size_t j = 0; j < env->n; j++) { + jl_method_t *m = env->d[j]; + JL_GC_PROMISE_ROOTED(m); + if (jl_subtype(*env->isect, m->sig) || (*env->isect2 && jl_subtype(*env->isect2, m->sig))) { + // We now know that there actually was a previous + // method for this part of the type intersection. + if (!jl_type_morespecific(env->type, m->sig)) { + missing = 0; break; } } } - jl_array_ptr_1d_push(mt->backedges, typ); - jl_array_ptr_1d_push(mt->backedges, (jl_value_t*)caller); + } + *env->isect = *env->isect2 = NULL; + if (missing) { + jl_code_instance_t *backedge = (jl_code_instance_t*)d[i]; + JL_GC_PROMISE_ROOTED(backedge); + invalidate_code_instance(backedge, env->max_world, 0); + env->invalidated = 1; + if (_jl_debug_method_invalidation) + jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)backedgetyp); + } + else { + d[ins++] = d[i - 1]; + d[ins++] = d[i - 0]; } } - JL_UNLOCK(&mt->writelock); + if (ins == 0) + jl_eqtable_pop(jl_method_table->backedges, (jl_value_t*)tn, NULL, NULL); + else if (na != ins) + jl_array_del_end(backedges, na - ins); } struct invalidate_mt_env { @@ -2164,35 +2476,36 @@ static jl_typemap_entry_t *do_typemap_search(jl_methtable_t *mt JL_PROPAGATES_RO return (jl_typemap_entry_t *)closure; } -static void jl_method_table_invalidate(jl_methtable_t *mt, jl_method_t *replaced, size_t max_world) +static void _method_table_invalidate(jl_methcache_t *mc, void *env0) { - if (jl_options.incremental && jl_generating_output()) - jl_error("Method deletion is not possible during Module precompile."); - assert(!replaced->is_for_opaque_closure); - assert(jl_atomic_load_relaxed(&jl_world_counter) == max_world); - // drop this method from mt->cache - struct disable_mt_env mt_cache_env; - mt_cache_env.max_world = max_world; - mt_cache_env.replaced = replaced; - jl_typemap_visitor(jl_atomic_load_relaxed(&mt->cache), disable_mt_cache, (void*)&mt_cache_env); - jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache); + // drop this method from mc->cache + jl_typemap_visitor(jl_atomic_load_relaxed(&mc->cache), disable_mt_cache, env0); + jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mc->leafcache); size_t i, l = leafcache->length; for (i = 1; i < l; i += 2) { jl_typemap_entry_t *oldentry = (jl_typemap_entry_t*)jl_genericmemory_ptr_ref(leafcache, i); if (oldentry) { while ((jl_value_t*)oldentry != jl_nothing) { - disable_mt_cache(oldentry, (void*)&mt_cache_env); + disable_mt_cache(oldentry, env0); oldentry = jl_atomic_load_relaxed(&oldentry->next); } } } +} + +static void jl_method_table_invalidate(jl_method_t *replaced, size_t max_world) +{ + if (jl_options.incremental && jl_generating_output()) + jl_error("Method deletion is not possible during Module precompile."); + assert(!replaced->is_for_opaque_closure); + assert(jl_atomic_load_relaxed(&jl_world_counter) == max_world); // Invalidate the backedges int invalidated = 0; jl_value_t *specializations = jl_atomic_load_relaxed(&replaced->specializations); JL_GC_PUSH1(&specializations); if (!jl_is_svec(specializations)) specializations = (jl_value_t*)jl_svec1(specializations); - l = jl_svec_len(specializations); + size_t i, l = jl_svec_len(specializations); for (i = 0; i < l; i++) { jl_method_instance_t *mi = (jl_method_instance_t*)jl_svecref(specializations, i); if ((jl_value_t*)mi != jl_nothing) { @@ -2200,6 +2513,12 @@ static void jl_method_table_invalidate(jl_methtable_t *mt, jl_method_t *replaced invalidate_backedges(mi, max_world, "jl_method_table_disable"); } } + + jl_methtable_t *mt = jl_method_get_table(replaced); + struct disable_mt_env mt_cache_env; + mt_cache_env.max_world = max_world; + mt_cache_env.replaced = replaced; + _method_table_invalidate(mt->cache, &mt_cache_env); JL_GC_POP(); // XXX: this might have resolved an ambiguity, for which we have not tracked the edge here, // and thus now introduce a mistake into inference @@ -2236,13 +2555,7 @@ static int erase_method_backedges(jl_typemap_entry_t *def, void *closure) static int erase_all_backedges(jl_methtable_t *mt, void *env) { - // removes all method caches - // this might not be entirely safe (GC or MT), thus we only do it very early in bootstrapping - JL_LOCK(&mt->writelock); - mt->backedges = NULL; - JL_UNLOCK(&mt->writelock); - jl_typemap_visitor(jl_atomic_load_relaxed(&mt->defs), erase_method_backedges, env); - return 1; + return jl_typemap_visitor(jl_atomic_load_relaxed(&mt->defs), erase_method_backedges, env); } JL_DLLEXPORT void jl_disable_new_worlds(void) @@ -2252,59 +2565,39 @@ JL_DLLEXPORT void jl_disable_new_worlds(void) JL_LOCK(&world_counter_lock); jl_atomic_store_relaxed(&allow_new_worlds, 0); JL_UNLOCK(&world_counter_lock); - jl_foreach_reachable_mtable(erase_all_backedges, (void*)NULL); + jl_array_t *mod_array = jl_get_loaded_modules(); + JL_GC_PUSH1(&mod_array); + jl_foreach_reachable_mtable(erase_all_backedges, mod_array, (void*)NULL); + + JL_LOCK(&jl_method_table->cache->writelock); + jl_method_table->backedges = (jl_genericmemory_t*)jl_an_empty_memory_any; + JL_UNLOCK(&jl_method_table->cache->writelock); + JL_GC_POP(); } -JL_DLLEXPORT void jl_method_table_disable(jl_methtable_t *mt, jl_method_t *method) +JL_DLLEXPORT void jl_method_table_disable(jl_method_t *method) { + jl_methtable_t *mt = jl_method_get_table(method); jl_typemap_entry_t *methodentry = do_typemap_search(mt, method); JL_LOCK(&world_counter_lock); if (!jl_atomic_load_relaxed(&allow_new_worlds)) jl_error("Method changes have been disabled via a call to disable_new_worlds."); int enabled = jl_atomic_load_relaxed(&methodentry->max_world) == ~(size_t)0; if (enabled) { - JL_LOCK(&mt->writelock); - // Narrow the world age on the method to make it uncallable + // Narrow the world age on the method to make it uncallable size_t world = jl_atomic_load_relaxed(&jl_world_counter); assert(method == methodentry->func.method); jl_atomic_store_relaxed(&method->dispatch_status, 0); assert(jl_atomic_load_relaxed(&methodentry->max_world) == ~(size_t)0); jl_atomic_store_relaxed(&methodentry->max_world, world); - jl_method_table_invalidate(mt, method, world); + jl_method_table_invalidate(method, world); jl_atomic_store_release(&jl_world_counter, world + 1); - JL_UNLOCK(&mt->writelock); - } + } JL_UNLOCK(&world_counter_lock); if (!enabled) jl_errorf("Method of %s already disabled", jl_symbol_name(method->name)); } -static int jl_type_intersection2(jl_value_t *t1, jl_value_t *t2, jl_value_t **isect JL_REQUIRE_ROOTED_SLOT, jl_value_t **isect2 JL_REQUIRE_ROOTED_SLOT) -{ - *isect2 = NULL; - int is_subty = 0; - *isect = jl_type_intersection_env_s(t1, t2, NULL, &is_subty); - if (*isect == jl_bottom_type) - return 0; - if (is_subty) - return 1; - // TODO: sometimes type intersection returns types with free variables - if (jl_has_free_typevars(t1) || jl_has_free_typevars(t2)) - return 1; - // determine if type-intersection can be convinced to give a better, non-bad answer - // if the intersection was imprecise, see if we can do better by switching the types - *isect2 = jl_type_intersection(t2, t1); - if (*isect2 == jl_bottom_type) { - *isect = jl_bottom_type; - *isect2 = NULL; - return 0; - } - if (jl_types_egal(*isect2, *isect)) { - *isect2 = NULL; - } - return 1; -} - jl_typemap_entry_t *jl_method_table_add(jl_methtable_t *mt, jl_method_t *method, jl_tupletype_t *simpletype) { JL_TIMING(ADD_METHOD, ADD_METHOD); @@ -2313,30 +2606,32 @@ jl_typemap_entry_t *jl_method_table_add(jl_methtable_t *mt, jl_method_t *method, jl_timing_show_method(method, JL_TIMING_DEFAULT_BLOCK); jl_typemap_entry_t *newentry = NULL; JL_GC_PUSH1(&newentry); - JL_LOCK(&mt->writelock); // add our new entry assert(jl_atomic_load_relaxed(&method->primary_world) == ~(size_t)0); // min-world assert((jl_atomic_load_relaxed(&method->dispatch_status) & METHOD_SIG_LATEST_WHICH) == 0); assert((jl_atomic_load_relaxed(&method->dispatch_status) & METHOD_SIG_LATEST_ONLY) == 0); + JL_LOCK(&mt->cache->writelock); newentry = jl_typemap_alloc((jl_tupletype_t*)method->sig, simpletype, jl_emptysvec, (jl_value_t*)method, ~(size_t)0, 1); - jl_typemap_insert(&mt->defs, (jl_value_t*)mt, newentry, jl_cachearg_offset(mt)); - update_max_args(mt, method->sig); - JL_UNLOCK(&mt->writelock); + jl_typemap_insert(&mt->defs, (jl_value_t*)mt, newentry, 0); + + if (mt == jl_method_table) + update_max_args(method->sig); + JL_UNLOCK(&mt->cache->writelock); JL_GC_POP(); return newentry; } -void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) +void jl_method_table_activate(jl_typemap_entry_t *newentry) { JL_TIMING(ADD_METHOD, ADD_METHOD); jl_method_t *method = newentry->func.method; + jl_methtable_t *mt = jl_method_get_table(method); assert(jl_is_mtable(mt)); assert(jl_is_method(method)); jl_timing_show_method(method, JL_TIMING_DEFAULT_BLOCK); jl_value_t *type = (jl_value_t*)newentry->sig; jl_value_t *oldvalue = NULL; jl_array_t *oldmi = NULL; - JL_LOCK(&mt->writelock); size_t world = jl_atomic_load_relaxed(&method->primary_world); assert(world == jl_atomic_load_relaxed(&jl_world_counter) + 1); // min-world assert((jl_atomic_load_relaxed(&method->dispatch_status) & METHOD_SIG_LATEST_WHICH) == 0); @@ -2353,19 +2648,30 @@ void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) JL_GC_PUSH6(&oldvalue, &oldmi, &loctag, &isect, &isect2, &isect3); jl_typemap_entry_t *replaced = NULL; // then check what entries we replaced - oldvalue = get_intersect_matches(jl_atomic_load_relaxed(&mt->defs), newentry, &replaced, jl_cachearg_offset(mt), max_world); + oldvalue = get_intersect_matches(jl_atomic_load_relaxed(&mt->defs), newentry, &replaced, max_world); + int invalidated = 0; - int only = !(jl_atomic_load_relaxed(&method->dispatch_status) & METHOD_SIG_PRECOMPILE_MANY); // will compute if this will be currently the only result that would returned from `ml_matches` given `sig` + int dispatch_bits = METHOD_SIG_LATEST_WHICH; // Always set LATEST_WHICH + // Check precompiled dispatch status bits + int precompiled_status = jl_atomic_load_relaxed(&method->dispatch_status); + if (!(precompiled_status & METHOD_SIG_PRECOMPILE_MANY)) + dispatch_bits |= METHOD_SIG_LATEST_ONLY; // Tentatively set, will be cleared if not applicable + if (precompiled_status & METHOD_SIG_PRECOMPILE_HAS_NOTMORESPECIFIC) + dispatch_bits |= METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC; if (replaced) { oldvalue = (jl_value_t*)replaced; jl_method_t *m = replaced->func.method; invalidated = 1; method_overwrite(newentry, m); - // this is an optimized version of below, given we know the type-intersection is exact - jl_method_table_invalidate(mt, m, max_world); + // This is an optimized version of below, given we know the type-intersection is exact + jl_method_table_invalidate(m, max_world); int m_dispatch = jl_atomic_load_relaxed(&m->dispatch_status); - jl_atomic_store_relaxed(&m->dispatch_status, 0); - only = m_dispatch & METHOD_SIG_LATEST_ONLY; + // Clear METHOD_SIG_LATEST_ONLY and METHOD_SIG_LATEST_WHICH bits, only keeping NOTMORESPECIFIC + jl_atomic_store_relaxed(&m->dispatch_status, m_dispatch & METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC); + // Edge case: don't set dispatch_bits |= METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC unconditionally since `m` is not an visible method for invalidations + dispatch_bits |= (m_dispatch & METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC); + if (!(m_dispatch & METHOD_SIG_LATEST_ONLY)) + dispatch_bits &= ~METHOD_SIG_LATEST_ONLY; } else { jl_method_t *const *d; @@ -2378,69 +2684,31 @@ void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) assert(jl_is_array(oldvalue)); d = (jl_method_t**)jl_array_ptr_data(oldvalue); n = jl_array_nrows(oldvalue); - } - if (mt->backedges) { - jl_value_t **backedges = jl_array_ptr_data(mt->backedges); - size_t i, na = jl_array_nrows(mt->backedges); - size_t ins = 0; - for (i = 1; i < na; i += 2) { - jl_value_t *backedgetyp = backedges[i - 1]; - JL_GC_PROMISE_ROOTED(backedgetyp); - int missing = 0; - if (jl_type_intersection2(backedgetyp, (jl_value_t*)type, &isect, &isect2)) { - // See if the intersection was actually already fully - // covered, but that the new method is ambiguous. - // -> no previous method: now there is one, need to update the missing edge - // -> one+ previously matching method(s): - // -> more specific then all of them: need to update the missing edge - // -> some may have been ambiguous: now there is a replacement - // -> some may have been called: now there is a replacement (also will be detected in the loop later) - // -> less specific or ambiguous with any one of them: can ignore the missing edge (not missing) - // -> some may have been ambiguous: still are - // -> some may have been called: they may be partly replaced (will be detected in the loop later) - // c.f. `is_replacing`, which is a similar query, but with an existing method match to compare against - missing = 1; - size_t j; - for (j = 0; j < n; j++) { - jl_method_t *m = d[j]; - if (jl_subtype(isect, m->sig) || (isect2 && jl_subtype(isect2, m->sig))) { - // We now know that there actually was a previous - // method for this part of the type intersection. - if (!jl_type_morespecific(type, m->sig)) { - missing = 0; - break; - } - } - } - } - if (missing) { - jl_code_instance_t *backedge = (jl_code_instance_t*)backedges[i]; - JL_GC_PROMISE_ROOTED(backedge); - invalidate_code_instance(backedge, max_world, 0); - invalidated = 1; - if (_jl_debug_method_invalidation) - jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)backedgetyp); - } - else { - backedges[ins++] = backedges[i - 1]; - backedges[ins++] = backedges[i - 0]; - } - } - if (ins == 0) - mt->backedges = NULL; - else - jl_array_del_end(mt->backedges, na - ins); - } - if (oldvalue) { + oldmi = jl_alloc_vec_any(0); char *morespec = (char*)alloca(n); - memset(morespec, morespec_unknown, n); + // Compute all morespec values upfront + for (j = 0; j < n; j++) + morespec[j] = (char)jl_type_morespecific(d[j]->sig, type); for (j = 0; j < n; j++) { jl_method_t *m = d[j]; - if (morespec[j] == (char)morespec_is) { - only = 0; - continue; + // Compute ambig state: is there an ambiguity between new method and old m? + char ambig = !morespec[j] && !jl_type_morespecific(type, m->sig); + // Compute updates to the dispatch state bits + int m_dispatch = jl_atomic_load_relaxed(&m->dispatch_status); + if (morespec[j] || ambig) { + // !morespecific(new, old) + dispatch_bits &= ~METHOD_SIG_LATEST_ONLY; + m_dispatch |= METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC; + } + if (!morespec[j]) { + // !morespecific(old, new) + dispatch_bits |= METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC; + m_dispatch &= ~METHOD_SIG_LATEST_ONLY; } + jl_atomic_store_relaxed(&m->dispatch_status, m_dispatch); + if (morespec[j]) + continue; loctag = jl_atomic_load_relaxed(&m->specializations); // use loctag for a gcroot _Atomic(jl_method_instance_t*) *data; size_t l; @@ -2452,32 +2720,26 @@ void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) data = (_Atomic(jl_method_instance_t*)*) &loctag; l = 1; } - enum morespec_options ambig = morespec_unknown; for (size_t i = 0; i < l; i++) { jl_method_instance_t *mi = jl_atomic_load_relaxed(&data[i]); if ((jl_value_t*)mi == jl_nothing) continue; isect3 = jl_type_intersection(m->sig, (jl_value_t*)mi->specTypes); if (jl_type_intersection2(type, isect3, &isect, &isect2)) { + // Replacing a method--see if this really was the selected method previously + // over the intersection (not ambiguous) and the new method will be selected now (morespec_is). // TODO: this only checks pair-wise for ambiguities, but the ambiguities could arise from the interaction of multiple methods // and thus might miss a case where we introduce an ambiguity between two existing methods // We could instead work to sort this into 3 groups `morespecific .. ambiguous .. lesspecific`, with `type` in ambiguous, // such that everything in `morespecific` dominates everything in `ambiguous`, and everything in `ambiguous` dominates everything in `lessspecific` // And then compute where each isect falls, and whether it changed group--necessitating invalidation--or not. - if (morespec[j] == (char)morespec_unknown) - morespec[j] = (char)(jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot); - if (morespec[j] == (char)morespec_is) - // not actually shadowing--the existing method is still better - break; - if (ambig == morespec_unknown) - ambig = jl_type_morespecific(type, m->sig) ? morespec_isnot : morespec_is; - // replacing a method--see if this really was the selected method previously - // over the intersection (not ambiguous) and the new method will be selected now (morespec_is) int replaced_dispatch = is_replacing(ambig, type, m, d, n, isect, isect2, morespec); // found that this specialization dispatch got replaced by m // call invalidate_backedges(mi, max_world, "jl_method_table_insert"); // but ignore invoke-type edges int invalidatedmi = _invalidate_dispatch_backedges(mi, type, m, d, n, replaced_dispatch, ambig, max_world, morespec); + if (replaced_dispatch) + jl_atomic_store_relaxed(&mi->dispatch_status, 0); jl_array_ptr_1d_push(oldmi, (jl_value_t*)mi); if (_jl_debug_method_invalidation && invalidatedmi) { jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)mi); @@ -2487,44 +2749,47 @@ void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) invalidated |= invalidatedmi; } } - // now compute and store updates to METHOD_SIG_LATEST_ONLY - int m_dispatch = jl_atomic_load_relaxed(&m->dispatch_status); - if (m_dispatch & METHOD_SIG_LATEST_ONLY) { - if (morespec[j] == (char)morespec_unknown) - morespec[j] = (char)(jl_type_morespecific(m->sig, type) ? morespec_is : morespec_isnot); - if (morespec[j] == (char)morespec_isnot) - jl_atomic_store_relaxed(&m->dispatch_status, ~METHOD_SIG_LATEST_ONLY & m_dispatch); - } - if (only) { - if (morespec[j] == (char)morespec_is || ambig == morespec_is || - (ambig == morespec_unknown && !jl_type_morespecific(type, m->sig))) { - only = 0; - } - } } - if (jl_array_nrows(oldmi)) { - // search mt->cache and leafcache and drop anything that might overlap with the new method - // this is very cheap, so we don't mind being fairly conservative at over-approximating this - struct invalidate_mt_env mt_cache_env; - mt_cache_env.max_world = max_world; - mt_cache_env.shadowed = oldmi; - mt_cache_env.newentry = newentry; - mt_cache_env.invalidated = 0; - - jl_typemap_visitor(jl_atomic_load_relaxed(&mt->cache), invalidate_mt_cache, (void*)&mt_cache_env); - jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache); - size_t i, l = leafcache->length; - for (i = 1; i < l; i += 2) { - jl_value_t *entry = jl_genericmemory_ptr_ref(leafcache, i); - if (entry) { - while (entry != jl_nothing) { - invalidate_mt_cache((jl_typemap_entry_t*)entry, (void*)&mt_cache_env); - entry = (jl_value_t*)jl_atomic_load_relaxed(&((jl_typemap_entry_t*)entry)->next); - } + } + + jl_methcache_t *mc = jl_method_table->cache; + JL_LOCK(&mc->writelock); + struct _typename_invalidate_backedge typename_env = {type, &isect, &isect2, d, n, max_world, invalidated}; + if (!jl_foreach_top_typename_for(_typename_invalidate_backedges, type, 1, &typename_env)) { + // if the new method cannot be split into exact backedges, scan the whole table for anything that might be affected + jl_genericmemory_t *allbackedges = jl_method_table->backedges; + for (size_t i = 0, n = allbackedges->length; i < n; i += 2) { + jl_value_t *tn = jl_genericmemory_ptr_ref(allbackedges, i); + jl_value_t *backedges = jl_genericmemory_ptr_ref(allbackedges, i+1); + if (tn && tn != jl_nothing && backedges) + _typename_invalidate_backedges((jl_typename_t*)tn, 0, &typename_env); + } + } + invalidated |= typename_env.invalidated; + if (oldmi && jl_array_nrows(oldmi)) { + // search mc->cache and leafcache and drop anything that might overlap with the new method + // this is very cheap, so we don't mind being fairly conservative at over-approximating this + struct invalidate_mt_env mt_cache_env; + mt_cache_env.max_world = max_world; + mt_cache_env.shadowed = oldmi; + mt_cache_env.newentry = newentry; + mt_cache_env.invalidated = 0; + + jl_typemap_visitor(jl_atomic_load_relaxed(&mc->cache), invalidate_mt_cache, (void*)&mt_cache_env); + jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mc->leafcache); + size_t i, l = leafcache->length; + for (i = 1; i < l; i += 2) { + jl_value_t *entry = jl_genericmemory_ptr_ref(leafcache, i); + if (entry) { + while (entry != jl_nothing) { + invalidate_mt_cache((jl_typemap_entry_t*)entry, (void*)&mt_cache_env); + entry = (jl_value_t*)jl_atomic_load_relaxed(&((jl_typemap_entry_t*)entry)->next); } } } + invalidated |= mt_cache_env.invalidated; } + JL_UNLOCK(&mc->writelock); } if (invalidated && _jl_debug_method_invalidation) { jl_array_ptr_1d_push(_jl_debug_method_invalidation, (jl_value_t*)method); @@ -2532,8 +2797,7 @@ void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry) jl_array_ptr_1d_push(_jl_debug_method_invalidation, loctag); } jl_atomic_store_relaxed(&newentry->max_world, ~(size_t)0); - jl_atomic_store_relaxed(&method->dispatch_status, METHOD_SIG_LATEST_WHICH | (only ? METHOD_SIG_LATEST_ONLY : 0)); // TODO: this should be sequenced fully after the world counter store - JL_UNLOCK(&mt->writelock); + jl_atomic_store_relaxed(&method->dispatch_status, dispatch_bits); // TODO: this should be sequenced fully after the world counter store JL_GC_POP(); } @@ -2546,7 +2810,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method jl_error("Method changes have been disabled via a call to disable_new_worlds."); size_t world = jl_atomic_load_relaxed(&jl_world_counter) + 1; jl_atomic_store_relaxed(&method->primary_world, world); - jl_method_table_activate(mt, newentry); + jl_method_table_activate(newentry); jl_atomic_store_release(&jl_world_counter, world); JL_UNLOCK(&world_counter_lock); JL_GC_POP(); @@ -2598,13 +2862,15 @@ static jl_tupletype_t *lookup_arg_type_tuple(jl_value_t *arg1 JL_PROPAGATES_ROOT JL_DLLEXPORT jl_value_t *jl_method_lookup_by_tt(jl_tupletype_t *tt, size_t world, jl_value_t *_mt) { jl_methtable_t *mt = NULL; - if (_mt == jl_nothing) - mt = jl_gf_ft_mtable(jl_tparam0(tt)); + if (_mt == jl_nothing) { + mt = jl_method_table; + } else { - assert(jl_isa(_mt, (jl_value_t*)jl_methtable_type)); + assert(jl_is_mtable(_mt)); mt = (jl_methtable_t*) _mt; } - jl_method_instance_t* mi = jl_mt_assoc_by_type(mt, tt, world); + jl_methcache_t *mc = mt->cache; + jl_method_instance_t *mi = jl_mt_assoc_by_type(mc, tt, world); if (!mi) return jl_nothing; return (jl_value_t*) mi; @@ -2613,13 +2879,13 @@ JL_DLLEXPORT jl_value_t *jl_method_lookup_by_tt(jl_tupletype_t *tt, size_t world JL_DLLEXPORT jl_method_instance_t *jl_method_lookup(jl_value_t **args, size_t nargs, size_t world) { assert(nargs > 0 && "expected caller to handle this case"); - jl_methtable_t *mt = jl_gf_mtable(args[0]); - jl_typemap_t *cache = jl_atomic_load_relaxed(&mt->cache); // XXX: gc root for this? - jl_typemap_entry_t *entry = jl_typemap_assoc_exact(cache, args[0], &args[1], nargs, jl_cachearg_offset(mt), world); + jl_methcache_t *mc = jl_method_table->cache; + jl_typemap_t *cache = jl_atomic_load_relaxed(&mc->cache); // XXX: gc root for this? + jl_typemap_entry_t *entry = jl_typemap_assoc_exact(cache, args[0], &args[1], nargs, jl_cachearg_offset(), world); if (entry) return entry->func.linfo; jl_tupletype_t *tt = arg_type_tuple(args[0], &args[1], nargs); - return jl_mt_assoc_by_type(mt, tt, world); + return jl_mt_assoc_by_type(mc, tt, world); } // return a Vector{Any} of svecs, each describing a method match: @@ -2642,10 +2908,9 @@ JL_DLLEXPORT jl_value_t *jl_matching_methods(jl_tupletype_t *types, jl_value_t * if (unw == (jl_value_t*)jl_emptytuple_type || jl_tparam0(unw) == jl_bottom_type) return (jl_value_t*)jl_an_empty_vec_any; if (mt == jl_nothing) - mt = (jl_value_t*)jl_method_table_for(unw); - if (mt == jl_nothing) - mt = NULL; - return ml_matches((jl_methtable_t*)mt, types, lim, include_ambiguous, 1, world, 1, min_valid, max_valid, ambig); + mt = (jl_value_t*)jl_method_table; + jl_methcache_t *mc = ((jl_methtable_t*)mt)->cache; + return ml_matches((jl_methtable_t*)mt, mc, types, lim, include_ambiguous, 1, world, 1, min_valid, max_valid, ambig); } JL_DLLEXPORT jl_method_instance_t *jl_get_unspecialized(jl_method_t *def JL_PROPAGATES_ROOT) @@ -3034,7 +3299,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t int should_skip_inference = !jl_is_method(mi->def.method) || jl_symbol_name(mi->def.method->name)[0] == '@'; if (!should_skip_inference) { - codeinst = jl_type_infer(mi, world, SOURCE_MODE_ABI); + codeinst = jl_type_infer(mi, world, SOURCE_MODE_ABI, jl_options.trim); } } @@ -3157,6 +3422,7 @@ JL_DLLEXPORT const jl_callptr_t jl_fptr_const_return_addr = &jl_fptr_const_retur JL_DLLEXPORT const jl_callptr_t jl_fptr_sparam_addr = &jl_fptr_sparam; +JL_CALLABLE(jl_f_opaque_closure_call); JL_DLLEXPORT const jl_callptr_t jl_f_opaque_closure_call_addr = (jl_callptr_t)&jl_f_opaque_closure_call; JL_DLLEXPORT const jl_callptr_t jl_fptr_wait_for_compiled_addr = &jl_fptr_wait_for_compiled; @@ -3178,14 +3444,13 @@ JL_DLLEXPORT int32_t jl_invoke_api(jl_code_instance_t *codeinst) return -1; } -JL_DLLEXPORT jl_value_t *jl_normalize_to_compilable_sig(jl_methtable_t *mt, jl_tupletype_t *ti, jl_svec_t *env, jl_method_t *m, +JL_DLLEXPORT jl_value_t *jl_normalize_to_compilable_sig(jl_tupletype_t *ti, jl_svec_t *env, jl_method_t *m, int return_if_compileable) { jl_tupletype_t *tt = NULL; jl_svec_t *newparams = NULL; JL_GC_PUSH2(&tt, &newparams); - jl_methtable_t *kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for(m->sig) : mt; - intptr_t max_varargs = get_max_varargs(m, kwmt, mt, NULL); + intptr_t max_varargs = get_max_varargs(m, NULL); jl_compilation_sig(ti, env, m, max_varargs, &newparams); int is_compileable = ((jl_datatype_t*)ti)->isdispatchtuple; if (newparams) { @@ -3211,10 +3476,7 @@ jl_method_instance_t *jl_normalize_to_compilable_mi(jl_method_instance_t *mi JL_ jl_method_t *def = mi->def.method; if (!jl_is_method(def) || !jl_is_datatype(mi->specTypes)) return mi; - jl_methtable_t *mt = jl_method_get_table(def); - if ((jl_value_t*)mt == jl_nothing) - return mi; - jl_value_t *compilationsig = jl_normalize_to_compilable_sig(mt, (jl_datatype_t*)mi->specTypes, mi->sparam_vals, def, 1); + jl_value_t *compilationsig = jl_normalize_to_compilable_sig((jl_datatype_t*)mi->specTypes, mi->sparam_vals, def, 1); if (compilationsig == jl_nothing || jl_egal(compilationsig, mi->specTypes)) return mi; jl_svec_t *env = NULL; @@ -3235,30 +3497,27 @@ JL_DLLEXPORT jl_method_instance_t *jl_method_match_to_mi(jl_method_match_t *matc jl_tupletype_t *ti = match->spec_types; jl_method_instance_t *mi = NULL; if (jl_is_datatype(ti)) { - jl_methtable_t *mt = jl_method_get_table(m); - assert(mt != NULL); - if ((jl_value_t*)mt != jl_nothing) { - // get the specialization, possibly also caching it - if (mt_cache && ((jl_datatype_t*)ti)->isdispatchtuple) { - // Since we also use this presence in the cache - // to trigger compilation when producing `.ji` files, - // inject it there now if we think it will be - // used via dispatch later (e.g. because it was hinted via a call to `precompile`) - JL_LOCK(&mt->writelock); - mi = cache_method(mt, &mt->cache, (jl_value_t*)mt, ti, m, world, min_valid, max_valid, env); - JL_UNLOCK(&mt->writelock); - } - else { - jl_value_t *tt = jl_normalize_to_compilable_sig(mt, ti, env, m, 1); - if (tt != jl_nothing) { - JL_GC_PUSH2(&tt, &env); - if (!jl_egal(tt, (jl_value_t*)ti)) { - jl_value_t *ti = jl_type_intersection_env((jl_value_t*)tt, (jl_value_t*)m->sig, &env); - assert(ti != jl_bottom_type); (void)ti; - } - mi = jl_specializations_get_linfo(m, (jl_value_t*)tt, env); - JL_GC_POP(); + // get the specialization, possibly also caching it + if (mt_cache && ((jl_datatype_t*)ti)->isdispatchtuple) { + // Since we also use this presence in the cache + // to trigger compilation when producing `.ji` files, + // inject it there now if we think it will be + // used via dispatch later (e.g. because it was hinted via a call to `precompile`) + jl_methcache_t *mc = jl_method_table->cache; + assert(mc); + JL_LOCK(&mc->writelock); + mi = cache_method(jl_method_get_table(m), mc, &mc->cache, (jl_value_t*)mc, ti, m, world, min_valid, max_valid, env); + } + else { + jl_value_t *tt = jl_normalize_to_compilable_sig(ti, env, m, 1); + if (tt != jl_nothing) { + JL_GC_PUSH2(&tt, &env); + if (!jl_egal(tt, (jl_value_t*)ti)) { + jl_value_t *ti = jl_type_intersection_env((jl_value_t*)tt, (jl_value_t*)m->sig, &env); + assert(ti != jl_bottom_type); (void)ti; } + mi = jl_specializations_get_linfo(m, (jl_value_t*)tt, env); + JL_GC_POP(); } } } @@ -3359,7 +3618,7 @@ static void _generate_from_hint(jl_method_instance_t *mi, size_t world) { jl_value_t *codeinst = jl_rettype_inferred_native(mi, world, world); if (codeinst == jl_nothing) { - (void)jl_type_infer(mi, world, SOURCE_MODE_NOT_REQUIRED); + (void)jl_type_infer(mi, world, SOURCE_MODE_NOT_REQUIRED, jl_options.trim); codeinst = jl_rettype_inferred_native(mi, world, world); } if (codeinst != jl_nothing) { @@ -3402,10 +3661,10 @@ JL_DLLEXPORT void jl_compile_method_instance(jl_method_instance_t *mi, jl_tuplet miflags = jl_atomic_load_relaxed(&mi2->flags) | JL_MI_FLAGS_MASK_PRECOMPILED; jl_atomic_store_relaxed(&mi2->flags, miflags); if (jl_rettype_inferred_native(mi2, world, world) == jl_nothing) - (void)jl_type_infer(mi2, world, SOURCE_MODE_NOT_REQUIRED); + (void)jl_type_infer(mi2, world, SOURCE_MODE_NOT_REQUIRED, jl_options.trim); if (jl_typeinf_func && jl_atomic_load_relaxed(&mi->def.method->primary_world) <= tworld) { if (jl_rettype_inferred_native(mi2, tworld, tworld) == jl_nothing) - (void)jl_type_infer(mi2, tworld, SOURCE_MODE_NOT_REQUIRED); + (void)jl_type_infer(mi2, tworld, SOURCE_MODE_NOT_REQUIRED, jl_options.trim); } } } @@ -3633,7 +3892,6 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t *F, jl_value_t (callsite >> 16) & (N_CALL_CACHE - 1), (callsite >> 24 | callsite << 8) & (N_CALL_CACHE - 1)}; jl_typemap_entry_t *entry = NULL; - jl_methtable_t *mt = NULL; int i; // check each cache entry to see if it matches //#pragma unroll @@ -3660,8 +3918,8 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t *F, jl_value_t if (i == 4) { // if no method was found in the associative cache, check the full cache JL_TIMING(METHOD_LOOKUP_FAST, METHOD_LOOKUP_FAST); - mt = jl_gf_mtable(F); - jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache); + jl_methcache_t *mc = jl_method_table->cache; + jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mc->leafcache); entry = NULL; int cache_entry_count = jl_atomic_load_relaxed(&((jl_datatype_t*)FT)->name->cache_entry_count); if (leafcache != (jl_genericmemory_t*)jl_an_empty_memory_any && (cache_entry_count == 0 || cache_entry_count >= 8)) { @@ -3671,8 +3929,8 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t *F, jl_value_t entry = lookup_leafcache(leafcache, (jl_value_t*)tt, world); } if (entry == NULL) { - jl_typemap_t *cache = jl_atomic_load_relaxed(&mt->cache); // XXX: gc root required? - entry = jl_typemap_assoc_exact(cache, F, args, nargs, jl_cachearg_offset(mt), world); + jl_typemap_t *cache = jl_atomic_load_relaxed(&mc->cache); // XXX: gc root required? + entry = jl_typemap_assoc_exact(cache, F, args, nargs, jl_cachearg_offset(), world); if (entry == NULL) { last_alloc = jl_options.malloc_log ? jl_gc_diff_total_bytes() : 0; if (tt == NULL) { @@ -3700,7 +3958,8 @@ STATIC_INLINE jl_method_instance_t *jl_lookup_generic_(jl_value_t *F, jl_value_t else { assert(tt); // cache miss case - mfunc = jl_mt_assoc_by_type(mt, tt, world); + jl_methcache_t *mc = jl_method_table->cache; + mfunc = jl_mt_assoc_by_type(mc, tt, world); if (jl_options.malloc_log) jl_gc_sync_total_bytes(last_alloc); // discard allocation count from compilation if (mfunc == NULL) { @@ -3741,18 +4000,15 @@ JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t *F, jl_value_t **args, uint return _jl_invoke(F, args, nargs, mfunc, world); } -static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, jl_value_t *mt, size_t world, size_t *min_valid, size_t *max_valid) +static jl_method_match_t *_gf_invoke_lookup(jl_value_t *types JL_PROPAGATES_ROOT, jl_methtable_t *mt, size_t world, int cache_result, size_t *min_valid, size_t *max_valid) { jl_value_t *unw = jl_unwrap_unionall((jl_value_t*)types); if (!jl_is_tuple_type(unw)) return NULL; if (jl_tparam0(unw) == jl_bottom_type) return NULL; - if (mt == jl_nothing) - mt = (jl_value_t*)jl_method_table_for(unw); - if (mt == jl_nothing) - mt = NULL; - jl_value_t *matches = ml_matches((jl_methtable_t*)mt, (jl_tupletype_t*)types, 1, 0, 0, world, 1, min_valid, max_valid, NULL); + jl_methcache_t *mc = ((jl_methtable_t*)mt)->cache; + jl_value_t *matches = ml_matches((jl_methtable_t*)mt, mc, (jl_tupletype_t*)types, 1, 0, 0, world, cache_result, min_valid, max_valid, NULL); if (matches == jl_nothing || jl_array_nrows(matches) != 1) return NULL; jl_method_match_t *matc = (jl_method_match_t*)jl_array_ptr_ref(matches, 0); @@ -3764,7 +4020,9 @@ JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, jl_value_t *mt, // Deprecated: Use jl_gf_invoke_lookup_worlds for future development size_t min_valid = 0; size_t max_valid = ~(size_t)0; - jl_method_match_t *matc = _gf_invoke_lookup(types, mt, world, &min_valid, &max_valid); + if (mt == jl_nothing) + mt = (jl_value_t*)jl_method_table; + jl_method_match_t *matc = _gf_invoke_lookup(types, (jl_methtable_t*)mt, world, 1, &min_valid, &max_valid); if (matc == NULL) return jl_nothing; return (jl_value_t*)matc->method; @@ -3773,7 +4031,9 @@ JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup(jl_value_t *types, jl_value_t *mt, JL_DLLEXPORT jl_value_t *jl_gf_invoke_lookup_worlds(jl_value_t *types, jl_value_t *mt, size_t world, size_t *min_world, size_t *max_world) { - jl_method_match_t *matc = _gf_invoke_lookup(types, mt, world, min_world, max_world); + if (mt == jl_nothing) + mt = (jl_value_t*)jl_method_table; + jl_method_match_t *matc = _gf_invoke_lookup(types, (jl_methtable_t*)mt, world, 1, min_world, max_world); if (matc == NULL) return jl_nothing; return (jl_value_t*)matc; @@ -3835,8 +4095,7 @@ jl_value_t *jl_gf_invoke_by_method(jl_method_t *method, jl_value_t *gf, jl_value int sub = jl_subtype_matching((jl_value_t*)tt, (jl_value_t*)method->sig, &tpenv); assert(sub); (void)sub; } - - mfunc = cache_method(NULL, &method->invokes, (jl_value_t*)method, tt, method, 1, 1, ~(size_t)0, tpenv); + mfunc = cache_method(NULL, NULL, &method->invokes, (jl_value_t*)method, tt, method, 1, 1, ~(size_t)0, tpenv); } JL_UNLOCK(&method->writelock); JL_GC_POP(); @@ -3880,8 +4139,8 @@ jl_function_t *jl_new_generic_function_with_supertype(jl_sym_t *name, jl_module_ 0, 0, 0); assert(jl_is_datatype(ftype)); JL_GC_PUSH1(&ftype); - ftype->name->mt->name = name; - jl_gc_wb(ftype->name->mt, name); + ftype->name->singletonname = name; + jl_gc_wb(ftype->name, name); jl_declare_constant_val3(NULL, module, tname, (jl_value_t*)ftype, PARTITION_KIND_CONST, new_world); jl_value_t *f = jl_new_struct(ftype); ftype->instance = f; @@ -3982,7 +4241,7 @@ static int ml_matches_visitor(jl_typemap_entry_t *ml, struct typemap_intersectio static int ml_mtable_visitor(jl_methtable_t *mt, void *closure0) { struct typemap_intersection_env* env = (struct typemap_intersection_env*)closure0; - return jl_typemap_intersection_visitor(jl_atomic_load_relaxed(&mt->defs), jl_cachearg_offset(mt), env); + return jl_typemap_intersection_visitor(jl_atomic_load_relaxed(&mt->defs), 0, env); } // Visit the candidate methods, starting from t[idx], to determine a possible valid sort ordering, @@ -4265,7 +4524,7 @@ static int sort_mlmatches(jl_array_t *t, size_t idx, arraylist_t *visited, array // fully-covers is a Bool indicating subtyping, though temporarily it may be // tri-values, with `nothing` indicating a match that is not a subtype, but // which is dominated by one which is (and thus should be excluded unless ambiguous) -static jl_value_t *ml_matches(jl_methtable_t *mt, +static jl_value_t *ml_matches(jl_methtable_t *mt, jl_methcache_t *mc, jl_tupletype_t *type, int lim, int include_ambiguous, int intersections, size_t world, int cache_result, size_t *min_valid, size_t *max_valid, int *ambig) @@ -4294,10 +4553,10 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, jl_value_t *isect2 = NULL; JL_GC_PUSH6(&env.t, &env.matc, &env.match.env, &search.env, &env.match.ti, &isect2); - if (mt) { + if (mc) { // check the leaf cache if this type can be in there if (((jl_datatype_t*)unw)->isdispatchtuple) { - jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mt->leafcache); + jl_genericmemory_t *leafcache = jl_atomic_load_relaxed(&mc->leafcache); jl_typemap_entry_t *entry = lookup_leafcache(leafcache, (jl_value_t*)type, world); if (entry) { jl_method_instance_t *mi = entry->func.linfo; @@ -4330,49 +4589,43 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, } // then check the full cache if it seems profitable if (((jl_datatype_t*)unw)->isdispatchtuple) { - jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&mt->cache), &search, jl_cachearg_offset(mt), /*subtype*/1); + jl_typemap_entry_t *entry = jl_typemap_assoc_by_type(jl_atomic_load_relaxed(&mc->cache), &search, jl_cachearg_offset(), /*subtype*/1); if (entry && (((jl_datatype_t*)unw)->isdispatchtuple || entry->guardsigs == jl_emptysvec)) { jl_method_instance_t *mi = entry->func.linfo; jl_method_t *meth = mi->def.method; - if (!jl_is_unionall(meth->sig) && ((jl_datatype_t*)unw)->isdispatchtuple) { - env.match.env = jl_emptysvec; - env.match.ti = unw; - } - else { - // this just calls jl_subtype_env (since we know that `type <: meth->sig` by transitivity) - env.match.ti = jl_type_intersection_env((jl_value_t*)type, (jl_value_t*)meth->sig, &env.match.env); - } - env.matc = make_method_match((jl_tupletype_t*)env.match.ti, - env.match.env, meth, FULLY_COVERS); - env.t = (jl_value_t*)jl_alloc_vec_any(1); - jl_array_ptr_set(env.t, 0, env.matc); size_t min_world = jl_atomic_load_relaxed(&entry->min_world); - size_t max_world = jl_atomic_load_relaxed(&entry->max_world); - if (*min_valid < min_world) - *min_valid = min_world; - if (*max_valid > max_world) - *max_valid = max_world; - JL_GC_POP(); - return env.t; + // only return this if it appears min_would is fully computed, otherwise do the full lookup to compute min_world exactly + if (min_world == jl_atomic_load_relaxed(&meth->primary_world)) { + size_t max_world = jl_atomic_load_relaxed(&entry->max_world); + if (!jl_is_unionall(meth->sig) && ((jl_datatype_t*)unw)->isdispatchtuple) { + env.match.env = jl_emptysvec; + env.match.ti = unw; + } + else { + // this just calls jl_subtype_env (since we know that `type <: meth->sig` by transitivity) + env.match.ti = jl_type_intersection_env((jl_value_t*)type, (jl_value_t*)meth->sig, &env.match.env); + } + env.matc = make_method_match((jl_tupletype_t*)env.match.ti, + env.match.env, meth, FULLY_COVERS); + env.t = (jl_value_t*)jl_alloc_vec_any(1); + jl_array_ptr_set(env.t, 0, env.matc); + if (*min_valid < min_world) + *min_valid = min_world; + if (*max_valid > max_world) + *max_valid = max_world; + JL_GC_POP(); + return env.t; + } } } - if (!ml_mtable_visitor(mt, &env.match) && env.t == jl_an_empty_vec_any) { - JL_GC_POP(); - // if we return early without returning methods, set only the min/max valid collected from matching - *min_valid = env.match.min_valid; - *max_valid = env.match.max_valid; - return jl_nothing; - } } - else { - // else: scan everything - if (!jl_foreach_reachable_mtable(ml_mtable_visitor, &env.match) && env.t == jl_an_empty_vec_any) { - JL_GC_POP(); - // if we return early without returning methods, set only the min/max valid collected from matching - *min_valid = env.match.min_valid; - *max_valid = env.match.max_valid; - return jl_nothing; - } + // then scan everything + if (!ml_mtable_visitor(mt, &env.match) && env.t == jl_an_empty_vec_any) { + JL_GC_POP(); + // if we return early without returning methods, set only the min/max valid collected from matching + *min_valid = env.match.min_valid; + *max_valid = env.match.max_valid; + return jl_nothing; } // if we return early, set only the min/max valid collected from matching *min_valid = env.match.min_valid; @@ -4620,14 +4873,13 @@ static jl_value_t *ml_matches(jl_methtable_t *mt, if (env.match.min_valid < min_world) env.match.min_valid = min_world; } - if (mt && cache_result && ((jl_datatype_t*)unw)->isdispatchtuple) { // cache_result parameter keeps this from being recursive + if (mc && cache_result && ((jl_datatype_t*)unw)->isdispatchtuple) { // cache_result parameter keeps this from being recursive if (len == 1 && !has_ambiguity) { env.matc = (jl_method_match_t*)jl_array_ptr_ref(env.t, 0); jl_method_t *meth = env.matc->method; jl_svec_t *tpenv = env.matc->sparams; - JL_LOCK(&mt->writelock); - cache_method(mt, &mt->cache, (jl_value_t*)mt, (jl_tupletype_t*)unw, meth, world, env.match.min_valid, env.match.max_valid, tpenv); - JL_UNLOCK(&mt->writelock); + JL_LOCK(&mc->writelock); + cache_method(mt, mc, &mc->cache, (jl_value_t*)mc, (jl_tupletype_t*)unw, meth, world, env.match.min_valid, env.match.max_valid, tpenv); } } *min_valid = env.match.min_valid; @@ -4693,8 +4945,6 @@ JL_DLLEXPORT void jl_extern_c(jl_value_t *name, jl_value_t *declrt, jl_tupletype jl_error("@ccallable: function object must be a singleton"); // compute / validate return type - if (!jl_is_concrete_type(declrt) || jl_is_kind(declrt)) - jl_error("@ccallable: return type must be concrete and correspond to a C type"); if (!jl_type_mappable_to_c(declrt)) jl_error("@ccallable: return type doesn't correspond to a C type"); @@ -4707,7 +4957,7 @@ JL_DLLEXPORT void jl_extern_c(jl_value_t *name, jl_value_t *declrt, jl_tupletype } // save a record of this so that the alias is generated when we write an object file - jl_method_t *meth = (jl_method_t*)jl_methtable_lookup(ft->name->mt, (jl_value_t*)sigt, jl_atomic_load_acquire(&jl_world_counter)); + jl_method_t *meth = (jl_method_t*)jl_methtable_lookup((jl_value_t*)sigt, jl_atomic_load_acquire(&jl_world_counter)); if (!jl_is_method(meth)) jl_error("@ccallable: could not find requested method"); JL_GC_PUSH1(&meth); diff --git a/src/init.c b/src/init.c index 83cff02872b96..e11b360b5d378 100644 --- a/src/init.c +++ b/src/init.c @@ -23,9 +23,7 @@ #include "julia.h" #include "julia_internal.h" -#define DEFINE_BUILTIN_GLOBALS #include "builtin_proto.h" -#undef DEFINE_BUILTIN_GLOBALS #include "threading.h" #include "julia_assert.h" #include "processor.h" @@ -251,7 +249,7 @@ 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")); + jl_value_t *f = jl_get_global_value(jl_base_module, jl_symbol("_atexit"), ct->world_age); if (f != NULL) { jl_value_t **fargs; JL_GC_PUSHARGS(fargs, 2); @@ -357,13 +355,14 @@ JL_DLLEXPORT void jl_postoutput_hook(void) if (jl_base_module) { jl_task_t *ct = jl_get_current_task(); - jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_postoutput")); + size_t last_age = ct->world_age; + ct->world_age = jl_get_world_counter(); + jl_value_t *f = jl_get_global_value(jl_base_module, jl_symbol("_postoutput"), ct->world_age); if (f != NULL) { JL_TRY { - size_t last_age = ct->world_age; - ct->world_age = jl_get_world_counter(); + JL_GC_PUSH1(&f); jl_apply(&f, 1); - ct->world_age = last_age; + JL_GC_POP(); } JL_CATCH { jl_printf((JL_STREAM*)STDERR_FILENO, "\npostoutput hook threw an error: "); @@ -372,6 +371,7 @@ JL_DLLEXPORT void jl_postoutput_hook(void) jlbacktrace(); // written to STDERR_FILENO } } + ct->world_age = last_age; } return; } @@ -594,7 +594,6 @@ static NOINLINE void _finish_jl_init_(jl_image_buf_t sysimage, jl_ptls_t ptls, j 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(); } @@ -607,7 +606,6 @@ static NOINLINE void _finish_jl_init_(jl_image_buf_t sysimage, jl_ptls_t ptls, j jl_n_threads_per_pool[JL_THREADPOOL_ID_INTERACTIVE] = 0; jl_n_threads_per_pool[JL_THREADPOOL_ID_DEFAULT] = 1; } else { - jl_current_task->world_age = jl_atomic_load_acquire(&jl_world_counter); post_image_load_hooks(); } jl_start_threads(); diff --git a/src/interpreter.c b/src/interpreter.c index 7ab284df78dff..57c3e715ffed6 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -101,9 +101,8 @@ static jl_value_t *eval_methoddef(jl_expr_t *ex, interpreter_state *s) fname = eval_value(args[0], s); jl_methtable_t *mt = NULL; - if (jl_typetagis(fname, jl_methtable_type)) { + if (jl_is_mtable(fname)) mt = (jl_methtable_t*)fname; - } atypes = eval_value(args[1], s); meth = eval_value(args[2], s); jl_method_def((jl_svec_t*)atypes, mt, (jl_code_info_t*)meth, s->module); @@ -162,17 +161,19 @@ static jl_value_t *do_invoke(jl_value_t **args, size_t nargs, interpreter_state return result; } -jl_value_t *jl_eval_global_var(jl_module_t *m, jl_sym_t *e) +// get the global (throwing if null) in the current world +jl_value_t *jl_eval_global_var(jl_module_t *m, jl_sym_t *e, size_t world) { - jl_value_t *v = jl_get_global(m, e); + jl_value_t *v = jl_get_global_value(m, e, world); if (v == NULL) jl_undefined_var_error(e, (jl_value_t*)m); return v; } -jl_value_t *jl_eval_globalref(jl_globalref_t *g) +// get the global (throwing if null) in the current world, optimized +jl_value_t *jl_eval_globalref(jl_globalref_t *g, size_t world) { - jl_value_t *v = jl_get_globalref_value(g); + jl_value_t *v = jl_get_globalref_value(g, world); if (v == NULL) jl_undefined_var_error(g->name, (jl_value_t*)g->mod); return v; @@ -217,10 +218,10 @@ static jl_value_t *eval_value(jl_value_t *e, interpreter_state *s) return jl_quotenode_value(e); } if (jl_is_globalref(e)) { - return jl_eval_globalref((jl_globalref_t*)e); + return jl_eval_globalref((jl_globalref_t*)e, jl_current_task->world_age); } if (jl_is_symbol(e)) { // bare symbols appear in toplevel exprs not wrapped in `thunk` - return jl_eval_global_var(s->module, (jl_sym_t*)e); + return jl_eval_global_var(s->module, (jl_sym_t*)e, jl_current_task->world_age); } if (jl_is_pinode(e)) { jl_value_t *val = eval_value(jl_fieldref_noalloc(e, 0), s); diff --git a/src/ircode.c b/src/ircode.c index ddd5bb29fdfac..9a94c4c62431a 100644 --- a/src/ircode.c +++ b/src/ircode.c @@ -1616,14 +1616,12 @@ void jl_init_serializer(void) jl_densearray_type, jl_function_type, jl_typename_type, jl_builtin_type, jl_task_type, jl_uniontype_type, jl_array_any_type, jl_intrinsic_type, - jl_methtable_type, jl_typemap_level_type, jl_voidpointer_type, jl_newvarnode_type, jl_abstractstring_type, jl_array_symbol_type, jl_anytuple_type, jl_tparam0(jl_anytuple_type), jl_emptytuple_type, jl_array_uint8_type, jl_array_uint32_type, jl_code_info_type, jl_typeofbottom_type, jl_typeofbottom_type->super, jl_namedtuple_type, jl_array_int32_type, jl_uint32_type, jl_uint64_type, - jl_type_type_mt, jl_nonfunction_mt, jl_opaque_closure_type, jl_memory_any_type, jl_memory_uint8_type, diff --git a/src/jitlayers.cpp b/src/jitlayers.cpp index 2e2756dec35f1..3ea95ea42f596 100644 --- a/src/jitlayers.cpp +++ b/src/jitlayers.cpp @@ -666,8 +666,17 @@ static void jl_compile_codeinst_now(jl_code_instance_t *codeinst) if (!decls.specFunctionObject.empty()) NewDefs.push_back(decls.specFunctionObject); } - auto Addrs = jl_ExecutionEngine->findSymbols(NewDefs); - + // Split batches to avoid stack overflow in the JIT linker. + // FIXME: Patch ORCJITs InPlaceTaskDispatcher to not recurse on task dispatches but + // push the tasks to a queue to be drained later. This avoids the stackoverflow caused by recursion + // in the linker when compiling a large number of functions at once. + SmallVector Addrs; + for (size_t i = 0; i < NewDefs.size(); i += 1000) { + auto end = std::min(i + 1000, NewDefs.size()); + SmallVector batch(NewDefs.begin() + i, NewDefs.begin() + end); + auto AddrsBatch = jl_ExecutionEngine->findSymbols(batch); + Addrs.append(AddrsBatch); + } size_t nextaddr = 0; for (auto &this_code : linkready) { auto it = invokenames.find(this_code); diff --git a/src/jl_exported_data.inc b/src/jl_exported_data.inc index df3b9c121837c..76e8368132424 100644 --- a/src/jl_exported_data.inc +++ b/src/jl_exported_data.inc @@ -65,7 +65,7 @@ XX(jl_interconditional_type) \ XX(jl_interrupt_exception) \ XX(jl_intrinsic_type) \ - XX(jl_kwcall_func) \ + XX(jl_kwcall_type) \ XX(jl_libdl_module) \ XX(jl_libdl_dlopen_func) \ XX(jl_lineinfonode_type) \ @@ -91,13 +91,13 @@ XX(jl_method_match_type) \ XX(jl_method_type) \ XX(jl_methtable_type) \ + XX(jl_methcache_type) \ XX(jl_missingcodeerror_type) \ XX(jl_module_type) \ XX(jl_n_threads_per_pool) \ XX(jl_namedtuple_type) \ XX(jl_namedtuple_typename) \ XX(jl_newvarnode_type) \ - XX(jl_nonfunction_mt) \ XX(jl_nothing) \ XX(jl_nothing_type) \ XX(jl_number_type) \ @@ -135,7 +135,6 @@ XX(jl_typename_type) \ XX(jl_typeofbottom_type) \ XX(jl_type_type) \ - XX(jl_type_type_mt) \ XX(jl_type_typename) \ XX(jl_uint16_type) \ XX(jl_uint32_type) \ diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index 60a5256af2b58..e5631ae24849a 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -243,6 +243,7 @@ XX(jl_init_) \ XX(jl_init_options) \ XX(jl_init_restored_module) \ + XX(jl_init_with_image) \ XX(jl_init_with_image_file) \ XX(jl_init_with_image_handle) \ XX(jl_install_sigint_handler) \ diff --git a/src/jl_uv.c b/src/jl_uv.c index 3498952622dce..a21b05433b8c6 100644 --- a/src/jl_uv.c +++ b/src/jl_uv.c @@ -160,10 +160,11 @@ static void jl_uv_call_close_callback(jl_value_t *val) { jl_value_t **args; JL_GC_PUSHARGS(args, 2); // val is "rooted" in the finalizer list only right now - args[0] = jl_get_global(jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), - jl_symbol("_uv_hook_close")); // topmod(typeof(val))._uv_hook_close + args[0] = jl_eval_global_var( + jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), + jl_symbol("_uv_hook_close"), + jl_current_task->world_age); // topmod(typeof(val))._uv_hook_close args[1] = val; - assert(args[0]); jl_apply(args, 2); // TODO: wrap in try-catch? JL_GC_POP(); } diff --git a/src/jlapi.c b/src/jlapi.c index 47d5b84fa5606..6559adc94c1b9 100644 --- a/src/jlapi.c +++ b/src/jlapi.c @@ -50,24 +50,28 @@ JL_DLLEXPORT int jl_is_initialized(void) * @param argc The number of command line arguments. * @param argv Array of command line arguments. */ -JL_DLLEXPORT void jl_set_ARGS(int argc, char **argv) +JL_DLLEXPORT jl_value_t *jl_set_ARGS(int argc, char **argv) { - if (jl_core_module != NULL) { - jl_array_t *args = (jl_array_t*)jl_get_global(jl_core_module, jl_symbol("ARGS")); - if (args == NULL) { - args = jl_alloc_vec_any(0); - JL_GC_PUSH1(&args); + jl_array_t *args = NULL; + jl_value_t *vecstr = NULL; + JL_GC_PUSH2(&args, &vecstr); + if (jl_core_module != NULL) + args = (jl_array_t*)jl_get_global(jl_core_module, jl_symbol("ARGS")); + if (args == NULL) { + vecstr = jl_apply_array_type((jl_value_t*)jl_string_type, 1); + args = jl_alloc_array_1d(vecstr, 0); + if (jl_core_module != NULL) jl_set_const(jl_core_module, jl_symbol("ARGS"), (jl_value_t*)args); - JL_GC_POP(); - } - assert(jl_array_nrows(args) == 0); - jl_array_grow_end(args, argc); - int i; - for (i = 0; i < argc; i++) { - jl_value_t *s = (jl_value_t*)jl_cstr_to_string(argv[i]); - jl_array_ptr_set(args, i, s); - } } + assert(jl_array_nrows(args) == 0); + jl_array_grow_end(args, argc); + int i; + for (i = 0; i < argc; i++) { + jl_value_t *s = (jl_value_t*)jl_cstr_to_string(argv[i]); + jl_array_ptr_set(args, i, s); + } + JL_GC_POP(); + return (jl_value_t*)args; } JL_DLLEXPORT void jl_init_with_image_handle(void *handle) { @@ -116,6 +120,13 @@ JL_DLLEXPORT void jl_init_with_image_file(const char *julia_bindir, jl_exception_clear(); } +// Deprecated function, kept for backward compatibility +JL_DLLEXPORT void jl_init_with_image(const char *julia_bindir, + const char *image_path) +{ + jl_init_with_image_file(julia_bindir, image_path); +} + /** * @brief Initialize the Julia runtime. * @@ -951,12 +962,14 @@ static NOINLINE int true_main(int argc, char *argv[]) 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_function_t*)jl_get_global_value(jl_base_module, jl_symbol("_start"), ct->world_age) : NULL; if (start_client) { int ret = 1; JL_TRY { + JL_GC_PUSH1(&start_client); jl_value_t *r = jl_apply(&start_client, 1); + JL_GC_POP(); 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); diff --git a/src/jloptions.c b/src/jloptions.c index 79afe65ea9bf7..96cce1c8d29a3 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -662,6 +662,9 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) if (nthreadsi == 0) jl_options.nthreadpools = 1; } + } else if (nthreads == 1) { // User asked for 1 thread so don't add an interactive one + jl_options.nthreadpools = 1; + nthreadsi = 0; } jl_options.nthreads = nthreads + nthreadsi; } diff --git a/src/jltypes.c b/src/jltypes.c index 52e707b618211..d30adbd4b72fa 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -2954,7 +2954,9 @@ void jl_init_types(void) JL_GC_DISABLED XX(symbol); jl_simplevector_type = jl_new_uninitialized_datatype(); XX(simplevector); + jl_methcache_type = jl_new_uninitialized_datatype(); jl_methtable_type = jl_new_uninitialized_datatype(); + jl_method_table = jl_new_method_table(jl_symbol("GlobalMethods"), core); jl_emptysvec = (jl_svec_t*)jl_gc_permobj(sizeof(void*), jl_simplevector_type); jl_set_typetagof(jl_emptysvec, jl_simplevector_tag, GC_OLD_MARKED); @@ -2962,14 +2964,10 @@ void jl_init_types(void) JL_GC_DISABLED jl_any_type = (jl_datatype_t*)jl_new_abstracttype((jl_value_t*)jl_symbol("Any"), core, NULL, jl_emptysvec); jl_any_type->super = jl_any_type; - jl_nonfunction_mt = jl_any_type->name->mt; - jl_any_type->name->mt = NULL; jl_datatype_t *type_type = jl_new_abstracttype((jl_value_t*)jl_symbol("Type"), core, jl_any_type, jl_emptysvec); jl_type_type = (jl_unionall_t*)type_type; jl_type_typename = type_type->name; - jl_type_type_mt = jl_new_method_table(jl_type_typename->name, core); - jl_type_typename->mt = jl_type_type_mt; // initialize them. lots of cycles. // NOTE: types are not actually mutable, but we want to ensure they are heap-allocated with stable addresses @@ -3004,56 +3002,59 @@ void jl_init_types(void) JL_GC_DISABLED jl_typename_type->name = jl_new_typename_in(jl_symbol("TypeName"), core, 0, 1); jl_typename_type->name->wrapper = (jl_value_t*)jl_typename_type; - jl_typename_type->name->mt = jl_nonfunction_mt; jl_typename_type->super = jl_any_type; jl_typename_type->parameters = jl_emptysvec; - jl_typename_type->name->n_uninitialized = 17 - 2; - jl_typename_type->name->names = jl_perm_symsvec(17, "name", "module", + jl_typename_type->name->n_uninitialized = 18 - 2; + jl_typename_type->name->names = jl_perm_symsvec(18, "name", "module", "singletonname", "names", "atomicfields", "constfields", "wrapper", "Typeofwrapper", "cache", "linearcache", - "mt", "partial", - "hash", "n_uninitialized", + "partial", "hash", "max_args", "n_uninitialized", "flags", // "abstract", "mutable", "mayinlinealloc", "cache_entry_count", "max_methods", "constprop_heuristic"); - const static uint32_t typename_constfields[1] = { 0b00011101000100111 }; // TODO: put back atomicfields and constfields in this list - const static uint32_t typename_atomicfields[1] = { 0b00100000110000000 }; + const static uint32_t typename_constfields[1] = { 0b000110100001001011 }; // TODO: put back atomicfields and constfields in this list + const static uint32_t typename_atomicfields[1] = { 0b001001001110000000 }; jl_typename_type->name->constfields = typename_constfields; jl_typename_type->name->atomicfields = typename_atomicfields; jl_precompute_memoized_dt(jl_typename_type, 1); - jl_typename_type->types = jl_svec(17, jl_symbol_type, jl_any_type /*jl_module_type*/, - jl_simplevector_type, jl_any_type/*jl_voidpointer_type*/, jl_any_type/*jl_voidpointer_type*/, - jl_type_type, jl_type_type, jl_simplevector_type, jl_simplevector_type, - jl_methtable_type, jl_any_type, - jl_any_type /*jl_long_type*/, jl_any_type /*jl_int32_type*/, + jl_typename_type->types = jl_svec(18, jl_symbol_type, jl_any_type /*jl_module_type*/, jl_symbol_type, + jl_simplevector_type, + jl_any_type/*jl_voidpointer_type*/, jl_any_type/*jl_voidpointer_type*/, + jl_type_type, jl_simplevector_type, jl_simplevector_type, + jl_methcache_type, jl_any_type, + jl_any_type /*jl_long_type*/, + jl_any_type /*jl_int32_type*/, + jl_any_type /*jl_int32_type*/, jl_any_type /*jl_uint8_type*/, jl_any_type /*jl_uint8_type*/, jl_any_type /*jl_uint8_type*/, jl_any_type /*jl_uint8_type*/); + jl_methcache_type->name = jl_new_typename_in(jl_symbol("MethodCache"), core, 0, 1); + jl_methcache_type->name->wrapper = (jl_value_t*)jl_methcache_type; + jl_methcache_type->super = jl_any_type; + jl_methcache_type->parameters = jl_emptysvec; + jl_methcache_type->name->n_uninitialized = 4 - 2; + jl_methcache_type->name->names = jl_perm_symsvec(4, "leafcache", "cache", "", ""); + const static uint32_t methcache_atomicfields[1] = { 0b1111 }; + jl_methcache_type->name->atomicfields = methcache_atomicfields; + jl_precompute_memoized_dt(jl_methcache_type, 1); + jl_methcache_type->types = jl_svec(4, jl_any_type, jl_any_type, jl_any_type/*voidpointer*/, jl_any_type/*int32*/); + jl_methtable_type->name = jl_new_typename_in(jl_symbol("MethodTable"), core, 0, 1); jl_methtable_type->name->wrapper = (jl_value_t*)jl_methtable_type; - jl_methtable_type->name->mt = jl_nonfunction_mt; jl_methtable_type->super = jl_any_type; jl_methtable_type->parameters = jl_emptysvec; - jl_methtable_type->name->n_uninitialized = 11 - 6; - jl_methtable_type->name->names = jl_perm_symsvec(11, "name", "defs", - "leafcache", "cache", "max_args", - "module", "backedges", - "", "", "offs", ""); - const static uint32_t methtable_constfields[1] = { 0x00000020 }; // (1<<5); - const static uint32_t methtable_atomicfields[1] = { 0x0000001e }; // (1<<1)|(1<<2)|(1<<3)|(1<<4); + jl_methtable_type->name->n_uninitialized = 0; + jl_methtable_type->name->names = jl_perm_symsvec(5, "defs", "cache", "name", "module", "backedges"); + const static uint32_t methtable_constfields[1] = { 0b01110 }; + const static uint32_t methtable_atomicfields[1] = { 0b00001 }; jl_methtable_type->name->constfields = methtable_constfields; jl_methtable_type->name->atomicfields = methtable_atomicfields; jl_precompute_memoized_dt(jl_methtable_type, 1); - jl_methtable_type->types = jl_svec(11, jl_symbol_type, jl_any_type, jl_any_type, - jl_any_type, jl_any_type/*jl_long*/, - jl_any_type/*module*/, jl_any_type/*any vector*/, - jl_any_type/*voidpointer*/, jl_any_type/*int32*/, - jl_any_type/*uint8*/, jl_any_type/*uint8*/); + jl_methtable_type->types = jl_svec(5, jl_any_type, jl_methcache_type, jl_symbol_type, jl_any_type /*jl_module_type*/, jl_any_type); jl_symbol_type->name = jl_new_typename_in(jl_symbol("Symbol"), core, 0, 1); jl_symbol_type->name->wrapper = (jl_value_t*)jl_symbol_type; - jl_symbol_type->name->mt = jl_nonfunction_mt; jl_symbol_type->super = jl_any_type; jl_symbol_type->parameters = jl_emptysvec; jl_symbol_type->name->n_uninitialized = 0; @@ -3063,7 +3064,6 @@ void jl_init_types(void) JL_GC_DISABLED jl_simplevector_type->name = jl_new_typename_in(jl_symbol("SimpleVector"), core, 0, 1); jl_simplevector_type->name->wrapper = (jl_value_t*)jl_simplevector_type; - jl_simplevector_type->name->mt = jl_nonfunction_mt; jl_simplevector_type->super = jl_any_type; jl_simplevector_type->parameters = jl_emptysvec; jl_simplevector_type->name->n_uninitialized = 0; @@ -3249,8 +3249,6 @@ void jl_init_types(void) JL_GC_DISABLED jl_function_type = jl_new_abstracttype((jl_value_t*)jl_symbol("Function"), core, jl_any_type, jl_emptysvec); jl_builtin_type = jl_new_abstracttype((jl_value_t*)jl_symbol("Builtin"), core, jl_function_type, jl_emptysvec); - jl_function_type->name->mt = NULL; // subtypes of Function have independent method tables - jl_builtin_type->name->mt = NULL; // so they don't share the Any type table jl_svec_t *tv; @@ -3288,11 +3286,9 @@ void jl_init_types(void) JL_GC_DISABLED jl_perm_symsvec(3, "mod", "name", "binding"), jl_svec(3, jl_module_type, jl_symbol_type, jl_binding_type), jl_emptysvec, 0, 0, 3); + jl_globalref_type->name->mayinlinealloc = 0; // not at all worthwhile, since the only constructor returns a boxed object - core = jl_new_module(jl_symbol("Core"), NULL); - jl_type_typename->mt->module = core; - jl_core_module = core; - core = NULL; // not actually ready yet to use + jl_core_module = jl_new_module(jl_symbol("Core"), NULL); tv = jl_svec1(tvar("Backend")); jl_addrspace_typename = @@ -3376,11 +3372,12 @@ void jl_init_types(void) JL_GC_DISABLED jl_array_uint64_type = jl_apply_type2((jl_value_t*)jl_array_type, (jl_value_t*)jl_uint64_type, jl_box_long(1)); jl_an_empty_vec_any = (jl_value_t*)jl_alloc_vec_any(0); // used internally jl_an_empty_memory_any = (jl_value_t*)jl_alloc_memory_any(0); // used internally - jl_atomic_store_relaxed(&jl_nonfunction_mt->leafcache, (jl_genericmemory_t*)jl_an_empty_memory_any); - jl_atomic_store_relaxed(&jl_type_type_mt->leafcache, (jl_genericmemory_t*)jl_an_empty_memory_any); // finish initializing module Core core = jl_core_module; + jl_method_table->module = core; + jl_atomic_store_relaxed(&jl_method_table->cache->leafcache, (jl_genericmemory_t*)jl_an_empty_memory_any); + jl_method_table->backedges = (jl_genericmemory_t*)jl_an_empty_memory_any; jl_atomic_store_relaxed(&core->bindingkeyset, (jl_genericmemory_t*)jl_an_empty_memory_any); // export own name, so "using Foo" makes "Foo" itself visible jl_set_initial_const(core, core->name, (jl_value_t*)core, 1); @@ -3578,7 +3575,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_module_type, jl_symbol_type, jl_int32_type, - jl_int32_type, + jl_uint8_type, jl_ulong_type, jl_type_type, jl_any_type, // union(jl_simplevector_type, jl_method_instance_type), @@ -3610,33 +3607,35 @@ void jl_init_types(void) JL_GC_DISABLED 0, 1, 10); //const static uint32_t method_constfields[1] = { 0b0 }; // (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<6)|(1<<9)|(1<<10)|(1<<17)|(1<<21)|(1<<22)|(1<<23)|(1<<24)|(1<<25)|(1<<26)|(1<<27)|(1<<28)|(1<<29)|(1<<30); //jl_method_type->name->constfields = method_constfields; - const static uint32_t method_atomicfields[1] = { 0x00000030 }; // (1<<4)|(1<<5) + const static uint32_t method_atomicfields[1] = { 0x10000030 }; // (1<<4)|(1<<5)||(1<<28) jl_method_type->name->atomicfields = method_atomicfields; jl_method_instance_type = jl_new_datatype(jl_symbol("MethodInstance"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(7, + jl_perm_symsvec(8, "def", "specTypes", "sparam_vals", "backedges", "cache", "cache_with_orig", - "flags"), - jl_svec(7, + "flags", + "dispatch_status"), + jl_svec(8, jl_new_struct(jl_uniontype_type, jl_method_type, jl_module_type), jl_any_type, jl_simplevector_type, jl_array_any_type, jl_any_type/*jl_code_instance_type*/, jl_bool_type, - jl_bool_type), + jl_bool_type, + jl_uint8_type), jl_emptysvec, 0, 1, 3); // These fields should be constant, but Serialization wants to mutate them in initialization //const static uint32_t method_instance_constfields[1] = { 0b0000111 }; // fields 1, 2, 3 - const static uint32_t method_instance_atomicfields[1] = { 0b1010000 }; // fields 5, 7 + const static uint32_t method_instance_atomicfields[1] = { 0b11010000 }; // fields 5, 7, 8 //Fields 4 and 5 must be protected by method->write_lock, and thus all operations on jl_method_instance_t are threadsafe. //jl_method_instance_type->name->constfields = method_instance_constfields; jl_method_instance_type->name->atomicfields = method_instance_atomicfields; @@ -3718,13 +3717,6 @@ void jl_init_types(void) JL_GC_DISABLED jl_svec(4, jl_type_type, jl_simplevector_type, jl_method_type, jl_bool_type), jl_emptysvec, 0, 0, 4); - // all Kinds share the Type method table (not the nonfunction one) - jl_unionall_type->name->mt = - jl_uniontype_type->name->mt = - jl_datatype_type->name->mt = - jl_typeofbottom_type->name->mt = - jl_type_type_mt; - jl_intrinsic_type = jl_new_primitivetype((jl_value_t*)jl_symbol("IntrinsicFunction"), core, jl_builtin_type, jl_emptysvec, 32); @@ -3848,23 +3840,20 @@ void jl_init_types(void) JL_GC_DISABLED jl_svecset(jl_datatype_type->types, 6, jl_int32_type); jl_svecset(jl_datatype_type->types, 7, jl_uint16_type); jl_svecset(jl_typename_type->types, 1, jl_module_type); - jl_svecset(jl_typename_type->types, 3, jl_voidpointer_type); jl_svecset(jl_typename_type->types, 4, jl_voidpointer_type); - jl_svecset(jl_typename_type->types, 5, jl_type_type); + jl_svecset(jl_typename_type->types, 5, jl_voidpointer_type); jl_svecset(jl_typename_type->types, 6, jl_type_type); + jl_svecset(jl_typename_type->types, 7, jl_type_type); jl_svecset(jl_typename_type->types, 11, jl_long_type); jl_svecset(jl_typename_type->types, 12, jl_int32_type); - jl_svecset(jl_typename_type->types, 13, jl_uint8_type); + jl_svecset(jl_typename_type->types, 13, jl_int32_type); jl_svecset(jl_typename_type->types, 14, jl_uint8_type); jl_svecset(jl_typename_type->types, 15, jl_uint8_type); jl_svecset(jl_typename_type->types, 16, jl_uint8_type); - jl_svecset(jl_methtable_type->types, 4, jl_long_type); - jl_svecset(jl_methtable_type->types, 5, jl_module_type); - jl_svecset(jl_methtable_type->types, 6, jl_array_any_type); - jl_svecset(jl_methtable_type->types, 7, jl_long_type); // voidpointer - jl_svecset(jl_methtable_type->types, 8, jl_long_type); // uint32_t plus alignment - jl_svecset(jl_methtable_type->types, 9, jl_uint8_type); - jl_svecset(jl_methtable_type->types, 10, jl_uint8_type); + jl_svecset(jl_typename_type->types, 17, jl_uint8_type); + jl_svecset(jl_methcache_type->types, 2, jl_long_type); // voidpointer + jl_svecset(jl_methcache_type->types, 3, jl_long_type); // uint32_t plus alignment + jl_svecset(jl_methtable_type->types, 3, jl_module_type); 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); @@ -3879,6 +3868,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_compute_field_offsets(jl_uniontype_type); jl_compute_field_offsets(jl_tvar_type); jl_compute_field_offsets(jl_methtable_type); + jl_compute_field_offsets(jl_methcache_type); jl_compute_field_offsets(jl_method_instance_type); jl_compute_field_offsets(jl_code_instance_type); jl_compute_field_offsets(jl_unionall_type); @@ -3966,9 +3956,9 @@ void post_boot_hooks(void) jl_trimfailure_type = (jl_datatype_t*)core("TrimFailure"); jl_pair_type = core("Pair"); - jl_kwcall_func = core("kwcall"); - jl_kwcall_mt = ((jl_datatype_t*)jl_typeof(jl_kwcall_func))->name->mt; - jl_atomic_store_relaxed(&jl_kwcall_mt->max_args, 0); + jl_value_t *kwcall_func = core("kwcall"); + jl_kwcall_type = (jl_datatype_t*)jl_typeof(kwcall_func); + jl_atomic_store_relaxed(&jl_kwcall_type->name->max_args, 0); jl_weakref_type = (jl_datatype_t*)core("WeakRef"); jl_vecelement_typename = ((jl_datatype_t*)jl_unwrap_unionall(core("VecElement")))->name; @@ -3976,27 +3966,6 @@ void post_boot_hooks(void) jl_abioverride_type = (jl_datatype_t*)core("ABIOverride"); jl_init_box_caches(); - - // set module field of primitive types - jl_svec_t *bindings = jl_atomic_load_relaxed(&jl_core_module->bindings); - jl_value_t **table = jl_svec_data(bindings); - for (size_t i = 0; i < jl_svec_len(bindings); i++) { - if (table[i] != jl_nothing) { - jl_binding_t *b = (jl_binding_t*)table[i]; - jl_value_t *v = jl_get_binding_value(b); - if (v) { - if (jl_is_unionall(v)) - v = jl_unwrap_unionall(v); - if (jl_is_datatype(v)) { - jl_datatype_t *tt = (jl_datatype_t*)v; - tt->name->module = jl_core_module; - if (tt->name->mt) - tt->name->mt->module = jl_core_module; - } - } - } - } - export_jl_small_typeof(); } diff --git a/src/julia.h b/src/julia.h index 1d7e599302e69..2d8eecbf358f2 100644 --- a/src/julia.h +++ b/src/julia.h @@ -197,6 +197,7 @@ typedef struct _jl_datatype_t jl_tupletype_t; struct _jl_code_instance_t; typedef struct _jl_method_instance_t jl_method_instance_t; typedef struct _jl_globalref_t jl_globalref_t; +typedef struct _jl_typemap_entry_t jl_typemap_entry_t; // TypeMap is an implicitly defined type @@ -331,7 +332,7 @@ typedef struct _jl_method_t { struct _jl_module_t *module; jl_sym_t *file; int32_t line; - _Atomic(int32_t) dispatch_status; // bits defined in staticdata.jl + _Atomic(uint8_t) dispatch_status; // bits defined in staticdata.jl _Atomic(size_t) primary_world; // method's type signature. redundant with TypeMapEntry->specTypes @@ -376,6 +377,7 @@ typedef struct _jl_method_t { uint8_t nospecializeinfer; // bit flags, 0x01 = scanned // 0x02 = added to module scanned list (either from scanning or inference edge) + // 0x04 = Source was invalidated since jl_require_world _Atomic(uint8_t) did_scan_source; // uint8 settings @@ -415,6 +417,7 @@ struct _jl_method_instance_t { // bit 2: The ->backedges field is currently being walked higher up the stack - entries may be deleted, but not moved // bit 3: The ->backedges field was modified and should be compacted when clearing bit 2 _Atomic(uint8_t) flags; + _Atomic(uint8_t) dispatch_status; // bits defined in staticdata.jl }; #define JL_MI_FLAGS_MASK_PRECOMPILED 0x01 #define JL_MI_FLAGS_MASK_DISPATCHED 0x02 @@ -518,6 +521,7 @@ typedef struct { JL_DATA_TYPE jl_sym_t *name; struct _jl_module_t *module; + jl_sym_t *singletonname; // sometimes used for debug printing jl_svec_t *names; // field names const uint32_t *atomicfields; // if any fields are atomic, we record them here const uint32_t *constfields; // if any fields are const, we record them here @@ -527,15 +531,15 @@ typedef struct { _Atomic(jl_value_t*) Typeofwrapper; // cache for Type{wrapper} _Atomic(jl_svec_t*) cache; // sorted array _Atomic(jl_svec_t*) linearcache; // unsorted array - struct _jl_methtable_t *mt; jl_array_t *partial; // incomplete instantiations of this type intptr_t hash; + _Atomic(int32_t) max_args; // max # of non-vararg arguments in a signature with this type as the function int32_t n_uninitialized; // type properties uint8_t abstract:1; uint8_t mutabl:1; uint8_t mayinlinealloc:1; - uint8_t _reserved:5; + uint8_t _unused:5; _Atomic(uint8_t) cache_entry_count; // (approximate counter of TypeMapEntry for heuristics) uint8_t max_methods; // override for inference's max_methods setting (0 = no additional limit or relaxation) uint8_t constprop_heustic; // override for inference's constprop heuristic @@ -837,7 +841,7 @@ struct _jl_globalref_t { }; // one Type-to-Value entry -typedef struct _jl_typemap_entry_t { +struct _jl_typemap_entry_t { JL_DATA_TYPE _Atomic(struct _jl_typemap_entry_t*) next; // invasive linked list jl_tupletype_t *sig; // the type signature for this entry @@ -854,7 +858,7 @@ typedef struct _jl_typemap_entry_t { int8_t isleafsig; // isleaftype(sig) & !any(isType, sig) : unsorted and very fast int8_t issimplesig; // all(isleaftype | isAny | isType | isVararg, sig) : sorted and fast int8_t va; // isVararg(sig) -} jl_typemap_entry_t; +}; // one level in a TypeMap tree (each level splits on a type at a given offset) typedef struct _jl_typemap_level_t { @@ -874,19 +878,21 @@ typedef struct _jl_typemap_level_t { _Atomic(jl_typemap_t*) any; } jl_typemap_level_t; -// contains the TypeMap for one Type -typedef struct _jl_methtable_t { +typedef struct _jl_methcache_t { JL_DATA_TYPE - jl_sym_t *name; // sometimes used for debug printing - _Atomic(jl_typemap_t*) defs; _Atomic(jl_genericmemory_t*) leafcache; _Atomic(jl_typemap_t*) cache; - _Atomic(intptr_t) max_args; // max # of non-vararg arguments in a signature - jl_module_t *module; // sometimes used for debug printing - jl_array_t *backedges; // (sig, caller::CodeInstance) pairs jl_mutex_t writelock; - uint8_t offs; // 0, or 1 to skip splitting typemap on first (function) argument - uint8_t frozen; // whether this accepts adding new methods +} jl_methcache_t; + +// contains global MethodTable +typedef struct _jl_methtable_t { + JL_DATA_TYPE + _Atomic(jl_typemap_t*) defs; + jl_methcache_t *cache; + jl_sym_t *name; // sometimes used for debug printing + jl_module_t *module; // sometimes used for debug printing + jl_genericmemory_t *backedges; // IdDict{top typenames, Vector{uncovered (sig => caller::CodeInstance)}} } jl_methtable_t; typedef struct { @@ -1109,16 +1115,17 @@ extern JL_DLLIMPORT jl_datatype_t *jl_upsilonnode_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_quotenode_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_newvarnode_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_intrinsic_type JL_GLOBALLY_ROOTED; +extern JL_DLLIMPORT jl_datatype_t *jl_methcache_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_methtable_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_typemap_level_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_datatype_t *jl_typemap_entry_type JL_GLOBALLY_ROOTED; +extern JL_DLLIMPORT jl_datatype_t *jl_kwcall_type JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_svec_t *jl_emptysvec JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_emptytuple JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_true JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_false JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_nothing JL_GLOBALLY_ROOTED; -extern JL_DLLIMPORT jl_value_t *jl_kwcall_func JL_GLOBALLY_ROOTED; extern JL_DLLIMPORT jl_value_t *jl_libdl_dlopen_func JL_GLOBALLY_ROOTED; @@ -1475,9 +1482,7 @@ STATIC_INLINE void jl_array_uint32_set(void *a, size_t i, uint32_t x) JL_NOTSAFE #define jl_string_data(s) ((char*)s + sizeof(void*)) #define jl_string_len(s) (*(size_t*)s) -#define jl_gf_ft_mtable(ft) (((jl_datatype_t*)ft)->name->mt) -#define jl_gf_mtable(f) (jl_gf_ft_mtable(jl_typeof(f))) -#define jl_gf_name(f) (jl_gf_mtable(f)->name) +#define jl_gf_name(f) (((jl_datatype_t*)jl_typeof(f))->name->singletonname) // struct type info JL_DLLEXPORT jl_svec_t *jl_compute_fieldtypes(jl_datatype_t *st JL_PROPAGATES_ROOT, void *stack, int cacheable); @@ -1672,6 +1677,7 @@ static inline int jl_field_isconst(jl_datatype_t *st, int i) JL_NOTSAFEPOINT #define jl_is_method(v) jl_typetagis(v,jl_method_type) #define jl_is_module(v) jl_typetagis(v,jl_module_tag<<4) #define jl_is_mtable(v) jl_typetagis(v,jl_methtable_type) +#define jl_is_mcache(v) jl_typetagis(v,jl_methcache_type) #define jl_is_task(v) jl_typetagis(v,jl_task_tag<<4) #define jl_is_string(v) jl_typetagis(v,jl_string_tag<<4) #define jl_is_cpointer(v) jl_is_cpointer_type(jl_typeof(v)) @@ -2113,7 +2119,6 @@ JL_DLLEXPORT jl_value_t *jl_get_existing_strong_gf(jl_binding_t *b JL_PROPAGATES JL_DLLEXPORT int jl_boundp(jl_module_t *m, jl_sym_t *var, int allow_import); 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 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); JL_DLLEXPORT void jl_set_const(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT); @@ -2614,7 +2619,7 @@ uint64_t parse_heap_size_hint(const char *optarg, const char *option_name); // Set julia-level ARGS array according to the arguments provided in // argc/argv -JL_DLLEXPORT void jl_set_ARGS(int argc, char **argv); +JL_DLLEXPORT jl_value_t *jl_set_ARGS(int argc, char **argv); JL_DLLEXPORT int jl_generating_output(void) JL_NOTSAFEPOINT; @@ -2720,12 +2725,7 @@ JL_DLLEXPORT jl_task_t *jl_get_current_task(void) JL_GLOBALLY_ROOTED JL_NOTSAFEP STATIC_INLINE jl_function_t *jl_get_function(jl_module_t *m, const char *name) { - jl_task_t *ct = jl_get_current_task(); - size_t last_world = ct->world_age; - ct->world_age = jl_get_world_counter(); - jl_value_t *r = jl_get_global(m, jl_symbol(name)); - ct->world_age = last_world; - return (jl_function_t*)r; + return (jl_function_t*)jl_get_global(m, jl_symbol(name)); } // TODO: we need to pin the task while using this (set pure bit) diff --git a/src/julia_internal.h b/src/julia_internal.h index 8a4b9d42c4c20..42f77c6a59f72 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -21,6 +21,9 @@ #include #include +#define STR(x) #x +#define XSTR(x) STR(x) + #if !defined(_WIN32) #include #else @@ -385,9 +388,7 @@ static inline void memassign_safe(int hasptr, char *dst, const jl_value_t *src, #define GC_IN_IMAGE 4 // useful constants -extern JL_DLLIMPORT jl_methtable_t *jl_type_type_mt JL_GLOBALLY_ROOTED; -extern JL_DLLIMPORT jl_methtable_t *jl_nonfunction_mt JL_GLOBALLY_ROOTED; -extern jl_methtable_t *jl_kwcall_mt JL_GLOBALLY_ROOTED; +extern jl_methtable_t *jl_method_table JL_GLOBALLY_ROOTED; extern JL_DLLEXPORT jl_method_t *jl_opaque_closure_method JL_GLOBALLY_ROOTED; extern JL_DLLEXPORT _Atomic(size_t) jl_world_counter; extern jl_debuginfo_t *jl_nulldebuginfo JL_GLOBALLY_ROOTED; @@ -676,13 +677,15 @@ typedef union { #define METHOD_SIG_LATEST_WHICH 0b0001 #define METHOD_SIG_LATEST_ONLY 0b0010 #define METHOD_SIG_PRECOMPILE_MANY 0b0100 +#define METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC 0b1000 // indicates there exists some other method that is not more specific than this one +#define METHOD_SIG_PRECOMPILE_HAS_NOTMORESPECIFIC 0b10000 // precompiled version of METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC 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 JL_PROPAGATES_ROOT, 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, uint8_t trim_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( @@ -775,16 +778,11 @@ JL_DLLEXPORT void jl_typeassert(jl_value_t *x, jl_value_t *t); #define JL_CALLABLE(name) \ JL_DLLEXPORT jl_value_t *name(jl_value_t *F, jl_value_t **args, uint32_t nargs) -JL_CALLABLE(jl_f_svec); JL_CALLABLE(jl_f_tuple); -JL_CALLABLE(jl_f_intrinsic_call); -JL_CALLABLE(jl_f_opaque_closure_call); void jl_install_default_signal_handlers(void); void restore_signals(void); void jl_install_thread_signal_handler(jl_ptls_t ptls); -JL_DLLEXPORT jl_fptr_args_t jl_get_builtin_fptr(jl_datatype_t *dt); - extern uv_loop_t *jl_io_loop; JL_DLLEXPORT void jl_uv_flush(uv_stream_t *stream); @@ -809,9 +807,9 @@ int jl_has_concrete_subtype(jl_value_t *typ); jl_tupletype_t *jl_inst_arg_tuple_type(jl_value_t *arg1, jl_value_t **args, size_t nargs, int leaf); jl_tupletype_t *jl_lookup_arg_tuple_type(jl_value_t *arg1 JL_PROPAGATES_ROOT, jl_value_t **args, size_t nargs, int leaf); JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method, jl_tupletype_t *simpletype); -void jl_method_table_activate(jl_methtable_t *mt, jl_typemap_entry_t *newentry); +void jl_method_table_activate(jl_typemap_entry_t *newentry); jl_typemap_entry_t *jl_method_table_add(jl_methtable_t *mt, jl_method_t *method, jl_tupletype_t *simpletype); -jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_args_t fptr) JL_GC_DISABLED; +jl_method_t *jl_mk_builtin_func(jl_datatype_t *dt, jl_sym_t *name, jl_fptr_args_t fptr) JL_GC_DISABLED; int jl_obviously_unequal(jl_value_t *a, jl_value_t *b); int jl_has_bound_typevars(jl_value_t *v, jl_typeenv_t *env) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_array_t *jl_find_free_typevars(jl_value_t *v); @@ -861,8 +859,7 @@ int setonce_bits(jl_datatype_t *rty, char *p, jl_value_t *owner, jl_value_t *rhs 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, 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); +int jl_foreach_reachable_mtable(int (*visit)(jl_methtable_t *mt, void *env), jl_array_t *mod_array, void *env); void jl_init_main_module(void); JL_DLLEXPORT int jl_is_submodule(jl_module_t *child, jl_module_t *parent) JL_NOTSAFEPOINT; jl_array_t *jl_get_loaded_modules(void); @@ -906,7 +903,10 @@ STATIC_INLINE size_t module_usings_max(jl_module_t *m) JL_NOTSAFEPOINT { JL_DLLEXPORT jl_sym_t *jl_module_name(jl_module_t *m) JL_NOTSAFEPOINT; void jl_add_scanned_method(jl_module_t *m, jl_method_t *meth); -jl_value_t *jl_eval_global_var(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *e); +jl_value_t *jl_eval_global_var(jl_module_t *m JL_PROPAGATES_ROOT, jl_sym_t *e, size_t world); +JL_DLLEXPORT jl_value_t *jl_eval_globalref(jl_globalref_t *g, size_t world); +jl_value_t *jl_get_globalref_value(jl_globalref_t *gr, size_t world); +jl_value_t *jl_get_global_value(jl_module_t *m, jl_sym_t *var, size_t world); jl_value_t *jl_interpret_opaque_closure(jl_opaque_closure_t *clos, jl_value_t **args, size_t nargs); jl_value_t *jl_interpret_toplevel_thunk(jl_module_t *m, jl_code_info_t *src); jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_t *e, @@ -931,10 +931,16 @@ jl_datatype_t *jl_nth_argument_datatype(jl_value_t *argtypes JL_PROPAGATES_ROOT, JL_DLLEXPORT jl_value_t *jl_argument_datatype(jl_value_t *argt JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_methtable_t *jl_method_table_for( jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; +JL_DLLEXPORT jl_methcache_t *jl_method_cache_for( + jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; jl_methtable_t *jl_kwmethod_table_for( jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; +jl_methcache_t *jl_kwmethod_cache_for( + jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; JL_DLLEXPORT jl_methtable_t *jl_method_get_table( jl_method_t *method JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; +JL_DLLEXPORT jl_methcache_t *jl_method_get_cache( + jl_method_t *method JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT; JL_DLLEXPORT int jl_pointer_egal(jl_value_t *t); JL_DLLEXPORT jl_value_t *jl_nth_slot_type(jl_value_t *sig JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; @@ -1290,17 +1296,18 @@ JL_DLLEXPORT jl_method_t *jl_new_method_uninit(jl_module_t*); jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, uint8_t default_using_core, uint8_t self_name); jl_module_t *jl_add_standard_imports(jl_module_t *m); JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module); +JL_DLLEXPORT jl_methcache_t *jl_new_method_cache(void); JL_DLLEXPORT jl_method_instance_t *jl_get_specialization1(jl_tupletype_t *types JL_PROPAGATES_ROOT, 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_PROPAGATES_ROOT; 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_value_t *jl_methtable_lookup(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_value_t *type, size_t world); +JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_value_t *type, size_t world) JL_GLOBALLY_ROOTED; 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); jl_method_instance_t *jl_specializations_get_or_insert(jl_method_instance_t *mi_ins JL_PROPAGATES_ROOT); JL_DLLEXPORT void jl_method_instance_add_backedge(jl_method_instance_t *callee, jl_value_t *invokesig, jl_code_instance_t *caller); -JL_DLLEXPORT void jl_method_table_add_backedge(jl_methtable_t *mt, jl_value_t *typ, jl_code_instance_t *caller); +JL_DLLEXPORT void jl_method_table_add_backedge(jl_value_t *typ, jl_code_instance_t *caller); JL_DLLEXPORT void jl_mi_cache_insert(jl_method_instance_t *mi JL_ROOTING_ARGUMENT, jl_code_instance_t *ci JL_ROOTED_ARGUMENT JL_MAYBE_UNROOTED); JL_DLLEXPORT int jl_mi_try_insert(jl_method_instance_t *mi JL_ROOTING_ARGUMENT, diff --git a/src/llvm-codegen-shared.h b/src/llvm-codegen-shared.h index d474fb4f61183..fcdecb365b1c7 100644 --- a/src/llvm-codegen-shared.h +++ b/src/llvm-codegen-shared.h @@ -13,9 +13,6 @@ #include "julia.h" -#define STR(csym) #csym -#define XSTR(csym) STR(csym) - static constexpr std::nullopt_t None = std::nullopt; enum AddressSpace { diff --git a/src/llvm-lower-handlers.cpp b/src/llvm-lower-handlers.cpp index c359bf6c117ce..f67baf26cc372 100644 --- a/src/llvm-lower-handlers.cpp +++ b/src/llvm-lower-handlers.cpp @@ -27,6 +27,9 @@ #include "llvm-codegen-shared.h" #include +#define STR(x) #x +#define XSTR(x) STR(x) + #define DEBUG_TYPE "lower_handlers" #undef DEBUG STATISTIC(MaxExceptionHandlerDepth, "Maximum nesting of exception handlers"); diff --git a/src/llvm-pass-helpers.cpp b/src/llvm-pass-helpers.cpp index 9d415d923ecb6..e596efd94807a 100644 --- a/src/llvm-pass-helpers.cpp +++ b/src/llvm-pass-helpers.cpp @@ -18,6 +18,9 @@ #include "julia_assert.h" #include "llvm-pass-helpers.h" +#define STR(csym) #csym +#define XSTR(csym) STR(csym) + using namespace llvm; JuliaPassContext::JuliaPassContext() diff --git a/src/method.c b/src/method.c index 09d9eae9ad037..a04035086df90 100644 --- a/src/method.c +++ b/src/method.c @@ -10,14 +10,12 @@ #include "julia.h" #include "julia_internal.h" #include "julia_assert.h" +#include "builtin_proto.h" #ifdef __cplusplus extern "C" { #endif -extern jl_value_t *jl_builtin_getfield; -extern jl_value_t *jl_builtin_tuple; -jl_methtable_t *jl_kwcall_mt; jl_method_t *jl_opaque_closure_method; static void check_c_types(const char *where, jl_value_t *rt, jl_value_t *at) @@ -225,7 +223,7 @@ static jl_value_t *resolve_definition_effects(jl_value_t *expr, jl_module_t *mod jl_sym_t *fe_sym = jl_globalref_name(fe); // look at some known called functions jl_binding_t *b = jl_get_binding(fe_mod, fe_sym); - if (jl_get_latest_binding_value_if_const(b) == jl_builtin_tuple) { + if (jl_get_latest_binding_value_if_const(b) == BUILTIN(tuple)) { size_t j; for (j = 1; j < nargs; j++) { if (!jl_is_quotenode(jl_exprarg(e, j))) @@ -611,6 +609,7 @@ JL_DLLEXPORT jl_method_instance_t *jl_new_method_instance_uninit(void) jl_atomic_store_relaxed(&mi->cache, NULL); mi->cache_with_orig = 0; jl_atomic_store_relaxed(&mi->flags, 0); + jl_atomic_store_relaxed(&mi->dispatch_status, 0); return mi; } @@ -804,7 +803,8 @@ JL_DLLEXPORT jl_code_info_t *jl_code_for_staged(jl_method_instance_t *mi, size_t else if (jl_is_mtable(kind)) { assert(i < l); ex = data[i++]; - jl_method_table_add_backedge((jl_methtable_t*)kind, ex, ci); + if ((jl_methtable_t*)kind == jl_method_table) + jl_method_table_add_backedge(ex, ci); } else { assert(i < l); @@ -1155,54 +1155,33 @@ JL_DLLEXPORT jl_value_t *jl_declare_const_gf(jl_module_t *mod, jl_sym_t *name) return gf; } -static jl_methtable_t *nth_methtable(jl_value_t *a JL_PROPAGATES_ROOT, int n) JL_NOTSAFEPOINT -{ - if (jl_is_datatype(a)) { - if (n == 0) { - jl_methtable_t *mt = ((jl_datatype_t*)a)->name->mt; - if (mt != NULL) - return mt; - } - else if (jl_is_tuple_type(a)) { - if (jl_nparams(a) >= n) - return nth_methtable(jl_tparam(a, n - 1), 0); - } - } - else if (jl_is_typevar(a)) { - return nth_methtable(((jl_tvar_t*)a)->ub, n); - } - else if (jl_is_unionall(a)) { - return nth_methtable(((jl_unionall_t*)a)->body, n); - } - else if (jl_is_uniontype(a)) { - jl_uniontype_t *u = (jl_uniontype_t*)a; - jl_methtable_t *m1 = nth_methtable(u->a, n); - if ((jl_value_t*)m1 != jl_nothing) { - jl_methtable_t *m2 = nth_methtable(u->b, n); - if (m1 == m2) - return m1; - } - } - return (jl_methtable_t*)jl_nothing; -} // get the MethodTable for dispatch, or `nothing` if cannot be determined JL_DLLEXPORT jl_methtable_t *jl_method_table_for(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { - return nth_methtable(argtypes, 1); + return jl_method_table; +} + +// get a MethodCache for dispatch +JL_DLLEXPORT jl_methcache_t *jl_method_cache_for(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT +{ + return jl_method_table->cache; } -jl_methtable_t *jl_kwmethod_table_for(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT +jl_methcache_t *jl_kwmethod_cache_for(jl_value_t *argtypes JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { - jl_methtable_t *kwmt = nth_methtable(argtypes, 3); - if ((jl_value_t*)kwmt == jl_nothing) - return NULL; - return kwmt; + return jl_method_table->cache; } JL_DLLEXPORT jl_methtable_t *jl_method_get_table(jl_method_t *method JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT { - return method->external_mt ? (jl_methtable_t*)method->external_mt : jl_method_table_for(method->sig); + return method->external_mt ? (jl_methtable_t*)method->external_mt : jl_method_table; +} + +// get an arbitrary MethodCache for dispatch optimizations of method +JL_DLLEXPORT jl_methcache_t *jl_method_get_cache(jl_method_t *method JL_PROPAGATES_ROOT) JL_NOTSAFEPOINT +{ + return jl_method_get_table(method)->cache; } JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, @@ -1219,25 +1198,29 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, size_t nargs = jl_svec_len(atypes); assert(nargs > 0); int isva = jl_is_vararg(jl_svecref(atypes, nargs - 1)); - if (!jl_is_type(jl_svecref(atypes, 0)) || (isva && nargs == 1)) + jl_value_t *ft = jl_svecref(atypes, 0); + if (!jl_is_type(ft) || (isva && nargs == 1)) jl_error("function type in method definition is not a type"); jl_sym_t *name; jl_method_t *m = NULL; jl_value_t *argtype = NULL; - JL_GC_PUSH3(&f, &m, &argtype); + JL_GC_PUSH4(&ft, &f, &m, &argtype); size_t i, na = jl_svec_len(atypes); argtype = jl_apply_tuple_type(atypes, 1); if (!jl_is_datatype(argtype)) jl_error("invalid type in method definition (Union{})"); - jl_methtable_t *external_mt = mt; if (!mt) - mt = jl_method_table_for(argtype); - if ((jl_value_t*)mt == jl_nothing) - jl_error("Method dispatch is unimplemented currently for this method signature"); - if (mt->frozen) - jl_error("cannot add methods to a builtin function"); + mt = jl_method_table; + jl_methtable_t *external_mt = mt == jl_method_table ? NULL : mt; + + //if (!external_mt) { + // jl_value_t **ttypes = { jl_builtin_type, jl_tparam0(jl_anytuple_type) }; + // jl_value_t *invalidt = jl_apply_tuple_type_v(ttypes, 2); // Tuple{Union{Builtin,OpaqueClosure}, Vararg} + // if (!jl_has_empty_intersection(argtype, invalidt)) + // jl_error("cannot add methods to a builtin function"); + //} assert(jl_is_linenode(functionloc)); jl_sym_t *file = (jl_sym_t*)jl_linenode_file(functionloc); @@ -1246,21 +1229,13 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, int32_t line = jl_linenode_line(functionloc); // TODO: derive our debug name from the syntax instead of the type - jl_methtable_t *kwmt = mt == jl_kwcall_mt ? jl_kwmethod_table_for(argtype) : mt; // if we have a kwcall, try to derive the name from the callee argument method table - name = (kwmt ? kwmt : mt)->name; - if (kwmt == jl_type_type_mt || kwmt == jl_nonfunction_mt || external_mt) { - // our value for `name` is bad, try to guess what the syntax might have had, - // like `jl_static_show_func_sig` might have come up with - jl_datatype_t *dt = jl_nth_argument_datatype(argtype, mt == jl_kwcall_mt ? 3 : 1); - if (dt != NULL) { - name = dt->name->name; - if (jl_is_type_type((jl_value_t*)dt)) { - dt = (jl_datatype_t*)jl_argument_datatype(jl_tparam0(dt)); - if ((jl_value_t*)dt != jl_nothing) { - name = dt->name->name; - } - } + jl_datatype_t *dtname = (jl_datatype_t*)jl_argument_datatype(jl_kwcall_type && ft == (jl_value_t*)jl_kwcall_type && nargs >= 3 ? jl_svecref(atypes, 2) : ft); + name = (jl_value_t*)dtname != jl_nothing ? dtname->name->singletonname : jl_any_type->name->singletonname; + if (jl_is_type_type((jl_value_t*)dtname)) { + dtname = (jl_datatype_t*)jl_argument_datatype(jl_tparam0(dtname)); + if ((jl_value_t*)dtname != jl_nothing) { + name = dtname->name->singletonname; } } @@ -1321,6 +1296,9 @@ JL_DLLEXPORT jl_method_t* jl_method_def(jl_svec_t *argdata, jl_symbol_name(file), line); } + ft = jl_rewrap_unionall(ft, argtype); + if (!external_mt && !jl_has_empty_intersection(ft, (jl_value_t*)jl_builtin_type)) // disallow adding methods to Any, Function, Builtin, and subtypes, or Unions of those + jl_error("cannot add methods to a builtin function"); m = jl_new_method_uninit(module); m->external_mt = (jl_value_t*)external_mt; diff --git a/src/module.c b/src/module.c index 0bfa2148f5465..a792861ca55a9 100644 --- a/src/module.c +++ b/src/module.c @@ -366,7 +366,7 @@ JL_DLLEXPORT jl_binding_partition_t *jl_maybe_reresolve_implicit(jl_binding_t *b JL_DLLEXPORT void jl_update_loaded_bpart(jl_binding_t *b, jl_binding_partition_t *bpart) { - struct implicit_search_resolution resolution = jl_resolve_implicit_import(b, NULL, jl_atomic_load_relaxed(&jl_world_counter), 0); + struct implicit_search_resolution resolution = jl_resolve_implicit_import(b, NULL, jl_atomic_load_acquire(&jl_world_counter), 0); jl_atomic_store_relaxed(&bpart->min_world, resolution.min_world); jl_atomic_store_relaxed(&bpart->max_world, resolution.max_world); bpart->restriction = resolution.binding_or_const; @@ -470,6 +470,25 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_leaf_partitions_value_if_const(jl_bindin return NULL; } +JL_DLLEXPORT size_t jl_binding_backedges_length(jl_binding_t *b) +{ + JL_LOCK(&b->globalref->mod->lock); + size_t len = 0; + if (b->backedges) + len = jl_array_len(b->backedges); + JL_UNLOCK(&b->globalref->mod->lock); + return len; +} + +JL_DLLEXPORT jl_value_t *jl_binding_backedges_getindex(jl_binding_t *b, size_t i) +{ + JL_LOCK(&b->globalref->mod->lock); + assert(b->backedges); + jl_value_t *ret = jl_array_ptr_ref(b->backedges, i-1); + JL_UNLOCK(&b->globalref->mod->lock); + return ret; +} + static jl_module_t *jl_new_module__(jl_sym_t *name, jl_module_t *parent) { jl_task_t *ct = jl_current_task; @@ -482,9 +501,10 @@ static jl_module_t *jl_new_module__(jl_sym_t *name, jl_module_t *parent) m->parent = parent ? parent : m; m->istopmod = 0; m->uuid = uuid_zero; - static unsigned int mcounter; // simple counter backup, in case hrtime is not incrementing + static _Atomic(unsigned int) mcounter; // simple counter backup, in case hrtime is not incrementing + unsigned int count = jl_atomic_fetch_add_relaxed(&mcounter, 1); // TODO: this is used for ir decompression and is liable to hash collisions so use more of the bits - m->build_id.lo = bitmix(jl_hrtime() + (++mcounter), jl_rand()); + m->build_id.lo = bitmix(jl_hrtime() + count, jl_rand()); if (!m->build_id.lo) m->build_id.lo++; // build id 0 is invalid m->build_id.hi = ~(uint64_t)0; @@ -526,7 +546,9 @@ jl_module_t *jl_new_module_(jl_sym_t *name, jl_module_t *parent, uint8_t default { jl_module_t *m = jl_new_module__(name, parent); JL_GC_PUSH1(&m); + JL_LOCK(&world_counter_lock); jl_add_default_names(m, default_using_core, self_name); + JL_UNLOCK(&world_counter_lock); JL_GC_POP(); return m; } @@ -831,11 +853,12 @@ JL_DLLEXPORT jl_binding_t *jl_get_binding_wr(jl_module_t *m JL_PROPAGATES_ROOT, // return module of binding JL_DLLEXPORT jl_module_t *jl_get_module_of_binding(jl_module_t *m, jl_sym_t *var) { + size_t world = jl_current_task->world_age; jl_binding_t *b = jl_get_module_binding(m, var, 1); - jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); - jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age); + jl_binding_partition_t *bpart = jl_get_binding_partition(b, world); + jl_walk_binding_inplace(&b, &bpart, world); if (jl_binding_kind(bpart) == PARTITION_KIND_IMPLICIT_CONST) { - struct implicit_search_resolution resolution = jl_resolve_implicit_import(b, NULL, jl_current_task->world_age, 0); + struct implicit_search_resolution resolution = jl_resolve_implicit_import(b, NULL, world, 0); if (!resolution.debug_only_ultimate_binding) jl_error("Constant binding was imported from multiple modules"); b = resolution.debug_only_ultimate_binding; @@ -845,8 +868,6 @@ JL_DLLEXPORT jl_module_t *jl_get_module_of_binding(jl_module_t *m, jl_sym_t *var static NOINLINE void print_backdate_admonition(jl_binding_t *b) JL_NOTSAFEPOINT { - if (jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) - jl_undefined_var_error(b->globalref->name, (jl_value_t*)b->globalref->mod); jl_safe_printf( "WARNING: Detected access to binding `%s.%s` in a world prior to its definition world.\n" " Julia 1.12 has introduced more strict world age semantics for global bindings.\n" @@ -859,9 +880,13 @@ static NOINLINE void print_backdate_admonition(jl_binding_t *b) JL_NOTSAFEPOINT static inline void check_backdated_binding(jl_binding_t *b, enum jl_partition_kind kind) JL_NOTSAFEPOINT { - if (__unlikely(kind == PARTITION_KIND_BACKDATED_CONST) && - !(jl_atomic_fetch_or_relaxed(&b->flags, BINDING_FLAG_DID_PRINT_BACKDATE_ADMONITION) & BINDING_FLAG_DID_PRINT_BACKDATE_ADMONITION)) { - print_backdate_admonition(b); + if (__unlikely(kind == PARTITION_KIND_BACKDATED_CONST)) { + // We don't want functions that inference executes speculatively to print this warning, so turn those into + // an error for inference purposes. + if (jl_current_task->ptls->in_pure_callback || jl_options.depwarn == JL_OPTIONS_DEPWARN_ERROR) + jl_undefined_var_error(b->globalref->name, (jl_value_t*)b->globalref->mod); + if (!(jl_atomic_fetch_or_relaxed(&b->flags, BINDING_FLAG_DID_PRINT_BACKDATE_ADMONITION) & BINDING_FLAG_DID_PRINT_BACKDATE_ADMONITION)) + print_backdate_admonition(b); } } @@ -885,16 +910,17 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_in_world(jl_binding_t *b, size_t w return jl_atomic_load_relaxed(&b->value); } -JL_DLLEXPORT jl_value_t *jl_get_binding_value_depwarn(jl_binding_t *b) +static jl_value_t *jl_get_binding_value_depwarn(jl_binding_t *b, size_t world) { - 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); if (jl_options.depwarn) { int needs_depwarn = 0; - jl_walk_binding_inplace_depwarn(&b, &bpart, jl_current_task->world_age, &needs_depwarn); + jl_walk_binding_inplace_depwarn(&b, &bpart, world, &needs_depwarn); if (needs_depwarn) jl_binding_deprecation_warning(b); - } else { - jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age); + } + else { + jl_walk_binding_inplace(&b, &bpart, world); } enum jl_partition_kind kind = jl_binding_kind(bpart); if (jl_bkind_is_some_guard(kind)) @@ -907,11 +933,11 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_depwarn(jl_binding_t *b) return jl_atomic_load_relaxed(&b->value); } - JL_DLLEXPORT jl_value_t *jl_get_binding_value_seqcst(jl_binding_t *b) { - jl_binding_partition_t *bpart = jl_get_binding_partition(b, jl_current_task->world_age); - jl_walk_binding_inplace(&b, &bpart, jl_current_task->world_age); + size_t world = jl_current_task->world_age; + jl_binding_partition_t *bpart = jl_get_binding_partition(b, world); + jl_walk_binding_inplace(&b, &bpart, world); enum jl_partition_kind kind = jl_binding_kind(bpart); if (jl_bkind_is_some_guard(kind)) return NULL; @@ -926,7 +952,7 @@ JL_DLLEXPORT jl_value_t *jl_get_binding_value_seqcst(jl_binding_t *b) JL_DLLEXPORT jl_value_t *jl_get_latest_binding_value_if_const(jl_binding_t *b) { // See note below. Note that this is for some deprecated uses, and should not be added to new code. - size_t world = jl_atomic_load_relaxed(&jl_world_counter); + size_t world = jl_atomic_load_acquire(&jl_world_counter); jl_binding_partition_t *bpart = jl_get_binding_partition(b, world); jl_walk_binding_inplace(&b, &bpart, world); enum jl_partition_kind kind = jl_binding_kind(bpart); @@ -1157,14 +1183,14 @@ static void jl_binding_dep_message(jl_binding_t *b) jl_printf(JL_STDERR, " instead."); } else { - jl_methtable_t *mt = jl_gf_mtable(v); - if (mt != NULL) { + jl_typename_t *tn = ((jl_datatype_t*)jl_typeof(v))->name; + if (tn != NULL) { jl_printf(JL_STDERR, ", use "); - if (mt->module != jl_core_module) { - jl_static_show(JL_STDERR, (jl_value_t*)mt->module); + if (tn->module != jl_core_module) { + jl_static_show(JL_STDERR, (jl_value_t*)tn->module); jl_printf(JL_STDERR, "."); } - jl_printf(JL_STDERR, "%s", jl_symbol_name(mt->name)); + jl_printf(JL_STDERR, "%s", jl_symbol_name(tn->singletonname)); jl_printf(JL_STDERR, " instead."); } } @@ -1535,18 +1561,27 @@ 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) +// get the value (or null) in the world +jl_value_t *jl_get_globalref_value(jl_globalref_t *gr, size_t world) { jl_binding_t *b = gr->binding; if (!b) b = jl_get_module_binding(gr->mod, gr->name, 1); - return jl_get_binding_value_depwarn(b); + return jl_get_binding_value_depwarn(b, world); +} + +// get the value (or null) in the world +jl_value_t *jl_get_global_value(jl_module_t *m, jl_sym_t *var, size_t world) +{ + jl_binding_t *b = jl_get_module_binding(m, var, 1); + return jl_get_binding_value_depwarn(b, world); } +// get the global (or null) in the latest world JL_DLLEXPORT jl_value_t *jl_get_global(jl_module_t *m, jl_sym_t *var) { jl_binding_t *b = jl_get_module_binding(m, var, 1); - return jl_get_binding_value_depwarn(b); + return jl_get_binding_value_depwarn(b, jl_atomic_load_acquire(&jl_world_counter)); } JL_DLLEXPORT void jl_set_global(jl_module_t *m JL_ROOTING_ARGUMENT, jl_sym_t *var, jl_value_t *val JL_ROOTED_ARGUMENT) @@ -1603,6 +1638,7 @@ void jl_invalidate_binding_refs(jl_globalref_t *ref, jl_binding_partition_t *inv JL_DLLEXPORT void jl_add_binding_backedge(jl_binding_t *b, jl_value_t *edge) { + JL_LOCK(&b->globalref->mod->lock); if (!b->backedges) { b->backedges = jl_alloc_vec_any(0); jl_gc_wb(b, b->backedges); @@ -1610,9 +1646,11 @@ JL_DLLEXPORT void jl_add_binding_backedge(jl_binding_t *b, jl_value_t *edge) jl_array_ptr_ref(b->backedges, jl_array_len(b->backedges)-1) == edge) { // Optimization: Deduplicate repeated insertion of the same edge (e.g. during // definition of a method that contains many references to the same global) + JL_UNLOCK(&b->globalref->mod->lock); return; } jl_array_ptr_1d_push(b->backedges, edge); + JL_UNLOCK(&b->globalref->mod->lock); } // Called for all GlobalRefs found in lowered code. Adds backedges for cross-module diff --git a/src/precompile.c b/src/precompile.c index c21cf5367fba6..8d4e8495fc4bd 100644 --- a/src/precompile.c +++ b/src/precompile.c @@ -36,27 +36,30 @@ void write_srctext(ios_t *f, jl_array_t *udeps, int64_t srctextpos) { // char*: src text // At the end we write int32(0) as a terminal sentinel. size_t len = jl_array_nrows(udeps); - static jl_value_t *replace_depot_func = NULL; - if (!replace_depot_func) - replace_depot_func = jl_get_global(jl_base_module, jl_symbol("replace_depot_path")); - static jl_value_t *normalize_depots_func = NULL; - if (!normalize_depots_func) - normalize_depots_func = jl_get_global(jl_base_module, jl_symbol("normalize_depots_for_relocation")); ios_t srctext; - jl_value_t *deptuple = NULL, *depots = NULL; - JL_GC_PUSH3(&deptuple, &udeps, &depots); + jl_value_t *replace_depot_func = NULL; + jl_value_t *normalize_depots_func = NULL; + jl_value_t *deptuple = NULL; + jl_value_t *depots = NULL; jl_task_t *ct = jl_current_task; size_t last_age = ct->world_age; ct->world_age = jl_atomic_load_acquire(&jl_world_counter); + JL_GC_PUSH4(&deptuple, &depots, &replace_depot_func, &normalize_depots_func); + replace_depot_func = jl_eval_global_var(jl_base_module, jl_symbol("replace_depot_path"), jl_current_task->world_age); + normalize_depots_func = jl_eval_global_var(jl_base_module, jl_symbol("normalize_depots_for_relocation"), jl_current_task->world_age); depots = jl_apply(&normalize_depots_func, 1); - ct->world_age = last_age; + jl_datatype_t *deptuple_p[5] = {jl_module_type, jl_string_type, jl_uint64_type, jl_uint32_type, jl_float64_type}; + jl_value_t *jl_deptuple_type = jl_apply_tuple_type_v((jl_value_t**)deptuple_p, 5); + JL_GC_PROMISE_ROOTED(jl_deptuple_type); +#define jl_is_deptuple(v) (jl_typeis((v), jl_deptuple_type)) for (size_t i = 0; i < len; i++) { deptuple = jl_array_ptr_ref(udeps, i); - jl_value_t *depmod = jl_fieldref(deptuple, 0); // module + jl_value_t *depmod = jl_fieldref_noalloc(deptuple, 0); // module // Dependencies declared with `include_dependency` are excluded // because these may not be Julia code (and could be huge) + JL_TYPECHK(write_srctext, deptuple, deptuple); if (depmod != (jl_value_t*)jl_main_module) { - jl_value_t *abspath = jl_fieldref(deptuple, 1); // file abspath + jl_value_t *abspath = jl_fieldref_noalloc(deptuple, 1); // file abspath const char *abspathstr = jl_string_data(abspath); if (!abspathstr[0]) continue; @@ -67,17 +70,11 @@ void write_srctext(ios_t *f, jl_array_t *udeps, int64_t srctextpos) { continue; } - jl_value_t **replace_depot_args; - JL_GC_PUSHARGS(replace_depot_args, 3); + jl_value_t *replace_depot_args[3]; replace_depot_args[0] = replace_depot_func; replace_depot_args[1] = abspath; replace_depot_args[2] = depots; - jl_task_t *ct = jl_current_task; - size_t last_age = ct->world_age; - ct->world_age = jl_atomic_load_acquire(&jl_world_counter); jl_value_t *depalias = (jl_value_t*)jl_apply(replace_depot_args, 3); - ct->world_age = last_age; - JL_GC_POP(); size_t slen = jl_string_len(depalias); write_int32(f, slen); @@ -91,6 +88,8 @@ void write_srctext(ios_t *f, jl_array_t *udeps, int64_t srctextpos) { ios_seek_end(f); } } + ct->world_age = last_age; +#undef jl_is_deptuple JL_GC_POP(); } write_int32(f, 0); // mark the end of the source text @@ -140,7 +139,6 @@ JL_DLLEXPORT void jl_write_compiler_output(void) } } - assert(jl_precompile_toplevel_module == NULL); void *native_code = NULL; bool_t emit_native = jl_options.outputo || jl_options.outputbc || jl_options.outputunoptbc || jl_options.outputasm; diff --git a/src/precompile_utils.c b/src/precompile_utils.c index 295f91ad31e67..86bb723443925 100644 --- a/src/precompile_utils.c +++ b/src/precompile_utils.c @@ -159,12 +159,12 @@ static int compile_all_collect_(jl_methtable_t *mt, void *env) return 1; } -static void jl_compile_all_defs(jl_array_t *mis, int all) +static void jl_compile_all_defs(jl_array_t *mis, int all, jl_array_t *mod_array) { jl_array_t *allmeths = jl_alloc_vec_any(0); JL_GC_PUSH1(&allmeths); - jl_foreach_reachable_mtable(compile_all_collect_, allmeths); + jl_foreach_reachable_mtable(compile_all_collect_, mod_array, allmeths); size_t world = jl_atomic_load_acquire(&jl_world_counter); size_t i, l = jl_array_nrows(allmeths); @@ -224,38 +224,53 @@ static int precompile_enq_specialization_(jl_method_instance_t *mi, void *closur return 1; } -static int precompile_enq_all_specializations__(jl_typemap_entry_t *def, void *closure) +struct precompile_enq_all_specializations_env { + jl_array_t *worklist; + jl_array_t *m; +}; + +static int precompile_enq_all_specializations__(jl_typemap_entry_t *def, void *env) { jl_method_t *m = def->func.method; - if (m->external_mt) - return 1; + assert(!m->external_mt); + struct precompile_enq_all_specializations_env *closure = (struct precompile_enq_all_specializations_env*)env; + if (closure->worklist) { + size_t i, l = jl_array_nrows(closure->worklist); + for (i = 0; i < l; i++) { + if (m->module == (jl_module_t*)jl_array_ptr_ref(closure->worklist, i)) + break; + } + if (i == l) + return 1; + } if ((m->name == jl_symbol("__init__") || m->ccallable) && jl_is_dispatch_tupletype(m->sig)) { // ensure `__init__()` and @ccallables get strongly-hinted, specialized, and compiled jl_method_instance_t *mi = jl_specializations_get_linfo(m, m->sig, jl_emptysvec); - jl_array_ptr_1d_push((jl_array_t*)closure, (jl_value_t*)mi); + jl_array_ptr_1d_push(closure->m, (jl_value_t*)mi); } else { jl_value_t *specializations = jl_atomic_load_relaxed(&def->func.method->specializations); if (!jl_is_svec(specializations)) { - precompile_enq_specialization_((jl_method_instance_t*)specializations, closure); + precompile_enq_specialization_((jl_method_instance_t*)specializations, closure->m); } else { size_t i, l = jl_svec_len(specializations); for (i = 0; i < l; i++) { jl_value_t *mi = jl_svecref(specializations, i); if (mi != jl_nothing) - precompile_enq_specialization_((jl_method_instance_t*)mi, closure); + precompile_enq_specialization_((jl_method_instance_t*)mi, closure->m); } } } if (m->ccallable) - jl_array_ptr_1d_push((jl_array_t*)closure, (jl_value_t*)m->ccallable); + jl_array_ptr_1d_push(closure->m, (jl_value_t*)m->ccallable); return 1; } -static int precompile_enq_all_specializations_(jl_methtable_t *mt, void *env) +static int precompile_enq_all_specializations_(jl_array_t *worklist, jl_array_t *env) { - return jl_typemap_visitor(jl_atomic_load_relaxed(&mt->defs), precompile_enq_all_specializations__, env); + struct precompile_enq_all_specializations_env closure = {worklist, env}; + return jl_typemap_visitor(jl_atomic_load_relaxed(&jl_method_table->defs), precompile_enq_all_specializations__, &closure); } static void *jl_precompile_(jl_array_t *m, int external_linkage) @@ -284,13 +299,13 @@ static void *jl_precompile_(jl_array_t *m, int external_linkage) return native_code; } -static void *jl_precompile(int all) +static void *jl_precompile(int all, jl_array_t *mod_array) { // array of MethodInstances and ccallable aliases to include in the output jl_array_t *m = jl_alloc_vec_any(0); JL_GC_PUSH1(&m); - jl_compile_all_defs(m, all); - jl_foreach_reachable_mtable(precompile_enq_all_specializations_, m); + jl_compile_all_defs(m, all, mod_array); + precompile_enq_all_specializations_(NULL, m); void *native_code = jl_precompile_(m, 0); JL_GC_POP(); return native_code; @@ -311,13 +326,8 @@ static void *jl_precompile_worklist(jl_array_t *worklist, jl_array_t *extext_met jl_array_t *m = jl_alloc_vec_any(0); JL_GC_PUSH1(&m); if (!suppress_precompile) { - size_t i, n = jl_array_nrows(worklist); - for (i = 0; i < n; i++) { - jl_module_t *mod = (jl_module_t*)jl_array_ptr_ref(worklist, i); - assert(jl_is_module(mod)); - foreach_mtable_in_module(mod, precompile_enq_all_specializations_, m); - } - n = jl_array_nrows(extext_methods); + precompile_enq_all_specializations_(worklist, m); + size_t i, n = jl_array_nrows(extext_methods); for (i = 0; i < n; i++) { jl_method_t *method = (jl_method_t*)jl_array_ptr_ref(extext_methods, i); assert(jl_is_method(method)); @@ -350,21 +360,15 @@ static void *jl_precompile_worklist(jl_array_t *worklist, jl_array_t *extext_met static int enq_ccallable_entrypoints_(jl_typemap_entry_t *def, void *closure) { jl_method_t *m = def->func.method; - if (m->external_mt) - return 1; + assert(!m->external_mt); if (m->ccallable) jl_add_entrypoint((jl_tupletype_t*)jl_svecref(m->ccallable, 1)); return 1; } -static int enq_ccallable_entrypoints(jl_methtable_t *mt, void *env) -{ - return jl_typemap_visitor(jl_atomic_load_relaxed(&mt->defs), enq_ccallable_entrypoints_, env); -} - JL_DLLEXPORT void jl_add_ccallable_entrypoints(void) { - jl_foreach_reachable_mtable(enq_ccallable_entrypoints, NULL); + jl_typemap_visitor(jl_atomic_load_relaxed(&jl_method_table->defs), enq_ccallable_entrypoints_, NULL); } static void *jl_precompile_trimmed(size_t world) @@ -402,35 +406,39 @@ static void *jl_precompile_trimmed(size_t world) return native_code; } -static void jl_rebuild_methtables(arraylist_t* MIs, htable_t* mtables) +static void jl_rebuild_methtables(arraylist_t *MIs, htable_t *mtables) JL_GC_DISABLED { - size_t i; - for (i = 0; i < MIs->len; i++) { + // Rebuild MethodTable to contain only those methods for which we compiled code. + // This can have significant soundness problems if there previously existed + // any ambiguous methods, but it would probably be pretty hard to do this + // fully correctly (with the necessary inserted guard entries). + htable_t ms; + htable_new(&ms, 0); + for (size_t i = 0; i < MIs->len; i++) { jl_method_instance_t *mi = (jl_method_instance_t*)MIs->items[i]; jl_method_t *m = mi->def.method; + // Check if the method is already in the new table, if not then insert it there + void **inserted = ptrhash_bp(&ms, m); + if (*inserted != HT_NOTFOUND) + continue; + *inserted = (void*)m; jl_methtable_t *old_mt = jl_method_get_table(m); if ((jl_value_t *)old_mt == jl_nothing) continue; - jl_sym_t *name = old_mt->name; if (!ptrhash_has(mtables, old_mt)) - ptrhash_put(mtables, old_mt, jl_new_method_table(name, m->module)); + ptrhash_put(mtables, old_mt, jl_new_method_table(old_mt->name, old_mt->module)); jl_methtable_t *mt = (jl_methtable_t*)ptrhash_get(mtables, old_mt); - size_t world = jl_atomic_load_acquire(&jl_world_counter); - jl_value_t *lookup = jl_methtable_lookup(mt, m->sig, world); - // Check if the method is already in the new table, if not then insert it there - if (lookup == jl_nothing || (jl_method_t*)lookup != m) { - //TODO: should this be a function like unsafe_insert_method? - size_t min_world = jl_atomic_load_relaxed(&m->primary_world); - size_t max_world = ~(size_t)0; - assert(min_world == jl_atomic_load_relaxed(&m->primary_world)); - int dispatch_status = jl_atomic_load_relaxed(&m->dispatch_status); - jl_atomic_store_relaxed(&m->primary_world, ~(size_t)0); - jl_atomic_store_relaxed(&m->dispatch_status, 0); - jl_typemap_entry_t *newentry = jl_method_table_add(mt, m, NULL); - jl_atomic_store_relaxed(&m->primary_world, min_world); - jl_atomic_store_relaxed(&m->dispatch_status, dispatch_status); - jl_atomic_store_relaxed(&newentry->min_world, min_world); - jl_atomic_store_relaxed(&newentry->max_world, max_world); // short-circuit jl_method_table_insert - } + //TODO: should this be a function like unsafe_insert_method, since all that is wanted is the jl_typemap_insert on a copy of the existing entry + size_t min_world = jl_atomic_load_relaxed(&m->primary_world); + size_t max_world = ~(size_t)0; + int dispatch_status = jl_atomic_load_relaxed(&m->dispatch_status); + jl_atomic_store_relaxed(&m->primary_world, ~(size_t)0); + jl_atomic_store_relaxed(&m->dispatch_status, 0); + jl_typemap_entry_t *newentry = jl_method_table_add(mt, m, NULL); + jl_atomic_store_relaxed(&m->primary_world, min_world); + jl_atomic_store_relaxed(&m->dispatch_status, dispatch_status); + jl_atomic_store_relaxed(&newentry->min_world, min_world); + jl_atomic_store_relaxed(&newentry->max_world, max_world); // short-circuit jl_method_table_insert } + htable_free(&ms); } diff --git a/src/processor_arm.cpp b/src/processor_arm.cpp index 66704a718a14d..b73f5c3e4bbac 100644 --- a/src/processor_arm.cpp +++ b/src/processor_arm.cpp @@ -166,9 +166,11 @@ enum class CPU : uint32_t { apple_a14, apple_a15, apple_a16, + apple_a17, apple_m1, apple_m2, apple_m3, + apple_m4, apple_s4, apple_s5, @@ -355,9 +357,11 @@ constexpr auto apple_a13 = armv8_4a_crypto | get_feature_masks(fp16fml, fullfp16 constexpr auto apple_a14 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3); constexpr auto apple_a15 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3, i8mm, bf16); constexpr auto apple_a16 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3, i8mm, bf16); +constexpr auto apple_a17 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3, i8mm, bf16); constexpr auto apple_m1 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3); constexpr auto apple_m2 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3, i8mm, bf16); constexpr auto apple_m3 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3, i8mm, bf16); +constexpr auto apple_m4 = armv8_5a_crypto | get_feature_masks(dotprod,fp16fml, fullfp16, sha3, i8mm, bf16); // Features based on https://github.com/llvm/llvm-project/blob/82507f1798768280cf5d5aab95caaafbc7fe6f47/llvm/include/llvm/Support/AArch64TargetParser.def // and sysctl -a hw.optional constexpr auto apple_s4 = apple_a12; @@ -441,9 +445,11 @@ static constexpr CPUSpec cpus[] = { {"apple-a14", CPU::apple_a14, CPU::apple_a13, 120000, Feature::apple_a14}, {"apple-a15", CPU::apple_a15, CPU::apple_a14, 160000, Feature::apple_a15}, {"apple-a16", CPU::apple_a16, CPU::apple_a14, 160000, Feature::apple_a16}, + {"apple-a17", CPU::apple_a17, CPU::apple_a16, 190000, Feature::apple_a17}, {"apple-m1", CPU::apple_m1, CPU::apple_a14, 130000, Feature::apple_m1}, {"apple-m2", CPU::apple_m2, CPU::apple_m1, 160000, Feature::apple_m2}, {"apple-m3", CPU::apple_m3, CPU::apple_m2, 180000, Feature::apple_m3}, + {"apple-m4", CPU::apple_m4, CPU::apple_m3, 190000, Feature::apple_m4}, {"apple-s4", CPU::apple_s4, CPU::generic, 100000, Feature::apple_s4}, {"apple-s5", CPU::apple_s5, CPU::generic, 100000, Feature::apple_s5}, {"thunderx3t110", CPU::marvell_thunderx3t110, CPU::cavium_thunderx2t99, 110000, @@ -722,6 +728,8 @@ static NOINLINE std::pair> _get_host_cpu() return std::make_pair((uint32_t)CPU::apple_m2, Feature::apple_m2); else if (cpu_name.find("M3") != StringRef ::npos) return std::make_pair((uint32_t)CPU::apple_m3, Feature::apple_m3); + else if (cpu_name.find("M4") != StringRef ::npos) + return std::make_pair((uint32_t)CPU::apple_m4, Feature::apple_m4); else return std::make_pair((uint32_t)CPU::apple_m1, Feature::apple_m1); } @@ -1042,7 +1050,10 @@ static CPU get_cpu_name(CPUID cpuid) default: return CPU::generic; } case 0x61: // 'a': Apple - // https://opensource.apple.com/source/xnu/xnu-7195.141.2/osfmk/arm/cpuid.h.auto.html + // Data here is partially based on these sources: + // https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/arm/cpuid.h + // https://asahilinux.org/docs/hw/soc/soc-codenames/#socs + // https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/AArch64/AArch64Processors.td switch (cpuid.part) { case 0x0: // Swift return CPU::apple_swift; @@ -1067,31 +1078,57 @@ static CPU get_cpu_name(CPUID cpuid) return CPU::apple_a12; case 0xF: // Tempest M9 return CPU::apple_s4; - case 0x12: // Lightning - case 0x13: // Thunder + case 0x12: // H12 Cebu p-Core "Lightning" + case 0x13: // H12 Cebu e-Core "Thunder" return CPU::apple_a13; - case 0x20: // Icestorm - case 0x21: // Firestorm + case 0x20: // H13 Sicily e-Core "Icestorm" + case 0x21: // H13 Sicily p-Core "Firestorm" return CPU::apple_a14; - case 0x22: // Icestorm m1 - case 0x23: // Firestorm m1 - case 0x24: - case 0x25: // From https://github.com/AsahiLinux/m1n1/blob/3b9a71422e45209ef57c563e418f877bf54358be/src/chickens.c#L9 - case 0x28: - case 0x29: + case 0x22: // H13G Tonga e-Core "Icestorm" used in Apple M1 + case 0x23: // H13G Tonga p-Core "Firestorm" used in Apple M1 + case 0x24: // H13J Jade Chop e-Core "Icestorm" used in Apple M1 Pro + case 0x25: // H13J Jade Chop p-Core "Firestorm" used in Apple M1 Pro + case 0x28: // H13J Jade Die e-Core "Icestorm" used in Apple M1 Max / Ultra + case 0x29: // H13J Jade Die p-Core "Firestorm" used in Apple M1 Max / Ultra return CPU::apple_m1; - case 0x30: // Blizzard m2 - case 0x31: // Avalanche m2 - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x38: - case 0x39: + case 0x30: // H14 Ellis e-Core "Blizzard" used in Apple A15 + case 0x31: // H14 Ellis p-Core "Avalanche" used in Apple A15 + return CPU::apple_a15; + case 0x32: // H14G Staten e-Core "Blizzard" used in Apple M2 + case 0x33: // H14G Staten p-Core "Avalanche" used in Apple M2 + case 0x34: // H14S Rhodes Chop e-Core "Blizzard" used in Apple M2 Pro + case 0x35: // H14S Rhodes Chop p-Core "Avalanche" used in Apple M2 Pro + case 0x38: // H14C Rhodes Die e-Core "Blizzard" used in Apple M2 Max / Ultra + case 0x39: // H14C Rhodes Die p-Core "Avalanche" used in Apple M2 Max / Ultra return CPU::apple_m2; - case 0x49: // Everest m3 - case 0x48: // Sawtooth m3 + case 0x40: // H15 Crete e-Core "Sawtooth" used in Apple A16 + case 0x41: // H15 Crete p-Core "Everest" used in Apple A16 + return CPU::apple_a16; + case 0x42: // H15 Ibiza e-Core "Sawtooth" used in Apple M3 + case 0x43: // H15 Ibiza p-Core "Everest" used in Apple M3 + case 0x44: // H15 Lobos e-Core "Sawtooth" used in Apple M3 Pro + case 0x45: // H15 Lobos p-Core "Everest" used in Apple M3 Pro + case 0x49: // H15 Palma e-Core "Sawtooth" used in Apple M3 Max + case 0x48: // H15 Palma p-Core "Everest" used in Apple M3 Max return CPU::apple_m3; + //case 0x46: // M11 e-Core "Sawtooth" used in Apple S9 + //case 0x47: does not exist + //return CPU::apple_s9; + case 0x50: // H15 Coll e-Core "Sawtooth" used in Apple A17 Pro + case 0x51: // H15 Coll p-Core "Everest" used in Apple A17 Pro + return CPU::apple_a17; + case 0x52: // H16G Donan e-Core used in Apple M4 + case 0x53: // H16H Donan p-Core used in Apple M4 + case 0x54: // H16S Brava S e-Core used in Apple M4 Pro + case 0x55: // H16S Brava S p-Core used in Apple M4 Pro + case 0x58: // H16C Brava C e-Core used in Apple M4 Max + case 0x59: // H16C Brava C p-Core used in Apple M4 Max + return CPU::apple_m4; + //case 0x60: // H17P Tahiti e-Core used in Apple A18 Pro + //case 0x61: // H17P Tahiti p-Core used in Apple A18 Pro + //case 0x6a: // H17A Tupai e-Core used in Apple A18 + //case 0x6b: // H17A Tupai p-Core used in Apple A18 + //return CPU::apple_a18; default: return CPU::generic; } case 0x68: // 'h': Huaxintong Semiconductor diff --git a/src/rtutils.c b/src/rtutils.c index 3b71a3ed42b59..e3672ab5d887e 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -673,7 +673,7 @@ JL_DLLEXPORT jl_value_t *jl_argument_datatype(jl_value_t *argt JL_PROPAGATES_ROO static int is_globname_binding(jl_value_t *v, jl_datatype_t *dv) JL_NOTSAFEPOINT { - jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL; + jl_sym_t *globname = dv->name->singletonname; if (globname && dv->name->module) { jl_binding_t *b = jl_get_module_binding(dv->name->module, globname, 0); jl_value_t *bv = jl_get_latest_binding_value_if_resolved_and_const_debug_only(b); @@ -685,7 +685,7 @@ static int is_globname_binding(jl_value_t *v, jl_datatype_t *dv) JL_NOTSAFEPOINT static int is_globfunction(jl_value_t *v, jl_datatype_t *dv, jl_sym_t **globname_out) JL_NOTSAFEPOINT { - jl_sym_t *globname = dv->name->mt != NULL ? dv->name->mt->name : NULL; + jl_sym_t *globname = dv->name->singletonname; *globname_out = globname; if (globname && !strchr(jl_symbol_name(globname), '#') && !strchr(jl_symbol_name(globname), '@')) { return 1; @@ -894,6 +894,9 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt else if (v == (jl_value_t*)jl_methtable_type) { n += jl_printf(out, "Core.MethodTable"); } + else if (v == (jl_value_t*)jl_methcache_type) { + n += jl_printf(out, "Core.MethodCache"); + } else if (v == (jl_value_t*)jl_any_type) { n += jl_printf(out, "Any"); } @@ -1077,6 +1080,9 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt else if (v == jl_nothing || (jl_nothing && (jl_value_t*)vt == jl_typeof(jl_nothing))) { n += jl_printf(out, "nothing"); } + else if (v == (jl_value_t*)jl_method_table) { + n += jl_printf(out, "Core.GlobalMethods"); + } else if (vt == jl_string_type) { n += jl_static_show_string(out, jl_string_data(v), jl_string_len(v), 1, 0); } @@ -1506,10 +1512,8 @@ size_t jl_static_show_func_sig_(JL_STREAM *s, jl_value_t *type, jl_static_show_c return n; } if ((jl_nparams(ftype) == 0 || ftype == ((jl_datatype_t*)ftype)->name->wrapper) && - ((jl_datatype_t*)ftype)->name->mt && - ((jl_datatype_t*)ftype)->name->mt != jl_type_type_mt && - ((jl_datatype_t*)ftype)->name->mt != jl_nonfunction_mt) { - n += jl_static_show_symbol(s, ((jl_datatype_t*)ftype)->name->mt->name); + !jl_is_type_type(ftype) && !jl_is_type_type((jl_value_t*)((jl_datatype_t*)ftype)->super)) { // aka !iskind + n += jl_static_show_symbol(s, ((jl_datatype_t*)ftype)->name->singletonname); } else { n += jl_printf(s, "(::"); @@ -1585,15 +1589,18 @@ JL_DLLEXPORT void jl_test_failure_breakpoint(jl_value_t *v) // logging tools -------------------------------------------------------------- +// DO NOT USE THIS FUNCTION FOR NEW CODE +// The internal should not be doing anything that requires logging, which means most functions would trigger UB if calling this void jl_log(int level, jl_value_t *module, jl_value_t *group, jl_value_t *id, jl_value_t *file, jl_value_t *line, jl_value_t *kwargs, jl_value_t *msg) { - static jl_value_t *logmsg_func = NULL; - if (!logmsg_func && jl_base_module) { - jl_value_t *corelogging = jl_get_global(jl_base_module, jl_symbol("CoreLogging")); + jl_value_t *logmsg_func = NULL; + jl_task_t *ct = jl_current_task; + if (jl_base_module) { + jl_value_t *corelogging = jl_get_global_value(jl_base_module, jl_symbol("CoreLogging"), ct->world_age); if (corelogging && jl_is_module(corelogging)) { - logmsg_func = jl_get_global((jl_module_t*)corelogging, jl_symbol("logmsg_shim")); + logmsg_func = jl_get_global_value((jl_module_t*)corelogging, jl_symbol("logmsg_shim"), ct->world_age); } } if (!logmsg_func) { diff --git a/src/runtime_ccall.cpp b/src/runtime_ccall.cpp index dd5ceb2c6ad90..f3f1632751c87 100644 --- a/src/runtime_ccall.cpp +++ b/src/runtime_ccall.cpp @@ -401,7 +401,7 @@ void *jl_get_abi_converter(jl_task_t *ct, _Atomic(void*) *fptr, _Atomic(size_t) } JL_UNLOCK(&cfun_lock); // next, try to figure out what the target should look like (outside of the lock since this is very slow) - codeinst = mi ? jl_type_infer(mi, world, SOURCE_MODE_ABI) : nullptr; + codeinst = mi ? jl_type_infer(mi, world, SOURCE_MODE_ABI, jl_options.trim) : nullptr; // relock for the remainder of the function JL_LOCK(&cfun_lock); } while (jl_atomic_load_acquire(&jl_world_counter) != world); // restart entirely, since jl_world_counter changed thus jl_get_specialization1 might have changed diff --git a/src/scheduler.c b/src/scheduler.c index 731a0c5146605..b13e4072c7d73 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -329,12 +329,15 @@ void jl_task_wait_empty(void) jl_task_t *ct = jl_current_task; if (jl_atomic_load_relaxed(&ct->tid) == 0 && jl_base_module) { jl_wait_empty_begin(); - jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("wait")); - wait_empty = ct; size_t lastage = ct->world_age; ct->world_age = jl_atomic_load_acquire(&jl_world_counter); - if (f) + jl_value_t *f = jl_get_global_value(jl_base_module, jl_symbol("wait"), ct->world_age); + wait_empty = ct; + if (f) { + JL_GC_PUSH1(&f); jl_apply_generic(f, NULL, 0); + JL_GC_POP(); + } // we are back from jl_task_get_next now ct->world_age = lastage; wait_empty = NULL; diff --git a/src/signals-mach.c b/src/signals-mach.c index 1c4af2cf9d033..4a670547bdfcd 100644 --- a/src/signals-mach.c +++ b/src/signals-mach.c @@ -146,8 +146,6 @@ static void jl_mach_gc_wait(jl_ptls_t ptls2, mach_port_t thread, int16_t tid) static mach_port_t segv_port = 0; -#define STR(x) #x -#define XSTR(x) STR(x) #define HANDLE_MACH_ERROR(msg, retval) \ if (retval != KERN_SUCCESS) { mach_error(msg XSTR(: __FILE__:__LINE__:), (retval)); abort(); } diff --git a/src/staticdata.c b/src/staticdata.c index 1ed933107dd46..88304c1eb6f7f 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -116,228 +116,176 @@ extern "C" { // TODO: put WeakRefs on the weak_refs list during deserialization // TODO: handle finalizers -#define NUM_TAGS 197 +#define NUM_TAGS 151 // 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. -jl_value_t **const*const get_tags(void) { +static void get_tags(jl_value_t **tags[NUM_TAGS]) +{ // Make sure to keep an extra slot at the end to sentinel length - static void * _tags[NUM_TAGS] = {NULL}; - - // Lazyily-initialize this list - if (_tags[0] == NULL) { - unsigned int i = 0; -#define INSERT_TAG(sym) _tags[i++] = &(sym) - // builtin types - INSERT_TAG(jl_any_type); - INSERT_TAG(jl_symbol_type); - INSERT_TAG(jl_ssavalue_type); - INSERT_TAG(jl_datatype_type); - INSERT_TAG(jl_slotnumber_type); - INSERT_TAG(jl_simplevector_type); - INSERT_TAG(jl_array_type); - INSERT_TAG(jl_expr_type); - INSERT_TAG(jl_binding_type); - INSERT_TAG(jl_binding_partition_type); - INSERT_TAG(jl_globalref_type); - INSERT_TAG(jl_string_type); - INSERT_TAG(jl_module_type); - INSERT_TAG(jl_tvar_type); - INSERT_TAG(jl_method_instance_type); - INSERT_TAG(jl_method_type); - INSERT_TAG(jl_code_instance_type); - INSERT_TAG(jl_linenumbernode_type); - INSERT_TAG(jl_lineinfonode_type); - INSERT_TAG(jl_gotonode_type); - INSERT_TAG(jl_quotenode_type); - INSERT_TAG(jl_gotoifnot_type); - INSERT_TAG(jl_enternode_type); - INSERT_TAG(jl_argument_type); - INSERT_TAG(jl_returnnode_type); - INSERT_TAG(jl_const_type); - INSERT_TAG(jl_partial_struct_type); - INSERT_TAG(jl_partial_opaque_type); - INSERT_TAG(jl_interconditional_type); - INSERT_TAG(jl_method_match_type); - INSERT_TAG(jl_pinode_type); - INSERT_TAG(jl_phinode_type); - INSERT_TAG(jl_phicnode_type); - INSERT_TAG(jl_upsilonnode_type); - INSERT_TAG(jl_type_type); - INSERT_TAG(jl_bottom_type); - INSERT_TAG(jl_ref_type); - INSERT_TAG(jl_pointer_type); - INSERT_TAG(jl_llvmpointer_type); - INSERT_TAG(jl_vararg_type); - INSERT_TAG(jl_abstractarray_type); - INSERT_TAG(jl_densearray_type); - INSERT_TAG(jl_nothing_type); - INSERT_TAG(jl_function_type); - INSERT_TAG(jl_typeofbottom_type); - INSERT_TAG(jl_unionall_type); - INSERT_TAG(jl_typename_type); - INSERT_TAG(jl_builtin_type); - INSERT_TAG(jl_code_info_type); - INSERT_TAG(jl_opaque_closure_type); - INSERT_TAG(jl_task_type); - INSERT_TAG(jl_uniontype_type); - INSERT_TAG(jl_abstractstring_type); - INSERT_TAG(jl_array_any_type); - INSERT_TAG(jl_intrinsic_type); - INSERT_TAG(jl_methtable_type); - INSERT_TAG(jl_typemap_level_type); - INSERT_TAG(jl_typemap_entry_type); - INSERT_TAG(jl_voidpointer_type); - INSERT_TAG(jl_uint8pointer_type); - INSERT_TAG(jl_newvarnode_type); - INSERT_TAG(jl_anytuple_type_type); - INSERT_TAG(jl_anytuple_type); - INSERT_TAG(jl_namedtuple_type); - INSERT_TAG(jl_emptytuple_type); - INSERT_TAG(jl_array_symbol_type); - INSERT_TAG(jl_array_uint8_type); - INSERT_TAG(jl_array_uint32_type); - INSERT_TAG(jl_array_int32_type); - INSERT_TAG(jl_array_uint64_type); - INSERT_TAG(jl_int32_type); - INSERT_TAG(jl_int64_type); - INSERT_TAG(jl_bool_type); - INSERT_TAG(jl_uint8_type); - INSERT_TAG(jl_uint16_type); - INSERT_TAG(jl_uint32_type); - INSERT_TAG(jl_uint64_type); - INSERT_TAG(jl_char_type); - INSERT_TAG(jl_weakref_type); - INSERT_TAG(jl_int8_type); - INSERT_TAG(jl_int16_type); - INSERT_TAG(jl_float16_type); - INSERT_TAG(jl_float32_type); - INSERT_TAG(jl_float64_type); - INSERT_TAG(jl_bfloat16_type); - INSERT_TAG(jl_floatingpoint_type); - INSERT_TAG(jl_number_type); - INSERT_TAG(jl_signed_type); - INSERT_TAG(jl_pair_type); - INSERT_TAG(jl_genericmemory_type); - INSERT_TAG(jl_memory_any_type); - INSERT_TAG(jl_memory_uint8_type); - INSERT_TAG(jl_memory_uint16_type); - INSERT_TAG(jl_memory_uint32_type); - INSERT_TAG(jl_memory_uint64_type); - INSERT_TAG(jl_genericmemoryref_type); - INSERT_TAG(jl_memoryref_any_type); - INSERT_TAG(jl_memoryref_uint8_type); - INSERT_TAG(jl_addrspace_type); - 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); - INSERT_TAG(jl_pointer_typename); - INSERT_TAG(jl_llvmpointer_typename); - INSERT_TAG(jl_array_typename); - INSERT_TAG(jl_type_typename); - INSERT_TAG(jl_namedtuple_typename); - INSERT_TAG(jl_vecelement_typename); - INSERT_TAG(jl_opaque_closure_typename); - INSERT_TAG(jl_genericmemory_typename); - INSERT_TAG(jl_genericmemoryref_typename); - - // special exceptions - INSERT_TAG(jl_errorexception_type); - INSERT_TAG(jl_argumenterror_type); - INSERT_TAG(jl_typeerror_type); - INSERT_TAG(jl_methoderror_type); - INSERT_TAG(jl_loaderror_type); - INSERT_TAG(jl_initerror_type); - INSERT_TAG(jl_undefvarerror_type); - INSERT_TAG(jl_fielderror_type); - INSERT_TAG(jl_stackovf_exception); - INSERT_TAG(jl_diverror_exception); - INSERT_TAG(jl_interrupt_exception); - INSERT_TAG(jl_boundserror_type); - INSERT_TAG(jl_memory_exception); - INSERT_TAG(jl_undefref_exception); - INSERT_TAG(jl_readonlymemory_exception); - INSERT_TAG(jl_atomicerror_type); - INSERT_TAG(jl_missingcodeerror_type); - INSERT_TAG(jl_precompilable_error); - INSERT_TAG(jl_trimfailure_type); - - // other special values - INSERT_TAG(jl_emptysvec); - INSERT_TAG(jl_emptytuple); - INSERT_TAG(jl_false); - INSERT_TAG(jl_true); - INSERT_TAG(jl_an_empty_string); - INSERT_TAG(jl_an_empty_vec_any); - INSERT_TAG(jl_an_empty_memory_any); - INSERT_TAG(jl_module_init_order); - INSERT_TAG(jl_core_module); - INSERT_TAG(jl_base_module); - INSERT_TAG(jl_main_module); - INSERT_TAG(jl_top_module); - INSERT_TAG(jl_typeinf_func); - INSERT_TAG(jl_type_type_mt); - INSERT_TAG(jl_nonfunction_mt); - INSERT_TAG(jl_kwcall_mt); - INSERT_TAG(jl_kwcall_func); - INSERT_TAG(jl_opaque_closure_method); - INSERT_TAG(jl_nulldebuginfo); - - // some Core.Builtin Functions that we want to be able to reference: - INSERT_TAG(jl_builtin_throw); - INSERT_TAG(jl_builtin_is); - INSERT_TAG(jl_builtin_typeof); - INSERT_TAG(jl_builtin_sizeof); - INSERT_TAG(jl_builtin_issubtype); - INSERT_TAG(jl_builtin_isa); - INSERT_TAG(jl_builtin_typeassert); - INSERT_TAG(jl_builtin__apply_iterate); - INSERT_TAG(jl_builtin_isdefined); - INSERT_TAG(jl_builtin_nfields); - INSERT_TAG(jl_builtin_tuple); - INSERT_TAG(jl_builtin_svec); - INSERT_TAG(jl_builtin_getfield); - INSERT_TAG(jl_builtin_setfield); - INSERT_TAG(jl_builtin_swapfield); - INSERT_TAG(jl_builtin_modifyfield); - 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); - INSERT_TAG(jl_builtin_memoryrefset); - INSERT_TAG(jl_builtin_memoryref_isassigned); - INSERT_TAG(jl_builtin_memoryrefswap); - INSERT_TAG(jl_builtin_memoryrefmodify); - INSERT_TAG(jl_builtin_memoryrefreplace); - INSERT_TAG(jl_builtin_memoryrefsetonce); - INSERT_TAG(jl_builtin_apply_type); - INSERT_TAG(jl_builtin_applicable); - INSERT_TAG(jl_builtin_invoke); - INSERT_TAG(jl_builtin__expr); - INSERT_TAG(jl_builtin_ifelse); - INSERT_TAG(jl_builtin__typebody); - INSERT_TAG(jl_builtin_donotdelete); - 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); - INSERT_TAG(jl_builtin_setglobalonce); - INSERT_TAG(jl_builtin_current_scope); - // n.b. must update NUM_TAGS when you add something here + unsigned int i = 0; +#define INSERT_TAG(sym) tags[i++] = (jl_value_t**)&(sym) + // builtin types + INSERT_TAG(jl_any_type); + INSERT_TAG(jl_symbol_type); + INSERT_TAG(jl_ssavalue_type); + INSERT_TAG(jl_datatype_type); + INSERT_TAG(jl_slotnumber_type); + INSERT_TAG(jl_simplevector_type); + INSERT_TAG(jl_array_type); + INSERT_TAG(jl_expr_type); + INSERT_TAG(jl_binding_type); + INSERT_TAG(jl_binding_partition_type); + INSERT_TAG(jl_globalref_type); + INSERT_TAG(jl_string_type); + INSERT_TAG(jl_module_type); + INSERT_TAG(jl_tvar_type); + INSERT_TAG(jl_method_instance_type); + INSERT_TAG(jl_method_type); + INSERT_TAG(jl_code_instance_type); + INSERT_TAG(jl_linenumbernode_type); + INSERT_TAG(jl_lineinfonode_type); + INSERT_TAG(jl_gotonode_type); + INSERT_TAG(jl_quotenode_type); + INSERT_TAG(jl_gotoifnot_type); + INSERT_TAG(jl_enternode_type); + INSERT_TAG(jl_argument_type); + INSERT_TAG(jl_returnnode_type); + INSERT_TAG(jl_const_type); + INSERT_TAG(jl_partial_struct_type); + INSERT_TAG(jl_partial_opaque_type); + INSERT_TAG(jl_interconditional_type); + INSERT_TAG(jl_method_match_type); + INSERT_TAG(jl_pinode_type); + INSERT_TAG(jl_phinode_type); + INSERT_TAG(jl_phicnode_type); + INSERT_TAG(jl_upsilonnode_type); + INSERT_TAG(jl_type_type); + INSERT_TAG(jl_bottom_type); + INSERT_TAG(jl_ref_type); + INSERT_TAG(jl_pointer_type); + INSERT_TAG(jl_llvmpointer_type); + INSERT_TAG(jl_vararg_type); + INSERT_TAG(jl_abstractarray_type); + INSERT_TAG(jl_densearray_type); + INSERT_TAG(jl_nothing_type); + INSERT_TAG(jl_function_type); + INSERT_TAG(jl_typeofbottom_type); + INSERT_TAG(jl_unionall_type); + INSERT_TAG(jl_typename_type); + INSERT_TAG(jl_builtin_type); + INSERT_TAG(jl_code_info_type); + INSERT_TAG(jl_opaque_closure_type); + INSERT_TAG(jl_task_type); + INSERT_TAG(jl_uniontype_type); + INSERT_TAG(jl_abstractstring_type); + INSERT_TAG(jl_array_any_type); + INSERT_TAG(jl_intrinsic_type); + INSERT_TAG(jl_methtable_type); + INSERT_TAG(jl_methcache_type); + INSERT_TAG(jl_typemap_level_type); + INSERT_TAG(jl_typemap_entry_type); + INSERT_TAG(jl_voidpointer_type); + INSERT_TAG(jl_uint8pointer_type); + INSERT_TAG(jl_newvarnode_type); + INSERT_TAG(jl_anytuple_type_type); + INSERT_TAG(jl_anytuple_type); + INSERT_TAG(jl_namedtuple_type); + INSERT_TAG(jl_emptytuple_type); + INSERT_TAG(jl_array_symbol_type); + INSERT_TAG(jl_array_uint8_type); + INSERT_TAG(jl_array_uint32_type); + INSERT_TAG(jl_array_int32_type); + INSERT_TAG(jl_array_uint64_type); + INSERT_TAG(jl_int32_type); + INSERT_TAG(jl_int64_type); + INSERT_TAG(jl_bool_type); + INSERT_TAG(jl_uint8_type); + INSERT_TAG(jl_uint16_type); + INSERT_TAG(jl_uint32_type); + INSERT_TAG(jl_uint64_type); + INSERT_TAG(jl_char_type); + INSERT_TAG(jl_weakref_type); + INSERT_TAG(jl_int8_type); + INSERT_TAG(jl_int16_type); + INSERT_TAG(jl_float16_type); + INSERT_TAG(jl_float32_type); + INSERT_TAG(jl_float64_type); + INSERT_TAG(jl_bfloat16_type); + INSERT_TAG(jl_floatingpoint_type); + INSERT_TAG(jl_number_type); + INSERT_TAG(jl_signed_type); + INSERT_TAG(jl_pair_type); + INSERT_TAG(jl_genericmemory_type); + INSERT_TAG(jl_memory_any_type); + INSERT_TAG(jl_memory_uint8_type); + INSERT_TAG(jl_memory_uint16_type); + INSERT_TAG(jl_memory_uint32_type); + INSERT_TAG(jl_memory_uint64_type); + INSERT_TAG(jl_genericmemoryref_type); + INSERT_TAG(jl_memoryref_any_type); + INSERT_TAG(jl_memoryref_uint8_type); + INSERT_TAG(jl_addrspace_type); + INSERT_TAG(jl_addrspace_typename); + INSERT_TAG(jl_addrspacecore_type); + INSERT_TAG(jl_debuginfo_type); + INSERT_TAG(jl_abioverride_type); + INSERT_TAG(jl_kwcall_type); + + // special typenames + INSERT_TAG(jl_tuple_typename); + INSERT_TAG(jl_pointer_typename); + INSERT_TAG(jl_llvmpointer_typename); + INSERT_TAG(jl_array_typename); + INSERT_TAG(jl_type_typename); + INSERT_TAG(jl_namedtuple_typename); + INSERT_TAG(jl_vecelement_typename); + INSERT_TAG(jl_opaque_closure_typename); + INSERT_TAG(jl_genericmemory_typename); + INSERT_TAG(jl_genericmemoryref_typename); + + // special exceptions + INSERT_TAG(jl_errorexception_type); + INSERT_TAG(jl_argumenterror_type); + INSERT_TAG(jl_typeerror_type); + INSERT_TAG(jl_methoderror_type); + INSERT_TAG(jl_loaderror_type); + INSERT_TAG(jl_initerror_type); + INSERT_TAG(jl_undefvarerror_type); + INSERT_TAG(jl_fielderror_type); + INSERT_TAG(jl_stackovf_exception); + INSERT_TAG(jl_diverror_exception); + INSERT_TAG(jl_interrupt_exception); + INSERT_TAG(jl_boundserror_type); + INSERT_TAG(jl_memory_exception); + INSERT_TAG(jl_undefref_exception); + INSERT_TAG(jl_readonlymemory_exception); + INSERT_TAG(jl_atomicerror_type); + INSERT_TAG(jl_missingcodeerror_type); + INSERT_TAG(jl_precompilable_error); + INSERT_TAG(jl_trimfailure_type); + + // other special values + INSERT_TAG(jl_emptysvec); + INSERT_TAG(jl_emptytuple); + INSERT_TAG(jl_false); + INSERT_TAG(jl_true); + INSERT_TAG(jl_an_empty_string); + INSERT_TAG(jl_an_empty_vec_any); + INSERT_TAG(jl_an_empty_memory_any); + INSERT_TAG(jl_module_init_order); + INSERT_TAG(jl_core_module); + INSERT_TAG(jl_base_module); + INSERT_TAG(jl_main_module); + INSERT_TAG(jl_top_module); + INSERT_TAG(jl_typeinf_func); + INSERT_TAG(jl_opaque_closure_method); + INSERT_TAG(jl_nulldebuginfo); + INSERT_TAG(jl_method_table); + // n.b. must update NUM_TAGS when you add something here #undef INSERT_TAG - assert(i == NUM_TAGS - 1); - } - return (jl_value_t**const*const) _tags; + assert(i == NUM_TAGS - 1); + tags[i] = NULL; } // hash of definitions for predefined tagged object @@ -373,12 +321,12 @@ static uintptr_t img_max; // HT_NOTFOUND is a valid integer ID, so we store the integer ids mangled. // This pair of functions mangles/demanges -static size_t from_seroder_entry(void *entry) +static size_t from_seroder_entry(void *entry) JL_NOTSAFEPOINT { return (size_t)((char*)entry - (char*)HT_NOTFOUND - 1); } -static void *to_seroder_entry(size_t idx) +static void *to_seroder_entry(size_t idx) JL_NOTSAFEPOINT { return (void*)((char*)HT_NOTFOUND + 1 + idx); } @@ -386,7 +334,7 @@ static void *to_seroder_entry(size_t idx) static htable_t new_methtables; static size_t precompilation_world; -static int ptr_cmp(const void *l, const void *r) +static int ptr_cmp(const void *l, const void *r) JL_NOTSAFEPOINT { uintptr_t left = *(const uintptr_t*)l; uintptr_t right = *(const uintptr_t*)r; @@ -394,7 +342,7 @@ static int ptr_cmp(const void *l, const void *r) } // Build an eytzinger tree from a sorted array -static int eytzinger(uintptr_t *src, uintptr_t *dest, size_t i, size_t k, size_t n) +static int eytzinger(uintptr_t *src, uintptr_t *dest, size_t i, size_t k, size_t n) JL_NOTSAFEPOINT { if (k <= n) { i = eytzinger(src, dest, i, 2 * k, n); @@ -434,7 +382,7 @@ static size_t eyt_obj_idx(jl_value_t *obj) JL_NOTSAFEPOINT } //used in staticdata.c after we add an image -void rebuild_image_blob_tree(void) +void rebuild_image_blob_tree(void) JL_NOTSAFEPOINT { size_t inc = 1 + jl_linkage_blobs.len - eytzinger_image_tree.len; assert(eytzinger_idxs.len == eytzinger_image_tree.len); @@ -510,33 +458,15 @@ JL_DLLEXPORT jl_value_t *jl_object_top_module(jl_value_t* v) JL_NOTSAFEPOINT } // hash of definitions for predefined function pointers +// (reverse is jl_builtin_f_addrs) static htable_t fptr_to_id; + void *native_functions; // opaque jl_native_code_desc_t blob used for fetching data from LLVM // table of struct field addresses to rewrite during saving static htable_t field_replace; static htable_t bits_replace; -// array of definitions for the predefined function pointers -// (reverse of fptr_to_id) -// This is a manually constructed dual of the fvars array, which would be produced by codegen for Julia code, for C. -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_invokelatest, &jl_f_invoke_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_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, - &jl_f_ifelse, &jl_f__structtype, &jl_f__abstracttype, &jl_f__primitivetype, - &jl_f__typebody, &jl_f__setsuper, &jl_f__equiv_typedef, &jl_f__defaultctors, - &jl_f_opaque_closure_call, &jl_f_donotdelete, &jl_f_compilerbarrier, &jl_f_get_binding_type, - &jl_f_getglobal, &jl_f_setglobal, &jl_f_swapglobal, &jl_f_modifyglobal, &jl_f_replaceglobal, &jl_f_setglobalonce, - &jl_f_finalizer, &jl_f__compute_sparams, &jl_f__svec_ref, - &jl_f_current_scope, - NULL }; typedef struct { ios_t *s; // the main stream @@ -802,7 +732,8 @@ static void jl_queue_module_for_serialization(jl_serializer_state *s, jl_module_ !strcmp(jl_symbol_name(b->globalref->name), "__init__") || // ... or point to Base functions accessed by the runtime (m == jl_base_module && (!strcmp(jl_symbol_name(b->globalref->name), "wait") || - !strcmp(jl_symbol_name(b->globalref->name), "task_done_hook"))))) { + !strcmp(jl_symbol_name(b->globalref->name), "task_done_hook") || + !strcmp(jl_symbol_name(b->globalref->name), "_uv_hook_close"))))) { jl_queue_for_serialization(s, b); } } @@ -869,12 +800,14 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ // we only need 3 specific fields of this (the rest are restored afterward, if valid) // in particular, cache is repopulated by jl_mi_cache_insert for all foreign function, // so must not be present here - record_field_change((jl_value_t**)&mi->backedges, NULL); record_field_change((jl_value_t**)&mi->cache, NULL); } else { assert(!needs_recaching(v, s->query_cache)); } + // Any back-edges will be re-validated and added by staticdata.jl, so + // drop them from the image here + record_field_change((jl_value_t**)&mi->backedges, NULL); // n.b. opaque closures cannot be inspected and relied upon like a // normal method since they can get improperly introduced by generated // functions, so if they appeared at all, we will probably serialize @@ -882,11 +815,19 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ // prevent this from happening, so we do not need to detect that user // error now. } - } - if (jl_is_mtable(v)) { - jl_methtable_t *mt = (jl_methtable_t*)v; - if (jl_options.trim || jl_options.strip_ir) { - record_field_change((jl_value_t**)&mt->backedges, NULL); + // don't recurse into all backedges memory (yet) + jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mi->backedges, 1); + if (backedges) { + assert(!jl_options.trim && !jl_options.strip_ir); + jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1); + size_t i = 0, n = jl_array_nrows(backedges); + while (i < n) { + jl_value_t *invokeTypes; + jl_code_instance_t *caller; + i = get_next_edge((jl_array_t*)backedges, i, &invokeTypes, &caller); + if (invokeTypes) + jl_queue_for_serialization(s, invokeTypes); + } } } if (jl_is_binding(v)) { @@ -899,6 +840,18 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ if (jl_options.trim || jl_options.strip_ir) { record_field_change((jl_value_t**)&b->backedges, NULL); } + else { + // don't recurse into all backedges memory (yet) + jl_value_t *backedges = get_replaceable_field((jl_value_t**)&b->backedges, 1); + if (backedges) { + jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1); + for (size_t i = 0, n = jl_array_nrows(backedges); i < n; i++) { + jl_value_t *b = jl_array_ptr_ref(backedges, i); + if (!jl_is_code_instance(b) && !jl_is_method_instance(b) && !jl_is_method(b)) // otherwise usually a Binding? + jl_queue_for_serialization(s, b); + } + } + } } if (s->incremental && jl_is_globalref(v)) { jl_globalref_t *gr = (jl_globalref_t*)v; @@ -916,6 +869,33 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ assert(!jl_object_in_image((jl_value_t*)tn->wrapper)); } } + if (jl_is_mtable(v)) { + jl_methtable_t *mt = (jl_methtable_t*)v; + // Any back-edges will be re-validated and added by staticdata.jl, so + // drop them from the image here + if (s->incremental || jl_options.trim || jl_options.strip_ir) { + record_field_change((jl_value_t**)&mt->backedges, jl_an_empty_memory_any); + } + else { + // don't recurse into all backedges memory (yet) + jl_value_t *allbackedges = get_replaceable_field((jl_value_t**)&mt->backedges, 1); + jl_queue_for_serialization_(s, allbackedges, 0, 1); + for (size_t i = 0, n = ((jl_genericmemory_t*)allbackedges)->length; i < n; i += 2) { + jl_value_t *tn = jl_genericmemory_ptr_ref(allbackedges, i); + jl_queue_for_serialization(s, tn); + jl_value_t *backedges = jl_genericmemory_ptr_ref(allbackedges, i + 1); + if (backedges && backedges != jl_nothing) { + jl_queue_for_serialization_(s, (jl_value_t*)((jl_array_t*)backedges)->ref.mem, 0, 1); + jl_queue_for_serialization(s, backedges); + for (size_t i = 0, n = jl_array_nrows(backedges); i < n; i += 2) { + jl_value_t *t = jl_array_ptr_ref(backedges, i); + assert(!jl_is_code_instance(t)); + jl_queue_for_serialization(s, t); + } + } + } + } + } 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); @@ -1036,7 +1016,7 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ } } } - else if (jl_typetagis(v, jl_module_tag << 4)) { + else if (jl_is_module(v)) { jl_queue_module_for_serialization(s, (jl_module_t*)v); } else if (layout->nfields > 0) { @@ -1046,15 +1026,21 @@ static void jl_insert_into_serialization_queue(jl_serializer_state *s, jl_value_ if (jl_is_svec(jl_atomic_load_relaxed(&m->specializations))) jl_queue_for_serialization_(s, (jl_value_t*)jl_atomic_load_relaxed(&m->specializations), 0, 1); } - else if (jl_typetagis(v, jl_typename_type)) { - jl_typename_t *tn = (jl_typename_t*)v; - if (tn->mt != NULL && !tn->mt->frozen) { - jl_methtable_t * new_methtable = (jl_methtable_t *)ptrhash_get(&new_methtables, tn->mt); - if (new_methtable != HT_NOTFOUND) - record_field_change((jl_value_t **)&tn->mt, (jl_value_t*)new_methtable); - else - record_field_change((jl_value_t **)&tn->mt, NULL); + else if (jl_is_mtable(v)) { + jl_methtable_t *mt = (jl_methtable_t*)v; + jl_methtable_t *newmt = (jl_methtable_t*)ptrhash_get(&new_methtables, mt); + if (newmt != HT_NOTFOUND) + record_field_change((jl_value_t **)&mt->defs, (jl_value_t*)jl_atomic_load_relaxed(&newmt->defs)); + else + record_field_change((jl_value_t **)&mt->defs, jl_nothing); + } + else if (jl_is_mcache(v)) { + jl_methcache_t *mc = (jl_methcache_t*)v; + jl_value_t *cache = jl_atomic_load_relaxed(&mc->cache); + if (!jl_typetagis(cache, jl_typemap_entry_type) || ((jl_typemap_entry_t*)cache)->sig != jl_tuple_type) { // aka Builtins (maybe sometimes OpaqueClosure too) + record_field_change((jl_value_t **)&mc->cache, jl_nothing); } + record_field_change((jl_value_t **)&mc->leafcache, jl_an_empty_memory_any); } // TODO: prune any partitions and partition data that has been deleted in the current world //else if (jl_is_binding(v)) { @@ -1119,7 +1105,20 @@ static void jl_queue_for_serialization_(jl_serializer_state *s, jl_value_t *v, i if (!jl_needs_serialization(s, v)) return; - jl_value_t *t = jl_typeof(v); + jl_datatype_t *t = (jl_datatype_t*)jl_typeof(v); + // check early from errors, so we have a little bit of contextual state for debugging them + if (t == jl_task_type) { + jl_error("Task cannot be serialized"); + } + if (s->incremental && needs_uniquing(v, s->query_cache) && t == jl_binding_type) { + jl_binding_t *b = (jl_binding_t*)v; + if (b->globalref == NULL) + jl_error("Binding cannot be serialized"); // no way (currently) to recover its identity + } + if (jl_is_foreign_type(t) == 1) { + jl_error("Cannot serialize instances of foreign datatypes"); + } + // Items that require postorder traversal must visit their children prior to insertion into // the worklist/serialization_order (and also before their first use) if (s->incremental && !immediate) { @@ -1202,7 +1201,8 @@ static void write_pointer(ios_t *s) JL_NOTSAFEPOINT } // Records the buildid holding `v` and returns the tagged offset within the corresponding image -static uintptr_t add_external_linkage(jl_serializer_state *s, jl_value_t *v, jl_array_t *link_ids) { +static uintptr_t add_external_linkage(jl_serializer_state *s, jl_value_t *v, jl_array_t *link_ids) JL_GC_DISABLED +{ size_t i = external_blob_index(v); if (i < n_linkage_blobs()) { // We found the sysimg/pkg that this item links against @@ -1231,7 +1231,7 @@ static uintptr_t add_external_linkage(jl_serializer_state *s, jl_value_t *v, jl_ // but symbols, small integers, and a couple of special items (`nothing` and the root Task) // have special handling. #define backref_id(s, v, link_ids) _backref_id(s, (jl_value_t*)(v), link_ids) -static uintptr_t _backref_id(jl_serializer_state *s, jl_value_t *v, jl_array_t *link_ids) JL_NOTSAFEPOINT +static uintptr_t _backref_id(jl_serializer_state *s, jl_value_t *v, jl_array_t *link_ids) JL_GC_DISABLED { assert(v != NULL && "cannot get backref to NULL object"); if (jl_is_symbol(v)) { @@ -1444,7 +1444,7 @@ static void record_memoryrefs_inside(jl_serializer_state *s, jl_datatype_t *t, s } } -static void record_gvars(jl_serializer_state *s, arraylist_t *globals) JL_NOTSAFEPOINT +static void record_gvars(jl_serializer_state *s, arraylist_t *globals) JL_GC_DISABLED { for (size_t i = 0; i < globals->len; i++) jl_queue_for_serialization(s, globals->items[i]); @@ -1526,8 +1526,6 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED if (needs_uniquing(v, s->query_cache)) { if (jl_is_binding(v)) { jl_binding_t *b = (jl_binding_t*)v; - if (b->globalref == NULL) - jl_error("Binding cannot be serialized"); // no way (currently) to recover its identity write_pointerfield(s, (jl_value_t*)b->globalref->mod); write_pointerfield(s, (jl_value_t*)b->globalref->name); continue; @@ -1692,7 +1690,7 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED jl_write_module(s, item, (jl_module_t*)v); } else if (jl_typetagis(v, jl_task_tag << 4)) { - jl_error("Task cannot be serialized"); + abort(); // unreachable } else if (jl_is_svec(v)) { assert(f == s->s); @@ -1708,7 +1706,7 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED write_uint8(f, '\0'); // null-terminated strings for easier C-compatibility } else if (jl_is_foreign_type(t) == 1) { - jl_error("Cannot serialize instances of foreign datatypes"); + abort(); // unreachable } else if (jl_datatype_nfields(t) == 0) { // The object has no fields, so we just snapshot its byte representation @@ -1836,7 +1834,12 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED if (jl_atomic_load_relaxed(&newm->primary_world) > 1) { jl_atomic_store_relaxed(&newm->primary_world, ~(size_t)0); // min-world int dispatch_status = jl_atomic_load_relaxed(&newm->dispatch_status); - jl_atomic_store_relaxed(&newm->dispatch_status, dispatch_status & METHOD_SIG_LATEST_ONLY ? 0 : METHOD_SIG_PRECOMPILE_MANY); + int new_dispatch_status = 0; + if (!(dispatch_status & METHOD_SIG_LATEST_ONLY)) + new_dispatch_status |= METHOD_SIG_PRECOMPILE_MANY; + if (dispatch_status & METHOD_SIG_LATEST_HAS_NOTMORESPECIFIC) + new_dispatch_status |= METHOD_SIG_PRECOMPILE_HAS_NOTMORESPECIFIC; + jl_atomic_store_relaxed(&newm->dispatch_status, new_dispatch_status); arraylist_push(&s->fixup_objs, (void*)reloc_offset); } } @@ -1848,6 +1851,9 @@ static void jl_write_values(jl_serializer_state *s) JL_GC_DISABLED assert(f == s->s); jl_method_instance_t *newmi = (jl_method_instance_t*)&f->buf[reloc_offset]; jl_atomic_store_relaxed(&newmi->flags, 0); + if (s->incremental) { + jl_atomic_store_relaxed(&newmi->dispatch_status, 0); + } } else if (jl_is_code_instance(v)) { assert(f == s->s); @@ -2081,7 +2087,7 @@ static uintptr_t get_reloc_for_item(uintptr_t reloc_item, size_t reloc_offset) case FunctionRef: if (offset & BuiltinFunctionTag) { offset &= ~BuiltinFunctionTag; - assert(offset < sizeof(id_to_fptrs) / sizeof(*id_to_fptrs) && "unknown function pointer id"); + assert(offset < jl_n_builtins && "unknown function pointer id"); } else { assert(offset < JL_API_MAX && "unknown function pointer id"); @@ -2136,8 +2142,8 @@ static inline uintptr_t get_item_for_reloc(jl_serializer_state *s, uintptr_t bas case FunctionRef: if (offset & BuiltinFunctionTag) { offset &= ~BuiltinFunctionTag; - assert(offset < sizeof(id_to_fptrs) / sizeof(*id_to_fptrs) && "unknown function pointer ID"); - return (uintptr_t)id_to_fptrs[offset]; + assert(offset < jl_n_builtins && "unknown function pointer ID"); + return (uintptr_t)jl_builtin_f_addrs[offset]; } switch ((jl_callingconv_t)offset) { case JL_API_BOXED: @@ -2350,7 +2356,7 @@ void gc_sweep_sysimg(void) // the image proper. For example, new methods added to external callables require // insertion into the appropriate method table. #define jl_write_value(s, v) _jl_write_value((s), (jl_value_t*)(v)) -static void _jl_write_value(jl_serializer_state *s, jl_value_t *v) +static void _jl_write_value(jl_serializer_state *s, jl_value_t *v) JL_GC_DISABLED { if (v == NULL) { write_reloc_t(s->s, 0); @@ -2452,7 +2458,7 @@ static void jl_update_all_fptrs(jl_serializer_state *s, jl_image_t *image) jl_register_fptrs(image->base, &fvars, linfos, img_fvars_max); } -static uint32_t write_gvars(jl_serializer_state *s, arraylist_t *globals, arraylist_t *external_fns) JL_NOTSAFEPOINT +static uint32_t write_gvars(jl_serializer_state *s, arraylist_t *globals, arraylist_t *external_fns) JL_GC_DISABLED { size_t len = globals->len + external_fns->len; ios_ensureroom(s->gvar_record, len * sizeof(reloc_t)); @@ -2567,6 +2573,59 @@ static void jl_prune_type_cache_linear(jl_svec_t *cache) jl_svecset(cache, ins++, jl_nothing); } +static void jl_prune_mi_backedges(jl_array_t *backedges) +{ + if (backedges == NULL) + return; + size_t i = 0, ins = 0, n = jl_array_nrows(backedges); + while (i < n) { + jl_value_t *invokeTypes; + jl_code_instance_t *caller; + i = get_next_edge(backedges, i, &invokeTypes, &caller); + if (ptrhash_get(&serialization_order, caller) != HT_NOTFOUND) + ins = set_next_edge(backedges, ins, invokeTypes, caller); + } + jl_array_del_end(backedges, n - ins); +} + +static void jl_prune_tn_backedges(jl_array_t *backedges) +{ + size_t i = 0, ins = 0, n = jl_array_nrows(backedges); + for (i = 1; i < n; i += 2) { + jl_value_t *ci = jl_array_ptr_ref(backedges, i); + if (ptrhash_get(&serialization_order, ci) != HT_NOTFOUND) { + jl_array_ptr_set(backedges, ins++, jl_array_ptr_ref(backedges, i - 1)); + jl_array_ptr_set(backedges, ins++, ci); + } + } + jl_array_del_end(backedges, n - ins); +} + +static void jl_prune_mt_backedges(jl_genericmemory_t *allbackedges) +{ + for (size_t i = 0, n = allbackedges->length; i < n; i += 2) { + jl_value_t *tn = jl_genericmemory_ptr_ref(allbackedges, i); + jl_value_t *backedges = jl_genericmemory_ptr_ref(allbackedges, i + 1); + if (tn && tn != jl_nothing && backedges) + jl_prune_tn_backedges((jl_array_t*)backedges); + } +} + +static void jl_prune_binding_backedges(jl_array_t *backedges) +{ + if (backedges == NULL) + return; + size_t i = 0, ins = 0, n = jl_array_nrows(backedges); + for (i = 0; i < n; i++) { + jl_value_t *b = jl_array_ptr_ref(backedges, i); + if (ptrhash_get(&serialization_order, b) != HT_NOTFOUND) { + jl_array_ptr_set(backedges, ins, b); + ins++; + } + } + jl_array_del_end(backedges, n - ins); +} + uint_t bindingkey_hash(size_t idx, jl_value_t *data); @@ -2712,7 +2771,7 @@ static int strip_all_codeinfos__(jl_typemap_entry_t *def, void *_env) JL_GC_PUSH1(&slotnames); int tostrip = jl_array_len(slotnames); // for keyword methods, strip only nargs to keep the keyword names at the end for reflection - if (jl_tparam0(jl_unwrap_unionall(m->sig)) == jl_typeof(jl_kwcall_func)) + if (jl_tparam0(jl_unwrap_unionall(m->sig)) == (jl_value_t*)jl_kwcall_type) tostrip = m->nargs; strip_slotnames(slotnames, tostrip); m->slot_syms = jl_compress_argnames(slotnames); @@ -2744,14 +2803,14 @@ static int strip_all_codeinfos__(jl_typemap_entry_t *def, void *_env) return 1; } -static int strip_all_codeinfos_(jl_methtable_t *mt, void *_env) +static int strip_all_codeinfos_mt(jl_methtable_t *mt, void *_env) { return jl_typemap_visitor(jl_atomic_load_relaxed(&mt->defs), strip_all_codeinfos__, NULL); } -static void jl_strip_all_codeinfos(void) +static void jl_strip_all_codeinfos(jl_array_t *mod_array) { - jl_foreach_reachable_mtable(strip_all_codeinfos_, NULL); + jl_foreach_reachable_mtable(strip_all_codeinfos_mt, mod_array, NULL); } static int strip_module(jl_module_t *m, jl_sym_t *docmeta_sym) @@ -2956,15 +3015,7 @@ static void jl_prepare_serialization_data(jl_array_t *mod_array, jl_array_t *new *extext_methods = jl_alloc_vec_any(0); internal_methods = jl_alloc_vec_any(0); JL_GC_PUSH1(&internal_methods); - jl_collect_methtable_from_mod(jl_type_type_mt, *extext_methods); - jl_collect_methtable_from_mod(jl_nonfunction_mt, *extext_methods); - size_t i, len = jl_array_len(mod_array); - for (i = 0; i < len; i++) { - jl_module_t *m = (jl_module_t*)jl_array_ptr_ref(mod_array, i); - assert(jl_is_module(m)); - if (m->parent == m) // some toplevel modules (really just Base) aren't actually - jl_collect_extext_methods_from_mod(*extext_methods, m); - } + jl_collect_extext_methods(*extext_methods, mod_array); if (edges) { // Extract `edges` now (from info prepared by jl_collect_methcache_from_mod) @@ -2987,7 +3038,7 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, htable_new(&bits_replace, 0); // strip metadata and IR when requested if (jl_options.strip_metadata || jl_options.strip_ir) { - jl_strip_all_codeinfos(); + jl_strip_all_codeinfos(mod_array); jl_strip_all_docmeta(mod_array); } // collect needed methods and replace method tables that are in the tags array @@ -3044,39 +3095,19 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, size_t num_mis; jl_get_llvm_mis(native_functions, &num_mis, NULL); arraylist_grow(&MIs, num_mis); - jl_get_llvm_mis(native_functions, &num_mis, (jl_method_instance_t *)MIs.items); + jl_get_llvm_mis(native_functions, &num_mis, (jl_method_instance_t*)MIs.items); } } if (jl_options.trim) { jl_rebuild_methtables(&MIs, &new_methtables); - jl_methtable_t *mt = (jl_methtable_t *)ptrhash_get(&new_methtables, jl_type_type_mt); - JL_GC_PROMISE_ROOTED(mt); - if (mt != HT_NOTFOUND) - jl_type_type_mt = mt; - else - jl_type_type_mt = jl_new_method_table(jl_type_type_mt->name, jl_type_type_mt->module); - - mt = (jl_methtable_t *)ptrhash_get(&new_methtables, jl_kwcall_mt); - JL_GC_PROMISE_ROOTED(mt); - if (mt != HT_NOTFOUND) - jl_kwcall_mt = mt; - else - jl_kwcall_mt = jl_new_method_table(jl_kwcall_mt->name, jl_kwcall_mt->module); - - mt = (jl_methtable_t *)ptrhash_get(&new_methtables, jl_nonfunction_mt); - JL_GC_PROMISE_ROOTED(mt); - if (mt != HT_NOTFOUND) - jl_nonfunction_mt = mt; - else - jl_nonfunction_mt = jl_new_method_table(jl_nonfunction_mt->name, jl_nonfunction_mt->module); } nsym_tag = 0; htable_new(&symbol_table, 0); - htable_new(&fptr_to_id, sizeof(id_to_fptrs) / sizeof(*id_to_fptrs)); + htable_new(&fptr_to_id, jl_n_builtins); uintptr_t i; - for (i = 0; id_to_fptrs[i] != NULL; i++) { - ptrhash_put(&fptr_to_id, (void*)(uintptr_t)id_to_fptrs[i], (void*)(i + 2)); + for (i = 0; i < jl_n_builtins; i++) { + ptrhash_put(&fptr_to_id, (void*)(uintptr_t)jl_builtin_f_addrs[i], (void*)(i + 2)); } htable_new(&serialization_order, 25000); htable_new(&nullptrs, 0); @@ -3115,11 +3146,15 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, s.link_ids_external_fnvars = jl_alloc_array_1d(jl_array_int32_type, 0); s.method_roots_list = NULL; htable_new(&s.method_roots_index, 0); + jl_value_t **_tags[NUM_TAGS]; + jl_value_t ***tags = s.incremental ? NULL : _tags; if (worklist) { s.method_roots_list = jl_alloc_vec_any(0); s.worklist_key = jl_worklist_key(worklist); } - jl_value_t **const*const tags = get_tags(); // worklist == NULL ? get_tags() : NULL; + else { + get_tags(_tags); + } if (worklist == NULL) { // empty!(Core.ARGS) @@ -3145,6 +3180,8 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, jl_value_t *tag = *tags[i]; jl_queue_for_serialization(&s, tag); } + for (i = 0; i < jl_n_builtins; i++) + jl_queue_for_serialization(&s, jl_builtin_instances[i]); jl_queue_for_serialization(&s, s.ptls->root_task->tls); } else { @@ -3228,6 +3265,21 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, jl_gc_wb(tn, jl_atomic_load_relaxed(&tn->cache)); jl_prune_type_cache_linear(jl_atomic_load_relaxed(&tn->linearcache)); } + else if (jl_is_method_instance(v)) { + jl_method_instance_t *mi = (jl_method_instance_t*)v; + jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mi->backedges, 1); + jl_prune_mi_backedges((jl_array_t*)backedges); + } + else if (jl_is_binding(v)) { + jl_binding_t *b = (jl_binding_t*)v; + jl_value_t *backedges = get_replaceable_field((jl_value_t**)&b->backedges, 1); + jl_prune_binding_backedges((jl_array_t*)backedges); + } + else if (jl_is_mtable(v)) { + jl_methtable_t *mt = (jl_methtable_t*)v; + jl_value_t *backedges = get_replaceable_field((jl_value_t**)&mt->backedges, 1); + jl_prune_mt_backedges((jl_genericmemory_t*)backedges); + } } } @@ -3326,6 +3378,8 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, jl_value_t *tag = *tags[i]; jl_write_value(&s, tag); } + for (i = 0; i < jl_n_builtins; i++) + jl_write_value(&s, jl_builtin_instances[i]); jl_write_value(&s, global_roots_list); jl_write_value(&s, global_roots_keyset); jl_write_value(&s, s.ptls->root_task->tls); @@ -3392,9 +3446,6 @@ static void jl_save_system_image_to_stream(ios_t *f, jl_array_t *mod_array, static void jl_write_header_for_incremental(ios_t *f, jl_array_t *worklist, jl_array_t *mod_array, jl_array_t **udeps, int64_t *srctextpos, int64_t *checksumpos) { - assert(jl_precompile_toplevel_module == NULL); - jl_precompile_toplevel_module = (jl_module_t*)jl_array_ptr_ref(worklist, jl_array_len(worklist)-1); - *checksumpos = write_header(f, 0); write_uint8(f, jl_cache_flags()); // write description of contents (name, uuid, buildid) @@ -3452,9 +3503,7 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli // Generate _native_data` if (_native_data != NULL) { jl_prepare_serialization_data(mod_array, newly_inferred, &extext_methods, &new_ext_cis, NULL, &query_cache); - jl_precompile_toplevel_module = (jl_module_t*)jl_array_ptr_ref(worklist, jl_array_len(worklist)-1); *_native_data = jl_precompile_worklist(worklist, extext_methods, new_ext_cis); - jl_precompile_toplevel_module = NULL; extext_methods = NULL; new_ext_cis = NULL; } @@ -3473,7 +3522,7 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli if (jl_options.trim) *_native_data = jl_precompile_trimmed(precompilation_world); else - *_native_data = jl_precompile(jl_options.compile_enabled == JL_OPTIONS_COMPILE_ALL); + *_native_data = jl_precompile(jl_options.compile_enabled == JL_OPTIONS_COMPILE_ALL, mod_array); } // Make sure we don't run any Julia code concurrently after this point @@ -3501,7 +3550,6 @@ JL_DLLEXPORT void jl_create_system_image(void **_native_data, jl_array_t *workli // Re-enable running julia code for postoutput hooks, atexit, etc. jl_gc_enable_finalizers(ct, 1); ct->reentrant_timing &= ~0b1000u; - jl_precompile_toplevel_module = NULL; if (worklist) { // Go back and update the checksum in the header @@ -3697,6 +3745,7 @@ static int jl_validate_binding_partition(jl_binding_t *b, jl_binding_partition_t // We need to go through and re-validate any bindings in the same image that // may have imported us. if (b->backedges) { + JL_LOCK(&b->globalref->mod->lock); for (size_t i = 0; i < jl_array_len(b->backedges); i++) { jl_value_t *edge = jl_array_ptr_ref(b->backedges, i); if (!jl_is_binding(edge)) @@ -3704,8 +3753,11 @@ static int jl_validate_binding_partition(jl_binding_t *b, jl_binding_partition_t jl_binding_t *bedge = (jl_binding_t*)edge; if (!jl_atomic_load_relaxed(&bedge->partitions)) continue; + JL_UNLOCK(&b->globalref->mod->lock); jl_validate_binding_partition(bedge, jl_atomic_load_relaxed(&bedge->partitions), mod_idx, 0, 0); + JL_LOCK(&b->globalref->mod->lock); } + JL_UNLOCK(&b->globalref->mod->lock); } if (bpart->kind & PARTITION_FLAG_EXPORTED) { jl_module_t *mod = b->globalref->mod; @@ -3762,7 +3814,11 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, s.gvar_record = &gvar_record; s.fptr_record = &fptr_record; s.ptls = ct->ptls; - jl_value_t **const*const tags = get_tags(); + jl_value_t **_tags[NUM_TAGS]; + jl_value_t ***tags = s.incremental ? NULL : _tags; + if (!s.incremental) + get_tags(_tags); + htable_t new_dt_objs; htable_new(&new_dt_objs, 0); arraylist_new(&deser_sym, 0); @@ -3824,6 +3880,8 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl_value_t **tag = tags[i]; *tag = jl_read_value(&s); } + for (i = 0; i < jl_n_builtins; i++) + jl_builtin_instances[i] = jl_read_value(&s); #define XX(name) \ ijl_small_typeof[(jl_##name##_tag << 4) / sizeof(*ijl_small_typeof)] = jl_##name##_type; JL_SMALL_TYPEOF(XX) @@ -4498,49 +4556,6 @@ JL_DLLEXPORT jl_value_t *jl_restore_package_image_from_file(const char *fname, j return mod; } -JL_DLLEXPORT void _jl_promote_ci_to_current(jl_code_instance_t *ci, size_t validated_world) JL_NOTSAFEPOINT -{ - if (jl_atomic_load_relaxed(&ci->max_world) != validated_world) - return; - jl_atomic_store_relaxed(&ci->max_world, ~(size_t)0); - jl_svec_t *edges = jl_atomic_load_relaxed(&ci->edges); - for (size_t i = 0; i < jl_svec_len(edges); i++) { - jl_value_t *edge = jl_svecref(edges, i); - if (!jl_is_code_instance(edge)) - continue; - _jl_promote_ci_to_current((jl_code_instance_t *)edge, validated_world); - } -} - -JL_DLLEXPORT void jl_promote_ci_to_current(jl_code_instance_t *ci, size_t validated_world) -{ - size_t current_world = jl_atomic_load_relaxed(&jl_world_counter); - // No need to acquire the lock if we've been invalidated anyway - if (current_world > validated_world) - return; - JL_LOCK(&world_counter_lock); - current_world = jl_atomic_load_relaxed(&jl_world_counter); - if (current_world == validated_world) { - _jl_promote_ci_to_current(ci, validated_world); - } - JL_UNLOCK(&world_counter_lock); -} - -JL_DLLEXPORT void jl_promote_cis_to_current(jl_code_instance_t **cis, size_t n, size_t validated_world) -{ - size_t current_world = jl_atomic_load_relaxed(&jl_world_counter); - // No need to acquire the lock if we've been invalidated anyway - if (current_world > validated_world) - return; - JL_LOCK(&world_counter_lock); - current_world = jl_atomic_load_relaxed(&jl_world_counter); - if (current_world == validated_world) { - for (size_t i = 0; i < n; i++) { - _jl_promote_ci_to_current(cis[i], validated_world); - } - } - JL_UNLOCK(&world_counter_lock); -} #ifdef __cplusplus } diff --git a/src/staticdata_utils.c b/src/staticdata_utils.c index 65f7dc59d9397..0b8cfc1cf4ebd 100644 --- a/src/staticdata_utils.c +++ b/src/staticdata_utils.c @@ -332,9 +332,9 @@ static int jl_collect_methtable_from_mod(jl_methtable_t *mt, void *env) // Collect methods of external functions defined by modules in the worklist // "extext" = "extending external" // Also collect relevant backedges -static void jl_collect_extext_methods_from_mod(jl_array_t *s, jl_module_t *m) +static void jl_collect_extext_methods(jl_array_t *s, jl_array_t *mod_array) { - foreach_mtable_in_module(m, jl_collect_methtable_from_mod, s); + jl_foreach_reachable_mtable(jl_collect_methtable_from_mod, mod_array, s); } static void jl_record_edges(jl_method_instance_t *caller, jl_array_t *edges) @@ -532,35 +532,40 @@ static int64_t write_dependency_list(ios_t *s, jl_array_t* worklist, jl_array_t { int64_t initial_pos = 0; int64_t pos = 0; - static jl_array_t *deps = NULL; - if (!deps) - deps = (jl_array_t*)jl_get_global(jl_base_module, jl_symbol("_require_dependencies")); - - // unique(deps) to eliminate duplicates while preserving order: - // we preserve order so that the topmost included .jl file comes first - static jl_value_t *unique_func = NULL; - if (!unique_func) - unique_func = jl_get_global(jl_base_module, jl_symbol("unique")); - jl_value_t *uniqargs[2] = {unique_func, (jl_value_t*)deps}; jl_task_t *ct = jl_current_task; size_t last_age = ct->world_age; ct->world_age = jl_atomic_load_acquire(&jl_world_counter); - jl_array_t *udeps = (*udepsp = deps && unique_func ? (jl_array_t*)jl_apply(uniqargs, 2) : NULL); - ct->world_age = last_age; + jl_value_t *depots = NULL, *prefs_hash = NULL, *prefs_list = NULL; + jl_value_t *unique_func = NULL; + jl_value_t *replace_depot_func = NULL; + jl_value_t *normalize_depots_func = NULL; + jl_value_t *toplevel = NULL; + jl_value_t *prefs_hash_func = NULL; + jl_value_t *get_compiletime_prefs_func = NULL; + JL_GC_PUSH8(&depots, &prefs_list, &unique_func, &replace_depot_func, &normalize_depots_func, &toplevel, &prefs_hash_func, &get_compiletime_prefs_func); + + jl_array_t *udeps = (jl_array_t*)jl_get_global_value(jl_base_module, jl_symbol("_require_dependencies"), ct->world_age); + *udepsp = udeps; + + // unique(udeps) to eliminate duplicates while preserving order: + // we preserve order so that the topmost included .jl file comes first + if (udeps) { + unique_func = jl_eval_global_var(jl_base_module, jl_symbol("unique"), ct->world_age); + jl_value_t *uniqargs[2] = {unique_func, (jl_value_t*)udeps}; + udeps = (jl_array_t*)jl_apply(uniqargs, 2); + *udepsp = udeps; + JL_TYPECHK(write_dependency_list, array_any, (jl_value_t*)udeps); + } - static jl_value_t *replace_depot_func = NULL; - if (!replace_depot_func) - replace_depot_func = jl_get_global(jl_base_module, jl_symbol("replace_depot_path")); - static jl_value_t *normalize_depots_func = NULL; - if (!normalize_depots_func) - normalize_depots_func = jl_get_global(jl_base_module, jl_symbol("normalize_depots_for_relocation")); + replace_depot_func = jl_get_global_value(jl_base_module, jl_symbol("replace_depot_path"), ct->world_age); + normalize_depots_func = jl_eval_global_var(jl_base_module, jl_symbol("normalize_depots_for_relocation"), ct->world_age); - jl_value_t *depots = NULL, *prefs_hash = NULL, *prefs_list = NULL; - JL_GC_PUSH2(&depots, &prefs_list); - last_age = ct->world_age; - ct->world_age = jl_atomic_load_acquire(&jl_world_counter); depots = jl_apply(&normalize_depots_func, 1); - ct->world_age = last_age; + + jl_datatype_t *deptuple_p[5] = {jl_module_type, jl_string_type, jl_uint64_type, jl_uint32_type, jl_float64_type}; + jl_value_t *jl_deptuple_type = jl_apply_tuple_type_v((jl_value_t**)deptuple_p, 5); + JL_GC_PROMISE_ROOTED(jl_deptuple_type); +#define jl_is_deptuple(v) (jl_typeis((v), jl_deptuple_type)) // write a placeholder for total size so that we can quickly seek past all of the // dependencies if we don't need them @@ -569,20 +574,16 @@ static int64_t write_dependency_list(ios_t *s, jl_array_t* worklist, jl_array_t size_t i, l = udeps ? jl_array_nrows(udeps) : 0; for (i = 0; i < l; i++) { jl_value_t *deptuple = jl_array_ptr_ref(udeps, i); - jl_value_t *deppath = jl_fieldref(deptuple, 1); + JL_TYPECHK(write_dependency_list, deptuple, deptuple); + jl_value_t *deppath = jl_fieldref_noalloc(deptuple, 1); if (replace_depot_func) { - jl_value_t **replace_depot_args; - JL_GC_PUSHARGS(replace_depot_args, 3); + jl_value_t *replace_depot_args[3]; replace_depot_args[0] = replace_depot_func; replace_depot_args[1] = deppath; replace_depot_args[2] = depots; - ct = jl_current_task; - size_t last_age = ct->world_age; - ct->world_age = jl_atomic_load_acquire(&jl_world_counter); deppath = (jl_value_t*)jl_apply(replace_depot_args, 3); - ct->world_age = last_age; - JL_GC_POP(); + JL_TYPECHK(write_dependency_list, string, deppath); } size_t slen = jl_string_len(deppath); @@ -591,7 +592,7 @@ static int64_t write_dependency_list(ios_t *s, jl_array_t* worklist, jl_array_t write_uint64(s, jl_unbox_uint64(jl_fieldref(deptuple, 2))); // fsize write_uint32(s, jl_unbox_uint32(jl_fieldref(deptuple, 3))); // hash write_float64(s, jl_unbox_float64(jl_fieldref(deptuple, 4))); // mtime - jl_module_t *depmod = (jl_module_t*)jl_fieldref(deptuple, 0); // evaluating module + jl_module_t *depmod = (jl_module_t*)jl_fieldref_noalloc(deptuple, 0); // evaluating module jl_module_t *depmod_top = depmod; while (!is_serialization_root_module(depmod_top)) depmod_top = depmod_top->parent; @@ -615,34 +616,31 @@ static int64_t write_dependency_list(ios_t *s, jl_array_t* worklist, jl_array_t // Calculate Preferences hash for current package. if (jl_base_module) { // Toplevel module is the module we're currently compiling, use it to get our preferences hash - jl_value_t * toplevel = (jl_value_t*)jl_get_global(jl_base_module, jl_symbol("__toplevel__")); - jl_value_t * prefs_hash_func = jl_get_global(jl_base_module, jl_symbol("get_preferences_hash")); - jl_value_t * get_compiletime_prefs_func = jl_get_global(jl_base_module, jl_symbol("get_compiletime_preferences")); - - if (toplevel && prefs_hash_func && get_compiletime_prefs_func) { - // Temporary invoke in newest world age - size_t last_age = ct->world_age; - ct->world_age = jl_atomic_load_acquire(&jl_world_counter); + toplevel = jl_get_global_value(jl_base_module, jl_symbol("__toplevel__"), ct->world_age); + prefs_hash_func = jl_eval_global_var(jl_base_module, jl_symbol("get_preferences_hash"), ct->world_age); + get_compiletime_prefs_func = jl_eval_global_var(jl_base_module, jl_symbol("get_compiletime_preferences"), ct->world_age); + if (toplevel) { // call get_compiletime_prefs(__toplevel__) jl_value_t *args[3] = {get_compiletime_prefs_func, (jl_value_t*)toplevel, NULL}; prefs_list = (jl_value_t*)jl_apply(args, 2); + JL_TYPECHK(write_dependency_list, array, prefs_list); // Call get_preferences_hash(__toplevel__, prefs_list) args[0] = prefs_hash_func; args[2] = prefs_list; prefs_hash = (jl_value_t*)jl_apply(args, 3); - - // Reset world age to normal - ct->world_age = last_age; + JL_TYPECHK(write_dependency_list, uint64, prefs_hash); } } + ct->world_age = last_age; // If we successfully got the preferences, write it out, otherwise write `0` for this `.ji` file. if (prefs_hash != NULL && prefs_list != NULL) { size_t i, l = jl_array_nrows(prefs_list); for (i = 0; i < l; i++) { jl_value_t *pref_name = jl_array_ptr_ref(prefs_list, i); + JL_TYPECHK(write_dependency_list, string, pref_name); size_t slen = jl_string_len(pref_name); write_int32(s, slen); ios_write(s, jl_string_data(pref_name), slen); @@ -660,6 +658,7 @@ static int64_t write_dependency_list(ios_t *s, jl_array_t* worklist, jl_array_t write_uint64(s, 0); } JL_GC_POP(); // for depots, prefs_list +#undef jl_is_deptuple // write a dummy file position to indicate the beginning of the source-text pos = ios_pos(s); @@ -727,9 +726,7 @@ static void jl_activate_methods(jl_array_t *external, jl_array_t *internal, size } for (i = 0; i < l; i++) { jl_typemap_entry_t *entry = (jl_typemap_entry_t*)jl_array_ptr_ref(external, i); - jl_methtable_t *mt = jl_method_get_table(entry->func.method); - assert((jl_value_t*)mt != jl_nothing); - jl_method_table_activate(mt, entry); + jl_method_table_activate(entry); } } } diff --git a/src/task.c b/src/task.c index 37e7f0e1f5440..019a301b1f062 100644 --- a/src/task.c +++ b/src/task.c @@ -335,7 +335,7 @@ void JL_NORETURN jl_finish_task(jl_task_t *ct) // let the runtime know this task is dead and find a new task to run jl_function_t *done = jl_atomic_load_relaxed(&task_done_hook_func); if (done == NULL) { - done = (jl_function_t*)jl_get_global(jl_base_module, jl_symbol("task_done_hook")); + done = (jl_function_t*)jl_get_global_value(jl_base_module, jl_symbol("task_done_hook"), ct->world_age); if (done != NULL) jl_atomic_store_release(&task_done_hook_func, done); } diff --git a/src/threading.c b/src/threading.c index 4ab0f7630f560..655cf26c782b2 100644 --- a/src/threading.c +++ b/src/threading.c @@ -404,9 +404,11 @@ static _Atomic(jl_function_t*) init_task_lock_func JL_GLOBALLY_ROOTED = NULL; static void jl_init_task_lock(jl_task_t *ct) { + size_t last_age = ct->world_age; + ct->world_age = jl_get_world_counter(); jl_function_t *done = jl_atomic_load_relaxed(&init_task_lock_func); if (done == NULL) { - done = (jl_function_t*)jl_get_global(jl_base_module, jl_symbol("init_task_lock")); + done = (jl_function_t*)jl_get_global_value(jl_base_module, jl_symbol("init_task_lock"), ct->world_age); if (done != NULL) jl_atomic_store_release(&init_task_lock_func, done); } @@ -419,6 +421,7 @@ static void jl_init_task_lock(jl_task_t *ct) jl_no_exc_handler(jl_current_exception(ct), ct); } } + ct->world_age = last_age; } JL_DLLEXPORT jl_gcframe_t **jl_adopt_thread(void) @@ -441,7 +444,6 @@ JL_DLLEXPORT jl_gcframe_t **jl_adopt_thread(void) JL_GC_PROMISE_ROOTED(ct); uv_random(NULL, NULL, &ct->rngState, sizeof(ct->rngState), 0, NULL); jl_atomic_fetch_add(&jl_gc_disable_counter, -1); - ct->world_age = jl_get_world_counter(); // root_task sets world_age to 1 jl_init_task_lock(ct); return &ct->gcstack; } @@ -733,6 +735,8 @@ void jl_init_threading(void) if (errno != 0 || endptr == cp || nthreads <= 0) nthreads = 1; cp = endptr; + if (nthreads == 1) // User asked for 1 thread so lets assume they dont want an interactive thread + nthreadsi = 0; } if (*cp == ',') { cp++; diff --git a/src/toplevel.c b/src/toplevel.c index b7479e2d1c24b..6398a1bb241ba 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -34,7 +34,7 @@ htable_t jl_current_modules; jl_mutex_t jl_modules_mutex; // During incremental compilation, the following gets set -jl_module_t *jl_precompile_toplevel_module = NULL; // the toplevel module currently being defined +jl_module_t *jl_precompile_toplevel_module = NULL; // the first toplevel module being defined jl_module_t *jl_add_standard_imports(jl_module_t *m) { @@ -54,12 +54,6 @@ void jl_init_main_module(void) jl_set_initial_const(jl_main_module, jl_symbol("Core"), (jl_value_t*)jl_core_module, 0); // const Core.Main = Main } -static jl_function_t *jl_module_get_initializer(jl_module_t *m JL_PROPAGATES_ROOT) -{ - return (jl_function_t*)jl_get_global(m, jl_symbol("__init__")); -} - - void jl_module_run_initializer(jl_module_t *m) { JL_TIMING(INIT_MODULE, INIT_MODULE); @@ -68,9 +62,12 @@ void jl_module_run_initializer(jl_module_t *m) size_t last_age = ct->world_age; JL_TRY { ct->world_age = jl_atomic_load_acquire(&jl_world_counter); - jl_function_t *f = jl_module_get_initializer(m); - if (f != NULL) + jl_value_t *f = jl_get_global_value(m, jl_symbol("__init__"), ct->world_age); + if (f != NULL) { + JL_GC_PUSH1(&f); jl_apply(&f, 1); + JL_GC_POP(); + } ct->world_age = last_age; } JL_CATCH { @@ -107,10 +104,10 @@ jl_array_t *jl_get_loaded_modules(void) return NULL; } -static int jl_is__toplevel__mod(jl_module_t *mod) +static int jl_is__toplevel__mod(jl_module_t *mod, jl_task_t *ct) { return jl_base_module && - (jl_value_t*)mod == jl_get_global(jl_base_module, jl_symbol("__toplevel__")); + (jl_value_t*)mod == jl_get_global_value(jl_base_module, jl_symbol("__toplevel__"), ct->world_age); } // TODO: add locks around global state mutation operations @@ -132,7 +129,7 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex jl_type_error("module", (jl_value_t*)jl_symbol_type, (jl_value_t*)name); } - int is_parent__toplevel__ = jl_is__toplevel__mod(parent_module); + int is_parent__toplevel__ = jl_is__toplevel__mod(parent_module, ct); // If we have `Base`, don't also try to import `Core` - the `Base` exports are a superset. // While we allow multiple imports of the same binding from different modules, various error printing // performs reflection on which module a binding came from and we'd prefer users see "Base" here. @@ -175,7 +172,6 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex } } - jl_module_t *old_toplevel_module = jl_precompile_toplevel_module; size_t last_age = ct->world_age; if (parent_module == jl_main_module && name == jl_symbol("Base") && jl_base_module == NULL) { @@ -185,7 +181,7 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex if (is_parent__toplevel__) { jl_register_root_module(newm); - if (jl_options.incremental) { + if (jl_options.incremental && jl_precompile_toplevel_module == NULL) { jl_precompile_toplevel_module = newm; } } @@ -245,25 +241,22 @@ static jl_value_t *jl_eval_module_expr(jl_module_t *parent_module, jl_expr_t *ex } } - jl_precompile_toplevel_module = old_toplevel_module; - JL_GC_POP(); return (jl_value_t*)newm; } -static jl_value_t *jl_eval_dot_expr(jl_module_t *m, jl_value_t *x, jl_value_t *f, int fast, const char **toplevel_filename, int *toplevel_lineno) +static jl_value_t *jl_eval_dot_expr(jl_task_t *ct, jl_module_t *m, jl_value_t *x, jl_value_t *f, int fast, const char **toplevel_filename, int *toplevel_lineno) { - jl_task_t *ct = jl_current_task; jl_value_t **args; JL_GC_PUSHARGS(args, 3); args[1] = jl_toplevel_eval_flex(m, x, fast, 0, toplevel_filename, toplevel_lineno); args[2] = jl_toplevel_eval_flex(m, f, fast, 0, toplevel_filename, toplevel_lineno); if (jl_is_module(args[1])) { JL_TYPECHK(getglobal, symbol, args[2]); - args[0] = jl_eval_global_var((jl_module_t*)args[1], (jl_sym_t*)args[2]); + args[0] = jl_eval_global_var((jl_module_t*)args[1], (jl_sym_t*)args[2], ct->world_age); } else { - args[0] = jl_eval_global_var(jl_base_relative_to(m), jl_symbol("getproperty")); + args[0] = jl_eval_global_var(jl_base_relative_to(m), jl_symbol("getproperty"), ct->world_age); size_t last_age = ct->world_age; ct->world_age = jl_atomic_load_acquire(&jl_world_counter); args[0] = jl_apply(args, 3); @@ -426,7 +419,7 @@ static void expr_attributes(jl_value_t *v, jl_array_t *body, int *has_ccall, int if (jl_is_intrinsic(called) && jl_unbox_int32(called) == (int)llvmcall) { *has_ccall = 1; } - if (called == jl_builtin__typebody) { // TODO: rely on latestworld instead of function callee detection here (or add it to jl_is_toplevel_only_expr) + if (called == BUILTIN(_typebody)) { // TODO: rely on latestworld instead of function callee detection here (or add it to jl_is_toplevel_only_expr) *has_defs = 1; } } @@ -566,7 +559,7 @@ static jl_module_t *eval_import_path(jl_task_t *ct, jl_module_t *where, jl_modul jl_errorf("invalid %s path: \".\" in identifier path", keyword); if (i == jl_array_nrows(args)-1) break; - m = (jl_module_t*)jl_eval_global_var(m, var); + m = (jl_module_t*)jl_eval_global_var(m, var, ct->world_age); JL_GC_PROMISE_ROOTED(m); if (!jl_is_module(m)) jl_errorf("invalid %s path: \"%s\" does not name a module", keyword, jl_symbol_name(var)); @@ -676,7 +669,7 @@ static jl_module_t *eval_import_from(jl_task_t *ct, jl_module_t *m JL_PROPAGATES jl_sym_t *name = NULL; jl_module_t *from = eval_import_path(ct, m, NULL, path->args, &name, keyword); if (name != NULL) { - from = (jl_module_t*)jl_eval_global_var(from, name); + from = (jl_module_t*)jl_eval_global_var(from, name, ct->world_age); if (!from || !jl_is_module(from)) jl_errorf("invalid %s path: \"%s\" does not name a module", keyword, jl_symbol_name(name)); } @@ -705,7 +698,7 @@ static void jl_eval_throw(jl_module_t *m, jl_value_t *exc, const char *filename, { jl_value_t *throw_ex = (jl_value_t*)jl_exprn(jl_call_sym, 2); JL_GC_PUSH1(&throw_ex); - jl_exprargset(throw_ex, 0, jl_builtin_throw); + jl_exprargset(throw_ex, 0, BUILTIN(throw)); jl_exprargset(throw_ex, 1, exc); jl_toplevel_eval_flex(m, throw_ex, 0, 0, &filename, &lineno); JL_GC_POP(); @@ -761,6 +754,16 @@ JL_DLLEXPORT void jl_eval_const_decl(jl_module_t *m, jl_value_t *arg, jl_value_t JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_value_t *e, int fast, int expanded, const char **toplevel_filename, int *toplevel_lineno) { jl_task_t *ct = jl_current_task; + if (jl_is_globalref(e)) { + return jl_eval_globalref((jl_globalref_t*)e, ct->world_age); + } + if (jl_is_symbol(e)) { + char *n = jl_symbol_name((jl_sym_t*)e), *n0 = n; + while (*n == '_') ++n; + if (*n == 0 && n > n0) + jl_eval_errorf(m, *toplevel_filename, *toplevel_lineno, "all-underscore identifiers are write-only and their values cannot be used in expressions"); + return jl_eval_global_var(m, (jl_sym_t*)e, ct->world_age); + } if (!jl_is_expr(e)) { if (jl_is_linenode(e)) { *toplevel_lineno = jl_linenode_line(e); @@ -774,12 +777,6 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val jl_lineno = *toplevel_lineno; return jl_nothing; } - if (jl_is_symbol(e)) { - char *n = jl_symbol_name((jl_sym_t*)e), *n0 = n; - while (*n == '_') ++n; - if (*n == 0 && n > n0) - jl_eval_errorf(m, *toplevel_filename, *toplevel_lineno, "all-underscore identifiers are write-only and their values cannot be used in expressions"); - } return jl_interpret_toplevel_expr_in(m, e, NULL, NULL); } @@ -792,7 +789,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val jl_value_t *rhs = jl_exprarg(ex, 1); // only handle `a.b` syntax here, so qualified names can be eval'd in pure contexts if (jl_is_quotenode(rhs) && jl_is_symbol(jl_fieldref(rhs, 0))) { - return jl_eval_dot_expr(m, lhs, rhs, fast, toplevel_filename, toplevel_lineno); + return jl_eval_dot_expr(ct, m, lhs, rhs, fast, toplevel_filename, toplevel_lineno); } } @@ -838,7 +835,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val else { jl_module_t *u = import; if (name != NULL) - u = (jl_module_t*)jl_eval_global_var(import, name); + u = (jl_module_t*)jl_eval_global_var(import, name, ct->world_age); if (!jl_is_module(u)) jl_eval_errorf(m, *toplevel_filename, *toplevel_lineno, "invalid using path: \"%s\" does not name a module", @@ -992,7 +989,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val } else if (jl_is_symbol(ex)) { JL_GC_POP(); - return jl_eval_global_var(m, (jl_sym_t*)ex); + return jl_eval_global_var(m, (jl_sym_t*)ex, ct->world_age); } else if (head == NULL) { JL_GC_POP(); @@ -1022,7 +1019,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_flex(jl_module_t *JL_NONNULL m, jl_val 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_ABI); + (void)jl_type_infer(mfunc, world, SOURCE_MODE_ABI, jl_options.trim); } result = jl_invoke(/*func*/NULL, /*args*/NULL, /*nargs*/0, mfunc); ct->world_age = last_age; @@ -1069,7 +1066,7 @@ JL_DLLEXPORT void jl_check_top_level_effect(jl_module_t *m, char *fname) } } JL_UNLOCK(&jl_modules_mutex); - if (!open && !jl_is__toplevel__mod(m)) { + if (!open && !jl_is__toplevel__mod(m, jl_current_task)) { const char* name = jl_symbol_name(m->name); jl_errorf("Evaluation into the closed module `%s` breaks incremental compilation " "because the side effects will not be permanent. " @@ -1091,7 +1088,7 @@ JL_DLLEXPORT jl_value_t *jl_toplevel_eval_in(jl_module_t *m, jl_value_t *ex) jl_filename = "none"; size_t last_age = ct->world_age; JL_TRY { - ct->world_age = jl_atomic_load_relaxed(&jl_world_counter); + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); v = jl_toplevel_eval(m, ex); } JL_CATCH { @@ -1150,10 +1147,10 @@ static jl_value_t *jl_parse_eval_all(jl_module_t *module, jl_value_t *text, jl_lineno = lineno; continue; } - ct->world_age = jl_atomic_load_relaxed(&jl_world_counter); + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); expression = jl_expand_with_loc_warn(expression, module, jl_string_data(filename), lineno); - ct->world_age = jl_atomic_load_relaxed(&jl_world_counter); + ct->world_age = jl_atomic_load_acquire(&jl_world_counter); result = jl_toplevel_eval_flex(module, expression, 1, 1, &filename_str, &lineno); } ct->world_age = last_age; diff --git a/stdlib/Artifacts/src/Artifacts.jl b/stdlib/Artifacts/src/Artifacts.jl index e21db58b9445e..f240f6defa0d0 100644 --- a/stdlib/Artifacts/src/Artifacts.jl +++ b/stdlib/Artifacts/src/Artifacts.jl @@ -562,7 +562,7 @@ function _artifact_str(__module__, artifacts_toml, name, path_tail, artifact_dic meta = artifact_meta(name, artifact_dict, artifacts_toml; platform) if meta !== nothing && get(meta, "lazy", false) if LazyArtifacts isa Module && isdefined(LazyArtifacts, :ensure_artifact_installed) - if nameof(LazyArtifacts) in (:Pkg, :Artifacts) + if nameof(LazyArtifacts) in (:Pkg, :Artifacts, :PkgArtifacts) Base.depwarn("using Pkg instead of using LazyArtifacts is deprecated", :var"@artifact_str", force=true) end return jointail(LazyArtifacts.ensure_artifact_installed(string(name), meta, artifacts_toml; platform), path_tail) @@ -697,7 +697,7 @@ macro artifact_str(name, platform=nothing) # Check if the user has provided `LazyArtifacts`, and thus supports lazy artifacts # If not, check to see if `Pkg` or `Pkg.Artifacts` has been imported. LazyArtifacts = nothing - for module_name in (:LazyArtifacts, :Pkg, :Artifacts) + for module_name in (:LazyArtifacts, :Pkg, :Artifacts, :PkgArtifacts) if isdefined(__module__, module_name) LazyArtifacts = GlobalRef(__module__, module_name) break diff --git a/stdlib/Distributed.version b/stdlib/Distributed.version index be52c0d684b50..99b5238a55491 100644 --- a/stdlib/Distributed.version +++ b/stdlib/Distributed.version @@ -1,4 +1,4 @@ DISTRIBUTED_BRANCH = master -DISTRIBUTED_SHA1 = 51e52978481835413d15b589919aba80dd85f890 +DISTRIBUTED_SHA1 = 3679026d7b510befdedfa8c6497e3cb032f9cea1 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/InteractiveUtils/src/InteractiveUtils.jl b/stdlib/InteractiveUtils/src/InteractiveUtils.jl index 6b75a228b2761..c39112eded49a 100644 --- a/stdlib/InteractiveUtils/src/InteractiveUtils.jl +++ b/stdlib/InteractiveUtils/src/InteractiveUtils.jl @@ -120,7 +120,7 @@ function versioninfo(io::IO=stdout; verbose::Bool=false) Note: This is an unofficial build, please report bugs to the project responsible for this build and not to the Julia project unless you can - reproduce the issue using official builds available at https://julialang.org/downloads + reproduce the issue using official builds available at https://julialang.org """ ) end diff --git a/stdlib/LLD_jll/Project.toml b/stdlib/LLD_jll/Project.toml index 1aafd275d99b7..eb799f48d2309 100644 --- a/stdlib/LLD_jll/Project.toml +++ b/stdlib/LLD_jll/Project.toml @@ -1,6 +1,6 @@ name = "LLD_jll" uuid = "d55e3150-da41-5e91-b323-ecfd1eec6109" -version = "18.1.7+3" +version = "18.1.7+5" [deps] Zlib_jll = "83775a58-1f1d-513f-b197-d71354ab007a" diff --git a/stdlib/LinearAlgebra.version b/stdlib/LinearAlgebra.version index ae590e6655aa8..10e03e5e0f103 100644 --- a/stdlib/LinearAlgebra.version +++ b/stdlib/LinearAlgebra.version @@ -1,4 +1,4 @@ LINEARALGEBRA_BRANCH = release-1.12 -LINEARALGEBRA_SHA1 = 7264a497869f2232eaa3d740ba3b145ade3fc9f4 +LINEARALGEBRA_SHA1 = 6cc040592fd509ee048658e9afb8a99a2dc20e1b 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/Manifest.toml b/stdlib/Manifest.toml index 0dcd58d217d0b..e0d3d3182b377 100644 --- a/stdlib/Manifest.toml +++ b/stdlib/Manifest.toml @@ -73,7 +73,7 @@ version = "1.12.0" [[deps.LLD_jll]] deps = ["Artifacts", "Libdl", "Zlib_jll", "libLLVM_jll"] uuid = "d55e3150-da41-5e91-b323-ecfd1eec6109" -version = "18.1.7+3" +version = "18.1.7+5" [[deps.LLVMLibUnwind_jll]] deps = ["Artifacts", "Libdl"] @@ -282,7 +282,7 @@ version = "2.2.5+2" [[deps.libLLVM_jll]] deps = ["Artifacts", "Libdl"] uuid = "8f36deef-c2a5-5394-99ed-8e07531fb29a" -version = "18.1.7+3" +version = "18.1.7+5" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] diff --git a/stdlib/OpenSSL_jll/Project.toml b/stdlib/OpenSSL_jll/Project.toml index 28ecf86381213..d11c3b25a6922 100644 --- a/stdlib/OpenSSL_jll/Project.toml +++ b/stdlib/OpenSSL_jll/Project.toml @@ -1,6 +1,6 @@ name = "OpenSSL_jll" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.0+0" +version = "3.5.1+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/OpenSSL_jll/test/runtests.jl b/stdlib/OpenSSL_jll/test/runtests.jl index e5ae938b68311..9ef99d57134e0 100644 --- a/stdlib/OpenSSL_jll/test/runtests.jl +++ b/stdlib/OpenSSL_jll/test/runtests.jl @@ -6,5 +6,5 @@ using Test, Libdl, OpenSSL_jll 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.5.0" + @test VersionNumber(major, minor, patch) == v"3.5.1" end diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index 63845886099aa..83277d857f05e 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ -PKG_BRANCH = master -PKG_SHA1 = 7aeec766cf637e2bc2af161eba8abd3a4b68d025 +PKG_BRANCH = release-1.12 +PKG_SHA1 = e7a2dfecbfe43cf1c32f1ccd1e98a4dca52726ee 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/REPL/src/REPL.jl b/stdlib/REPL/src/REPL.jl index 9eaecf44c7633..f7485c75e95c5 100644 --- a/stdlib/REPL/src/REPL.jl +++ b/stdlib/REPL/src/REPL.jl @@ -1876,7 +1876,7 @@ function create_global_out!(mod) end return out end - return getglobal(mod, Out) + return getglobal(mod, :Out) end function capture_result(n::Ref{Int}, @nospecialize(x)) diff --git a/stdlib/REPL/src/REPLCompletions.jl b/stdlib/REPL/src/REPLCompletions.jl index 4244111f0aa36..e30a59b8c00d5 100644 --- a/stdlib/REPL/src/REPLCompletions.jl +++ b/stdlib/REPL/src/REPLCompletions.jl @@ -330,7 +330,8 @@ end const PATH_cache_lock = Base.ReentrantLock() const PATH_cache = Set{String}() -PATH_cache_task::Union{Task,Nothing} = nothing # used for sync in tests +PATH_cache_task::Union{Task,Nothing} = nothing +PATH_cache_condition::Union{Threads.Condition, Nothing} = nothing # used for sync in tests next_cache_update::Float64 = 0.0 function maybe_spawn_cache_PATH() global PATH_cache_task, next_cache_update @@ -339,7 +340,11 @@ function maybe_spawn_cache_PATH() time() < next_cache_update && return PATH_cache_task = Threads.@spawn begin REPLCompletions.cache_PATH() - @lock PATH_cache_lock PATH_cache_task = nothing # release memory when done + @lock PATH_cache_lock begin + next_cache_update = time() + 10 # earliest next update can run is 10s after + PATH_cache_task = nothing # release memory when done + PATH_cache_condition !== nothing && notify(PATH_cache_condition) + end end Base.errormonitor(PATH_cache_task) end @@ -350,8 +355,6 @@ function cache_PATH() path = get(ENV, "PATH", nothing) path isa String || return - global next_cache_update - # Calling empty! on PATH_cache would be annoying for async typing hints as completions would temporarily disappear. # So keep track of what's added this time and at the end remove any that didn't appear this time from the global cache. this_PATH_cache = Set{String}() @@ -414,7 +417,6 @@ function cache_PATH() @lock PATH_cache_lock begin intersect!(PATH_cache, this_PATH_cache) # remove entries from PATH_cache that weren't found this time - next_cache_update = time() + 10 # earliest next update can run is 10s after end @debug "caching PATH files took $t seconds" length(pathdirs) length(PATH_cache) diff --git a/stdlib/REPL/test/replcompletions.jl b/stdlib/REPL/test/replcompletions.jl index 5f2990e970d97..43bea08e285f1 100644 --- a/stdlib/REPL/test/replcompletions.jl +++ b/stdlib/REPL/test/replcompletions.jl @@ -1073,6 +1073,39 @@ let c, r, res @test res === false end +# A pair of utility function for the REPL completions test to test PATH_cache +# dependent completions, which ordinarily happen asynchronously. +# Only to be used from the test suite +function test_only_arm_cache_refresh() + @lock REPL.REPLCompletions.PATH_cache_lock begin + @assert REPL.REPLCompletions.PATH_cache_condition === nothing + + # Arm a condition we can wait on + REPL.REPLCompletions.PATH_cache_condition = Threads.Condition(REPL.REPLCompletions.PATH_cache_lock) + + # Check if the previous update is still running - if so, wait for it to finish + while REPL.REPLCompletions.PATH_cache_task !== nothing + @assert !istaskdone(REPL.REPLCompletions.PATH_cache_task) + wait(REPL.REPLCompletions.PATH_cache_condition) + end + + # force the next cache update to happen immediately + REPL.REPLCompletions.next_cache_update = 0 + end + return REPL.REPLCompletions.PATH_cache_condition +end + +function test_only_wait_cache_path_done() + @lock REPL.REPLCompletions.PATH_cache_lock begin + @assert REPL.REPLCompletions.PATH_cache_condition !== nothing + + while REPL.REPLCompletions.next_cache_update == 0. + wait(REPL.REPLCompletions.PATH_cache_condition) + end + REPL.REPLCompletions.PATH_cache_condition = nothing + end +end + if Sys.isunix() let s, c, r #Assume that we can rely on the existence and accessibility of /tmp @@ -1204,12 +1237,9 @@ let s, c, r # Files reachable by PATH are cached async when PATH is seen to have been changed by `complete_path` # so changes are unlikely to appear in the first complete. For testing purposes we can wait for # caching to finish - @lock REPL.REPLCompletions.PATH_cache_lock begin - # force the next cache update to happen immediately - REPL.REPLCompletions.next_cache_update = 0 - end + test_only_arm_cache_refresh() c,r = test_scomplete(s) - timedwait(()->REPL.REPLCompletions.next_cache_update != 0, 5) # wait for caching to complete + test_only_wait_cache_path_done() c,r = test_scomplete(s) @test "tmp-executable" in c @test r == 1:9 @@ -1238,12 +1268,9 @@ let s, c, r withenv("PATH" => string(tempdir(), ":", dir)) do s = string("repl-completio") - @lock REPL.REPLCompletions.PATH_cache_lock begin - # force the next cache update to happen immediately - REPL.REPLCompletions.next_cache_update = 0 - end + test_only_arm_cache_refresh() c,r = test_scomplete(s) - timedwait(()->REPL.REPLCompletions.next_cache_update != 0, 5) # wait for caching to complete + test_only_wait_cache_path_done() c,r = test_scomplete(s) @test ["repl-completion"] == c @test s[r] == "repl-completio" diff --git a/stdlib/Serialization/src/Serialization.jl b/stdlib/Serialization/src/Serialization.jl index 3362c9439d385..3c4152bf10598 100644 --- a/stdlib/Serialization/src/Serialization.jl +++ b/stdlib/Serialization/src/Serialization.jl @@ -467,6 +467,18 @@ function serialize(s::AbstractSerializer, meth::Method) nothing end +function serialize(s::AbstractSerializer, mt::Core.MethodTable) + serialize_type(s, typeof(mt)) + serialize(s, mt.name) + serialize(s, mt.module) + nothing +end + +function serialize(s::AbstractSerializer, mc::Core.MethodCache) + error("cannot serialize MethodCache objects") +end + + function serialize(s::AbstractSerializer, linfo::Core.MethodInstance) serialize_cycle(s, linfo) && return writetag(s.io, METHODINSTANCE_TAG) @@ -536,11 +548,12 @@ function serialize_typename(s::AbstractSerializer, t::Core.TypeName) serialize(s, t.flags & 0x2 == 0x2) # .mutable serialize(s, Int32(length(primary.types) - t.n_uninitialized)) serialize(s, t.max_methods) - if isdefined(t, :mt) && t.mt !== Symbol.name.mt - serialize(s, t.mt.name) - serialize(s, collect(Base.MethodList(t.mt))) - serialize(s, t.mt.max_args) - kws = collect(methods(Core.kwcall, (Any, t.wrapper, Vararg))) + ms = Base.matches_to_methods(Base._methods_by_ftype(Tuple{t.wrapper, Vararg}, -1, Base.get_world_counter()), t, nothing).ms + if t.singletonname !== t.name || !isempty(ms) + serialize(s, t.singletonname) + serialize(s, ms) + serialize(s, t.max_args) + kws = Base.matches_to_methods(Base._methods_by_ftype(Tuple{typeof(Core.kwcall), Any, t.wrapper, Vararg}, -1, Base.get_world_counter()), t, nothing).ms if isempty(kws) writetag(s.io, UNDEFREF_TAG) else @@ -555,21 +568,17 @@ end # decide whether to send all data for a type (instead of just its name) function should_send_whole_type(s, t::DataType) tn = t.name - if isdefined(tn, :mt) - # TODO improve somehow - # send whole type for anonymous functions in Main - name = tn.mt.name - mod = tn.module - isanonfunction = mod === Main && # only Main - t.super === Function && # only Functions - unsafe_load(unsafe_convert(Ptr{UInt8}, tn.name)) == UInt8('#') && # hidden type - (!isdefined(mod, name) || t != typeof(getglobal(mod, name))) # XXX: 95% accurate test for this being an inner function - # TODO: more accurate test? (tn.name !== "#" name) - #TODO: iskw = startswith(tn.name, "#kw#") && ??? - #TODO: iskw && return send-as-kwftype - return mod === __deserialized_types__ || isanonfunction - end - return false + # TODO improve somehow? + # send whole type for anonymous functions in Main + name = tn.singletonname + mod = tn.module + mod === __deserialized_types__ && return true + isanonfunction = mod === Main && # only Main + t.super === Function && # only Functions + unsafe_load(unsafe_convert(Ptr{UInt8}, tn.name)) == UInt8('#') && # hidden type + (!isdefined(mod, name) || t != typeof(getglobal(mod, name))) # XXX: 95% accurate test for this being an inner function + # TODO: more accurate test? (tn.name !== "#" name) + return isanonfunction end function serialize_type_data(s, @nospecialize(t::DataType)) @@ -1112,8 +1121,8 @@ function deserialize(s::AbstractSerializer, ::Type{Method}) meth.recursion_relation = recursion_relation end if !is_for_opaque_closure - mt = ccall(:jl_method_table_for, Any, (Any,), sig) - if mt !== nothing && nothing === ccall(:jl_methtable_lookup, Any, (Any, Any, UInt), mt, sig, Base.get_world_counter()) + mt = Core.GlobalMethods + if nothing === ccall(:jl_methtable_lookup, Any, (Any, UInt), sig, Base.get_world_counter()) # XXX: quite sketchy? ccall(:jl_method_table_insert, Cvoid, (Any, Any, Ptr{Cvoid}), mt, meth, C_NULL) end end @@ -1122,6 +1131,12 @@ function deserialize(s::AbstractSerializer, ::Type{Method}) return meth end +function deserialize(s::AbstractSerializer, ::Type{Core.MethodTable}) + name = deserialize(s)::Symbol + mod = deserialize(s)::Module + return getglobal(mod, name)::Core.MethodTable +end + function deserialize(s::AbstractSerializer, ::Type{Core.MethodInstance}) linfo = ccall(:jl_new_method_instance_uninit, Ref{Core.MethodInstance}, (Ptr{Cvoid},), C_NULL) deserialize_cycle(s, linfo) @@ -1471,20 +1486,10 @@ function deserialize_typename(s::AbstractSerializer, number) if tag != UNDEFREF_TAG mtname = handle_deserialize(s, tag) defs = deserialize(s) - maxa = deserialize(s)::Int + maxa = deserialize(s)::Union{Int,Int32} if makenew - mt = ccall(:jl_new_method_table, Any, (Any, Any), name, tn.module) - if !isempty(parameters) - mt.offs = 0 - end - mt.name = mtname - setfield!(mt, :max_args, maxa, :monotonic) - ccall(:jl_set_nth_field, Cvoid, (Any, Csize_t, Any), tn, Base.fieldindex(Core.TypeName, :mt)-1, mt) - for def in defs - if isdefined(def, :sig) - ccall(:jl_method_table_insert, Cvoid, (Any, Any, Ptr{Cvoid}), mt, def, C_NULL) - end - end + tn.singletonname = mtname + setfield!(tn, :max_args, Int32(maxa), :monotonic) end tag = Int32(read(s.io, UInt8)::UInt8) if tag != UNDEFREF_TAG @@ -1494,9 +1499,6 @@ function deserialize_typename(s::AbstractSerializer, number) @eval Core.kwcall(kwargs::NamedTuple, f::$ty, args...) = $kws(kwargs, f, args...) end end - elseif makenew - mt = Symbol.name.mt - ccall(:jl_set_nth_field, Cvoid, (Any, Csize_t, Any), tn, Base.fieldindex(Core.TypeName, :mt)-1, mt) end return tn end diff --git a/stdlib/Sockets/test/runtests.jl b/stdlib/Sockets/test/runtests.jl index 5a822315ba2cd..26f95d4ce1819 100644 --- a/stdlib/Sockets/test/runtests.jl +++ b/stdlib/Sockets/test/runtests.jl @@ -547,12 +547,14 @@ end fetch(r) end - let addr = Sockets.InetAddr(ip"192.0.2.5", 4444) + let addr = Sockets.InetAddr(ip"127.0.0.1", 4444) + srv = listen(addr) s = Sockets.TCPSocket() Sockets.connect!(s, addr) r = @async close(s) @test_throws Base._UVError("connect", Base.UV_ECANCELED) Sockets.wait_connected(s) fetch(r) + close(srv) end end diff --git a/stdlib/SparseArrays.version b/stdlib/SparseArrays.version index f690a34eb5ae4..4e9de62c06d6f 100644 --- a/stdlib/SparseArrays.version +++ b/stdlib/SparseArrays.version @@ -1,4 +1,4 @@ -SPARSEARRAYS_BRANCH = main -SPARSEARRAYS_SHA1 = 72c7cac6bbf21367a3c2fbc5c50e908aea5984bb +SPARSEARRAYS_BRANCH = release-1.12 +SPARSEARRAYS_SHA1 = cdbad55530fba0c7aa27d4bcc64dde2204ff133f 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/Test/src/Test.jl b/stdlib/Test/src/Test.jl index e8d670b3d7d00..20a1df8e773bd 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -230,7 +230,8 @@ struct Error <: Result end if test_type === :test_error || test_type === :nontest_error bt_str = try # try the latest world for this, since we might have eval'd new code for show - Base.invokelatest(sprint, Base.show_exception_stack, bt; context=stdout) + # Apply REPL backtrace scrubbing to hide REPL internals, similar to how REPL.jl handles it + Base.invokelatest(sprint, Base.show_exception_stack, Base.scrub_repl_backtrace(bt); context=stdout) catch ex "#=ERROR showing exception stack=# " * try @@ -1664,6 +1665,10 @@ end trigger_test_failure_break(@nospecialize(err)) = ccall(:jl_test_failure_breakpoint, Cvoid, (Any,), err) +is_failfast_error(err::FailFastError) = true +is_failfast_error(err::LoadError) = is_failfast_error(err.error) # handle `include` barrier +is_failfast_error(err) = false + """ Generate the code for an `@testset` with a `let` argument. """ @@ -1775,7 +1780,7 @@ function testset_beginend_call(args, tests, source) # something in the test block threw an error. Count that as an # error in this test set trigger_test_failure_break(err) - if err isa FailFastError + if is_failfast_error(err) get_testset_depth() > 1 ? rethrow() : failfast_print() else record(ts, Error(:nontest_error, Expr(:tuple), err, Base.current_exceptions(), $(QuoteNode(source)))) @@ -1863,7 +1868,9 @@ function testset_forloop(args, testloop, source) # Something in the test block threw an error. Count that as an # error in this test set trigger_test_failure_break(err) - if !isa(err, FailFastError) + if is_failfast_error(err) + get_testset_depth() > 1 ? rethrow() : failfast_print() + else record(ts, Error(:nontest_error, Expr(:tuple), err, Base.current_exceptions(), $(QuoteNode(source)))) end end @@ -2153,30 +2160,7 @@ function detect_ambiguities(mods::Module...; end end end - work = Base.loaded_modules_array() - filter!(mod -> mod === parentmodule(mod), work) # some items in loaded_modules_array are not top modules (really just Base) - while !isempty(work) - mod = pop!(work) - for n in names(mod, all = true) - Base.isdeprecated(mod, n) && continue - if !isdefined(mod, n) - if is_in_mods(mod, recursive, mods) - if allowed_undefineds === nothing || GlobalRef(mod, n) ∉ allowed_undefineds - println("Skipping ", mod, '.', n) # typically stale exports - end - end - continue - end - f = Base.unwrap_unionall(getfield(mod, n)) - if isa(f, Module) && f !== mod && parentmodule(f) === mod && nameof(f) === n - push!(work, f) - elseif isa(f, DataType) && isdefined(f.name, :mt) && parentmodule(f) === mod && nameof(f) === n && f.name.mt !== Symbol.name.mt && f.name.mt !== DataType.name.mt - examine(f.name.mt) - end - end - end - examine(Symbol.name.mt) - examine(DataType.name.mt) + examine(Core.GlobalMethods) return collect(ambs) end @@ -2224,30 +2208,7 @@ function detect_unbound_args(mods...; push!(ambs, m) end end - work = Base.loaded_modules_array() - filter!(mod -> mod === parentmodule(mod), work) # some items in loaded_modules_array are not top modules (really just Base) - while !isempty(work) - mod = pop!(work) - for n in names(mod, all = true) - Base.isdeprecated(mod, n) && continue - if !isdefined(mod, n) - if is_in_mods(mod, recursive, mods) - if allowed_undefineds === nothing || GlobalRef(mod, n) ∉ allowed_undefineds - println("Skipping ", mod, '.', n) # typically stale exports - end - end - continue - end - f = Base.unwrap_unionall(getfield(mod, n)) - if isa(f, Module) && f !== mod && parentmodule(f) === mod && nameof(f) === n - push!(work, f) - elseif isa(f, DataType) && isdefined(f.name, :mt) && parentmodule(f) === mod && nameof(f) === n && f.name.mt !== Symbol.name.mt && f.name.mt !== DataType.name.mt - examine(f.name.mt) - end - end - end - examine(Symbol.name.mt) - examine(DataType.name.mt) + examine(Core.GlobalMethods) return collect(ambs) end diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index 02523dc6fd911..66cab6c6aabbe 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -1348,7 +1348,7 @@ end @test occursin(expected, result) end end - @testset "failfast" begin + @testset "failfast begin-end" begin expected = r""" Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds @@ -1373,6 +1373,32 @@ end @test occursin(expected, result) end end + @testset "failfast for-loop" begin + expected = r""" + Test Summary: \| Fail Total +Time + Foo \| 1 1 \s*\d*\.\ds + 1 \| 1 1 \s*\d*\.\ds + """ + mktemp() do f, _ + write(f, + """ + using Test + + @testset "Foo" failfast=true begin + @testset "\$x" for x in 1:2 + @test false + end + @testset "Bar" begin + @test false + @test true + end + end + """) + cmd = `$(Base.julia_cmd()) --startup-file=no --color=no $f` + result = read(pipeline(ignorestatus(cmd), stderr=devnull), String) + @test occursin(expected, result) + end + end @testset "failfast passes to child testsets" begin expected = r""" Test Summary: \| Fail Total +Time diff --git a/stdlib/Unicode/test/runtests.jl b/stdlib/Unicode/test/runtests.jl index 7fa57508cffbf..2af7015afa249 100644 --- a/stdlib/Unicode/test/runtests.jl +++ b/stdlib/Unicode/test/runtests.jl @@ -284,6 +284,8 @@ end @test_throws BoundsError graphemes("äöüx", 2:5) @test_throws BoundsError graphemes("äöüx", 5:5) @test_throws ArgumentError graphemes("äöüx", 0:1) + + @test @allocated(length(graphemes("äöüx"))) == 0 end @testset "#3721, #6939 up-to-date character widths" begin diff --git a/stdlib/libLLVM_jll/Project.toml b/stdlib/libLLVM_jll/Project.toml index f6c343d878abb..32b1c5509b802 100644 --- a/stdlib/libLLVM_jll/Project.toml +++ b/stdlib/libLLVM_jll/Project.toml @@ -1,6 +1,6 @@ name = "libLLVM_jll" uuid = "8f36deef-c2a5-5394-99ed-8e07531fb29a" -version = "18.1.7+4" +version = "18.1.7+5" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/libblastrampoline_jll/Project.toml b/stdlib/libblastrampoline_jll/Project.toml index d1dde4c6074a7..ea4f645dc153c 100644 --- a/stdlib/libblastrampoline_jll/Project.toml +++ b/stdlib/libblastrampoline_jll/Project.toml @@ -1,13 +1,13 @@ name = "libblastrampoline_jll" uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.12.0+0" +version = "5.13.1+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [compat] -julia = "1.12" +julia = "1.13" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/sysimage.mk b/sysimage.mk index 55a28695acceb..abb5243de4275 100644 --- a/sysimage.mk +++ b/sysimage.mk @@ -70,14 +70,14 @@ RELDATADIR := $(call rel_path,$(JULIAHOME)/base,$(build_datarootdir))/ # <-- mak $(build_private_libdir)/basecompiler.ji: $(COMPILER_SRCS) @$(call PRINT_JULIA, cd $(JULIAHOME)/base && \ JULIA_NUM_THREADS=1 $(call spawn,$(JULIA_EXECUTABLE)) -C "$(JULIA_CPU_TARGET)" $(HEAPLIM) --output-ji $(call cygpath_w,$@).tmp \ - --startup-file=no --warn-overwrite=yes -g$(BOOTSTRAP_DEBUG_LEVEL) -O1 Base_compiler.jl --buildroot $(RELBUILDROOT) --dataroot $(RELDATADIR)) + --startup-file=no --warn-overwrite=yes --depwarn=error -g$(BOOTSTRAP_DEBUG_LEVEL) -O1 Base_compiler.jl --buildroot $(RELBUILDROOT) --dataroot $(RELDATADIR)) @mv $@.tmp $@ $(build_private_libdir)/sys.ji: $(build_private_libdir)/basecompiler.ji $(JULIAHOME)/VERSION $(BASE_SRCS) $(STDLIB_SRCS) @$(call PRINT_JULIA, cd $(JULIAHOME)/base && \ if ! JULIA_BINDIR=$(call cygpath_w,$(build_bindir)) WINEPATH="$(call cygpath_w,$(build_bindir));$$WINEPATH" \ JULIA_NUM_THREADS=1 $(call spawn, $(JULIA_EXECUTABLE)) -g1 -O1 -C "$(JULIA_CPU_TARGET)" $(HEAPLIM) --output-ji $(call cygpath_w,$@).tmp $(JULIA_SYSIMG_BUILD_FLAGS) \ - --startup-file=no --warn-overwrite=yes --sysimage $(call cygpath_w,$<) sysimg.jl --buildroot $(RELBUILDROOT) --dataroot $(RELDATADIR); then \ + --startup-file=no --warn-overwrite=yes --depwarn=error --sysimage $(call cygpath_w,$<) sysimg.jl --buildroot $(RELBUILDROOT) --dataroot $(RELDATADIR); then \ echo '*** This error might be fixed by running `make clean`. If the error persists$(COMMA) try `make cleanall`. ***'; \ false; \ fi ) @@ -93,7 +93,7 @@ $$(build_private_libdir)/sys$1-o.a $$(build_private_libdir)/sys$1-bc.a : $$(buil JULIA_DEPOT_PATH=':' \ JULIA_NUM_THREADS=1 \ $$(call spawn, $3) $2 -C "$$(JULIA_CPU_TARGET)" $$(HEAPLIM) --output-$$* $$(call cygpath_w,$$@).tmp $$(JULIA_SYSIMG_BUILD_FLAGS) \ - --startup-file=no --warn-overwrite=yes --sysimage $$(call cygpath_w,$$<) $$(call cygpath_w,$$(JULIAHOME)/contrib/generate_precompile.jl) $(JULIA_PRECOMPILE); then \ + --startup-file=no --warn-overwrite=yes --depwarn=error --sysimage $$(call cygpath_w,$$<) $$(call cygpath_w,$$(JULIAHOME)/contrib/generate_precompile.jl) $(JULIA_PRECOMPILE); then \ echo '*** This error is usually fixed by running `make clean`. If the error persists$$(COMMA) try `make cleanall`. ***'; \ false; \ fi ) diff --git a/test/Makefile b/test/Makefile index 9b151cd213274..69b7ad1451d0f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -24,7 +24,7 @@ EMBEDDING_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(SRCDIR)/embedding" "CC=$(CC GCEXT_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(SRCDIR)/gcext" "CC=$(CC)" -TRIMMING_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(JULIAHOME)/usr/bin" "CC=$(CC)" +TRIMMING_ARGS := "JULIA=$(JULIA_EXECUTABLE)" "BIN=$(SRCDIR)/trimming" "CC=$(CC)" default: diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 446102bc625d1..fae2cc2d982e5 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -831,6 +831,9 @@ function test_cat(::Type{TestAbstractArray}) r = rand(Float32, 56, 56, 64, 1); f(r) = cat(r, r, dims=(3,)) @inferred f(r); + + #58866 - ensure proper dimension calculation for 0-dimension elements + @test [zeros(1, 0) zeros(1,0); zeros(0,0) zeros(0, 0)] == Matrix{Float64}(undef, 1, 0) end function test_ind2sub(::Type{TestAbstractArray}) @@ -1743,6 +1746,9 @@ using Base: typed_hvncat @test ["A";;"B";;"C";;"D"] == ["A" "B" "C" "D"] @test ["A";"B";;"C";"D"] == ["A" "C"; "B" "D"] @test [["A";"B"];;"C";"D"] == ["A" "C"; "B" "D"] + + #58866 - ensure proper dimension calculation for 0-dimension elements + @test [zeros(1, 0) zeros(1,0);;; zeros(0,0) zeros(0, 0)] == Array{Float64, 3}(undef, 1, 0, 0) end @testset "stack" begin diff --git a/test/arrayops.jl b/test/arrayops.jl index d5fba79c47017..836bbb1daec9a 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -100,6 +100,18 @@ using Dates @test Array{eltype(a)}(a) !== a @test Vector(a) !== a end +@testset "effect inference for `reshape` for `Array`" begin + for Arr ∈ (Array{<:Any, 0}, Vector, Matrix, Array{<:Any, 3}) + for Shape ∈ (Tuple{Int}, Tuple{Int, Int}) + effects = Base.infer_effects(reshape, Tuple{Arr{Float32}, Shape}) + @test Base.Compiler.is_effect_free(effects) + @test Base.Compiler.is_terminates(effects) + @test Base.Compiler.is_notaskstate(effects) + @test Base.Compiler.is_noub(effects) + @test Base.Compiler.is_nortcall(effects) + end + end +end @testset "reshaping SubArrays" begin a = Array(reshape(1:5, 1, 5)) @testset "linearfast" begin diff --git a/test/channels.jl b/test/channels.jl index 721eb478bd13a..f646b41cfa1a0 100644 --- a/test/channels.jl +++ b/test/channels.jl @@ -463,14 +463,15 @@ end cb = first(async.cond.waitq) @test isopen(async) ccall(:uv_async_send, Cvoid, (Ptr{Cvoid},), async) + ccall(:uv_async_send, Cvoid, (Ptr{Cvoid},), async) + @test isempty(Base.Workqueue) Base.process_events() # schedule event Sys.iswindows() && Base.process_events() # schedule event (windows?) + @test length(Base.Workqueue) == 1 ccall(:uv_async_send, Cvoid, (Ptr{Cvoid},), async) @test tc[] == 0 yield() # consume event @test tc[] == 1 - ccall(:uv_async_send, Cvoid, (Ptr{Cvoid},), async) - Base.process_events() Sys.iswindows() && Base.process_events() # schedule event (windows?) yield() # consume event @test tc[] == 2 diff --git a/test/clangsa/MissingRoots.c b/test/clangsa/MissingRoots.c index 0a0d5369eba44..84341f9410e1e 100644 --- a/test/clangsa/MissingRoots.c +++ b/test/clangsa/MissingRoots.c @@ -277,20 +277,6 @@ void nonconst_loads2() static inline void look_at_value2(jl_value_t *v) { look_at_value(v); } -void mtable(jl_value_t *f) { - look_at_value2((jl_value_t*)jl_gf_mtable(f)); - jl_value_t *val = NULL; - JL_GC_PUSH1(&val); - val = (jl_value_t*)jl_gf_mtable(f); - JL_GC_POP(); -} - -void mtable2(jl_value_t **v) { - jl_value_t *val = NULL; - JL_GC_PUSH1(&val); - val = (jl_value_t*)jl_gf_mtable(v[2]); - JL_GC_POP(); -} void tparam0(jl_value_t *atype) { look_at_value(jl_tparam0(atype)); diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index f5325c9eb67ce..09cb4c1d6bf9a 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -351,6 +351,7 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` # -t, --threads code = "print(Threads.threadpoolsize())" + code2 = "print(Threads.maxthreadid())" cpu_threads = ccall(:jl_effective_threads, Int32, ()) @test string(cpu_threads) == read(`$exename --threads auto -e $code`, String) == @@ -361,6 +362,11 @@ let exename = `$(Base.julia_cmd()) --startup-file=no --color=no` withenv("JULIA_NUM_THREADS" => nt) do @test read(`$exename --threads=2 -e $code`, String) == read(`$exename -t 2 -e $code`, String) == "2" + if nt === nothing + @test read(`$exename -e $code2`, String) == "2" #default + interactive + elseif nt == "1" + @test read(`$exename -e $code2`, String) == "1" #if user asks for 1 give 1 + end end end # We want to test oversubscription, but on manycore machines, this can @@ -1281,3 +1287,6 @@ end end end end + +# https://github.com/JuliaLang/julia/issues/58229 Recursion in jitlinking with inline=no +@test success(`$(Base.julia_cmd()) --inline=no -e 'Base.compilecache(Base.identify_package("Pkg"))'`) diff --git a/test/core.jl b/test/core.jl index 5f7f857ad6e35..63ee04ddc0c41 100644 --- a/test/core.jl +++ b/test/core.jl @@ -17,10 +17,11 @@ for (T, c) in ( (Core.CodeInstance, [:def, :owner, :rettype, :exctype, :rettype_const, :analysis_results, :time_infer_total, :time_infer_cache_saved, :time_infer_self]), (Core.Method, [#=:name, :module, :file, :line, :primary_world, :sig, :slot_syms, :external_mt, :nargs, :called, :nospecialize, :nkw, :isva, :is_for_opaque_closure, :constprop=#]), (Core.MethodInstance, [#=:def, :specTypes, :sparam_vals=#]), - (Core.MethodTable, [:module]), + (Core.MethodTable, [:cache, :module, :name]), + (Core.MethodCache, []), (Core.TypeMapEntry, [:sig, :simplesig, :guardsigs, :func, :isleafsig, :issimplesig, :va]), (Core.TypeMapLevel, []), - (Core.TypeName, [:name, :module, :names, :wrapper, :mt, :hash, :n_uninitialized, :flags]), + (Core.TypeName, [:name, :module, :names, :wrapper, :hash, :n_uninitialized, :flags]), (DataType, [:name, :super, :parameters, :instance, :hash]), (TypeVar, [:name, :ub, :lb]), (Core.Memory, [:length, :ptr]), @@ -35,12 +36,13 @@ end for (T, c) in ( (Core.CodeInfo, []), (Core.CodeInstance, [:next, :min_world, :max_world, :inferred, :edges, :debuginfo, :ipo_purity_bits, :invoke, :specptr, :specsigflags, :precompile, :time_compile]), - (Core.Method, [:primary_world, :dispatch_status]), - (Core.MethodInstance, [:cache, :flags]), - (Core.MethodTable, [:defs, :leafcache, :cache, :max_args]), + (Core.Method, [:primary_world, :did_scan_source, :dispatch_status]), + (Core.MethodInstance, [:cache, :flags, :dispatch_status]), + (Core.MethodTable, [:defs]), + (Core.MethodCache, [:leafcache, :cache, :var""]), (Core.TypeMapEntry, [:next, :min_world, :max_world]), (Core.TypeMapLevel, [:arg1, :targ, :name1, :tname, :list, :any]), - (Core.TypeName, [:cache, :linearcache, :cache_entry_count]), + (Core.TypeName, [:cache, :linearcache, :Typeofwrapper, :max_args, :cache_entry_count]), (DataType, [:types, :layout]), (Core.Memory, []), (Core.GenericMemoryRef, []), @@ -2634,11 +2636,14 @@ struct D14919 <: Function; end @test B14919()() == "It's a brand new world" @test C14919()() == D14919()() == "Boo." -for f in (:Any, :Function, :(Core.Builtin), :(Union{Nothing, Type}), :(Union{typeof(+), Type}), :(Union{typeof(+), typeof(-)}), :(Base.Callable)) - @test_throws ErrorException("Method dispatch is unimplemented currently for this method signature") @eval (::$f)() = 1 -end -for f in (:(Core.getfield), :((::typeof(Core.getfield))), :((::Core.IntrinsicFunction))) - @test_throws ErrorException("cannot add methods to a builtin function") @eval $f() = 1 +let ex = ErrorException("cannot add methods to a builtin function") + for f in (:(Core.Any), :(Core.Function), :(Core.Builtin), :(Base.Callable), :(Union{Nothing,F} where F), :(typeof(Core.getfield)), :(Core.IntrinsicFunction)) + @test_throws ex @eval (::$f)() = 1 + end + @test_throws ex @eval (::Union{Nothing,F})() where {F<:Function} = 1 + for f in (:(Core.getfield),) + @test_throws ex @eval $f() = 1 + end end # issue #33370 @@ -5079,7 +5084,7 @@ function f16340(x::T) where T return g end let g = f16340(1) - @test isa(typeof(g).name.mt.defs.sig, UnionAll) + @test isa(only(methods(g)).sig, UnionAll) end # issue #16793 diff --git a/test/errorshow.jl b/test/errorshow.jl index bca5475b07901..d992d478c3978 100644 --- a/test/errorshow.jl +++ b/test/errorshow.jl @@ -852,7 +852,8 @@ end # Check error message first errorMsg = sprint(Base.showerror, ex) - @test occursin("FieldError: type FieldFoo has no field `c`", errorMsg) + @test occursin("FieldError: type", errorMsg) + @test occursin("FieldFoo has no field `c`", errorMsg) @test occursin("available fields: `a`, `b`", errorMsg) @test occursin("Available properties: `x`, `y`", errorMsg) @@ -877,6 +878,24 @@ end @test occursin(hintExpected, errorMsg) end +module FieldErrorTest +struct Point end +p = Point() +end + +@testset "FieldError with changing fields" begin + # https://discourse.julialang.org/t/better-error-message-for-modified-structs-in-julia-1-12/129265 + err_str1 = @except_str FieldErrorTest.p.x FieldError + @test occursin("FieldErrorTest.Point", err_str1) + @eval FieldErrorTest struct Point{T} + x::T + y::T + end + err_str2 = @except_str FieldErrorTest.p.x FieldError + @test occursin("@world", err_str2) + @test occursin("FieldErrorTest.Point", err_str2) +end + # UndefVar error hints module A53000 export f diff --git a/test/misc.jl b/test/misc.jl index 6c8d76fa1cd1a..b51c5a2553825 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -1614,10 +1614,10 @@ end let errs = IOBuffer() run(`$(Base.julia_cmd()) -e ' using Test - @test isdefined(DataType.name.mt, :backedges) + @test !isempty(Core.GlobalMethods.backedges) Base.Experimental.disable_new_worlds() @test_throws "disable_new_worlds" @eval f() = 1 - @test !isdefined(DataType.name.mt, :backedges) + @test isempty(Core.GlobalMethods.backedges) @test_throws "disable_new_worlds" Base.delete_method(which(+, (Int, Int))) @test 1+1 == 2 using Dates diff --git a/test/precompile.jl b/test/precompile.jl index c1ac8e03b2d1a..4cf2b2ae473e3 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -956,6 +956,23 @@ precompile_test_harness("code caching") do dir use_stale(c) = stale(c[1]) + not_stale("hello") build_stale(x) = use_stale(Any[x]) + # bindings + struct InvalidatedBinding + x::Int + end + struct Wrapper + ib::InvalidatedBinding + end + makewib(x) = Wrapper(InvalidatedBinding(x)) + const gib = makewib(1) + fib() = gib.ib.x + + struct LogBindingInvalidation + x::Int + end + const glbi = LogBindingInvalidation(1) + flbi() = @__MODULE__().glbi.x + # force precompilation build_stale(37) stale('c') @@ -980,11 +997,15 @@ precompile_test_harness("code caching") do dir useA() = $StaleA.stale("hello") useA2() = useA() + useflbi() = $StaleA.flbi() + # force precompilation begin Base.Experimental.@force_compile useA2() + useflbi() end + precompile($StaleA.fib, ()) ## Reporting tests call_nbits(x::Integer) = $StaleA.nbits(x) @@ -1014,6 +1035,22 @@ precompile_test_harness("code caching") do dir @eval using $StaleA MA = invokelatest(getfield, @__MODULE__, StaleA) Base.eval(MA, :(nbits(::UInt8) = 8)) + Base.eval(MA, quote + struct InvalidatedBinding + x::Float64 + end + struct Wrapper + ib::InvalidatedBinding + end + const gib = makewib(2.0) + end) + # TODO: test a "method_globalref" invalidation also + Base.eval(MA, quote + struct LogBindingInvalidation # binding invalidations can't be done during precompilation + x::Float64 + end + const glbi = LogBindingInvalidation(2.0) + end) @eval using $StaleC invalidations = Base.StaticData.debug_method_invalidation(true) @eval using $StaleB @@ -1044,6 +1081,10 @@ precompile_test_harness("code caching") do dir m = only(methods(MC.call_buildstale)) mi = m.specializations::Core.MethodInstance @test hasvalid(mi, world) # was compiled with the new method + m = only(methods(MA.fib)) + mi = m.specializations::Core.MethodInstance + @test !hasvalid(mi, world) # invalidated by redefining `gib` before loading StaleB + @test MA.fib() === 2.0 # Reporting test (ensure SnoopCompile works) @test all(i -> isassigned(invalidations, i), eachindex(invalidations)) @@ -1070,6 +1111,16 @@ precompile_test_harness("code caching") do dir @test !hasvalid(mi, world) @test any(x -> x isa Core.CodeInstance && x.def === mi, invalidations) + idxb = findfirst(x -> x isa Core.Binding, invalidations) + @test invalidations[idxb+1] == "insert_backedges_callee" + idxv = findnext(==("verify_methods"), invalidations, idxb) + if invalidations[idxv-1].def.def.name === :getproperty + idxv = findnext(==("verify_methods"), invalidations, idxv+1) + end + @test invalidations[idxv-1].def.def.name === :flbi + idxv = findnext(==("verify_methods"), invalidations, idxv+1) + @test invalidations[idxv-1].def.def.name === :useflbi + m = only(methods(MB.map_nbits)) @test !hasvalid(m.specializations::Core.MethodInstance, world+1) # insert_backedges invalidations also trigger their backedges end @@ -1932,8 +1983,12 @@ precompile_test_harness("PkgCacheInspector") do load_path end 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 + for m in external_methods + m = m.func::Method + if m.name !== :f + @test m.name == :repl_cmd && m.nargs == 1 + end + end @test new_ext_cis === nothing || any(new_ext_cis) do ci mi = ci.def::Core.MethodInstance mi.specTypes == Tuple{typeof(Base.repl_cmd), Int, String} diff --git a/test/reduce.jl b/test/reduce.jl index f5140c8a34bd9..2f30fcb905808 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -299,19 +299,37 @@ end arr = zeros(N) @test minimum(arr) === 0.0 @test maximum(arr) === 0.0 + @test minimum(abs, arr) === 0.0 + @test maximum(abs, arr) === 0.0 + @test minimum(-, arr) === -0.0 + @test maximum(-, arr) === -0.0 arr[i] = -0.0 @test minimum(arr) === -0.0 @test maximum(arr) === 0.0 + @test minimum(abs, arr) === 0.0 + @test maximum(abs, arr) === 0.0 + @test minimum(-, arr) === -0.0 + @test maximum(-, arr) === 0.0 arr = -zeros(N) @test minimum(arr) === -0.0 @test maximum(arr) === -0.0 + @test minimum(abs, arr) === 0.0 + @test maximum(abs, arr) === 0.0 + @test minimum(-, arr) === 0.0 + @test maximum(-, arr) === 0.0 arr[i] = 0.0 @test minimum(arr) === -0.0 - @test maximum(arr) === 0.0 + @test maximum(arr) === 0.0 + @test minimum(abs, arr) === 0.0 + @test maximum(abs, arr) === 0.0 + @test minimum(-, arr) === -0.0 + @test maximum(-, arr) === 0.0 end end + + @test minimum(abs, fill(-0.0, 16)) === mapreduce(abs, (x,y)->min(x,y), fill(-0.0, 16)) === 0.0 end @testset "maximum works on generic order #30320" begin diff --git a/test/reflection.jl b/test/reflection.jl index fdb3c329c58da..2afb37072f24a 100644 --- a/test/reflection.jl +++ b/test/reflection.jl @@ -523,13 +523,13 @@ test_typed_ir_printing(g15714, Tuple{Vector{Float32}}, #@test used_dup_var_tested15715 @test used_unique_var_tested15714 -let li = typeof(fieldtype).name.mt.cache.func::Core.MethodInstance, +let li = only(methods(fieldtype)).unspecialized, lrepr = string(li), mrepr = string(li.def), lmime = repr("text/plain", li), mmime = repr("text/plain", li.def) - @test lrepr == lmime == "MethodInstance for fieldtype(...)" + @test lrepr == lmime == "MethodInstance for fieldtype(::Vararg{Any})" @test mrepr == "fieldtype(...) @ Core none:0" # simple print @test mmime == "fieldtype(...)\n @ Core none:0" # verbose print end diff --git a/test/reinterpretarray.jl b/test/reinterpretarray.jl index e6381329e4ec6..1d6748a89fb19 100644 --- a/test/reinterpretarray.jl +++ b/test/reinterpretarray.jl @@ -320,6 +320,23 @@ test_many_wrappers(fill(1.0, 5, 3), (identity, wrapper)) do a_ @test r[goodinds...] == -5 end end + +let a = rand(ComplexF32, 5) + r = reinterpret(reshape, Float32, a) + ref = Array(r) + + @test r[1, :, 1] == ref[1, :] + @test r[1, :, 1, 1, 1] == ref[1, :] + @test r[1, :, UInt8(1)] == ref[1, :] + + r[2, :, 1] .= 0f0 + ref[2, :] .= 0f0 + @test r[2, :, 1] == ref[2, :] + + @test r[4] == ref[4] + @test_throws BoundsError r[1, :, 2] +end + let ar = [(1,2), (3,4)] arr = reinterpret(reshape, Int, ar) @test @inferred(IndexStyle(arr)) == Base.IndexSCartesian2{2}() @@ -607,3 +624,9 @@ let R = reinterpret(reshape, Float32, ComplexF32[1.0f0+2.0f0*im, 4.0f0+3.0f0*im] @test !isassigned(R, 5) @test Array(R)::Matrix{Float32} == [1.0f0 4.0f0; 2.0f0 3.0f0] end + +@testset "issue #54623" begin + x = 0xabcdef01234567 + @test reinterpret(reshape, UInt8, fill(x)) == [0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00] + @test reinterpret(reshape, UInt8, [x]) == [0x67; 0x45; 0x23; 0x01; 0xef; 0xcd; 0xab; 0x00;;] +end diff --git a/test/show.jl b/test/show.jl index ffc9e228f5b39..7c51768579042 100644 --- a/test/show.jl +++ b/test/show.jl @@ -858,7 +858,7 @@ struct S45879{P} end let ms = methods(S45879) @test ms isa Base.MethodList @test length(ms) == 0 - @test sprint(show, Base.MethodList(Method[], typeof(S45879).name.mt)) isa String + @test sprint(show, Base.MethodList(Method[], typeof(S45879).name)) isa String end function f49475(a=12.0; b) end @@ -1651,7 +1651,7 @@ struct f_with_params{t} <: Function end end let io = IOBuffer() - show(io, MIME"text/html"(), ModFWithParams.f_with_params.body.name.mt) + show(io, MIME"text/html"(), methods(ModFWithParams.f_with_params{Int}())) @test occursin("ModFWithParams.f_with_params", String(take!(io))) end @@ -1803,10 +1803,10 @@ end anonfn_type_repr = "$modname.var\"$(typeof(anonfn).name.name)\"" @test repr(typeof(anonfn)) == anonfn_type_repr @test repr(anonfn) == anonfn_type_repr * "()" - @test repr("text/plain", anonfn) == "$(typeof(anonfn).name.mt.name) (generic function with 1 method)" + @test repr("text/plain", anonfn) == "$(typeof(anonfn).name.singletonname) (generic function with 1 method)" mkclosure = x->y->x+y clo = mkclosure(10) - @test repr("text/plain", clo) == "$(typeof(clo).name.mt.name) (generic function with 1 method)" + @test repr("text/plain", clo) == "$(typeof(clo).name.singletonname) (generic function with 1 method)" @test repr(UnionAll) == "UnionAll" end @@ -2458,6 +2458,7 @@ end @test string(Union{M37012.SimpleU, Nothing, T} where T) == "Union{Nothing, $(curmod_prefix)M37012.SimpleU, T} where T" @test string(Union{AbstractVector{T}, T} where T) == "Union{AbstractVector{T}, T} where T" @test string(Union{AbstractVector, T} where T) == "Union{AbstractVector, T} where T" +@test string(Union{Array, Memory}) == "Union{Array, Memory}" @test sprint(show, :(./)) == ":((./))" @test sprint(show, :((.|).(.&, b))) == ":((.|).((.&), b))" diff --git a/test/stacktraces.jl b/test/stacktraces.jl index ca553c2a2e801..3df0998fe88f6 100644 --- a/test/stacktraces.jl +++ b/test/stacktraces.jl @@ -90,7 +90,7 @@ f(x) = (y = h(x); y) trace = (try; f(3); catch; stacktrace(catch_backtrace()); end)[1:3] 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 + @test frame.func === typeof(func).name.singletonname # broken until #50082 can be addressed mi = isa(frame.linfo, Core.CodeInstance) ? frame.linfo.def : frame.linfo @test mi.def.module === which(func, (Any,)).module broken=inlined @@ -109,10 +109,10 @@ let src = Meta.lower(Main, quote let x = 1 end end).args[1]::Core.CodeInfo repr = string(sf) @test repr == "Toplevel MethodInstance thunk at b:3" end -let li = typeof(fieldtype).name.mt.cache.func::Core.MethodInstance, +let li = only(methods(fieldtype)).unspecialized, sf = StackFrame(:a, :b, 3, li, false, false, 0), repr = string(sf) - @test repr == "fieldtype(...) at b:3" + @test repr == "fieldtype(::Vararg{Any}) at b:3" end let ctestptr = cglobal((:ctest, "libccalltest")), diff --git a/test/strings/basic.jl b/test/strings/basic.jl index c3e0bcc501070..f36f45e9a2ce3 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -1078,6 +1078,7 @@ let s = "∀x∃y", u = codeunits(s) @test_throws Base.CanonicalIndexError (u[1] = 0x00) @test collect(u) == b"∀x∃y" @test Base.elsize(u) == Base.elsize(typeof(u)) == 1 + @test similar(typeof(u), 3) isa Vector{UInt8} end @testset "issue #24388" begin diff --git a/test/strings/util.jl b/test/strings/util.jl index bb87881bbaa1d..9ced27ee3f8d0 100644 --- a/test/strings/util.jl +++ b/test/strings/util.jl @@ -8,6 +8,8 @@ SubStr(s) = SubString("abc$(s)de", firstindex(s) + 3, lastindex(s) + 3) @test textwidth(c^3) == w*3 @test w == @invoke textwidth(c::AbstractChar) end + @test textwidth('\xc0\xa0') == 1 # overlong + @test textwidth('\xf0\x80\x80') == 1 # malformed for i in 0x00:0x7f # test all ASCII chars (which have fast path) w = Int(ccall(:utf8proc_charwidth, Cint, (UInt32,), i)) c = Char(i) diff --git a/test/syntax.jl b/test/syntax.jl index 9be2dff6c3cfa..9ced29245ea6b 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -592,10 +592,9 @@ let thismodule = @__MODULE__, @test !isdefined(M16096, :foo16096) @test !isdefined(M16096, :it) @test typeof(local_foo16096).name.module === thismodule - @test typeof(local_foo16096).name.mt.module === thismodule - @test getfield(thismodule, typeof(local_foo16096).name.mt.name) === local_foo16096 + @test getfield(thismodule, typeof(local_foo16096).name.singletonname) === local_foo16096 @test getfield(thismodule, typeof(local_foo16096).name.name) === typeof(local_foo16096) - @test !isdefined(M16096, typeof(local_foo16096).name.mt.name) + @test !isdefined(M16096, typeof(local_foo16096).name.singletonname) @test !isdefined(M16096, typeof(local_foo16096).name.name) end diff --git a/test/trimming/Makefile b/test/trimming/Makefile index 63114a2764570..c3145765655e7 100644 --- a/test/trimming/Makefile +++ b/test/trimming/Makefile @@ -16,7 +16,6 @@ endif # location of test source SRCDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) JULIAHOME := $(abspath $(SRCDIR)/../..) -BUILDSCRIPT := $(BIN)/../share/julia/juliac-buildscript.jl include $(JULIAHOME)/Make.inc # get the executable suffix, if any @@ -24,32 +23,36 @@ EXE := $(suffix $(abspath $(JULIA))) # get compiler and linker flags. (see: `contrib/julia-config.jl`) JULIA_CONFIG := $(JULIA) -e 'include(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "julia-config.jl"))' -- +JULIA_LIBDIR := $(shell $(JULIA) -e 'println(joinpath(Sys.BINDIR, "..", "lib"))' --) CPPFLAGS_ADD := CFLAGS_ADD = $(shell $(JULIA_CONFIG) --cflags) LDFLAGS_ADD = -lm $(shell $(JULIA_CONFIG) --ldflags --ldlibs) -ljulia-internal +# get the JuliaC build script +JULIAC_BUILDSCRIPT := $(shell $(JULIA) -e 'print(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "juliac", "juliac-buildscript.jl"))') + #============================================================================= -release: hello$(EXE) basic_jll$(EXE) +release: $(BIN)/hello$(EXE) $(BIN)/basic_jll$(EXE) -hello-o.a: $(SRCDIR)/hello.jl $(BUILDSCRIPT) - $(JULIA) -t 1 -J $(BIN)/../lib/julia/sys.$(SHLIB_EXT) --startup-file=no --history-file=no --output-o $@ --output-incremental=no --strip-ir --strip-metadata --experimental --trim $(BUILDSCRIPT) $< --output-exe true +$(BIN)/hello-o.a: $(SRCDIR)/hello.jl $(JULIAC_BUILDSCRIPT) + $(JULIA) -t 1 -J $(JULIA_LIBDIR)/julia/sys.$(SHLIB_EXT) --startup-file=no --history-file=no --output-o $@ --output-incremental=no --strip-ir --strip-metadata --experimental --trim $(JULIAC_BUILDSCRIPT) $< --output-exe true -basic_jll-o.a: $(SRCDIR)/basic_jll.jl $(BUILDSCRIPT) - $(JULIA) -t 1 -J $(BIN)/../lib/julia/sys.$(SHLIB_EXT) --startup-file=no --history-file=no --project=$(SRCDIR) -e "using Pkg; Pkg.instantiate()" - $(JULIA) -t 1 -J $(BIN)/../lib/julia/sys.$(SHLIB_EXT) --startup-file=no --history-file=no --project=$(SRCDIR) --output-o $@ --output-incremental=no --strip-ir --strip-metadata --experimental --trim $(BUILDSCRIPT) $< --output-exe true +$(BIN)/basic_jll-o.a: $(SRCDIR)/basic_jll.jl $(JULIAC_BUILDSCRIPT) + $(JULIA) -t 1 -J $(JULIA_LIBDIR)/julia/sys.$(SHLIB_EXT) --startup-file=no --history-file=no --project=$(SRCDIR) -e "using Pkg; Pkg.instantiate()" + $(JULIA) -t 1 -J $(JULIA_LIBDIR)/julia/sys.$(SHLIB_EXT) --startup-file=no --history-file=no --project=$(SRCDIR) --output-o $@ --output-incremental=no --strip-ir --strip-metadata --experimental --trim $(JULIAC_BUILDSCRIPT) $< --output-exe true -hello$(EXE): hello-o.a +$(BIN)/hello$(EXE): $(BIN)/hello-o.a $(CC) -o $@ $(WHOLE_ARCHIVE) $< $(NO_WHOLE_ARCHIVE) $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS) -basic_jll$(EXE): basic_jll-o.a +$(BIN)/basic_jll$(EXE): $(BIN)/basic_jll-o.a $(CC) -o $@ $(WHOLE_ARCHIVE) $< $(NO_WHOLE_ARCHIVE) $(CPPFLAGS_ADD) $(CPPFLAGS) $(CFLAGS_ADD) $(CFLAGS) $(LDFLAGS_ADD) $(LDFLAGS) -check: hello$(EXE) basic_jll$(EXE) - $(JULIA) --depwarn=error $(SRCDIR)/../runtests.jl $(SRCDIR)/trimming +check: $(BIN)/hello$(EXE) $(BIN)/basic_jll$(EXE) + $(JULIA) --depwarn=error $(SRCDIR)/trimming.jl $< clean: - -rm -f hello$(EXE) basic_jll$(EXE) hello-o.a basic_jll-o.a + -rm -f $(BIN)/hello$(EXE) $(BIN)/basic_jll$(EXE) $(BIN)/hello-o.a $(BIN)/basic_jll-o.a .PHONY: release clean check diff --git a/test/trimming/basic_jll.jl b/test/trimming/basic_jll.jl index fc0137dd4eab2..79b7699a25b31 100644 --- a/test/trimming/basic_jll.jl +++ b/test/trimming/basic_jll.jl @@ -1,14 +1,29 @@ -module MyApp - using Libdl using Zstd_jll -Base.@ccallable function main()::Cint - println(Core.stdout, "Julia! Hello, world!") - fptr = dlsym(Zstd_jll.libzstd_handle, :ZSTD_versionString) +# JLL usage at build-time should function as expected +Zstd_jll.__init__() +const build_ver = unsafe_string(ccall((:ZSTD_versionString, libzstd), Cstring, ())) + +function print_string(fptr::Ptr{Cvoid}) println(Core.stdout, unsafe_string(ccall(fptr, Cstring, ()))) - println(Core.stdout, unsafe_string(ccall((:ZSTD_versionString, libzstd), Cstring, ()))) - return 0 end +function @main(args::Vector{String})::Cint + # Test the basic "Hello, world!" + println(Core.stdout, "Julia! Hello, world!") + + # JLL usage at run-time should function as expected + ver = unsafe_string(ccall((:ZSTD_versionString, libzstd), Cstring, ())) + println(Core.stdout, ver) + @assert ver == build_ver + + sleep(0.01) + + # Add an indirection via `@cfunction` / 1-arg ccall + cfunc = @cfunction(print_string, Cvoid, (Ptr{Cvoid},)) + fptr = dlsym(Zstd_jll.libzstd_handle, :ZSTD_versionString) + ccall(cfunc, Cvoid, (Ptr{Cvoid},), fptr) + + return 0 end diff --git a/test/trimming/hello.jl b/test/trimming/hello.jl index fef25f9e8558f..579ef4e18de38 100644 --- a/test/trimming/hello.jl +++ b/test/trimming/hello.jl @@ -1,13 +1,10 @@ -module MyApp - world::String = "world!" const str = OncePerProcess{String}() do return "Hello, " * world end -Base.@ccallable function main()::Cint +function @main(args::Vector{String})::Cint println(Core.stdout, str()) + foreach(x->println(Core.stdout, x), args) return 0 end - -end diff --git a/test/trimming/trimming.jl b/test/trimming/trimming.jl index a752c69460ad4..5d55ed62b03a8 100644 --- a/test/trimming/trimming.jl +++ b/test/trimming/trimming.jl @@ -1,12 +1,15 @@ using Test +@test length(ARGS) == 1 +bindir = dirname(ARGS[1]) + let exe_suffix = splitext(Base.julia_exename())[2] - hello_exe = joinpath(@__DIR__, "hello" * exe_suffix) - @test readchomp(`$hello_exe`) == "Hello, world!" - @test filesize(hello_exe) < 2000000 + hello_exe = joinpath(bindir, "hello" * exe_suffix) + @test readchomp(`$hello_exe arg1 arg2`) == "Hello, world!\n$hello_exe\narg1\narg2" + @test filesize(hello_exe) < 2_000_000 - basic_jll_exe = joinpath(@__DIR__, "basic_jll" * exe_suffix) + basic_jll_exe = joinpath(bindir, "basic_jll" * exe_suffix) lines = split(readchomp(`$basic_jll_exe`), "\n") @test lines[1] == "Julia! Hello, world!" @test lines[2] == lines[3] diff --git a/test/worlds.jl b/test/worlds.jl index 0ac54c3192b24..e6fd407b9d30f 100644 --- a/test/worlds.jl +++ b/test/worlds.jl @@ -194,31 +194,26 @@ f_gen265(x::Type{Int}) = 3 # would have capped those specializations if they were still valid f26506(@nospecialize(x)) = 1 g26506(x) = Base.inferencebarrier(f26506)(x[1]) -z = Any["ABC"] +z26506 = Any["ABC"] f26506(x::Int) = 2 -g26506(z) # Places an entry for f26506(::String) in mt.name.cache +g26506(z26506) # Places an entry for f26506(::String) in MethodTable cache +w26506 = Base.get_world_counter() +cache26506 = ccall(:jl_mt_find_cache_entry, Any, (Any, Any, UInt), Core.GlobalMethods.cache, Tuple{typeof(f26506),String}, w26506)::Core.TypeMapEntry +@test cache26506.max_world === typemax(UInt) +w26506 = Base.get_world_counter() f26506(x::String) = 3 -let cache = typeof(f26506).name.mt.cache - # The entry we created above should have been truncated - @test cache.min_world == cache.max_world -end -c26506_1, c26506_2 = Condition(), Condition() -# Captures the world age -result26506 = Any[] -t = Task(()->begin - wait(c26506_1) - push!(result26506, g26506(z)) - notify(c26506_2) -end) -yield(t) +@test w26506+1 === Base.get_world_counter() +# The entry we created above should have been truncated +@test cache26506.max_world == w26506 +# Captures the world age on creation +t26506 = @task g26506(z26506) f26506(x::Float64) = 4 -let cache = typeof(f26506).name.mt.cache - # The entry we created above should have been truncated - @test cache.min_world == cache.max_world -end -notify(c26506_1) -wait(c26506_2) -@test result26506[1] == 3 +@test cache26506.max_world == w26506 +f26506(x::String) = 5 +# The entry we created above should not have been changed +@test cache26506.max_world == w26506 +@test fetch(schedule(t26506)) === 3 +@test g26506(z26506) === 5 # issue #38435 f38435(::Int, ::Any) = 1 @@ -441,6 +436,34 @@ idxi = findfirst(==(m58080i), logmeths) @test logmeths[end-1] == m58080s @test logmeths[end] == "jl_method_table_insert" +# logging binding invalidations +struct LogBindingInvalidation + x::Int +end +makelbi(x) = LogBindingInvalidation(x) +const glbi = makelbi(1) +oLBI, oglbi = LogBindingInvalidation, glbi +flbi() = @__MODULE__().glbi.x +flbi() +milbi1 = only(Base.specializations(only(methods(makelbi)))) +milbi2 = only(Base.specializations(only(methods(flbi)))) +logmeths = ccall(:jl_debug_method_invalidation, Any, (Cint,), 1) +struct LogBindingInvalidation + x::Float64 +end +const glbi = makelbi(2.0) +@test flbi() === 2.0 +ccall(:jl_debug_method_invalidation, Any, (Cint,), 0) +@test milbi1.cache.def ∈ logmeths +@test milbi2.cache.next.def ∈ logmeths +i = findfirst(x -> isa(x, Core.BindingPartition), logmeths) +T = logmeths[i].restriction +@test T === oLBI +@test logmeths[i+1] == "jl_maybe_log_binding_invalidation" +T = logmeths[end-1].restriction +@test T === oglbi +@test logmeths[end] == "jl_maybe_log_binding_invalidation" + # issue #50091 -- missing invoke edge affecting nospecialized dispatch module ExceptionUnwrapping @nospecialize