Skip to content

Commit d3fcf6b

Browse files
committed
Work around excess ARC; store ASCII pointer and count
1 parent 77f0aff commit d3fcf6b

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

stdlib/public/core/StringUTF8.swift

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,12 @@ extension String.UTF8View {
487487
internal var _sourceIndex: Int
488488
@_versioned // FIXME(sil-serialize-all)
489489
internal var _buffer: _OutputBuffer
490+
491+
@_versioned
492+
internal var _endIndex: Int
493+
494+
@_versioned
495+
internal var _asciiPointer: UnsafePointer<UInt8>?
490496
}
491497

492498
public func makeIterator() -> Iterator {
@@ -499,8 +505,14 @@ extension String.UTF8View.Iterator : IteratorProtocol {
499505
@_versioned // FIXME(sil-serialize-all)
500506
internal init(_ guts: _StringGuts) {
501507
self._guts = guts
502-
_sourceIndex = 0
503-
_buffer = 0
508+
self._sourceIndex = 0
509+
self._buffer = 0
510+
self._endIndex = self._guts.count
511+
if _fastPath(self._guts._isContiguous && self._guts.isASCII) {
512+
self._asciiPointer = self._guts._unmanagedASCIIView.start
513+
} else {
514+
self._asciiPointer = nil
515+
}
504516
}
505517

506518
@_inlineable // FIXME(sil-serialize-all)
@@ -510,24 +522,23 @@ extension String.UTF8View.Iterator : IteratorProtocol {
510522
_buffer >>= 8
511523
return r
512524
}
513-
if _slowPath(_sourceIndex == _guts.count) { return nil }
514-
515-
let isContiguous = _guts._isContiguous
525+
if _slowPath(_sourceIndex == _endIndex) { return nil }
516526

517527
defer { _fixLifetime(_guts) }
518-
519-
if _fastPath(isContiguous) {
520-
if _guts.isASCII {
521-
let ascii = _guts._unmanagedASCIIView.start
522-
let result = ascii[_sourceIndex]
528+
529+
if _fastPath(self._asciiPointer != nil) {
530+
let ascii = self._asciiPointer._unsafelyUnwrappedUnchecked
531+
let result = ascii[_sourceIndex]
532+
_sourceIndex += 1
533+
for i in 0 ..< _OutputBuffer.bitWidth>>3 {
534+
if _sourceIndex == _endIndex { break }
535+
_buffer |= _OutputBuffer(ascii[_sourceIndex] &+ 1) &<< (i << 3)
523536
_sourceIndex += 1
524-
for i in 0 ..< _OutputBuffer.bitWidth>>3 {
525-
if _sourceIndex == _guts.count { break }
526-
_buffer |= _OutputBuffer(ascii[_sourceIndex] &+ 1) &<< (i << 3)
527-
_sourceIndex += 1
528-
}
529-
return result
530537
}
538+
return result
539+
}
540+
541+
if _fastPath(_guts._isContiguous) {
531542
return _next(refillingFrom: _guts._unmanagedUTF16View.buffer)
532543
}
533544

@@ -546,7 +557,7 @@ extension String.UTF8View.Iterator : IteratorProtocol {
546557
var shift = 0
547558

548559
// ASCII fastpath
549-
while _sourceIndex != _guts.endIndex && shift < _OutputBuffer.bitWidth {
560+
while _sourceIndex != _endIndex && shift < _OutputBuffer.bitWidth {
550561
let u = _guts[_sourceIndex]
551562
if u >= 0x80 { break }
552563
_buffer |= _OutputBuffer(UInt8(truncatingIfNeeded: u &+ 1)) &<< shift

0 commit comments

Comments
 (0)