diff --git a/base/array.jl b/base/array.jl index 4fcf29af69b4b..76d5981ba8861 100644 --- a/base/array.jl +++ b/base/array.jl @@ -1068,6 +1068,9 @@ function _growbeg!(a::Vector, delta::Integer) else @noinline (function() memlen = length(mem) + if offset + len - 1 > memlen || offset < 1 + throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks")) + end # 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) @@ -1083,6 +1086,9 @@ function _growbeg!(a::Vector, delta::Integer) newmem = array_new_memory(mem, newmemlen) end unsafe_copyto!(newmem, newoffset + delta, mem, offset, len) + if ref !== a.ref + @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently")) + end setfield!(a, :ref, @inbounds GenericMemoryRef(newmem, newoffset)) end)() end @@ -1103,6 +1109,10 @@ function _growend!(a::Vector, delta::Integer) newmemlen = offset + newlen - 1 if memlen < newmemlen @noinline (function() + if offset + len - 1 > memlen || offset < 1 + throw(ConcurrencyViolationError("Vector has invalid state. Don't modify internal fields incorrectly, or resize without correct locks")) + end + if offset - 1 > div(5 * newlen, 4) # If the offset is far enough that we can copy without resizing # while maintaining proportional spacing on both ends of the array @@ -1120,6 +1130,9 @@ function _growend!(a::Vector, delta::Integer) end newref = @inbounds GenericMemoryRef(newmem, newoffset) unsafe_copyto!(newref, ref, len) + if ref !== a.ref + @noinline throw(ConcurrencyViolationError("Vector can not be resized concurrently")) + end setfield!(a, :ref, newref) end)() end