Skip to content

Commit d23890f

Browse files
committed
Array resizing fixes and clean up
* Move some `memcpy` and `memmove` from julia to C This is dangerous especially for `ptrarray` since it bypasses the write barrier. * Make sure resizing a ptrarray always have the new memory cleared * Add more test for shared array resizing
1 parent cee4cb7 commit d23890f

File tree

4 files changed

+346
-212
lines changed

4 files changed

+346
-212
lines changed

base/array.jl

Lines changed: 13 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -387,66 +387,13 @@ setindex!{T, N}(A::Array{T, N}, x::Number, ::Vararg{Colon, N}) = fill!(A, x)
387387

388388
# efficiently grow an array
389389

390-
function _growat!(a::Vector, i::Integer, delta::Integer)
391-
n = length(a)
392-
if i < div(n,2)
393-
_growat_beg!(a, i, delta)
394-
else
395-
_growat_end!(a, i, delta)
396-
end
397-
return a
398-
end
399-
400-
function _growat_beg!(a::Vector, i::Integer, delta::Integer)
401-
ccall(:jl_array_grow_beg, Void, (Any, UInt), a, delta)
402-
if i > 1
403-
ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t),
404-
pointer(a, 1), pointer(a, 1+delta), (i-1)*elsize(a))
405-
end
406-
return a
407-
end
408-
409-
function _growat_end!(a::Vector, i::Integer, delta::Integer)
410-
ccall(:jl_array_grow_end, Void, (Any, UInt), a, delta)
411-
n = length(a)
412-
if n >= i+delta
413-
ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t),
414-
pointer(a, i+delta), pointer(a, i), (n-i-delta+1)*elsize(a))
415-
end
416-
return a
417-
end
390+
_growat!(a::Vector, i::Integer, delta::Integer) =
391+
ccall(:jl_array_grow_at, Void, (Any, Int, UInt), a, i - 1, delta)
418392

419393
# efficiently delete part of an array
420394

421-
function _deleteat!(a::Vector, i::Integer, delta::Integer)
422-
n = length(a)
423-
last = i+delta-1
424-
if i-1 < n-last
425-
_deleteat_beg!(a, i, delta)
426-
else
427-
_deleteat_end!(a, i, delta)
428-
end
429-
return a
430-
end
431-
432-
function _deleteat_beg!(a::Vector, i::Integer, delta::Integer)
433-
if i > 1
434-
ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t),
435-
pointer(a, 1+delta), pointer(a, 1), (i-1)*elsize(a))
436-
end
437-
ccall(:jl_array_del_beg, Void, (Any, UInt), a, delta)
438-
return a
439-
end
440-
441-
function _deleteat_end!(a::Vector, i::Integer, delta::Integer)
442-
n = length(a)
443-
if n >= i+delta
444-
ccall(:memmove, Ptr{Void}, (Ptr{Void}, Ptr{Void}, Csize_t),
445-
pointer(a, i), pointer(a, i+delta), (n-i-delta+1)*elsize(a))
446-
end
447-
ccall(:jl_array_del_end, Void, (Any, UInt), a, delta)
448-
return a
449-
end
395+
_deleteat!(a::Vector, i::Integer, delta::Integer) =
396+
ccall(:jl_array_del_at, Void, (Any, Int, UInt), a, i - 1, delta)
450397

451398
## Dequeue functionality ##
452399

@@ -526,34 +473,20 @@ function shift!(a::Vector)
526473
end
527474

528475
function insert!{T}(a::Array{T,1}, i::Integer, item)
529-
if !(1 <= i <= length(a)+1)
530-
throw(BoundsError())
531-
end
532-
if i == length(a)+1
533-
return push!(a, item)
534-
end
535-
item = convert(T, item)
476+
# Throw convert error before changing the shape of the array
477+
_item = convert(T, item)
536478
_growat!(a, i, 1)
537-
a[i] = item
479+
# _growat! already did bound check
480+
@inbounds a[i] = _item
538481
return a
539482
end
540483

541-
function deleteat!(a::Vector, i::Integer)
542-
if !(1 <= i <= length(a))
543-
throw(BoundsError())
544-
end
545-
return _deleteat!(a, i, 1)
546-
end
484+
deleteat!(a::Vector, i::Integer) = (_deleteat!(a, i, 1); a)
547485

548486
function deleteat!{T<:Integer}(a::Vector, r::UnitRange{T})
549487
n = length(a)
550-
isempty(r) && return a
551-
f = first(r)
552-
l = last(r)
553-
if !(1 <= f && l <= n)
554-
throw(BoundsError())
555-
end
556-
return _deleteat!(a, f, length(r))
488+
isempty(r) || _deleteat!(a, first(r), length(r))
489+
return a
557490
end
558491

559492
function deleteat!(a::Vector, inds)
@@ -620,18 +553,9 @@ function splice!{T<:Integer}(a::Vector, r::UnitRange{T}, ins=_default_splice)
620553

621554
if m < d
622555
delta = d - m
623-
if f-1 < n-l
624-
_deleteat_beg!(a, f, delta)
625-
else
626-
_deleteat_end!(a, l-delta+1, delta)
627-
end
556+
_deleteat!(a, (f - 1 < n - l) ? f : (l - delta + 1), delta)
628557
elseif m > d
629-
delta = m - d
630-
if f-1 < n-l
631-
_growat_beg!(a, f, delta)
632-
else
633-
_growat_end!(a, l+1, delta)
634-
end
558+
_growat!(a, (f - 1 < n - l) ? f : (l + 1), m - d)
635559
end
636560

637561
k = 1

base/precompile.jl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,7 @@ precompile(Libc.TmStruct, (Float64,))
154154
precompile(Base.VersionNumber, (Int, Int, Int, Tuple{}, Tuple{String}))
155155
precompile(Base._atexit, ())
156156
precompile(Base._deleteat!, (Array{UInt8, 1}, Int, Int))
157-
precompile(Base._deleteat_beg!, (Array{UInt8, 1}, Int, Int))
158-
precompile(Base._deleteat_end!, (Array{UInt8, 1}, Int, Int))
159-
precompile(Base._growat_beg!, (Array{UInt8, 1}, Int, Int))
160-
precompile(Base._growat_end!, (Array{UInt8, 1}, Int, Int))
157+
precompile(Base._growat!, (Array{UInt8, 1}, Int, Int))
161158
precompile(Base._setindex!, (Base.Dict{Symbol, Any}, Base.LineEdit.Prompt, Symbol, Int))
162159
precompile(Base._setindex!, (Dict{Any, Any}, Base.LineEdit.PromptState, Base.LineEdit.Prompt, Int))
163160
precompile(Base._setindex!, (Dict{Any, Any}, Bool, WeakRef, Int))

0 commit comments

Comments
 (0)