@@ -72,18 +72,9 @@ extension _SmallString {
7272 }
7373 }
7474
75- @inlinable
76- internal var discriminator : _StringObject . Discriminator {
77- @inline ( __always) get {
78- let value = _storage. 1 &>> _StringObject. Nibbles. discriminatorShift
79- return _StringObject. Discriminator ( UInt8 ( truncatingIfNeeded: value) )
80- }
81- @inline ( __always) set {
82- _storage. 1 &= _StringObject. Nibbles. largeAddressMask
83- _storage. 1 |= (
84- UInt64 ( truncatingIfNeeded: newValue. _value)
85- &<< _StringObject. Nibbles. discriminatorShift)
86- }
75+ @inlinable @inline ( __always)
76+ internal var rawDiscriminatedObject : UInt64 {
77+ return _storage. 1
8778 }
8879
8980 @inlinable
@@ -96,7 +87,7 @@ extension _SmallString {
9687 @inlinable
9788 internal var count : Int {
9889 @inline ( __always) get {
99- return discriminator . smallCount
90+ return _StringObject . getSmallCount ( fromRaw : rawDiscriminatedObject )
10091 }
10192 }
10293
@@ -108,27 +99,22 @@ extension _SmallString {
10899 @inlinable
109100 internal var isASCII : Bool {
110101 @inline ( __always) get {
111- return discriminator . smallIsASCII
102+ return _StringObject . getSmallIsASCII ( fromRaw : rawDiscriminatedObject )
112103 }
113104 }
114105
115106 // Give raw, nul-terminated code units. This is only for limited internal
116107 // usage: it always clears the discriminator and count (in case it's full)
117- @inlinable
108+ @inlinable @ inline ( __always )
118109 internal var zeroTerminatedRawCodeUnits : RawBitPattern {
119- @inline ( __always) get {
120- return (
121- self . _storage. 0 ,
122- self . _storage. 1 & _StringObject. Nibbles. largeAddressMask)
123- }
110+ let smallStringCodeUnitMask : UInt64 = 0x00FF_FFFF_FFFF_FFFF
111+ return ( self . _storage. 0 , self . _storage. 1 & smallStringCodeUnitMask)
124112 }
125113
126- @inlinable
127114 internal func computeIsASCII( ) -> Bool {
128- // TODO(String micro-performance): Evaluate other expressions, e.g. | first
129115 let asciiMask : UInt64 = 0x8080_8080_8080_8080
130116 let raw = zeroTerminatedRawCodeUnits
131- return ( raw. 0 & asciiMask == 0 ) && ( raw. 1 & asciiMask == 0 )
117+ return ( raw. 0 | raw. 1 ) & asciiMask == 0
132118 }
133119}
134120
@@ -220,7 +206,7 @@ extension _SmallString {
220206
221207 // Overwrite stored code units, including uninitialized. `f` should return the
222208 // new count.
223- @inlinable @ inline ( __always)
209+ @inline ( __always)
224210 internal mutating func withMutableCapacity(
225211 _ f: ( UnsafeMutableBufferPointer < UInt8 > ) throws -> Int
226212 ) rethrows {
@@ -231,14 +217,28 @@ extension _SmallString {
231217 return try f ( UnsafeMutableBufferPointer (
232218 start: ptr, count: _SmallString. capacity) )
233219 }
234-
235220 _internalInvariant ( len <= _SmallString. capacity)
236- discriminator = . small( withCount: len, isASCII: self . computeIsASCII ( ) )
221+
222+ let ( leading, trailing) = self . zeroTerminatedRawCodeUnits
223+ self = _SmallString ( leading: leading, trailing: trailing, count: len)
237224 }
238225}
239226
240227// Creation
241228extension _SmallString {
229+ @inlinable @inline ( __always)
230+ internal init ( leading: UInt64 , trailing: UInt64 , count: Int ) {
231+ _internalInvariant ( count <= _SmallString. capacity)
232+
233+ let isASCII = ( leading | trailing) & 0x8080_8080_8080_8080 == 0
234+ let countAndDiscriminator = UInt64 ( truncatingIfNeeded: count) &<< 56
235+ | _StringObject. Nibbles. small ( isASCII: isASCII)
236+ _internalInvariant ( trailing & countAndDiscriminator == 0 )
237+
238+ self . init ( raw: ( leading, trailing | countAndDiscriminator) )
239+ _internalInvariant ( self . count == count)
240+ }
241+
242242 // Direct from UTF-8
243243 @inlinable @inline ( __always)
244244 internal init ? ( _ input: UnsafeBufferPointer < UInt8 > ) {
@@ -251,11 +251,7 @@ extension _SmallString {
251251 let leading = _bytesToUInt64 ( ptr, Swift . min ( input. count, 8 ) )
252252 let trailing = count > 8 ? _bytesToUInt64 ( ptr + 8 , count &- 8 ) : 0
253253
254- let isASCII = ( leading | trailing) & 0x8080_8080_8080_8080 == 0
255- let discriminator = _StringObject. Discriminator. small (
256- withCount: count,
257- isASCII: isASCII)
258- self . init ( raw: ( leading, trailing | discriminator. rawBits) )
254+ self . init ( leading: leading, trailing: trailing, count: count)
259255 }
260256
261257 @usableFromInline // @testable
@@ -273,13 +269,8 @@ extension _SmallString {
273269 }
274270 _internalInvariant ( writeIdx == totalCount)
275271
276- let isASCII = base. isASCII && other. isASCII
277- let discriminator = _StringObject. Discriminator. small (
278- withCount: totalCount,
279- isASCII: isASCII)
280-
281272 let ( leading, trailing) = result. zeroTerminatedRawCodeUnits
282- self . init ( raw : ( leading, trailing | discriminator . rawBits ) )
273+ self . init ( leading : leading, trailing: trailing , count : totalCount )
283274 }
284275}
285276
0 commit comments