Skip to content

Commit

Permalink
backport JuliaLang#54647
Browse files Browse the repository at this point in the history
  • Loading branch information
oscardssmith committed Jun 12, 2024
1 parent c057940 commit c3d1d77
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 87 deletions.
30 changes: 15 additions & 15 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ isbitsunion(u::Type) = u isa Union && allocatedinline(u)
function _unsetindex!(A::Array, i::Int)
@inline
@boundscheck checkbounds(A, i)
@inbounds _unsetindex!(GenericMemoryRef(A.ref, i))
@inbounds _unsetindex!(memoryref(A.ref, i))
return A
end

Expand All @@ -239,14 +239,14 @@ function isassigned(a::Array, i::Int...)
@_noub_if_noinbounds_meta
@boundscheck checkbounds(Bool, a, i...) || return false
ii = _sub2ind(size(a), i...)
return @inbounds isassigned(memoryref(a.ref, ii, false))
return @inbounds isassigned(memoryrefnew(a.ref, ii, false))
end

function isassigned(a::Vector, i::Int) # slight compiler simplification for the most common case
@inline
@_noub_if_noinbounds_meta
@boundscheck checkbounds(Bool, a, i) || return false
return @inbounds isassigned(memoryref(a.ref, i, false))
return @inbounds isassigned(memoryrefnew(a.ref, i, false))
end


