Skip to content

Commit da44f47

Browse files
MilesCranmerIanButterworth
authored andcommitted
Set array size only after allocating the new memory portion (#58848)
The `.size` of an array might be getting set too early; before the memory is actually allocated, resulting in larger race windows for inconsistencies (in particular, during finalizers on this thread) to manifest. This helps keep those instructions more nearly consecutive to each other so there is a smaller window for races to be visible, in typical non-adversarial situations.
1 parent a4d42c9 commit da44f47

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

base/array.jl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,10 +1076,10 @@ function _growbeg!(a::Vector, delta::Integer)
10761076
len = length(a)
10771077
offset = memoryrefoffset(ref)
10781078
newlen = len + delta
1079-
setfield!(a, :size, (newlen,))
10801079
# if offset is far enough advanced to fit data in existing memory without copying
10811080
if delta <= offset - 1
10821081
setfield!(a, :ref, @inbounds memoryref(ref, 1 - delta))
1082+
setfield!(a, :size, (newlen,))
10831083
else
10841084
@noinline (function()
10851085
@_terminates_locally_meta
@@ -1111,6 +1111,7 @@ function _growbeg!(a::Vector, delta::Integer)
11111111
end
11121112
setfield!(a, :ref, @inbounds memoryref(newmem, newoffset))
11131113
end)()
1114+
setfield!(a, :size, (newlen,))
11141115
end
11151116
return
11161117
end
@@ -1125,7 +1126,6 @@ function _growend!(a::Vector, delta::Integer)
11251126
len = length(a)
11261127
newlen = len + delta
11271128
offset = memoryrefoffset(ref)
1128-
setfield!(a, :size, (newlen,))
11291129
newmemlen = offset + newlen - 1
11301130
if memlen < newmemlen
11311131
@noinline (function()
@@ -1156,6 +1156,7 @@ function _growend!(a::Vector, delta::Integer)
11561156
setfield!(a, :ref, newref)
11571157
end)()
11581158
end
1159+
setfield!(a, :size, (newlen,))
11591160
return
11601161
end
11611162

@@ -1173,7 +1174,6 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
11731174
memlen = length(mem)
11741175
newlen = len + delta
11751176
offset = memoryrefoffset(ref)
1176-
setfield!(a, :size, (newlen,))
11771177
newmemlen = offset + newlen - 1
11781178

11791179
# which side would we rather grow into?
@@ -1183,11 +1183,13 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
11831183
newref = @inbounds memoryref(mem, offset - delta)
11841184
unsafe_copyto!(newref, ref, i)
11851185
setfield!(a, :ref, newref)
1186+
setfield!(a, :size, (newlen,))
11861187
for j in i:i+delta-1
11871188
@inbounds _unsetindex!(a, j)
11881189
end
11891190
elseif !prefer_start && memlen >= newmemlen
11901191
unsafe_copyto!(mem, offset - 1 + delta + i, mem, offset - 1 + i, len - i + 1)
1192+
setfield!(a, :size, (newlen,))
11911193
for j in i:i+delta-1
11921194
@inbounds _unsetindex!(a, j)
11931195
end
@@ -1201,6 +1203,7 @@ function _growat!(a::Vector, i::Integer, delta::Integer)
12011203
unsafe_copyto!(newref, ref, i-1)
12021204
unsafe_copyto!(newmem, newoffset + delta + i - 1, mem, offset + i - 1, len - i + 1)
12031205
setfield!(a, :ref, newref)
1206+
setfield!(a, :size, (newlen,))
12041207
end
12051208
end
12061209

@@ -1213,11 +1216,11 @@ function _deletebeg!(a::Vector, delta::Integer)
12131216
@inbounds _unsetindex!(a, i)
12141217
end
12151218
newlen = len - delta
1219+
setfield!(a, :size, (newlen,))
12161220
if newlen != 0 # if newlen==0 we could accidentally index past the memory
12171221
newref = @inbounds memoryref(a.ref, delta + 1)
12181222
setfield!(a, :ref, newref)
12191223
end
1220-
setfield!(a, :size, (newlen,))
12211224
return
12221225
end
12231226
function _deleteend!(a::Vector, delta::Integer)

0 commit comments

Comments
 (0)