Skip to content

Commit d02f5bc

Browse files
committed
[string] Move wCSIA check higher than _HasContiguousBytes
1 parent ae224ca commit d02f5bc

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

stdlib/public/core/String.swift

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,24 @@ extension String {
423423
return
424424
}
425425

426+
// Fast path for user-defined Collections and typed contiguous collections.
427+
//
428+
// Note: this comes first, as the optimizer nearly always has insight into
429+
// wCSIA, but cannot prove that a type does not have conformance to
430+
// _HasContiguousBytes.
431+
if let str = codeUnits.withContiguousStorageIfAvailable({
432+
(buffer: UnsafeBufferPointer<C.Element>) -> String in
433+
Builtin.onFastPath() // encourage SIL Optimizer to inline this closure :-(
434+
let rawBufPtr = UnsafeRawBufferPointer(buffer)
435+
return String._fromUTF8Repairing(
436+
UnsafeBufferPointer(
437+
start: rawBufPtr.baseAddress?.assumingMemoryBound(to: UInt8.self),
438+
count: rawBufPtr.count)).0
439+
}) {
440+
self = str
441+
return
442+
}
443+
426444
// Fast path for untyped raw storage and known stdlib types
427445
if let contigBytes = codeUnits as? _HasContiguousBytes,
428446
contigBytes._providesContiguousBytesNoCopy
@@ -436,16 +454,6 @@ extension String {
436454
return
437455
}
438456

439-
// Fast path for user-defined Collections
440-
if let str = codeUnits.withContiguousStorageIfAvailable({
441-
(buffer: UnsafeBufferPointer<C.Element>) -> String in
442-
return String._fromUTF8Repairing(
443-
UnsafeRawBufferPointer(buffer).bindMemory(to: UInt8.self)).0
444-
}) {
445-
self = str
446-
return
447-
}
448-
449457
self = String._fromNonContiguousUnsafeBitcastUTF8Repairing(codeUnits).0
450458
}
451459

0 commit comments

Comments
 (0)