Expand Down Expand Up @@ -281,7 +281,7 @@ the same manner as C.
"""
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
n == 0 && return dest
unsafe_copyto!(GenericMemoryRef(dest.ref, doffs), GenericMemoryRef(src.ref, soffs), n)
unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n)
return dest
end

Expand All @@ -303,8 +303,8 @@ function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Arr
n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
@boundscheck checkbounds(dest, doffs:doffs+n-1)
@boundscheck checkbounds(src, soffs:soffs+n-1)
@inbounds let dest = GenericMemoryRef(dest isa Array ? getfield(dest, :ref) : dest, doffs)
src = GenericMemoryRef(src isa Array ? getfield(src, :ref) : src, soffs)
@inbounds let dest = memoryref(dest isa Array ? getfield(dest, :ref) : dest, doffs)
src = memoryref(src isa Array ? getfield(src, :ref) : src, soffs)
unsafe_copyto!(dest, src, n)
end
return dest
Expand Down Expand Up @@ -1059,7 +1059,7 @@ function _growbeg!(a::Vector, delta::Integer)
setfield!(a, :size, (newlen,))
# if offset is far enough advanced to fit data in existing memory without copying
if delta <= offset - 1
setfield!(a, :ref, @inbounds GenericMemoryRef(ref, 1 - delta))
setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
else
@noinline (function()
memlen = length(mem)
Expand All @@ -1078,7 +1078,7 @@ function _growbeg!(a::Vector, delta::Integer)
newmem = array_new_memory(mem, newmemlen)
end
unsafe_copyto!(newmem, newoffset + delta, mem, offset, len)
setfield!(a, :ref, @inbounds GenericMemoryRef(newmem, newoffset))
setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
end)()
end
return
Expand Down Expand Up @@ -1113,7 +1113,7 @@ function _growend!(a::Vector, delta::Integer)
newmem = array_new_memory(mem, newmemlen2)
newoffset = offset
end
newref = @inbounds GenericMemoryRef(newmem, newoffset)
newref = @inbounds memoryref(newmem, newoffset)
unsafe_copyto!(newref, ref, len)
setfield!(a, :ref, newref)
end)()
Expand Down Expand Up @@ -1142,7 +1142,7 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
prefer_start = i <= div(len, 2)
# if offset is far enough advanced to fit data in beginning of the memory
if prefer_start && delta <= offset - 1
newref = @inbounds GenericMemoryRef(mem, offset - delta)
newref = @inbounds memoryref(mem, offset - delta)
unsafe_copyto!(newref, ref, i)
setfield!(a, :ref, newref)
for j in i:i+delta-1
Expand All @@ -1159,7 +1159,7 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
newmemlen = max(overallocation(memlen), len+2*delta+1)
newoffset = (newmemlen - newlen) ÷ 2 + 1
newmem = array_new_memory(mem, newmemlen)
newref = @inbounds GenericMemoryRef(newmem, newoffset)
newref = @inbounds memoryref(newmem, newoffset)
unsafe_copyto!(newref, ref, i-1)
unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
setfield!(a, :ref, newref)
Expand All @@ -1176,7 +1176,7 @@ function _deletebeg!(a::Vector, delta::Integer)
end
newlen = len - delta
if newlen != 0 # if newlen==0 we could accidentally index past the memory
newref = @inbounds GenericMemoryRef(a.ref, delta + 1)
newref = @inbounds memoryref(a.ref, delta + 1)
setfield!(a, :ref, newref)
end
setfield!(a, :size, (newlen,))
Expand Down Expand Up @@ -1493,16 +1493,16 @@ function sizehint!(a::Vector, sz::Integer; first::Bool=false, shrink::Bool=true)
end
newmem = array_new_memory(mem, sz)
if first
newref = GenericMemoryRef(newmem, inc + 1)
newref = memoryref(newmem, inc + 1)
else
newref = GenericMemoryRef(newmem)
newref = memoryref(newmem)
end
unsafe_copyto!(newref, ref, len)
setfield!(a, :ref, newref)
elseif first
_growbeg!(a, inc)
newref = getfield(a, :ref)
newref = GenericMemoryRef(newref, inc + 1)
newref = memoryref(newref, inc + 1)
setfield!(a, :size, (len,)) # undo the size change from _growbeg!
setfield!(a, :ref, newref) # undo the offset change from _growbeg!
else # last
Expand Down
17 changes: 7 additions & 10 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -517,15 +517,12 @@ const undef = UndefInitializer()
# empty vector constructor
(self::Type{GenericMemory{kind,T,addrspace}})() where {T,kind,addrspace} = self(undef, 0)

memoryref(mem::GenericMemory) = memoryrefnew(mem)
memoryref(mem::GenericMemory, i::Integer) = memoryrefnew(memoryrefnew(mem), Int(i), @_boundscheck)
memoryref(ref::GenericMemoryRef, i::Integer) = memoryrefnew(ref, Int(i), @_boundscheck)
GenericMemoryRef(mem::GenericMemory) = memoryref(mem)
GenericMemoryRef(ref::GenericMemoryRef, i::Integer) = memoryref(ref, Int(i), @_boundscheck)
GenericMemoryRef(mem::GenericMemory, i::Integer) = memoryref(memoryref(mem), Int(i), @_boundscheck)
GenericMemoryRef{kind,<:Any,AS}(mem::GenericMemory{kind,<:Any,AS}) where {kind,AS} = memoryref(mem)
GenericMemoryRef{kind,<:Any,AS}(ref::GenericMemoryRef{kind,<:Any,AS}, i::Integer) where {kind,AS} = memoryref(ref, Int(i), @_boundscheck)
GenericMemoryRef{kind,<:Any,AS}(mem::GenericMemory{kind,<:Any,AS}, i::Integer) where {kind,AS} = memoryref(memoryref(mem), Int(i), @_boundscheck)
GenericMemoryRef{kind,T,AS}(mem::GenericMemory{kind,T,AS}) where {kind,T,AS} = memoryref(mem)
GenericMemoryRef{kind,T,AS}(ref::GenericMemoryRef{kind,T,AS}, i::Integer) where {kind,T,AS} = memoryref(ref, Int(i), @_boundscheck)
GenericMemoryRef{kind,T,AS}(mem::GenericMemory{kind,T,AS}, i::Integer) where {kind,T,AS} = memoryref(memoryref(mem), Int(i), @_boundscheck)
GenericMemoryRef(mem::GenericMemory, i::Integer) = memoryref(mem, i)
GenericMemoryRef(mem::GenericMemoryRef, i::Integer) = memoryref(mem, i)

const Memory{T} = GenericMemory{:not_atomic, T, CPU}
const MemoryRef{T} = GenericMemoryRef{:not_atomic, T, CPU}
Expand Down Expand Up @@ -633,12 +630,12 @@ module IR
export CodeInfo, MethodInstance, CodeInstance, GotoNode, GotoIfNot, ReturnNode,
NewvarNode, SSAValue, SlotNumber, Argument,
PiNode, PhiNode, PhiCNode, UpsilonNode, LineInfoNode,
Const, PartialStruct, InterConditional, EnterNode
Const, PartialStruct, InterConditional, EnterNode, memoryref

using Core: CodeInfo, MethodInstance, CodeInstance, GotoNode, GotoIfNot, ReturnNode,
NewvarNode, SSAValue, SlotNumber, Argument,
PiNode, PhiNode, PhiCNode, UpsilonNode, LineInfoNode,
Const, PartialStruct, InterConditional, EnterNode
Const, PartialStruct, InterConditional, EnterNode, memoryref

end # module IR

Expand Down
2 changes: 1 addition & 1 deletion base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ function iscall_with_boundscheck(@nospecialize(stmt), sv::PostOptAnalysisState)
f === nothing && return false
if f === getfield
nargs = 4
elseif f === memoryref || f === memoryrefget || f === memoryref_isassigned
elseif f === memoryrefnew || f === memoryrefget || f === memoryref_isassigned
nargs = 4
elseif f === memoryrefset!
nargs = 5
Expand Down
12 changes: 6 additions & 6 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2074,7 +2074,7 @@ end
hasintersect(widenconst(idx), Int) || return Bottom
return ref
end
add_tfunc(memoryref, 1, 3, memoryref_tfunc, 1)
add_tfunc(memoryrefnew, 1, 3, memoryref_tfunc, 1)

@nospecs function memoryrefoffset_tfunc(𝕃::AbstractLattice, mem)
hasintersect(widenconst(mem), GenericMemoryRef) || return Bottom
Expand Down Expand Up @@ -2224,7 +2224,7 @@ end
# Query whether the given builtin is guaranteed not to throw given the argtypes
@nospecs function _builtin_nothrow(𝕃::AbstractLattice, f, argtypes::Vector{Any}, rt)
= partialorder(𝕃)
if f === memoryref
if f === memoryrefnew
return memoryref_builtin_common_nothrow(argtypes)
elseif f === memoryrefoffset
length(argtypes) == 1 || return false
Expand Down Expand Up @@ -2348,7 +2348,7 @@ const _EFFECT_FREE_BUILTINS = [
isa,
UnionAll,
getfield,
memoryref,
memoryrefnew,
memoryrefoffset,
memoryrefget,
memoryref_isassigned,
Expand Down Expand Up @@ -2383,7 +2383,7 @@ const _INACCESSIBLEMEM_BUILTINS = Any[
]

const _ARGMEM_BUILTINS = Any[
memoryref,
memoryrefnew,
memoryrefoffset,
memoryrefget,
memoryref_isassigned,
Expand Down Expand Up @@ -2565,7 +2565,7 @@ function builtin_effects(𝕃::AbstractLattice, @nospecialize(f::Builtin), argty
else
if contains_is(_CONSISTENT_BUILTINS, f)
consistent = ALWAYS_TRUE
elseif f === memoryref || f === memoryrefoffset
elseif f === memoryrefnew || f === memoryrefoffset
consistent = ALWAYS_TRUE
elseif f === memoryrefget || f === memoryrefset! || f === memoryref_isassigned
consistent = CONSISTENT_IF_INACCESSIBLEMEMONLY
Expand Down Expand Up @@ -2604,7 +2604,7 @@ function memoryop_noub(@nospecialize(f), argtypes::Vector{Any})
nargs == 0 && return true # must throw and noub
lastargtype = argtypes[end]
isva = isvarargtype(lastargtype)
if f === memoryref
if f === memoryrefnew
if nargs == 1 && !isva
return true
elseif nargs == 2 && !isva
Expand Down
12 changes: 6 additions & 6 deletions base/deepcopy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,16 @@ function _deepcopy_memory_t(@nospecialize(x::Memory), T, stackdict::IdDict)
end
dest = typeof(x)(undef, length(x))
stackdict[x] = dest
xr = Core.memoryref(x)
dr = Core.memoryref(dest)
xr = memoryref(x)
dr = memoryref(dest)
for i = 1:length(x)
xi = Core.memoryref(xr, i, false)
xi = Core.memoryrefnew(xr, i, false)
if Core.memoryref_isassigned(xi, :not_atomic, false)
xi = Core.memoryrefget(xi, :not_atomic, false)
if !isbits(xi)
xi = deepcopy_internal(xi, stackdict)::typeof(xi)
end
di = Core.memoryref(dr, i, false)
di = Core.memoryrefnew(dr, i, false)
Core.memoryrefset!(di, xi, :not_atomic, false)
end
end
Expand All @@ -131,9 +131,9 @@ function deepcopy_internal(x::GenericMemoryRef, stackdict::IdDict)
return stackdict[x]::typeof(x)
end
mem = getfield(x, :mem)
dest = GenericMemoryRef(deepcopy_internal(mem, stackdict)::typeof(mem))
dest = memoryref(deepcopy_internal(mem, stackdict)::typeof(mem))
i = memoryrefoffset(x)
i == 1 || (dest = Core.memoryref(dest, i, true))
i == 1 || (dest = Core.memoryrefnew(dest, i, true))
return dest
end

Expand Down
18 changes: 8 additions & 10 deletions base/docs/basedocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2663,23 +2663,21 @@ julia> Memory{Float64}(undef, 3)
Memory{T}(::UndefInitializer, n)

"""
MemoryRef(memory)
Construct a MemoryRef from a memory object. This does not fail, but the
resulting memory may point out-of-bounds if the memory is empty.
`memoryref(::GenericMemory)`
Construct a `GenericMemoryRef` from a memory object. This does not fail, but the
resulting memory will point out-of-bounds if and only if the memory is empty.
"""
MemoryRef(::Memory)
memoryref(::GenericMemory)

"""
MemoryRef(::Memory, index::Integer)
MemoryRef(::MemoryRef, index::Integer)
Construct a MemoryRef from a memory object and an offset index (1-based) which
memoryref(::GenericMemory, index::Integer)
memoryref(::GenericMemoryRef, index::Integer)
Construct a `GenericMemoryRef` from a memory object and an offset index (1-based) which
can also be negative. This always returns an inbounds object, and will throw an
error if that is not possible (because the index would result in a shift
out-of-bounds of the underlying memory).
"""
MemoryRef(::Union{Memory,MemoryRef}, ::Integer)
memoryref(::Union{GenericMemory,GenericMemoryRef}, ::Integer)

"""
Vector{T}(undef, n)
Expand Down
10 changes: 5 additions & 5 deletions base/docs/intrinsicsdocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ The `Core.Intrinsics` module holds the `Core.IntrinsicFunction` objects.
Core.Intrinsics

