Skip to content

Commit c7eefc1

Browse files
authored
Merge pull request #14046 from milseman/string_guts_squash
StringGuts: New 2-word representation for String
2 parents ca4f797 + b61b533 commit c7eefc1

File tree

79 files changed

+6285
-2939
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+6285
-2939
lines changed

benchmark/utils/DriverUtils.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,9 @@ func internalMedian(_ inputs: [UInt64]) -> UInt64 {
298298
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
299299

300300
@_silgen_name("_swift_leaks_startTrackingObjects")
301-
func startTrackingObjects(_: UnsafeMutableRawPointer) -> ()
301+
func startTrackingObjects(_: UnsafePointer<CChar>) -> ()
302302
@_silgen_name("_swift_leaks_stopTrackingObjects")
303-
func stopTrackingObjects(_: UnsafeMutableRawPointer) -> Int
303+
func stopTrackingObjects(_: UnsafePointer<CChar>) -> Int
304304

305305
#endif
306306

@@ -346,15 +346,14 @@ class SampleRunner {
346346
func run(_ name: String, fn: (Int) -> Void, num_iters: UInt) -> UInt64 {
347347
// Start the timer.
348348
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
349-
var str = name
350-
startTrackingObjects(UnsafeMutableRawPointer(str._core.startASCII))
349+
name.withCString { p in startTrackingObjects(p) }
351350
#endif
352351
let start_ticks = timer.getTime()
353352
fn(Int(num_iters))
354353
// Stop the timer.
355354
let end_ticks = timer.getTime()
356355
#if SWIFT_RUNTIME_ENABLE_LEAK_CHECKER
357-
stopTrackingObjects(UnsafeMutableRawPointer(str._core.startASCII))
356+
name.withCString { p in stopTrackingObjects(p) }
358357
#endif
359358

360359
// Compute the spent time and the scaling factor.

stdlib/public/SDK/Foundation/NSString.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public class NSSimpleCString {}
2323
public class NSConstantString {}
2424

2525
// Called by the SwiftObject implementation.
26-
public func _convertStringToNSString(_ string: String) -> NSString {
27-
return string._bridgeToObjectiveC()
26+
public func _getDescription<T>(_ x: T) -> NSString {
27+
return String(reflecting: x)._bridgeToObjectiveC()
2828
}
2929

3030
extension NSString : ExpressibleByStringLiteral {

stdlib/public/core/Arrays.swift.gyb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,8 @@ extension ${Self} : RangeReplaceableCollection, ArrayProtocol {
12321232
/// element. Otherwise, `nil`.
12331233
@_inlineable
12341234
public var _baseAddressIfContiguous: UnsafeMutablePointer<Element>? {
1235-
return _buffer.firstElementAddressIfContiguous
1235+
@inline(__always) // FIXME(TODO: JIRA): Hack around test failure
1236+
get { return _buffer.firstElementAddressIfContiguous }
12361237
}
12371238

12381239
%if Self != 'Array': # // Array does not necessarily have contiguous storage

stdlib/public/core/Builtin.swift

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,13 @@ public func unsafeDowncast<T : AnyObject>(_ x: AnyObject, to type: T.Type) -> T
259259
return Builtin.castReference(x)
260260
}
261261

262+
@_inlineable // FIXME(sil-serialize-all)
263+
@_transparent
264+
public func _unsafeUncheckedDowncast<T : AnyObject>(_ x: AnyObject, to type: T.Type) -> T {
265+
_sanityCheck(x is T, "invalid unsafeDowncast")
266+
return Builtin.castReference(x)
267+
}
268+
262269
import SwiftShims
263270

264271
@_inlineable // FIXME(sil-serialize-all)
@@ -356,6 +363,14 @@ internal func _class_getInstancePositiveExtentSize(_ theClass: AnyClass) -> Int
356363
#endif
357364
}
358365

366+
@_inlineable
367+
@_versioned
368+
internal
369+
func _isValidAddress(_ address: UInt) -> Bool {
370+
// TODO: define (and use) ABI max valid pointer value
371+
return address >= _swift_abi_LeastValidPointerValue
372+
}
373+
359374
//===--- Builtin.BridgeObject ---------------------------------------------===//
360375

361376
// TODO(<rdar://problem/34837023>): Get rid of superfluous UInt constructor
@@ -419,6 +434,155 @@ internal func _nonPointerBits(_ x: Builtin.BridgeObject) -> UInt {
419434
internal func _isObjCTaggedPointer(_ x: AnyObject) -> Bool {
420435
return (Builtin.reinterpretCast(x) & _objCTaggedPointerBits) != 0
421436
}
437+
@_inlineable // FIXME(sil-serialize-all)
438+
@_versioned
439+
@inline(__always)
440+
internal func _isObjCTaggedPointer(_ x: UInt) -> Bool {
441+
return (x & _objCTaggedPointerBits) != 0
442+
}
443+
444+
/// TODO: describe extras
445+
446+
@_inlineable /*@_versioned*/ @inline(__always) public // FIXME
447+
func _isTaggedObject(_ x: Builtin.BridgeObject) -> Bool {
448+
return _bitPattern(x) & _objCTaggedPointerBits != 0
449+
}
450+
@_inlineable /*@_versioned*/ @inline(__always) public // FIXME
451+
func _isNativePointer(_ x: Builtin.BridgeObject) -> Bool {
452+
return (
453+
_bitPattern(x) & (_objCTaggedPointerBits | _objectPointerIsObjCBit)
454+
) == 0
455+
}
456+
@_inlineable /*@_versioned*/ @inline(__always) public // FIXME
457+
func _isNonTaggedObjCPointer(_ x: Builtin.BridgeObject) -> Bool {
458+
return !_isTaggedObject(x) && !_isNativePointer(x)
459+
}
460+
461+
@_inlineable
462+
@_versioned
463+
@inline(__always)
464+
func _getNonTagBits(_ x: Builtin.BridgeObject) -> UInt {
465+
// Zero out the tag bits, and leave them all at the top.
466+
_sanityCheck(_isTaggedObject(x), "not tagged!")
467+
return (_bitPattern(x) & ~_objCTaggedPointerBits)
468+
>> _objectPointerLowSpareBitShift
469+
}
470+
471+
// Values -> BridgeObject
472+
@inline(__always)
473+
@_inlineable
474+
public func _bridgeObject(fromNative x: AnyObject) -> Builtin.BridgeObject {
475+
_sanityCheck(!_isObjCTaggedPointer(x))
476+
let object = Builtin.castToBridgeObject(x, 0._builtinWordValue)
477+
_sanityCheck(_isNativePointer(object))
478+
return object
479+
}
480+
481+
@inline(__always)
482+
@_inlineable
483+
public func _bridgeObject(
484+
fromNonTaggedObjC x: AnyObject
485+
) -> Builtin.BridgeObject {
486+
_sanityCheck(!_isObjCTaggedPointer(x))
487+
let object = _makeObjCBridgeObject(x)
488+
_sanityCheck(_isNonTaggedObjCPointer(object))
489+
return object
490+
}
491+
492+
@inline(__always)
493+
@_inlineable
494+
public func _bridgeObject(fromTagged x: UInt) -> Builtin.BridgeObject {
495+
_sanityCheck(x & _objCTaggedPointerBits != 0)
496+
let object: Builtin.BridgeObject = Builtin.reinterpretCast(x)
497+
_sanityCheck(_isTaggedObject(object))
498+
return object
499+
}
500+
501+
@inline(__always)
502+
@_inlineable
503+
public func _bridgeObject(taggingPayload x: UInt) -> Builtin.BridgeObject {
504+
let shifted = x &<< _objectPointerLowSpareBitShift
505+
_sanityCheck(x == (shifted &>> _objectPointerLowSpareBitShift),
506+
"out-of-range: limited bit range requires some zero top bits")
507+
_sanityCheck(shifted & _objCTaggedPointerBits == 0,
508+
"out-of-range: post-shift use of tag bits")
509+
return _bridgeObject(fromTagged: shifted | _objCTaggedPointerBits)
510+
}
511+
512+
// BridgeObject -> Values
513+
@inline(__always)
514+
@_inlineable
515+
public func _bridgeObject(toNative x: Builtin.BridgeObject) -> AnyObject {
516+
_sanityCheck(_isNativePointer(x))
517+
return Builtin.castReferenceFromBridgeObject(x)
518+
}
519+
520+
@inline(__always)
521+
@_inlineable
522+
public func _bridgeObject(
523+
toNonTaggedObjC x: Builtin.BridgeObject
524+
) -> AnyObject {
525+
_sanityCheck(_isNonTaggedObjCPointer(x))
526+
return Builtin.castReferenceFromBridgeObject(x)
527+
}
528+
529+
@inline(__always)
530+
@_inlineable
531+
public func _bridgeObject(toTagged x: Builtin.BridgeObject) -> UInt {
532+
_sanityCheck(_isTaggedObject(x))
533+
let bits = _bitPattern(x)
534+
_sanityCheck(bits & _objCTaggedPointerBits != 0)
535+
return bits
536+
}
537+
@inline(__always)
538+
@_inlineable
539+
public func _bridgeObject(toTagPayload x: Builtin.BridgeObject) -> UInt {
540+
return _getNonTagBits(x)
541+
}
542+
543+
@inline(__always)
544+
@_inlineable
545+
public func _bridgeObject(
546+
fromNativeObject x: Builtin.NativeObject
547+
) -> Builtin.BridgeObject {
548+
return _bridgeObject(fromNative: _nativeObject(toNative: x))
549+
}
550+
551+
//
552+
// NativeObject
553+
//
554+
555+
@inline(__always)
556+
@_inlineable
557+
public func _nativeObject(fromNative x: AnyObject) -> Builtin.NativeObject {
558+
_sanityCheck(!_isObjCTaggedPointer(x))
559+
let native = Builtin.unsafeCastToNativeObject(x)
560+
// _sanityCheck(native == Builtin.castToNativeObject(x))
561+
return native
562+
}
563+
@inline(__always)
564+
@_inlineable
565+
public func _nativeObject(
566+
fromBridge x: Builtin.BridgeObject
567+
) -> Builtin.NativeObject {
568+
return _nativeObject(fromNative: _bridgeObject(toNative: x))
569+
}
570+
571+
@inline(__always)
572+
@_inlineable
573+
public func _nativeObject(toNative x: Builtin.NativeObject) -> AnyObject {
574+
return Builtin.castFromNativeObject(x)
575+
}
576+
577+
// FIXME
578+
extension ManagedBufferPointer {
579+
// FIXME: String Guts
580+
@inline(__always)
581+
@_inlineable
582+
public init(_nativeObject buffer: Builtin.NativeObject) {
583+
self._nativeBuffer = buffer
584+
}
585+
}
422586

423587
/// Create a `BridgeObject` around the given `nativeObject` with the
424588
/// given spare bits.

stdlib/public/core/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,18 +122,20 @@ set(SWIFTLIB_ESSENTIAL
122122
StringHashable.swift # ORDER DEPENDENCY: Must precede String.swift
123123
String.swift
124124
StringBridge.swift
125-
StringBuffer.swift
126125
StringComparable.swift
127-
StringCore.swift
126+
StringGuts.swift
127+
StringObject.swift
128128
StringIndex.swift
129129
StringInterpolation.swift
130130
StringLegacy.swift
131131
StringRangeReplaceableCollection.swift.gyb
132+
StringStorage.swift
132133
StringSwitch.swift
133134
StringIndexConversions.swift
134135
StringUnicodeScalarView.swift
135136
StringUTF16.swift
136137
StringUTF8.swift
138+
StringVariant.swift
137139
Substring.swift.gyb
138140
SwiftNativeNSArray.swift
139141
ThreadLocalStorage.swift
@@ -142,6 +144,8 @@ set(SWIFTLIB_ESSENTIAL
142144
UnicodeEncoding.swift
143145
UnicodeParser.swift
144146
Unmanaged.swift
147+
UnmanagedOpaqueString.swift
148+
UnmanagedString.swift
145149
UnsafeBitMap.swift
146150
UnsafeBufferPointer.swift.gyb
147151
UnsafeRawBufferPointer.swift.gyb
@@ -152,6 +156,7 @@ set(SWIFTLIB_ESSENTIAL
152156
UTF16.swift
153157
UTF32.swift
154158
Unicode.swift # ORDER DEPENDENCY: must follow new unicode support
159+
StringGraphemeBreaking.swift # ORDER DEPENDENCY: Must follow UTF16.swift
155160
ValidUTF8Buffer.swift
156161
WriteBackMutableSlice.swift
157162
)

stdlib/public/core/CString.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,7 @@ internal func _decodeCString<Encoding : _UnicodeEncoding>(
197197
let buffer = UnsafeBufferPointer<Encoding.CodeUnit>(
198198
start: cString, count: length)
199199

200-
let (stringBuffer, hadError) = _StringBuffer.fromCodeUnits(
200+
let (guts, hadError) = _StringGuts.fromCodeUnits(
201201
buffer, encoding: encoding, repairIllFormedSequences: isRepairing)
202-
return stringBuffer.map {
203-
(result: String(_storage: $0), repairsMade: hadError)
204-
}
202+
return guts.map { (result: String($0), repairsMade: hadError) }
205203
}

stdlib/public/core/CTypes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ extension CVaListPointer : CustomDebugStringConvertible {
229229
@_inlineable
230230
internal func _memcpy(
231231
dest destination: UnsafeMutableRawPointer,
232-
src: UnsafeMutableRawPointer,
232+
src: UnsafeRawPointer,
233233
size: UInt
234234
) {
235235
let dest = destination._rawValue

0 commit comments

Comments
 (0)