Skip to content

Commit 3f5dfea

Browse files
committed
[stdlib] String: Avoid retain/release operations around use sites of sharedStorage and cocoaObject
1 parent 7a11700 commit 3f5dfea

File tree

5 files changed

+57
-22
lines changed

5 files changed

+57
-22
lines changed

stdlib/public/core/StringGuts.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,11 @@ extension _StringGuts {
249249
) -> Int? {
250250
#if _runtime(_ObjC)
251251
// Currently, foreign means NSString
252-
if let res = _cocoaStringCopyUTF8(_object.cocoaObject,
253-
into: UnsafeMutableRawBufferPointer(start: mbp.baseAddress,
254-
count: mbp.count)) {
255-
return res
252+
let res = _object.withCocoaObject {
253+
_cocoaStringCopyUTF8($0, into: UnsafeMutableRawBufferPointer(mbp))
256254
}
257-
255+
if let res { return res }
256+
258257
// If the NSString contains invalid UTF8 (e.g. unpaired surrogates), we
259258
// can get nil from cocoaStringCopyUTF8 in situations where a character by
260259
// character loop would get something more useful like repaired contents

stdlib/public/core/StringObject.swift

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -933,11 +933,12 @@ extension _StringObject {
933933
_internalInvariant(largeFastIsShared)
934934
#if _runtime(_ObjC)
935935
if largeIsCocoa {
936-
return stableCocoaUTF8Pointer(cocoaObject)._unsafelyUnwrappedUnchecked
936+
return withCocoaObject {
937+
stableCocoaUTF8Pointer($0)._unsafelyUnwrappedUnchecked
938+
}
937939
}
938940
#endif
939-
940-
return sharedStorage.start
941+
return withSharedStorage { $0.start }
941942
}
942943

943944
@usableFromInline
@@ -970,6 +971,7 @@ extension _StringObject {
970971
_ body: (__StringStorage) -> R
971972
) -> R {
972973
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
974+
// FIXME: Do this properly.
973975
return body(nativeStorage)
974976
#else
975977
_internalInvariant(hasNativeStorage)
@@ -993,6 +995,21 @@ extension _StringObject {
993995
#endif
994996
}
995997

998+
@inline(__always)
999+
internal func withSharedStorage<R>(
1000+
_ body: (__SharedStringStorage) -> R
1001+
) -> R {
1002+
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
1003+
// FIXME: Do this properly.
1004+
return body(sharedStorage)
1005+
#else
1006+
_internalInvariant(largeFastIsShared && !largeIsCocoa)
1007+
_internalInvariant(hasSharedStorage)
1008+
let unmanaged = Unmanaged<__SharedStringStorage>.fromOpaque(largeAddress)
1009+
return unmanaged._withUnsafeGuaranteedRef { body($0) }
1010+
#endif
1011+
}
1012+
9961013
@inline(__always)
9971014
internal var cocoaObject: AnyObject {
9981015
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
@@ -1007,6 +1024,22 @@ extension _StringObject {
10071024
#endif
10081025
}
10091026

1027+
/// Call `body` with the bridged Cocoa object in `self`, without retaining
1028+
/// it.
1029+
@inline(__always)
1030+
internal func withCocoaObject<R>(
1031+
_ body: (AnyObject) -> R
1032+
) -> R {
1033+
#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
1034+
// FIXME: Do this properly.
1035+
return body(cocoaObject)
1036+
#else
1037+
_internalInvariant(largeIsCocoa && !isImmortal)
1038+
let unmanaged = Unmanaged<AnyObject>.fromOpaque(largeAddress)
1039+
return unmanaged._withUnsafeGuaranteedRef { body($0) }
1040+
#endif
1041+
}
1042+
10101043
@_alwaysEmitIntoClient
10111044
@inlinable
10121045
@inline(__always)

stdlib/public/core/StringStorage.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,9 @@ extension _StringGuts {
737737
if hasNativeStorage {
738738
mutPtr = _object.withNativeStorage { $0._breadcrumbsAddress }
739739
} else {
740-
mutPtr = UnsafeMutablePointer(
741-
Builtin.addressof(&_object.sharedStorage._breadcrumbs))
740+
mutPtr = _object.withSharedStorage {
741+
UnsafeMutablePointer(Builtin.addressof(&$0._breadcrumbs))
742+
}
742743
}
743744

744745
if let breadcrumbs = _stdlib_atomicAcquiringLoadARCRef(object: mutPtr) {

stdlib/public/core/StringUTF8View.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -541,10 +541,10 @@ extension String.UTF8View {
541541

542542
#if _runtime(_ObjC)
543543
// Currently, foreign means NSString
544-
if let count = _cocoaStringUTF8Count(
545-
_guts._object.cocoaObject,
546-
range: i._encodedOffset ..< j._encodedOffset
547-
) {
544+
let count = _guts._object.withCocoaObject {
545+
_cocoaStringUTF8Count($0, range: i._encodedOffset ..< j._encodedOffset)
546+
}
547+
if let count {
548548
// _cocoaStringUTF8Count gave us the scalar aligned count, but we still
549549
// need to compensate for sub-scalar indexing, e.g. if `i` is in the
550550
// middle of a two-byte UTF8 scalar.

stdlib/public/core/UnicodeHelpers.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,10 @@ extension _StringGuts {
247247
@_effects(releasenone)
248248
private func _getForeignCodeUnit(at i: Int) -> UInt16 {
249249
#if _runtime(_ObjC)
250-
// Currently, foreign means NSString
251-
return _cocoaStringSubscript(_object.cocoaObject, i)
250+
// Currently, foreign means NSString
251+
return _object.withCocoaObject { _cocoaStringSubscript($0, i) }
252252
#else
253-
fatalError("No foreign strings on Linux in this version of Swift")
253+
fatalError("No foreign strings on Linux in this version of Swift")
254254
#endif
255255
}
256256

@@ -386,11 +386,13 @@ extension _StringGuts {
386386
return withUnsafeTemporaryAllocation(
387387
of: UInt16.self, capacity: count
388388
) { buffer in
389-
_cocoaStringCopyCharacters(
390-
from: self._object.cocoaObject,
391-
range: start..<end,
392-
into: buffer.baseAddress._unsafelyUnwrappedUnchecked
393-
)
389+
self._object.withCocoaObject {
390+
_cocoaStringCopyCharacters(
391+
from: $0,
392+
range: start..<end,
393+
into: buffer.baseAddress._unsafelyUnwrappedUnchecked
394+
)
395+
}
394396
return Character(String._uncheckedFromUTF16(UnsafeBufferPointer(buffer)))
395397
}
396398
#else

0 commit comments

Comments
 (0)