Skip to content

Commit 81044d2

Browse files
committed
expand memoryrefnew capabilities
1 parent 66ec6ee commit 81044d2

File tree

5 files changed

+39
-16
lines changed

5 files changed

+39
-16
lines changed

Compiler/src/tfuncs.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2200,7 +2200,7 @@ function memoryref_builtin_common_nothrow(argtypes::Vector{Any})
22002200
idx = widenconst(argtypes[2])
22012201
idx Int || return false
22022202
boundscheck Bool || return false
2203-
memtype GenericMemoryRef || return false
2203+
memtype Union{GenericMemory, GenericMemoryRef} || return false
22042204
# If we have @inbounds (last argument is false), we're allowed to assume
22052205
# we don't throw bounds errors.
22062206
if isa(boundscheck, Const)

base/boot.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ const undef = UndefInitializer()
591591
(self::Type{GenericMemory{kind,T,addrspace}})() where {T,kind,addrspace} = self(undef, 0)
592592

593593
memoryref(mem::GenericMemory) = memoryrefnew(mem)
594-
memoryref(mem::GenericMemory, i::Integer) = memoryrefnew(memoryrefnew(mem), Int(i), @_boundscheck)
594+
memoryref(mem::GenericMemory, i::Integer) = memoryrefnew(me), Int(i), @_boundscheck)
595595
memoryref(ref::GenericMemoryRef, i::Integer) = memoryrefnew(ref, Int(i), @_boundscheck)
596596
GenericMemoryRef(mem::GenericMemory) = memoryref(mem)
597597
GenericMemoryRef(mem::GenericMemory, i::Integer) = memoryref(mem, i)

base/essentials.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ default_access_order(a::GenericMemoryRef{:not_atomic}) = :not_atomic
383383
default_access_order(a::GenericMemoryRef{:atomic}) = :monotonic
384384

385385
getindex(A::GenericMemory, i::Int) = (@_noub_if_noinbounds_meta;
386-
memoryrefget(memoryrefnew(memoryrefnew(A), i, @_boundscheck), default_access_order(A), false))
386+
memoryrefget(memoryrefnew(A, i, @_boundscheck), default_access_order(A), false))
387387
getindex(A::GenericMemoryRef) = memoryrefget(A, default_access_order(A), @_boundscheck)
388388

