Skip to content

Commit

Permalink
Merge branch 'master' into annotated-stacktraces
Browse files Browse the repository at this point in the history
  • Loading branch information
DilumAluthge committed Feb 11, 2024
2 parents 97cebb1 + c4bec9a commit 27660a7
Show file tree
Hide file tree
Showing 147 changed files with 2,043 additions and 1,949 deletions.
8 changes: 7 additions & 1 deletion Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,12 @@ JCXXFLAGS += -DGC_VERIFY
JCFLAGS += -DGC_VERIFY
endif

ifneq ($(JL_STACK_SIZE),)
JCXXFLAGS += -DJL_STACK_SIZE=$(JL_STACK_SIZE)
JCFLAGS += -DJL_STACK_SIZE=$(JL_STACK_SIZE)
endif


ifeq ($(WITH_GC_DEBUG_ENV), 1)
JCXXFLAGS += -DGC_DEBUG_ENV
JCFLAGS += -DGC_DEBUG_ENV
Expand Down Expand Up @@ -1386,7 +1392,7 @@ endif
ifeq ($(OS), WINNT)
HAVE_SSP := 1
OSLIBS += -Wl,--export-all-symbols -Wl,--version-script=$(BUILDROOT)/src/julia.expmap \
$(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic
$(NO_WHOLE_ARCHIVE) -lpsapi -lkernel32 -lws2_32 -liphlpapi -lwinmm -ldbghelp -luserenv -lsecur32 -latomic -lole32
JLDFLAGS += -Wl,--stack,8388608
ifeq ($(ARCH),i686)
JLDFLAGS += -Wl,--large-address-aware
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Compiler/Runtime improvements
* A new `LazyLibrary` type is exported from `Libdl` for use in building chained lazy library
loads, primarily to be used within JLLs ([#50074]).
* Added support for annotating `Base.@assume_effects` on code blocks ([#52400]).
* The libuv library has been updated from a base of v1.44.2 to v1.48.0 ([#49937]).

Command-line option changes
---------------------------
Expand Down Expand Up @@ -86,6 +87,7 @@ New library functions
* `Sys.username()` can be used to return the current user's username ([#51897]).
* `wrap(Array, m::Union{MemoryRef{T}, Memory{T}}, dims)` is the safe counterpart to `unsafe_wrap` ([#52049]).
* `GC.logging_enabled()` can be used to test whether GC logging has been enabled via `GC.enable_logging` ([#51647]).
* `IdSet` is now exported from Base and considered public ([#53262]).

New library features
--------------------
Expand Down Expand Up @@ -139,6 +141,7 @@ Standard library changes
* Structured matrices now retain either the axes of the parent (for `Symmetric`/`Hermitian`/`AbstractTriangular`/`UpperHessenberg`), or that of the principal diagonal (for banded matrices) ([#52480]).
* `bunchkaufman` and `bunchkaufman!` now work for any `AbstractFloat`, `Rational` and their complex variants. `bunchkaufman` now supports `Integer` types, by making an internal conversion to `Rational{BigInt}`. Added new function `inertia` that computes the inertia of the diagonal factor given by the `BunchKaufman` factorization object of a real symmetric or Hermitian matrix. For complex symmetric matrices, `inertia` only computes the number of zero eigenvalues of the diagonal factor ([#51487]).
* Packages that specialize matrix-matrix `mul!` with a method signature of the form `mul!(::AbstractMatrix, ::MyMatrix, ::AbstractMatrix, ::Number, ::Number)` no longer encounter method ambiguities when interacting with `LinearAlgebra`. Previously, ambiguities used to arise when multiplying a `MyMatrix` with a structured matrix type provided by LinearAlgebra, such as `AbstractTriangular`, which used to necessitate additional methods to resolve such ambiguities. Similar sources of ambiguities have also been removed for matrix-vector `mul!` operations ([#52837]).
* `lu` and `issuccess(::LU)` now accept an `allowsingular` keyword argument. When set to `true`, a valid factorization with rank-deficient U factor will be treated as success instead of throwing an error. Such factorizations are now shown by printing the factors together with a "rank-deficient" note rather than printing a "Failed Factorization" message ([#52957]).

#### Logging
* New `@create_log_macro` macro for creating new log macros like `@info`, `@warn` etc. For instance
Expand Down
51 changes: 50 additions & 1 deletion base/abstractdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ end
Update `d`, removing elements for which `f` is `false`.
The function `f` is passed `key=>value` pairs.
# Example
# Examples
```jldoctest
julia> d = Dict(1=>"a", 2=>"b", 3=>"c")
Dict{Int64, String} with 3 entries:
Expand Down Expand Up @@ -579,6 +579,55 @@ _tablesz(x::T) where T <: Integer = x < 16 ? T(16) : one(T)<<(top_set_bit(x-one(

TP{K,V} = Union{Type{Tuple{K,V}},Type{Pair{K,V}}}

# This error is thrown if `grow_to!` cannot validate the contents of the iterator argument to it, which it does by testing the iteration protocol (isiterable) on it each time it is about to start iteration on it
_throw_dict_kv_error() = throw(ArgumentError("AbstractDict(kv): kv needs to be an iterator of 2-tuples or pairs"))

function grow_to!(dest::AbstractDict, itr)
applicable(iterate, itr) || _throw_dict_kv_error()
y = iterate(itr)
y === nothing && return dest
kv, st = y
applicable(iterate, kv) || _throw_dict_kv_error()
k = iterate(kv)
k === nothing && _throw_dict_kv_error()
k, kvst = k
v = iterate(kv, kvst)
v === nothing && _throw_dict_kv_error()
v, kvst = v
iterate(kv, kvst) === nothing || _throw_dict_kv_error()
if !(dest isa AbstractDict{typeof(k), typeof(v)})
dest = empty(dest, typeof(k), typeof(v))
end
dest[k] = v
return grow_to!(dest, itr, st)
end

function grow_to!(dest::AbstractDict{K,V}, itr, st) where {K, V}
y = iterate(itr, st)
while y !== nothing
kv, st = y
applicable(iterate, kv) || _throw_dict_kv_error()
kst = iterate(kv)
kst === nothing && _throw_dict_kv_error()
k, kvst = kst
vst = iterate(kv, kvst)
vst === nothing && _throw_dict_kv_error()
v, kvst = vst
iterate(kv, kvst) === nothing || _throw_dict_kv_error()
if isa(k, K) && isa(v, V)
dest[k] = v
else
new = empty(dest, promote_typejoin(K, typeof(k)), promote_typejoin(V, typeof(v)))
merge!(new, dest)
new[k] = v
return grow_to!(new, itr, st)
end
y = iterate(itr, st)
end
return dest
end


dict_with_eltype(DT_apply, kv, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv)
dict_with_eltype(DT_apply, kv::Generator, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv)
dict_with_eltype(DT_apply, ::Type{Pair{K,V}}) where {K,V} = DT_apply(K, V)()
Expand Down
6 changes: 3 additions & 3 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,13 @@ eval(Core, quote
end)

function CodeInstance(
mi::MethodInstance, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const),
mi::MethodInstance, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const),
@nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt,
ipo_effects::UInt32, effects::UInt32, @nospecialize(analysis_results),
relocatability::UInt8)
return ccall(:jl_new_codeinst, Ref{CodeInstance},
(Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, UInt32, Any, UInt8),
mi, rettype, exctype, inferred_const, inferred, const_flags, min_world, max_world,
(Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, UInt32, Any, UInt8),
mi, owner, rettype, exctype, inferred_const, inferred, const_flags, min_world, max_world,
ipo_effects, effects, analysis_results,
relocatability)
end
Expand Down
2 changes: 1 addition & 1 deletion base/cartesian.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Generate a function call expression with keyword arguments `kw...`. As
in the case of [`@ncall`](@ref), `sym` represents any number of function arguments, the
last of which may be an anonymous-function expression and is expanded into `N` arguments.
# Example
# Examples
```jldoctest
julia> using Base.Cartesian
Expand Down
9 changes: 5 additions & 4 deletions base/cmd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
abstract type AbstractCmd end

# libuv process option flags
const UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = UInt8(1 << 2)
const UV_PROCESS_DETACHED = UInt8(1 << 3)
const UV_PROCESS_WINDOWS_HIDE = UInt8(1 << 4)
const UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = UInt32(1 << 2)
const UV_PROCESS_DETACHED = UInt32(1 << 3)
const UV_PROCESS_WINDOWS_HIDE = UInt32(1 << 4)
const UV_PROCESS_WINDOWS_DISABLE_EXACT_NAME = UInt32(1 << 7)

struct Cmd <: AbstractCmd
exec::Vector{String}
Expand All @@ -14,7 +15,7 @@ struct Cmd <: AbstractCmd
env::Union{Vector{String},Nothing}
dir::String
cpus::Union{Nothing,Vector{UInt16}}
Cmd(exec::Vector{String}) =
Cmd(exec::Vector{<:AbstractString}) =
new(exec, false, 0x00, nothing, "", nothing)
Cmd(cmd::Cmd, ignorestatus, flags, env, dir, cpus = nothing) =
new(cmd.exec, ignorestatus, flags, env,
Expand Down
4 changes: 4 additions & 0 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3304,6 +3304,10 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
end
if rt === Bottom
ssavaluetypes[currpc] = Bottom
# Special case: Bottom-typed PhiNodes do not error (but must also be unused)
if isa(stmt, PhiNode)
continue
end
@goto find_next_bb
end
if changes !== nothing
Expand Down
17 changes: 12 additions & 5 deletions base/compiler/cicache.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ Internally, each `MethodInstance` keep a unique global cache of code instances
that have been created for the given method instance, stratified by world age
ranges. This struct abstracts over access to this cache.
"""
struct InternalCodeCache end
struct InternalCodeCache
owner::Any # `jl_egal` is used for comparison
end

function setindex!(cache::InternalCodeCache, ci::CodeInstance, mi::MethodInstance)
@assert ci.owner === cache.owner
ccall(:jl_mi_cache_insert, Cvoid, (Any, Any), mi, ci)
return cache
end

const GLOBAL_CI_CACHE = InternalCodeCache()

struct WorldRange
min_world::UInt
max_world::UInt
Expand Down Expand Up @@ -49,11 +50,11 @@ WorldView(wvc::WorldView, wr::WorldRange) = WorldView(wvc.cache, wr)
WorldView(wvc::WorldView, args...) = WorldView(wvc.cache, args...)

function haskey(wvc::WorldView{InternalCodeCache}, mi::MethodInstance)
return ccall(:jl_rettype_inferred, Any, (Any, UInt, UInt), mi, first(wvc.worlds), last(wvc.worlds)) !== nothing
return ccall(:jl_rettype_inferred, Any, (Any, Any, UInt, UInt), wvc.cache.owner, mi, first(wvc.worlds), last(wvc.worlds)) !== nothing
end

function get(wvc::WorldView{InternalCodeCache}, mi::MethodInstance, default)
r = ccall(:jl_rettype_inferred, Any, (Any, UInt, UInt), mi, first(wvc.worlds), last(wvc.worlds))
r = ccall(:jl_rettype_inferred, Any, (Any, Any, UInt, UInt), wvc.cache.owner, mi, first(wvc.worlds), last(wvc.worlds))
if r === nothing
return default
end
Expand All @@ -70,3 +71,9 @@ function setindex!(wvc::WorldView{InternalCodeCache}, ci::CodeInstance, mi::Meth
setindex!(wvc.cache, ci, mi)
return wvc
end

function code_cache(interp::AbstractInterpreter)
cache = InternalCodeCache(cache_owner(interp))
worlds = WorldRange(get_inference_world(interp))
return WorldView(cache, worlds)
end
2 changes: 1 addition & 1 deletion base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
idx += 1
prevloc = codeloc
end
if ssavaluetypes[idx] === Union{} && !(oldidx in sv.unreachable)
if ssavaluetypes[idx] === Union{} && !(oldidx in sv.unreachable) && !isa(code[idx], PhiNode)
# We should have converted any must-throw terminators to an equivalent w/o control-flow edges
@assert !isterminator(code[idx])

Expand Down
2 changes: 1 addition & 1 deletion base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ function CodeInstance(interp::AbstractInterpreter, result::InferenceResult,
end
end
# relocatability = isa(inferred_result, String) ? inferred_result[end] : UInt8(0)
return CodeInstance(result.linfo,
return CodeInstance(result.linfo, cache_owner(interp),
widenconst(result_type), widenconst(result.exc_result), rettype_const, inferred_result,
const_flags, first(valid_worlds), last(valid_worlds),
# TODO: Actually do something with non-IPO effects
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ the following methods to satisfy the `AbstractInterpreter` API requirement:
- `OptimizationParams(interp::NewInterpreter)` - return an `OptimizationParams` instance
- `get_inference_world(interp::NewInterpreter)` - return the world age for this interpreter
- `get_inference_cache(interp::NewInterpreter)` - return the local inference cache
- `code_cache(interp::NewInterpreter)` - return the global inference cache
- `cache_owner(interp::NewInterpreter)` - return the owner of any new cache entries
"""
:(AbstractInterpreter)

Expand Down Expand Up @@ -404,7 +404,7 @@ InferenceParams(interp::NativeInterpreter) = interp.inf_params
OptimizationParams(interp::NativeInterpreter) = interp.opt_params
get_inference_world(interp::NativeInterpreter) = interp.world
get_inference_cache(interp::NativeInterpreter) = interp.inf_cache
code_cache(interp::NativeInterpreter) = WorldView(GLOBAL_CI_CACHE, get_inference_world(interp))
cache_owner(interp::NativeInterpreter) = nothing

"""
already_inferred_quick_test(::AbstractInterpreter, ::MethodInstance)
Expand Down
34 changes: 9 additions & 25 deletions base/compiler/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -321,25 +321,6 @@ function iterate(iter::BackedgeIterator, i::Int=1)
return BackedgePair(item, backedges[i+1]::MethodInstance), i+2 # `invoke` calls
end

"""
add_invalidation_callback!(callback, mi::MethodInstance)
Register `callback` to be triggered upon the invalidation of `mi`.
`callback` should a function taking two arguments, `callback(replaced::MethodInstance, max_world::UInt32)`,
and it will be recursively invoked on `MethodInstance`s within the invalidation graph.
"""
function add_invalidation_callback!(@nospecialize(callback), mi::MethodInstance)
if !isdefined(mi, :callbacks)
callbacks = mi.callbacks = Any[callback]
else
callbacks = mi.callbacks::Vector{Any}
if !any(@nospecialize(cb)->cb===callback, callbacks)
push!(callbacks, callback)
end
end
return callbacks
end

#########
# types #
#########
Expand Down Expand Up @@ -415,15 +396,15 @@ function find_ssavalue_uses(body::Vector{Any}, nvals::Int)
if isa(e, SSAValue)
push!(uses[e.id], line)
elseif isa(e, Expr)
find_ssavalue_uses(e, uses, line)
find_ssavalue_uses!(uses, e, line)
elseif isa(e, PhiNode)
find_ssavalue_uses(e, uses, line)
find_ssavalue_uses!(uses, e, line)
end
end
return uses
end

function find_ssavalue_uses(e::Expr, uses::Vector{BitSet}, line::Int)
function find_ssavalue_uses!(uses::Vector{BitSet}, e::Expr, line::Int)
head = e.head
is_meta_expr_head(head) && return
skiparg = (head === :(=))
Expand All @@ -433,13 +414,16 @@ function find_ssavalue_uses(e::Expr, uses::Vector{BitSet}, line::Int)
elseif isa(a, SSAValue)
push!(uses[a.id], line)
elseif isa(a, Expr)
find_ssavalue_uses(a, uses, line)
find_ssavalue_uses!(uses, a, line)
end
end
end

function find_ssavalue_uses(e::PhiNode, uses::Vector{BitSet}, line::Int)
for val in e.values
function find_ssavalue_uses!(uses::Vector{BitSet}, e::PhiNode, line::Int)
values = e.values
for i = 1:length(values)
isassigned(values, i) || continue
val = values[i]
if isa(val, SSAValue)
push!(uses[val.id], line)
end
Expand Down
2 changes: 1 addition & 1 deletion base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,7 @@ second is used for rounding the imaginary components.
which rounds to the nearest integer, with ties (fractional values of 0.5)
being rounded to the nearest even integer.
# Example
# Examples
```jldoctest
julia> round(3.14 + 4.5im)
3.0 + 4.0im
Expand Down
40 changes: 1 addition & 39 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,45 +114,7 @@ const AnyDict = Dict{Any,Any}
Dict(ps::Pair{K,V}...) where {K,V} = Dict{K,V}(ps)
Dict(ps::Pair...) = Dict(ps)

function Dict(kv)
try
dict_with_eltype((K, V) -> Dict{K, V}, kv, eltype(kv))
catch
if !isiterable(typeof(kv)) || !all(x->isa(x,Union{Tuple,Pair}),kv)
throw(ArgumentError("Dict(kv): kv needs to be an iterator of tuples or pairs"))
else
rethrow()
end
end
end

function grow_to!(dest::AbstractDict{K, V}, itr) where V where K
y = iterate(itr)
y === nothing && return dest
((k,v), st) = y
dest2 = empty(dest, typeof(k), typeof(v))
dest2[k] = v
grow_to!(dest2, itr, st)
end

# this is a special case due to (1) allowing both Pairs and Tuples as elements,
# and (2) Pair being invariant. a bit annoying.
function grow_to!(dest::AbstractDict{K,V}, itr, st) where V where K
y = iterate(itr, st)
while y !== nothing
(k,v), st = y
if isa(k,K) && isa(v,V)
dest[k] = v
else
new = empty(dest, promote_typejoin(K,typeof(k)), promote_typejoin(V,typeof(v)))
merge!(new, dest)
new[k] = v
return grow_to!(new, itr, st)
end
y = iterate(itr, st)
end
return dest
end
Dict(kv) = dict_with_eltype((K, V) -> Dict{K, V}, kv, eltype(kv))

empty(a::AbstractDict, ::Type{K}, ::Type{V}) where {K, V} = Dict{K, V}()

Expand Down
Loading

0 comments on commit 27660a7

Please sign in to comment.