Skip to content

Commit 9fdcb63

Browse files
committed
[String] Refactor 32-bit StringObject.
Remove Discriminator, Flags, etc., abstractions from StringObject. These cause code divergence between 32-bit and 64-bit ABI, complicate ABI changes, and otherwise contribute to bloat.
1 parent 09b5cf1 commit 9fdcb63

File tree

4 files changed

+249
-540
lines changed

4 files changed

+249
-540
lines changed

stdlib/public/core/SmallString.swift

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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,7 +99,7 @@ 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

@@ -123,12 +114,10 @@ extension _SmallString {
123114
}
124115
}
125116

126-
@inlinable
127117
internal func computeIsASCII() -> Bool {
128-
// TODO(String micro-performance): Evaluate other expressions, e.g. | first
129118
let asciiMask: UInt64 = 0x8080_8080_8080_8080
130119
let raw = zeroTerminatedRawCodeUnits
131-
return (raw.0 & asciiMask == 0) && (raw.1 & asciiMask == 0)
120+
return (raw.0 | raw.1) & asciiMask == 0
132121
}
133122
}
134123

@@ -220,7 +209,7 @@ extension _SmallString {
220209

221210
// Overwrite stored code units, including uninitialized. `f` should return the
222211
// new count.
223-
@inlinable @inline(__always)
212+
@inline(__always)
224213
internal mutating func withMutableCapacity(
225214
_ f: (UnsafeMutableBufferPointer<UInt8>) throws -> Int
226215
) rethrows {
@@ -231,14 +220,27 @@ extension _SmallString {
231220
return try f(UnsafeMutableBufferPointer(
232221
start: ptr, count: _SmallString.capacity))
233222
}
234-
235223
_internalInvariant(len <= _SmallString.capacity)
236-
discriminator = .small(withCount: len, isASCII: self.computeIsASCII())
224+
225+
let (leading, trailing) = self.zeroTerminatedRawCodeUnits
226+
self = _SmallString(leading: leading, trailing: trailing, count: len)
237227
}
238228
}
239229

240230
// Creation
241231
extension _SmallString {
232+
@inlinable @inline(__always)
233+
internal init(leading: UInt64, trailing: UInt64, count: Int) {
234+
_internalInvariant(count <= _SmallString.capacity)
235+
236+
let isASCII = (leading | trailing) & 0x8080_8080_8080_8080 == 0
237+
let countAndDiscriminator = UInt64(truncatingIfNeeded: count) &<< 56
238+
| _StringObject.Nibbles.small(isASCII: isASCII)
239+
_internalInvariant(trailing & countAndDiscriminator == 0)
240+
241+
self.init(raw: (leading, trailing | countAndDiscriminator))
242+
}
243+
242244
// Direct from UTF-8
243245
@inlinable @inline(__always)
244246
internal init?(_ input: UnsafeBufferPointer<UInt8>) {
@@ -251,11 +253,7 @@ extension _SmallString {
251253
let leading = _bytesToUInt64(ptr, Swift.min(input.count, 8))
252254
let trailing = count > 8 ? _bytesToUInt64(ptr + 8, count &- 8) : 0
253255

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))
256+
self.init(leading: leading, trailing: trailing, count: count)
259257
}
260258

261259
@usableFromInline // @testable
@@ -273,13 +271,8 @@ extension _SmallString {
273271
}
274272
_internalInvariant(writeIdx == totalCount)
275273

276-
let isASCII = base.isASCII && other.isASCII
277-
let discriminator = _StringObject.Discriminator.small(
278-
withCount: totalCount,
279-
isASCII: isASCII)
280-
281274
let (leading, trailing) = result.zeroTerminatedRawCodeUnits
282-
self.init(raw: (leading, trailing | discriminator.rawBits))
275+
self.init(leading: leading, trailing: trailing, count: totalCount)
283276
}
284277
}
285278

0 commit comments

Comments
 (0)