"""
Core.memoryref(::GenericMemory)
Core.memoryref(::GenericMemoryRef, index::Int, [boundscheck::Bool])
Core.memoryrefnew(::GenericMemory)
Core.memoryrefnew(::GenericMemoryRef, index::Int, [boundscheck::Bool])
Return a `GenericMemoryRef` for a `GenericMemory`. See [`MemoryRef`](@ref).
Return a `GenericMemoryRef` for a `GenericMemory`. See [`memoryref`](@ref).
!!! compat "Julia 1.11"
This function requires Julia 1.11 or later.
"""
Core.memoryref
Core.memoryrefnew

"""
Core..memoryrefoffset(::GenericMemoryRef)
Return the offset index that was used to construct the `MemoryRef`. See [`Core.memoryref`](@ref).
Return the offset index that was used to construct the `MemoryRef`. See [`memoryref`](@ref).
!!! compat "Julia 1.11"
This function requires Julia 1.11 or later.
Expand Down
10 changes: 5 additions & 5 deletions base/essentials.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

using Core: CodeInfo, SimpleVector, donotdelete, compilerbarrier, memoryref, memoryrefget, memoryrefset!
using Core: CodeInfo, SimpleVector, donotdelete, compilerbarrier, memoryrefnew, memoryrefget, memoryrefset!

const Callable = Union{Function,Type}

Expand Down Expand Up @@ -372,7 +372,7 @@ default_access_order(a::GenericMemoryRef{:not_atomic}) = :not_atomic
default_access_order(a::GenericMemoryRef{:atomic}) = :monotonic

getindex(A::GenericMemory, i::Int) = (@_noub_if_noinbounds_meta;
memoryrefget(memoryref(memoryref(A), i, @_boundscheck), default_access_order(A), false))
memoryrefget(memoryrefnew(memoryrefnew(A), i, @_boundscheck), default_access_order(A), false))
getindex(A::GenericMemoryRef) = memoryrefget(A, default_access_order(A), @_boundscheck)

function iterate end
Expand Down Expand Up @@ -890,16 +890,16 @@ end
function getindex(A::Array, i::Int)
@_noub_if_noinbounds_meta
@boundscheck ult_int(bitcast(UInt, sub_int(i, 1)), bitcast(UInt, length(A))) || throw_boundserror(A, (i,))
memoryrefget(memoryref(getfield(A, :ref), i, false), :not_atomic, false)
memoryrefget(memoryrefnew(getfield(A, :ref), i, false), :not_atomic, false)
end
# simple Array{Any} operations needed for bootstrap
function setindex!(A::Array{Any}, @nospecialize(x), i::Int)
@_noub_if_noinbounds_meta
@boundscheck ult_int(bitcast(UInt, sub_int(i, 1)), bitcast(UInt, length(A))) || throw_boundserror(A, (i,))
memoryrefset!(memoryref(getfield(A, :ref), i, false), x, :not_atomic, false)
memoryrefset!(memoryrefnew(getfield(A, :ref), i, false), x, :not_atomic, false)
return A
end
setindex!(A::Memory{Any}, @nospecialize(x), i::Int) = (memoryrefset!(memoryref(memoryref(A), i, @_boundscheck), x, :not_atomic, @_boundscheck); A)
setindex!(A::Memory{Any}, @nospecialize(x), i::Int) = (memoryrefset!(memoryrefnew(memoryrefnew(A), i, @_boundscheck), x, :not_atomic, @_boundscheck); A)
setindex!(A::MemoryRef{T}, x) where {T} = (memoryrefset!(A, convert(T, x), :not_atomic, @_boundscheck); A)
setindex!(A::MemoryRef{Any}, @nospecialize(x)) = (memoryrefset!(A, x, :not_atomic, @_boundscheck); A)

Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ export
mapfoldl,
mapfoldr,
mapreduce,
memoryref,
merge!,
mergewith!,
merge,
Expand Down
Loading

0 comments on commit c3d1d77

Please sign in to comment.