Skip to content

Commit

Permalink
some moer general cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Sep 25, 2023
1 parent fe3789c commit e89d249
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 95 deletions.
26 changes: 11 additions & 15 deletions base/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,29 +203,14 @@ include("views.jl")
include("baseext.jl")

include("c.jl")
# Initialize DL_LOAD_PATH as early as possible. We are defining things here in
# a slightly more verbose fashion than usual, because we're running so early.
const DL_LOAD_PATH = String[]
let os = ccall(:jl_get_UNAME, Any, ())
if os === :Darwin || os === :Apple
if Base.DARWIN_FRAMEWORK
push!(DL_LOAD_PATH, "@loader_path/Frameworks")
end
push!(DL_LOAD_PATH, "@loader_path")
end
end

include("ntuple.jl")

include("abstractdict.jl")
include("iddict.jl")
include("idset.jl")

include("iterators.jl")
using .Iterators: zip, enumerate, only
using .Iterators: Flatten, Filter, product # for generators
using .Iterators: Stateful # compat (was formerly used in reinterpretarray.jl)

include("namedtuple.jl")

# For OS specific stuff
Expand All @@ -241,6 +226,17 @@ function strcat(x::String, y::String)
end
include(strcat((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "build_h.jl")) # include($BUILDROOT/base/build_h.jl)
include(strcat((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "version_git.jl")) # include($BUILDROOT/base/version_git.jl)
# Initialize DL_LOAD_PATH as early as possible. We are defining things here in
# a slightly more verbose fashion than usual, because we're running so early.
const DL_LOAD_PATH = String[]
let os = ccall(:jl_get_UNAME, Any, ())
if os === :Darwin || os === :Apple
if Base.DARWIN_FRAMEWORK
push!(DL_LOAD_PATH, "@loader_path/Frameworks")
end
push!(DL_LOAD_PATH, "@loader_path")
end
end

# numeric operations
include("hashing.jl")
Expand Down
70 changes: 20 additions & 50 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -211,49 +211,17 @@ julia> Base.isbitsunion(Union{Float64, String})
false
```
"""
isbitsunion(u::Union) = allocatedinline(u)
isbitsunion(x) = false
isbitsunion(u::Type) = u isa Union && allocatedinline(u)

function _unsetindex!(A::Array{T}, i::Int) where {T}
function _unsetindex!(A::Array, i::Int)
@inline
@boundscheck checkbounds(A, i)
t = @_gc_preserve_begin A
p = Ptr{Ptr{Cvoid}}(pointer(A, i))
if !allocatedinline(T)
Intrinsics.atomic_pointerset(p, C_NULL, :monotonic)
elseif T isa DataType
if !datatype_pointerfree(T)
for j = 1:Core.sizeof(Ptr{Cvoid}):Core.sizeof(T)
Intrinsics.atomic_pointerset(p + j - 1, C_NULL, :monotonic)
end
end
end
@_gc_preserve_end t
@inbounds _unsetindex!(MemoryRef(A.ref, i))
return A
end


# TODO: deprecate this (aligned_sizeof and/or elsize and/or sizeof(Some{T}) are more correct)
"""
Base.bitsunionsize(U::Union) -> Int
For a `Union` of [`isbitstype`](@ref) types, return the size of the largest type; assumes `Base.isbitsunion(U) == true`.
# Examples
```jldoctest
julia> Base.bitsunionsize(Union{Float64, UInt8})
8
julia> Base.bitsunionsize(Union{Float64, UInt8, Int128})
16
```
"""
function bitsunionsize(u::Union)
isinline, sz, _ = uniontype_layout(u)
@assert isinline
return sz
end

elsize(::Type{A}) where {T,A<:Array{T}} = aligned_sizeof(T)
function elsize(::Type{Ptr{T}}) where T
# this only must return something valid for values which satisfy is_valid_intrinsic_elptr(T),
Expand Down Expand Up @@ -1144,12 +1112,12 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
unsafe_copyto!(newref, ref, i)
a.ref = newref
for j in i:i+delta-1
_unsetindex!(a, j)
@inbounds _unsetindex!(a, j)
end
elseif !prefer_start && memlen >= newmemlen
unsafe_copyto!(mem, offset+delta+i, mem, offset+i, len-i+1)
for j in i:i+delta-1
_unsetindex!(a, j)
@inbounds _unsetindex!(a, j)
end
else
# since we will allocate the array in the middle of the memory we need at least 2*delta extra space
Expand All @@ -1170,7 +1138,7 @@ function _deletebeg!(a::Vector, delta::Integer)
len = length(a)
0 <= delta <= len || throw(ArgumentError("_deleteat! requires delta in 0:length(a)"))
for i in 1:delta
_unsetindex!(a, i)
@inbounds _unsetindex!(a, i)
end
newlen = len - delta
if newlen != 0 # if newlen==0 we could accidentally index past the memory
Expand All @@ -1185,7 +1153,7 @@ function _deleteend!(a::Vector, delta::Integer)
0 <= delta <= len || throw(ArgumentError("_deleteat! requires delta in 0:length(a)"))
newlen = len - delta
for i in newlen+1:len
_unsetindex!(a, i)
@inbounds _unsetindex!(a, i)
end
a.size = (newlen,)
return
Expand Down Expand Up @@ -1782,17 +1750,19 @@ struct Nowhere; end
push!(::Nowhere, _) = nothing
_growend!(::Nowhere, _) = nothing

@inline function _push_deleted!(dltd, a::Vector, ind)
if @inbounds isassigned(a, ind)
push!(dltd, @inbounds a[ind])
function _push_deleted!(dltd, a::Vector, ind)
@_propagate_inbounds_meta
if isassigned(a, ind)
push!(dltd, a[ind])
else
_growend!(dltd, 1)
end
end

@inline function _copy_item!(a::Vector, p, q)
if @inbounds isassigned(a, q)
@inbounds a[p] = a[q]
function _copy_item!(a::Vector, p, q)
@_propagate_inbounds_meta
if isassigned(a, q)
a[p] = a[q]
else
_unsetindex!(a, p)
end
Expand All @@ -1804,7 +1774,7 @@ function _deleteat!(a::Vector, inds, dltd=Nowhere())
y === nothing && return a
(p, s) = y
checkbounds(a, p)
_push_deleted!(dltd, a, p)
@inbounds _push_deleted!(dltd, a, p)
q = p+1
while true
y = iterate(inds, s)
Expand All @@ -1818,14 +1788,14 @@ function _deleteat!(a::Vector, inds, dltd=Nowhere())
end
end
while q < i
_copy_item!(a, p, q)
@inbounds _copy_item!(a, p, q)
p += 1; q += 1
end
_push_deleted!(dltd, a, i)
@inbounds _push_deleted!(dltd, a, i)
q = i+1
end
while q <= n
_copy_item!(a, p, q)
@inbounds _copy_item!(a, p, q)
p += 1; q += 1
end
_deleteend!(a, n-p+1)
Expand All @@ -1838,7 +1808,7 @@ function deleteat!(a::Vector, inds::AbstractVector{Bool})
length(inds) == n || throw(BoundsError(a, inds))
p = 1
for (q, i) in enumerate(inds)
_copy_item!(a, p, q)
@inbounds _copy_item!(a, p, q)
p += !i
end
_deleteend!(a, n-p+1)
Expand Down
20 changes: 11 additions & 9 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1283,17 +1283,19 @@ end
fcnt = fieldcount_noerror(typ)
fcnt === nothing && return false
0 < fidx fcnt || return true # no undefined behavior if thrown
fidx datatype_min_ninitialized(typ) && return true # always defined
ftyp = fieldtype(typ, fidx)
is_undefref_fieldtype(ftyp) && return true
return fidx datatype_min_ninitialized(typ)
is_undefref_fieldtype(ftyp) && return true # always initialized
return false
end
# checks if a field of this type will not be initialized with undefined value
# and the access to that uninitialized field will cause and `UndefRefError`, e.g.,
# checks if a field of this type is guaranteed to be defined to a value
# and that access to an uninitialized field will cause an `UndefRefError` or return zero
# - is_undefref_fieldtype(String) === true
# - is_undefref_fieldtype(Integer) === true
# - is_undefref_fieldtype(Any) === true
# - is_undefref_fieldtype(Int) === false
# - is_undefref_fieldtype(Union{Int32,Int64}) === false
# - is_undefref_fieldtype(T) === false
function is_undefref_fieldtype(@nospecialize ftyp)
return !has_free_typevars(ftyp) && !allocatedinline(ftyp)
end
Expand Down Expand Up @@ -2063,15 +2065,15 @@ end

# whether getindex for the elements can potentially throw UndefRef
function array_type_undefable(@nospecialize(arytype))
arytype = unwrap_unionall(arytype)
if isa(arytype, Union)
return array_type_undefable(arytype.a) || array_type_undefable(arytype.b)
elseif isa(arytype, UnionAll)
return true
else
elmtype = memoryref_elemtype(arytype::DataType)
elseif arytype isa DataType
elmtype = memoryref_elemtype(arytype)
# TODO: use arraytype layout instead to derive this
return !(isbitstype(elmtype) || isbitsunion(elmtype))
return !((elmtype isa DataType && isbitstype(elmtype)) || (elmtype isa Union && isbitsunion(elmtype)))
end
return true
end

@nospecs function memoryset_typecheck(memtype, elemtype)
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function count_const_size(@nospecialize(x), count_self::Bool = true)
sz = count_self ? sizeof(dt) : 0
sz > MAX_INLINE_CONST_SIZE && return MAX_INLINE_CONST_SIZE + 1
dtfd = DataTypeFieldDesc(dt)
for i = 1:datatype_nfields(dt)
for i = 1:Int(datatype_nfields(dt))
isdefined(x, i) || continue
f = getfield(x, i)
if !dtfd[i].isptr && datatype_pointerfree(typeof(f))
Expand Down
30 changes: 19 additions & 11 deletions base/genericmemory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,27 @@ size(a::GenericMemory, d::Int) =
size(a::GenericMemory, d::Integer) = size(a, convert(d, Int))
size(a::GenericMemory) = (length(a),)

pointer(mem::GenericMemory, i::Int) = unsafe_convert(Ptr{Cvoid}, MemoryRef(mem, i))
function _unsetindex!(A::Memory{T}, i::Int) where {T}
pointer(mem::GenericMemory, i::Int) = (@_propagate_inbounds_meta; unsafe_convert(Ptr{Cvoid}, MemoryRef(mem, i))) # boundschecked, even for i==1
pointer(mem::MemoryRef) = unsafe_convert(Ptr{Cvoid}, mem) # no bounds check, even for empty array

_unsetindex!(A::Memory, i::Int) = (@_propagate_inbounds_meta; _unsetindex!(MemoryRef(A, i)); A)
function _unsetindex!(A::MemoryRef{:not_atomic,T}) where T
@_terminates_locally_meta
@_propagate_inbounds_meta
@inline
@boundscheck checkbounds(A, i)
t = @_gc_preserve_begin A
p = Ptr{Ptr{Cvoid}}(pointer(A, i))
# TODO(jwn): access datatype_layout from A instead
if !allocatedinline(T)
@boundscheck MemoryRef(A, 1)
mem = A.mem
MemT = typeof(mem)
arrayelem = datatype_arrayelem(MemT)
elsz = datatype_layoutsize(MemT)
isboxed = 1; isunion = 2
t = @_gc_preserve_begin mem
p = Ptr{Ptr{Cvoid}}(@inbounds pointer(A))
if arrayelem == isboxed
Intrinsics.atomic_pointerset(p, C_NULL, :monotonic)
elseif T isa DataType
if !datatype_pointerfree(T)
for j = 1:Core.sizeof(Ptr{Cvoid}):Core.sizeof(T)
elseif arrayelem != isunion
if !datatype_pointerfree(T::DataType)
for j = 1:Core.sizeof(Ptr{Cvoid}):elsz
Intrinsics.atomic_pointerset(p + j - 1, C_NULL, :monotonic)
end
end
Expand All @@ -65,7 +73,7 @@ function unsafe_copyto!(dest::MemoryRef{:not_atomic, T}, src::MemoryRef{:not_ato
@_terminates_locally_meta
n == 0 && return dest
@boundscheck MemoryRef(dest, n), MemoryRef(src, n)
ccall(:jl_genericmemory_copyto, Cvoid, (Any, Int, Any, Int, Int), dest.mem, dest.ptr, src.mem, src.ptr, Int(n))
ccall(:jl_genericmemory_copyto, Cvoid, (Any, Ptr{Cvoid}, Any, Ptr{Cvoid}, Int), dest.mem, dest.ptr, src.mem, src.ptr, Int(n))
return dest
end

Expand Down
2 changes: 1 addition & 1 deletion base/summarysize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ julia> Base.summarysize(1.0)
8
julia> Base.summarysize(Ref(rand(100)))
848
864
julia> sizeof(Ref(rand(100)))
8
Expand Down
2 changes: 1 addition & 1 deletion doc/src/base/c.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Base.unsafe_modify!
Base.unsafe_replace!
Base.unsafe_swap!
Base.unsafe_copyto!{T}(::Ptr{T}, ::Ptr{T}, ::Any)
Base.unsafe_copyto!{T}(::Array{T}, ::Any, ::Array{T}, ::Any, ::Any)
Base.unsafe_copyto!(::Array, ::Any, ::Array, ::Any, ::Any)
Base.copyto!
Base.pointer
Base.unsafe_wrap{T,N}(::Union{Type{Array},Type{Array{T}},Type{Array{T,N}}}, ::Ptr{T}, ::NTuple{N,Int})
Expand Down
2 changes: 2 additions & 0 deletions doc/src/devdocs/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ UnionAll
lb: Union{}
ub: Any
body: Array{T, N} <: DenseArray{T, N}
ref::MemoryRef{:not_atomic, T}
size::Tuple{Vararg{Int64, N}}
```

This indicates that `Array` actually names a `UnionAll` type. There is one `UnionAll` type for
Expand Down
6 changes: 3 additions & 3 deletions src/typemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(
jl_genericmemory_t *tname = jl_atomic_load_relaxed(&cache->tname); // reload after type-intersect
// couldn't figure out unique `a0` initial point, so scan all for matches
size_t i, l = tname->length;
_Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*) tname->data;
_Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*) jl_genericmemory_ptr_data(tname);
JL_GC_PUSH1(&tname);
for (i = 1; i < l; i += 2) {
jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i]);
Expand Down Expand Up @@ -1081,7 +1081,7 @@ jl_typemap_entry_t *jl_typemap_assoc_by_type(
else {
// doing subtype, but couldn't figure out unique `ty`, so scan all for supertypes
size_t i, l = name1->length;
_Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*) name1->data;
_Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*) jl_genericmemory_ptr_data(name1);
JL_GC_PUSH1(&name1);
for (i = 1; i < l; i += 2) {
jl_typemap_t *ml = jl_atomic_load_relaxed(&data[i]);
Expand Down Expand Up @@ -1237,7 +1237,7 @@ jl_typemap_entry_t *jl_typemap_level_assoc_exact(jl_typemap_level_t *cache, jl_v
else {
// couldn't figure out unique `name` initial point, so must scan all for matches
size_t i, l = tname->length;
_Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*) tname->data;
_Atomic(jl_typemap_t*) *data = (_Atomic(jl_typemap_t*)*) jl_genericmemory_ptr_data(tname);
JL_GC_PUSH1(&tname);
for (i = 1; i < l; i += 2) {
jl_typemap_t *ml_or_cache = jl_atomic_load_relaxed(&data[i]);
Expand Down
8 changes: 4 additions & 4 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6015,10 +6015,10 @@ const unboxedunions = [Union{Int8, Nothing},
@test Base.isbitsunion(unboxedunions[2])
@test Base.isbitsunion(unboxedunions[3])

@test Base.bitsunionsize(unboxedunions[1]) == 1
@test Base.bitsunionsize(unboxedunions[2]) == 2
@test Base.bitsunionsize(unboxedunions[3]) == 16
@test Base.bitsunionsize(unboxedunions[4]) == 8
@test Base.aligned_sizeof(unboxedunions[1]) == 1
@test Base.aligned_sizeof(unboxedunions[2]) == 2
@test Base.aligned_sizeof(unboxedunions[3]) == 16
@test Base.aligned_sizeof(unboxedunions[4]) == 8

@test sizeof(unboxedunions[1]) == 1
@test sizeof(unboxedunions[2]) == 2
Expand Down

0 comments on commit e89d249

Please sign in to comment.