389389
"""
@@ -959,7 +959,7 @@ function setindex!(A::Array{Any}, @nospecialize(x), i::Int)
959959
memoryrefset!(memoryrefnew(getfield(A, :ref), i, false), x, :not_atomic, false)
960960
return A
961961
end
962-
setindex!(A::Memory{Any}, @nospecialize(x), i::Int) = (memoryrefset!(memoryrefnew(memoryrefnew(A), i, @_boundscheck), x, :not_atomic, @_boundscheck); A)
962+
setindex!(A::Memory{Any}, @nospecialize(x), i::Int) = (memoryrefset!(memoryrefnew(A, i, @_boundscheck), x, :not_atomic, @_boundscheck); A)
963963
setindex!(A::MemoryRef{T}, x) where {T} = (memoryrefset!(A, convert(T, x), :not_atomic, @_boundscheck); A)
964964
setindex!(A::MemoryRef{Any}, @nospecialize(x)) = (memoryrefset!(A, x, :not_atomic, @_boundscheck); A)
965965

src/builtins.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,30 +1765,44 @@ JL_CALLABLE(jl_f_memoryrefnew)
17651765
return (jl_value_t*)jl_new_memoryref(typ, m, m->ptr);
17661766
}
17671767
else {
1768-
JL_TYPECHK(memoryrefnew, genericmemoryref, args[0]);
17691768
JL_TYPECHK(memoryrefnew, long, args[1]);
17701769
if (nargs == 3)
17711770
JL_TYPECHK(memoryrefnew, bool, args[2]);
1772-
jl_genericmemoryref_t *m = (jl_genericmemoryref_t*)args[0];
17731771
size_t i = jl_unbox_long(args[1]) - 1;
1774-
const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(m->mem))->layout;
1775-
char *data = (char*)m->ptr_or_offset;
1772+
char *data;
1773+
if(jl_is_genericmemory(args[0])) {
1774+
jl_genericmemory_t *m = (jl_genericmemory_t*)args[0];
1775+
jl_value_t *typ = jl_apply_type((jl_value_t*)jl_genericmemoryref_type, jl_svec_data(((jl_datatype_t*)jl_typetagof(m))->parameters), 3);
1776+
if (i >= m->length)
1777+
jl_bounds_error((jl_value_t*)m, args[1]);
1778+
const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(m))->layout;
1779+
if (layout->flags.arrayelem_isunion || layout->size == 0)
1780+
return (jl_value_t*)jl_new_memoryref(typ, m, (char*)i);
1781+
else if (layout->flags.arrayelem_isboxed)
1782+
return (jl_value_t*)jl_new_memoryref(typ, m, (char*)m->ptr + sizeof(jl_value_t*)*i);
1783+
return (jl_value_t*)jl_new_memoryref(typ, m, (char*)m->ptr + layout->size*i);
1784+
}
1785+
JL_TYPECHK(memoryrefnew, genericmemoryref, args[0]);
1786+
jl_genericmemoryref_t *m = (jl_genericmemoryref_t*)args[0];
1787+
jl_genericmemory_t *mem = m->mem;
1788+
data = (char*)m->ptr_or_offset;
1789+
const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(mem))->layout;
17761790
if (layout->flags.arrayelem_isboxed) {
1777-
if (((data - (char*)m->mem->ptr) / sizeof(jl_value_t*)) + i >= m->mem->length)
1791+
if (((data - (char*)mem->ptr) / sizeof(jl_value_t*)) + i >= mem->length)
17781792
jl_bounds_error((jl_value_t*)m, args[1]);
17791793
data += sizeof(jl_value_t*) * i;
17801794
}
17811795
else if (layout->flags.arrayelem_isunion || layout->size == 0) {
1782-
if ((size_t)data + i >= m->mem->length)
1796+
if ((size_t)data + i >= mem->length)
17831797
jl_bounds_error((jl_value_t*)m, args[1]);
17841798
data += i;
17851799
}
17861800
else {
1787-
if (((data - (char*)m->mem->ptr) / layout->size) + i >= m->mem->length)
1801+
if (((data - (char*)mem->ptr) / layout->size) + i >= mem->length)
17881802
jl_bounds_error((jl_value_t*)m, args[1]);
17891803
data += layout->size * i;
17901804
}
1791-
return (jl_value_t*)jl_new_memoryref((jl_value_t*)jl_typetagof(m), m->mem, data);
1805+
return (jl_value_t*)jl_new_memoryref((jl_value_t*)jl_typetagof(m), mem, data);
17921806
}
17931807
}
17941808

src/codegen.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4138,16 +4138,25 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
41384138

41394139
else if (f == BUILTIN(memoryrefnew) && (nargs == 2 || nargs == 3)) {
41404140
const jl_cgval_t &ref = argv[1];
4141-
jl_value_t *mty_dt = jl_unwrap_unionall(ref.typ);
4142-
if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type(mty_dt)) {
4143-
mty_dt = jl_field_type_concrete((jl_datatype_t*)mty_dt, 1);
4144-
const jl_datatype_layout_t *layout = ((jl_datatype_t*)mty_dt)->layout;
4141+
jl_datatype_t *mty_dt = (jl_datatype_t*)jl_unwrap_unionall(ref.typ);
4142+
if (jl_is_genericmemoryref_type(mty_dt) && jl_is_concrete_type((jl_value_t*)mty_dt)) {
4143+
mty_dt = (jl_datatype_t*)jl_field_type_concrete(mty_dt, 1);
4144+
const jl_datatype_layout_t *layout = mty_dt->layout;
41454145
jl_value_t *boundscheck = nargs == 3 ? argv[3].constant : nullptr;
41464146
if (nargs == 3)
41474147
emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryrefnew");
41484148
*ret = emit_memoryref(ctx, ref, argv[2], boundscheck, layout);
41494149
return true;
41504150
}
4151+
if (jl_is_genericmemory_type(mty_dt) && jl_is_concrete_type((jl_value_t*)mty_dt)) {
4152+
const jl_datatype_layout_t *layout = mty_dt->layout;
4153+
jl_value_t *boundscheck = nargs == 3 ? argv[3].constant : nullptr;
4154+
if (nargs == 3)
4155+
emit_typecheck(ctx, argv[3], (jl_value_t*)jl_bool_type, "memoryrefnew");
4156+
jl_value_t *typ = jl_apply_type((jl_value_t*)jl_genericmemoryref_type, jl_svec_data(mty_dt->parameters), jl_svec_len(mty_dt->parameters));
4157+
*ret = emit_memoryref(ctx, _emit_memoryref(ctx, ref, layout, typ), argv[2], boundscheck, layout);
4158+
return true;
4159+
}
41514160
}
41524161

41534162
else if (f == BUILTIN(memoryrefoffset) && nargs == 1) {

0 commit comments

Comments
 (0)