Skip to content

Commit

Permalink
add Core.memoryrefoffset intrinsic
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Sep 25, 2023
1 parent c3c4c41 commit fe3789c
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 147 deletions.
8 changes: 4 additions & 4 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ function _growbeg!(a::Vector, delta::Integer)
ref = a.ref
mem = ref.mem
len = length(a)
offset = memoffset(ref)
offset = memoryrefoffset(ref) - 1
newlen = len + delta
a.size = (newlen,)
# if offset is far enough advanced to fit data in existing memory without copying
Expand Down Expand Up @@ -1093,7 +1093,7 @@ function _growend!(a::Vector, delta::Integer)
memlen = length(mem)
len = length(a)
newlen = len + delta
offset = memoffset(ref)
offset = memoryrefoffset(ref) - 1
a.size = (newlen,)
newmemlen = offset + newlen
if memlen < newmemlen
Expand Down Expand Up @@ -1132,7 +1132,7 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
mem = ref.mem
memlen = length(mem)
newlen = len + delta
offset = memoffset(ref)
offset = memoryrefoffset(ref) - 1
a.size = (newlen,)
newmemlen = offset + newlen

Expand Down Expand Up @@ -1475,7 +1475,7 @@ function sizehint!(a::Vector, sz::Integer)
ref = a.ref
mem = ref.mem
memlen = length(mem)
offset = memoffset(ref)
offset = memoryrefoffset(ref) - 1
sz = max(Int(sz), offset+len)
if sz <= memlen
# if we don't save at least 1/8th memlen then its not worth it to shrink
Expand Down
15 changes: 14 additions & 1 deletion base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2012,6 +2012,13 @@ end
end
add_tfunc(memoryref, 1, 3, memoryref_tfunc, 1)

@nospecs function memoryrefoffset_tfunc(𝕃::AbstractLattice, mem)
hasintersect(widenconst(mem), MemoryRef) || return Bottom
return Int
end
add_tfunc(memoryrefoffset, 1, 1, memoryrefoffset_tfunc, 5)



