Skip to content

Commit 8df5ed5

Browse files
committed
Merge pull request #1599 from aschwaighofer/tune_withUnsafeMutableBufferPointer_for_inlining
Force inlining of Array.withUnsafeMutableBufferPointer
2 parents 43fcb6c + 3738178 commit 8df5ed5

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

stdlib/public/core/Arrays.swift.gyb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,16 @@ extension ${Self} {
867867
/// `body`: it may not appear to have its correct value. Instead,
868868
/// use only the `UnsafeMutableBufferPointer` argument to `body`.
869869
@_semantics("array.withUnsafeMutableBufferPointer")
870+
@inline(__always) // Performance: This method should get inlined into the
871+
// caller such that we can combine the partial apply with the apply in this
872+
// function saving on allocating a closure context. This becomes unnecessary
873+
// once we allocate noescape closures on the stack.
870874
public mutating func withUnsafeMutableBufferPointer<R>(
871875
@noescape body: (inout UnsafeMutableBufferPointer<Element>) throws -> R
872876
) rethrows -> R {
877+
let count = self.count
873878
// Ensure unique storage
874-
_arrayReserve(&_buffer, 0)
879+
_outlinedMakeUniqueBuffer(&_buffer, bufferCount: count)
875880

876881
// Ensure that body can't invalidate the storage or its bounds by
877882
// moving self into a temporary working array.
@@ -887,7 +892,6 @@ extension ${Self} {
887892

888893
// Create an UnsafeBufferPointer over work that we can pass to body
889894
let pointer = work._buffer.firstElementAddress
890-
let count = work.count
891895
var inoutBufferPointer = UnsafeMutableBufferPointer(
892896
start: pointer, count: count)
893897

@@ -1190,6 +1194,23 @@ internal struct _IgnorePointer<T> : _PointerFunctionType {
11901194
}
11911195
}
11921196

1197+
@inline(never)
1198+
internal func _outlinedMakeUniqueBuffer<
1199+
_Buffer : _ArrayBufferType where _Buffer.Index == Int
1200+
>(
1201+
buffer: inout _Buffer, bufferCount: Int
1202+
) {
1203+
if _fastPath(
1204+
buffer.requestUniqueMutableBackingBuffer(bufferCount) != nil) {
1205+
return
1206+
}
1207+
1208+
var newBuffer = Optional(
1209+
_forceCreateUniqueMutableBuffer(
1210+
&buffer, newCount: bufferCount, requiredCapacity: bufferCount))
1211+
_arrayOutOfPlaceUpdate(&buffer, &newBuffer, bufferCount, 0, _IgnorePointer())
1212+
}
1213+
11931214
internal func _arrayReserve<
11941215
_Buffer : _ArrayBufferType where _Buffer.Index == Int
11951216
>(

0 commit comments

Comments
 (0)