Skip to content

Commit 48fa06b

Browse files
committed
[stdlib] ContiguousArray & ArraySlice: Stop swapping self in wUMBP
Implements swiftlang#38867 for ContiguousArray and ArraySlice -- these have the same unnecessary swapping logic.
1 parent 12fa024 commit 48fa06b

File tree

3 files changed

+8
-35
lines changed

3 files changed

+8
-35
lines changed

stdlib/public/core/Array.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1604,7 +1604,7 @@ extension Array {
16041604
_makeMutableAndUnique()
16051605
let count = _buffer.mutableCount
16061606

1607-
// Create an UnsafeBufferPointer over work that we can pass to body
1607+
// Create an UnsafeBufferPointer that we can pass to body
16081608
let pointer = _buffer.mutableFirstElementAddress
16091609
var inoutBufferPointer = UnsafeMutableBufferPointer(
16101610
start: pointer, count: count)
@@ -1615,6 +1615,7 @@ extension Array {
16151615
inoutBufferPointer.count == count,
16161616
"Array withUnsafeMutableBufferPointer: replacing the buffer is not allowed")
16171617
_endMutation()
1618+
_fixLifetime(self)
16181619
}
16191620

16201621
// Invoke the body.

stdlib/public/core/ArraySlice.swift

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,32 +1239,18 @@ extension ArraySlice {
12391239
// Ensure unique storage
12401240
_makeMutableAndUnique()
12411241

1242-
// Ensure that body can't invalidate the storage or its bounds by
1243-
// moving self into a temporary working array.
1244-
// NOTE: The stack promotion optimization that keys of the
1245-
// "array.withUnsafeMutableBufferPointer" semantics annotation relies on the
1246-
// array buffer not being able to escape in the closure. It can do this
1247-
// because we swap the array buffer in self with an empty buffer here. Any
1248-
// escape via the address of self in the closure will therefore escape the
1249-
// empty array.
1250-
1251-
var work = ArraySlice()
1252-
(work, self) = (self, work)
1253-
1254-
// Create an UnsafeBufferPointer over work that we can pass to body
1255-
let pointer = work._buffer.firstElementAddress
1242+
// Create an UnsafeBufferPointer that we can pass to body
1243+
let pointer = _buffer.firstElementAddress
12561244
var inoutBufferPointer = UnsafeMutableBufferPointer(
12571245
start: pointer, count: count)
12581246

1259-
// Put the working array back before returning.
12601247
defer {
12611248
_precondition(
12621249
inoutBufferPointer.baseAddress == pointer &&
12631250
inoutBufferPointer.count == count,
12641251
"ArraySlice withUnsafeMutableBufferPointer: replacing the buffer is not allowed")
1265-
1266-
(work, self) = (self, work)
12671252
_endMutation()
1253+
_fixLifetime(self)
12681254
}
12691255

12701256
// Invoke the body.

stdlib/public/core/ContiguousArray.swift

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,32 +1176,18 @@ extension ContiguousArray {
11761176
_makeMutableAndUnique()
11771177
let count = _buffer.mutableCount
11781178

1179-
// Ensure that body can't invalidate the storage or its bounds by
1180-
// moving self into a temporary working array.
1181-
// NOTE: The stack promotion optimization that keys of the
1182-
// "array.withUnsafeMutableBufferPointer" semantics annotation relies on the
1183-
// array buffer not being able to escape in the closure. It can do this
1184-
// because we swap the array buffer in self with an empty buffer here. Any
1185-
// escape via the address of self in the closure will therefore escape the
1186-
// empty array.
1187-
1188-
var work = ContiguousArray()
1189-
(work, self) = (self, work)
1190-
1191-
// Create an UnsafeBufferPointer over work that we can pass to body
1192-
let pointer = work._buffer.mutableFirstElementAddress
1179+
// Create an UnsafeBufferPointer that we can pass to body
1180+
let pointer = _buffer.mutableFirstElementAddress
11931181
var inoutBufferPointer = UnsafeMutableBufferPointer(
11941182
start: pointer, count: count)
11951183

1196-
// Put the working array back before returning.
11971184
defer {
11981185
_precondition(
11991186
inoutBufferPointer.baseAddress == pointer &&
12001187
inoutBufferPointer.count == count,
12011188
"ContiguousArray withUnsafeMutableBufferPointer: replacing the buffer is not allowed")
1202-
1203-
(work, self) = (self, work)
12041189
_endMutation()
1190+
_fixLifetime(self)
12051191
}
12061192

12071193
// Invoke the body.

0 commit comments

Comments
 (0)