Skip to content

Commit

Permalink
delete add_null
Browse files Browse the repository at this point in the history
  • Loading branch information
oscardssmith committed Sep 14, 2023
1 parent d8f19ce commit e95de18
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 73 deletions.
37 changes: 8 additions & 29 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1092,15 +1092,15 @@ function overallocation(maxsize)
return maxsize
end

function array_new_memory(mem::Memory{T}, newlen::Int, add_null::Bool) where T
if false && ccall(:jl_mem_owner, Any, (Memory{T},), mem) isa String
function array_new_memory(mem::Memory{T}, newlen::Int) where T
if ccall(:jl_mem_owner, Any, (Memory{T},), mem) isa String
# if data is in a String, keep it that way
# TODO: use jl_gc_expand_string(oldstr, newlen)?
str = _string_n(newlen)
return ccall(:jl_string_to_genericmemory, Memory{T}, (Any,), str)
else
# TODO: when implimented, this should use a memory growing call
mem = Memory{T}(undef, newlen + add_null)
mem = Memory{T}(undef, newlen)
return mem
end
end
Expand All @@ -1120,7 +1120,6 @@ function _growbeg!(a::Vector, delta::Integer)
a.ref = MemoryRef(ref, 1 - delta, false)
else
@noinline (function()
add_null = a isa Union{Vector{UInt8},Vector{Int8}}
memlen = length(mem)
# since we will allocate the array in the middle of the memory we need at least 2*delta extra space
# the +1 is because I didn't want to have an off by 1 error.
Expand All @@ -1134,18 +1133,12 @@ function _growbeg!(a::Vector, delta::Integer)
newoffset = div(memlen - newlen, 2)
newmem = mem
else
newmem = array_new_memory(mem, newmemlen, add_null)
newmem = array_new_memory(mem, newmemlen)
end
if len > 0
unsafe_copyto!(newmem, newoffset+delta+1, mem, offset+1, len)
end
a.ref = MemoryRef(newmem, newoffset+1, false)
if add_null
ptr = reinterpret(Ptr{UInt8}, pointer(a, newlen+1))
if unsafe_load(ptr) != 0x0
unsafe_store!(ptr, 0x0)
end
end
end)()
end
return
Expand All @@ -1162,8 +1155,7 @@ function _growend!(a::Vector, delta::Integer)
offset = memoffset(ref)
a.size = (newlen,)
newmemlen = offset + newlen
add_null = newlen != 0 && a isa Union{Vector{UInt8},Vector{Int8}}
if memlen < newmemlen + add_null
if memlen < newmemlen
@noinline (function()
if offset > div(5*newlen, 4)
# If the offset is far enough that we can copy without resizing
Expand All @@ -1177,7 +1169,7 @@ function _growend!(a::Vector, delta::Integer)
# or exactly the requested size, whichever is larger
# TODO we should possibly increase the offset if the current offset is nonzero,
newmemlen2 = max(overallocation(memlen), newmemlen)
newmem = array_new_memory(mem, newmemlen2, add_null)
newmem = array_new_memory(mem, newmemlen2)
newoffset = offset
end
if len > 0
Expand All @@ -1186,12 +1178,6 @@ function _growend!(a::Vector, delta::Integer)
a.ref = MemoryRef(newmem, newoffset+1, false)
end)()
end
if add_null
ptr = reinterpret(Ptr{UInt8}, pointer(a, newlen+1))
if unsafe_load(ptr) != 0x0
unsafe_store!(ptr, 0x0)
end
end
return
end

Expand All @@ -1208,7 +1194,6 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
newlen = len + delta
offset = memoffset(ref)
a.size = (newlen,)
add_null = a isa Union{Vector{UInt8},Vector{Int8}}
newmemlen = offset + newlen

# which side would we rather grow into?
Expand All @@ -1217,24 +1202,18 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
if prefer_start && delta <= offset
a.ref = MemoryRef(mem, offset-delta+1, false)
unsafe_copyto!(mem, offset-delta+1, mem, offset+1, i)
elseif !prefer_start && memlen >= newmemlen + add_null
elseif !prefer_start && memlen >= newmemlen
unsafe_copyto!(mem, offset+delta+i, mem, offset+i, len-i+1)
else
# since we will allocate the array in the middle of the memory we need at least 2*delta extra space
# the +1 is because I didn't want to have an off by 1 error.
newmemlen = max(overallocation(memlen), len+2*delta+1)
newoffset = (newmemlen - newlen) ÷ 2
newmem = array_new_memory(mem, newmemlen, add_null)
newmem = array_new_memory(mem, newmemlen)
a.ref = MemoryRef(newmem, newoffset+1, false)
unsafe_copyto!(newmem, newoffset+1, mem, offset+1, i)
unsafe_copyto!(newmem, newoffset+delta+i, mem, offset+i, len-i+1)
end
if add_null
ptr = reinterpret(Ptr{UInt8}, pointer(a, newlen+1))
if unsafe_load(ptr) != 0x0
unsafe_store!(ptr, 0x0)
end
end
end

