diff --git a/base/array.jl b/base/array.jl index 83b85a23530d3..632db69c1591a 100644 --- a/base/array.jl +++ b/base/array.jl @@ -175,6 +175,20 @@ false isbitsunion(u::Union) = (@_pure_meta; ccall(:jl_array_store_unboxed, Cint, (Any,), u) != Cint(0)) isbitsunion(x) = false +isptrelement(t::Type) = (@_pure_meta; ccall(:jl_array_store_unboxed, Cint, (Any,), t) == Cint(0)) + +function _unsetindex!(A::Array{T}, i::Int) where {T} + @boundscheck checkbounds(A, i) + if isptrelement(T) + t = @_gc_preserve_begin A + p = Ptr{Ptr{Cvoid}}(pointer(A)) + unsafe_store!(p, C_NULL, i) + @_gc_preserve_end t + end + return A +end + + """ Base.bitsunionsize(U::Union) diff --git a/base/dict.jl b/base/dict.jl index 0bdb9901ba4db..00228fb1c5da4 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -620,8 +620,8 @@ end function _delete!(h::Dict{K,V}, index) where {K,V} @inbounds h.slots[index] = 0x2 - isbitstype(K) || isbitsunion(K) || ccall(:jl_arrayunset, Cvoid, (Any, UInt), h.keys, index-1) - isbitstype(V) || isbitsunion(V) || ccall(:jl_arrayunset, Cvoid, (Any, UInt), h.vals, index-1) + @inbounds _unsetindex!(h.keys, index) + @inbounds _unsetindex!(h.vals, index) h.ndel += 1 h.count -= 1 h.age += 1 diff --git a/src/array.c b/src/array.c index 5256ccf7266d0..133f42d1bb201 100644 --- a/src/array.c +++ b/src/array.c @@ -592,10 +592,9 @@ JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *rhs JL_DLLEXPORT void jl_arrayunset(jl_array_t *a, size_t i) { if (i >= jl_array_len(a)) - jl_bounds_error_int((jl_value_t*)a, i+1); - char *ptail = (char*)a->data + i*a->elsize; + jl_bounds_error_int((jl_value_t*)a, i + 1); if (a->flags.ptrarray) - memset(ptail, 0, a->elsize); + ((jl_value_t**)a->data)[i] = NULL; } // at this size and bigger, allocate resized array data with malloc