diff --git a/base/array.jl b/base/array.jl index 969786a2c96387..f21ced0ad2883f 100644 --- a/base/array.jl +++ b/base/array.jl @@ -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 @@ -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. @@ -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 @@ -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 @@ -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 @@ -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 @@ -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? @@ -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 diff --git a/base/boot.jl b/base/boot.jl index 618f9dcb25d1e0..119854251942ff 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -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 @@ -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} diff --git a/src/array.c b/src/array.c index f67a41a15b337b..9ca8b68f9dde66 100644 --- a/src/array.c +++ b/src/array.c @@ -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)); @@ -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); @@ -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) { @@ -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); @@ -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))) { @@ -379,7 +370,7 @@ 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; @@ -387,8 +378,6 @@ static int array_resize_buffer(jl_array_t *a, size_t newlen) 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; } @@ -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); @@ -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; @@ -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); @@ -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) @@ -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);