# efficiently delete part of an array
Expand Down
12 changes: 1 addition & 11 deletions base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -512,8 +512,6 @@ const Memory{T} = GenericMemory{:not_atomic, T}
# construction helpers for Array
new_as_memoryref(self::Type{MemoryRef{isatomic,T}}, m::Int) where {T,isatomic} = memoryref(fieldtype(self, :mem)(undef, m))

add_null(::Type{Array{T,N}}) where {T,N} = N === 1 && (T === Int8 || T === UInt8)

# checked-multiply intrinsic function for dimensions
_checked_mul_dims() = 1, false
_checked_mul_dims(m::Int) = m, Intrinsics.ule_int(typemax_Int, m) # equivalently: (m + 1) < 1
Expand Down Expand Up @@ -557,15 +555,7 @@ end))
# type and dimensionality specified, accepting dims as series of Ints
eval(Core, :(function (self::Type{Array{T,1}})(::UndefInitializer, m::Int) where {T}
@noinline
null = add_null(self) && Intrinsics.not_int(m === 0)
n = null ? Intrinsics.add_int(m, 1) : m
mem = fieldtype(fieldtype(self, :ref), :mem)(undef, n)
if null
ref = MemoryRef(mem, n, false)
if Intrinsics.not_int(memoryrefget(ref, :not_atomic, false) === bitcast(T, 0x00))
memoryrefset(ref, bitcast(T, 0x00), :not_atomic, false)
end
end
mem = fieldtype(fieldtype(self, :ref), :mem)(undef, m)
return $(Expr(:new, :self, :(memoryref(mem)), :((m,))))
end))
eval(Core, :(function (self::Type{Array{T,2}})(::UndefInitializer, m::Int, n::Int) where {T}
Expand Down
40 changes: 7 additions & 33 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ typedef uint64_t wideint_t;

#define MAXINTVAL (((size_t)-1)>>1)

#define JL_ARRAY_IMPL_NUL 1 // n.b. does unsafe_convert(Ptr{UInt8}, ::Vector{UInt8}) rely on this?

static inline void arrayassign_safe(int hasptr, jl_value_t *parent, char *dst, const jl_value_t *src) JL_NOTSAFEPOINT
{
size_t nb = jl_datatype_size(jl_typeof(src));
Expand Down Expand Up @@ -134,11 +132,7 @@ STATIC_INLINE jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *
jl_value_t *mtype = jl_field_type_concrete((jl_datatype_t*)jl_field_type_concrete((jl_datatype_t*)atype, 0), 1);
const jl_datatype_layout_t *layout = ((jl_datatype_t*)mtype)->layout;
// extra byte for all julia allocated byte vectors
int add_null = JL_ARRAY_IMPL_NUL && nel != 0 && ndims == 1 && layout->size == 1 && !layout->arrayelem_isunion;

jl_genericmemory_t *mem = jl_alloc_genericmemory(mtype, nel + add_null);
if (add_null && ((char*)mem->data)[nel] != '\0')
((char*)mem->data)[nel] = '\0';
jl_genericmemory_t *mem = jl_alloc_genericmemory(mtype, nel);
JL_GC_PUSH1(&mem);
int ndimwords = ndims;
int tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
Expand All @@ -164,6 +158,7 @@ STATIC_INLINE jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *

jl_genericmemory_t *jl_new_genericmemory_for_deserialization(jl_value_t *mtype, size_t nel, int isunion, int elsz);

// TODO: DELETE THIS
jl_array_t *jl_new_array_for_deserialization(jl_value_t *atype, uint32_t ndims, size_t *dims,
int isunboxed, int hasptr, int isunion, int elsz)
{
Expand All @@ -177,10 +172,7 @@ jl_array_t *jl_new_array_for_deserialization(jl_value_t *atype, uint32_t ndims,
jl_exceptionf(jl_argumenterror_type, "invalid Array dimensions");
jl_value_t *mtype = jl_field_type_concrete((jl_datatype_t*)jl_field_type_concrete((jl_datatype_t*)atype, 0), 1);
const jl_datatype_layout_t *layout = ((jl_datatype_t*)mtype)->layout;
int add_null = JL_ARRAY_IMPL_NUL && nel != 0 && ndims == 1 && layout->size == 1 && !layout->arrayelem_isunion;
jl_genericmemory_t *mem = jl_new_genericmemory_for_deserialization(mtype, nel + add_null, isunion, elsz);
if (add_null && ((char*)mem->data)[nel] != '\0')
((char*)mem->data)[nel] = '\0';
jl_genericmemory_t *mem = jl_new_genericmemory_for_deserialization(mtype, nel, isunion, elsz);
JL_GC_PUSH1(&mem);
int ndimwords = ndims;
int tsz = sizeof(jl_array_t) + ndimwords*sizeof(size_t);
Expand Down Expand Up @@ -364,7 +356,6 @@ static int array_resize_buffer(jl_array_t *a, size_t newlen)
// n.b. ndims == 1
jl_value_t *mtype = (jl_value_t*)jl_typetagof(a->ref.mem);
const jl_datatype_layout_t *layout = ((jl_datatype_t*)mtype)->layout;
int add_null = JL_ARRAY_IMPL_NUL && newlen != 0 && layout->size == 1 && !layout->arrayelem_isunion;
int newbuf = 1;
jl_genericmemory_t *mem;
if (jl_is_string(jl_array_owner(a))) {
Expand All @@ -379,16 +370,14 @@ static int array_resize_buffer(jl_array_t *a, size_t newlen)
JL_GC_POP();
}
else {
mem = jl_alloc_genericmemory(mtype, newlen + add_null);
mem = jl_alloc_genericmemory(mtype, newlen);
a->ref.mem = mem;
if (layout->arrayelem_isunion || layout->size == 0)
a->ref.data = 0;
else
a->ref.data = mem->data;
jl_gc_wb(a, mem);
}
if (add_null)
memset((char*)mem->data + jl_array_nrows(a), 0, newlen + add_null - jl_array_nrows(a));
return newbuf;
}

Expand All @@ -403,8 +392,7 @@ STATIC_INLINE void jl_array_shrink(jl_array_t *a, size_t dec)
byteoffset = (size_t)a->ref.data * elsz;
size_t nel = maxsize - dec;
size_t n = jl_array_nrows(a);
int add_null = JL_ARRAY_IMPL_NUL && elsz == 1 && !isbitsunion;
jl_genericmemory_t *newmem = jl_alloc_genericmemory((jl_value_t*)jl_typetagof(a->ref.mem), nel + add_null);
jl_genericmemory_t *newmem = jl_alloc_genericmemory((jl_value_t*)jl_typetagof(a->ref.mem), nel);
const char *olddata = (char*)a->ref.mem->data + byteoffset;
char *newdata = (char*)newmem->data + byteoffset;
memcpy(newdata, olddata, n * elsz);
Expand All @@ -413,11 +401,6 @@ STATIC_INLINE void jl_array_shrink(jl_array_t *a, size_t dec)
char *newtypetagdata = jl_genericmemory_typetagdata(newmem) + (uintptr_t)a->ref.data;
memcpy(newtypetagdata, typetagdata, n);
}
if (add_null) {
assert(&newdata[n] < (char*)newmem->data + newmem->length + jl_is_string(jl_genericmemory_owner(newmem)));
if (newdata[n] != 0)
newdata[n] = 0;
}
a->ref.mem = newmem;
if (!isbitsunion)
a->ref.data = newdata;
Expand Down Expand Up @@ -504,8 +487,7 @@ JL_DLLEXPORT void jl_array_grow_end(jl_array_t *a, size_t inc)
}
size_t oldmaxsize = a->ref.mem->length;
size_t reqmaxsize = oldoffset + n + inc;
int add_null = JL_ARRAY_IMPL_NUL && reqmaxsize != 0 && elsz == 1 && !isbitsunion;
if (__unlikely(reqmaxsize + add_null > oldmaxsize)) {
if (__unlikely(reqmaxsize > oldmaxsize)) {
// grow either by our computed overallocation factor or exactly the requested size,
// whichever is larger
size_t newmaxsize = overallocation(oldmaxsize);
Expand Down Expand Up @@ -538,11 +520,6 @@ JL_DLLEXPORT void jl_array_grow_end(jl_array_t *a, size_t inc)
}
size_t newnrows = n + inc;
a->dimsize[0] = newnrows;
if (add_null) {
assert(&data[newnrows] < (char*)a->ref.mem->data + a->ref.mem->length + jl_is_string(jl_array_owner(a)));
if (data[newnrows] != 0)
data[newnrows] = 0;
}
}

JL_DLLEXPORT void jl_array_del_end(jl_array_t *a, size_t dec)
Expand Down Expand Up @@ -666,10 +643,7 @@ JL_DLLEXPORT jl_array_t *jl_array_copy(jl_array_t *ary)
jl_task_t *ct = jl_current_task;
const jl_datatype_layout_t *layout = ((jl_datatype_t*)jl_typetagof(ary->ref.mem))->layout;
int ndims = jl_array_ndims(ary);
int add_null = JL_ARRAY_IMPL_NUL && len != 0 && ndims == 1 && layout->size == 1 && !layout->arrayelem_isunion;
jl_genericmemory_t *mem = jl_new_genericmemory_for_deserialization((jl_value_t*)jl_typetagof(ary->ref.mem), len + add_null, layout->arrayelem_isunion, layout->size);
if (add_null && ((char*)mem->data)[len] != '\0')
((char*)mem->data)[len] = '\0';
jl_genericmemory_t *mem = jl_new_genericmemory_for_deserialization((jl_value_t*)jl_typetagof(ary->ref.mem), len, layout->arrayelem_isunion, layout->size);
// ensure isbits union arrays copy their selector bytes correctly
if (layout->arrayelem_isunion) {
memcpy(mem->data, (char*)ary->ref.mem->data + (size_t)jl_array_data_(ary) * elsz, len * elsz);
Expand Down

0 comments on commit e95de18

Please sign in to comment.