Skip to content

Commit 7283f2c

Browse files
committed
[String] Switch ABI to only use 4 discriminator bits.
In anticipation of potential future HW features, e.g. armv8.5 memory tagging, only use the high 4 bytes as discriminator bits in _BridgeObject rather than the top 8 bits. Utilize two perf flags to cover this instead. This requires shifting around a fair amount of internal complexity.
1 parent 9fdcb63 commit 7283f2c

File tree

11 files changed

+312
-199
lines changed

11 files changed

+312
-199
lines changed

stdlib/public/core/SmallString.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,10 @@ extension _SmallString {
105105

106106
// Give raw, nul-terminated code units. This is only for limited internal
107107
// usage: it always clears the discriminator and count (in case it's full)
108-
@inlinable
108+
@inlinable @inline(__always)
109109
internal var zeroTerminatedRawCodeUnits: RawBitPattern {
110-
@inline(__always) get {
111-
return (
112-
self._storage.0,
113-
self._storage.1 & _StringObject.Nibbles.largeAddressMask)
114-
}
110+
let smallStringCodeUnitMask: UInt64 = 0x00FF_FFFF_FFFF_FFFF
111+
return (self._storage.0, self._storage.1 & smallStringCodeUnitMask)
115112
}
116113

117114
internal func computeIsASCII() -> Bool {
@@ -239,6 +236,7 @@ extension _SmallString {
239236
_internalInvariant(trailing & countAndDiscriminator == 0)
240237

241238
self.init(raw: (leading, trailing | countAndDiscriminator))
239+
_internalInvariant(self.count == count)
242240
}
243241

244242
// Direct from UTF-8

stdlib/public/core/StringBridge.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,13 @@ extension String {
281281
}
282282
}
283283
if _guts._object.isImmortal {
284+
// TODO: We'd rather emit a valid ObjC object statically than create a
285+
// shared string class instance.
286+
let gutsCountAndFlags = _guts._object._countAndFlags
284287
return _SharedStringStorage(
285288
immortal: _guts._object.fastUTF8.baseAddress!,
286-
countAndFlags: _guts._object._countAndFlags)
289+
countAndFlags: _StringObject.CountAndFlags(
290+
sharedCount: _guts.count, isASCII: gutsCountAndFlags.isASCII))
287291
}
288292

289293
_internalInvariant(_guts._object.hasObjCBridgeableObject,

stdlib/public/core/StringGuts.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ extension _StringGuts {
6161
}
6262

6363
internal init(_ storage: _SharedStringStorage) {
64-
// TODO(cleanup): We should probably pass whole perf flags struct around
65-
self.init(_StringObject(storage, isASCII: false))
64+
self.init(_StringObject(storage))
6665
}
6766

6867
internal init(
@@ -109,18 +108,15 @@ extension _StringGuts {
109108
@inline(__always) get { return isFastUTF8 && _object.isASCII }
110109
}
111110

112-
@inlinable
113-
internal var isNFC: Bool {
114-
@inline(__always) get { return _object.isNFC }
115-
}
111+
@inline(__always)
112+
internal var isNFC: Bool { return _object.isNFC }
116113

117-
@inlinable
118-
internal var isNFCFastUTF8: Bool {
114+
@inline(__always)
115+
internal var isNFCFastUTF8: Bool {
119116
// TODO(String micro-performance): Consider a dedicated bit for this
120-
@inline(__always) get { return _object.isNFC && isFastUTF8 }
117+
return _object.isNFC && isFastUTF8
121118
}
122119

123-
@inlinable
124120
internal var hasNativeStorage: Bool { return _object.hasNativeStorage }
125121

126122
internal var hasSharedStorage: Bool { return _object.hasSharedStorage }

0 commit comments

Comments
 (0)