@nospecs function memoryref_builtin_common_errorcheck(mem, order, boundscheck)
hasintersect(widenconst(mem), MemoryRef) || return false
Expand Down Expand Up @@ -2140,6 +2147,10 @@ end
= Core.Compiler.:(𝕃)
if f === memoryref
return memoryref_builtin_common_nothrow(argtypes)
elseif f === memoryrefoffset
length(argtypes) == 1 || return false
memtype = widenconst(argtypes[1])
return memtype MemoryRef
elseif f === memoryrefset
return memoryrefop_builtin_common_nothrow(argtypes, f)
elseif f === memoryrefget
Expand Down Expand Up @@ -2259,6 +2270,7 @@ const _EFFECT_FREE_BUILTINS = [
UnionAll,
getfield,
memoryref,
memoryrefoffset,
memoryrefget,
memoryref_isassigned,
isdefined,
Expand Down Expand Up @@ -2293,6 +2305,7 @@ const _INACCESSIBLEMEM_BUILTINS = Any[

const _ARGMEM_BUILTINS = Any[
memoryref,
memoryrefoffset,
memoryrefget,
memoryref_isassigned,
memoryrefset,
Expand Down Expand Up @@ -2466,7 +2479,7 @@ function builtin_effects(𝕃::AbstractLattice, @nospecialize(f::Builtin), argin
else
if contains_is(_CONSISTENT_BUILTINS, f)
consistent = ALWAYS_TRUE
elseif f === memoryref
elseif f === memoryref || f === memoryrefoffset
consistent = ALWAYS_TRUE
elseif f === memoryrefget || f === memoryrefset || f === memoryref_isassigned
consistent = CONSISTENT_IF_INACCESSIBLEMEMONLY
Expand Down
4 changes: 2 additions & 2 deletions base/deepcopy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ function deepcopy_internal(x::MemoryRef, stackdict::IdDict)
end
mem = getfield(x, :mem)
dest = MemoryRef(deepcopy_internal(mem, stackdict)::typeof(mem))
i = memoffset(x)
i == 0 || (dest = Core.memoryref(dest, i + 1, true))
i = memoryrefoffset(x)
i == 1 || (dest = Core.memoryref(dest, i, true))
return dest
end

Expand Down
4 changes: 2 additions & 2 deletions base/genericmemory.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Memory

## Basic functions ##

using Core: memoryref_isassigned # import more functions which were not essential
using Core: memoryrefoffset, memoryref_isassigned # import more functions which were not essential

size(a::GenericMemory, d::Int) =
d < 1 ? error("dimension out of range") :
Expand Down Expand Up @@ -72,7 +72,7 @@ end
function unsafe_copyto!(dest::MemoryRef, src::MemoryRef, n)
n == 0 && return dest
@boundscheck MemoryRef(dest, n), MemoryRef(src, n)
unsafe_copyto!(dest.mem, memoffset(dest)+1, src.mem, memoffset(src)+1, n)
unsafe_copyto!(dest.mem, memoryrefoffset(dest), src.mem, memoryrefoffset(src), n)
return dest
end

Expand Down
16 changes: 0 additions & 16 deletions base/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,6 @@ function unsafe_convert(::Type{Ptr{Cvoid}}, a::MemoryRef{<:Any,T}) where {T}
end
unsafe_convert(::Type{Ptr{T}}, a::MemoryRef) where {T} = convert(Ptr{T}, unsafe_convert(Ptr{Cvoid}, a))

function memoffset(a::MemoryRef{<:Any,T}) where {T} # n.b. offset + 1 = index
mem = getfield(a, :mem)
offset = getfield(a, :ptr)
MemT = typeof(mem)
arrayelem = datatype_arrayelem(MemT)
elsz = datatype_layoutsize(MemT)
isboxed = 1; isunion = 2
if arrayelem != isunion && elsz != 0
offset -= unsafe_convert(Ptr{Cvoid}, mem)
offset ÷= elsz
else
offset = UInt(offset)
end
return offset % Int
end

# unsafe pointer to array conversions
"""
unsafe_wrap(Array, pointer::Ptr{T}, dims; own = false)
Expand Down
1 change: 1 addition & 0 deletions src/builtin_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ DECLARE_BUILTIN(_apply_iterate);
DECLARE_BUILTIN(_apply_pure);
DECLARE_BUILTIN(apply_type);
DECLARE_BUILTIN(memoryref);
DECLARE_BUILTIN(memoryrefoffset);
DECLARE_BUILTIN(memoryrefget);
DECLARE_BUILTIN(memoryrefset);
DECLARE_BUILTIN(memoryref_isassigned);
Expand Down
20 changes: 20 additions & 0 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,25 @@ JL_CALLABLE(jl_f_memoryref)
}
}

JL_CALLABLE(jl_f_memoryrefoffset)
{
JL_NARGS(memoryrefoffset, 1, 1);
JL_TYPECHK(memoryref, 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;
if (layout->arrayelem_isboxed) {
offset = (((char*)m.data - (char*)m.mem->data) / sizeof(jl_value_t*));
}
else if (layout->arrayelem_isunion || layout->size == 0) {
offset = (size_t)m.data;
}
else {
offset = ((char*)m.data - (char*)m.mem->data) / layout->size;
}
return (jl_value_t*)jl_box_long(offset + 1);
}

JL_CALLABLE(jl_f_memoryrefget)
{
JL_NARGS(memoryrefget, 3, 3);
Expand Down Expand Up @@ -2099,6 +2118,7 @@ void jl_init_primitives(void) JL_GC_DISABLED

// memory primitives
jl_builtin_memoryref = add_builtin_func("memoryref", 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);
Expand Down
Loading

0 comments on commit fe3789c

Please sign in to comment.