Skip to content

Commit dfc3933

Browse files
authored
Merge pull request #3792 from atrick/rawptr-stdlib
2 parents c0b183a + 9886e4e commit dfc3933

15 files changed

+153
-130
lines changed

stdlib/private/SwiftPrivate/SwiftPrivate.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ public func withArrayOfCStrings<R>(
8181

8282
return argsBuffer.withUnsafeMutableBufferPointer {
8383
(argsBuffer) in
84-
let ptr = UnsafeMutablePointer<CChar>(argsBuffer.baseAddress!)
84+
let ptr = UnsafeMutableRawPointer(argsBuffer.baseAddress!).bindMemory(
85+
to: CChar.self, capacity: argsBuffer.count)
8586
var cStrings: [UnsafeMutablePointer<CChar>?] = argsOffsets.map { ptr + $0 }
8687
cStrings[cStrings.count - 1] = nil
8788
return body(cStrings)

stdlib/public/SDK/GLKit/GLKit.swift.gyb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ vectorElementNames = [
3434
@inline(__always)
3535
public func _indexHomogeneousValue<TTT, T>(_ aggregate: UnsafePointer<TTT>,
3636
_ index: Int) -> T {
37-
return UnsafePointer<T>(aggregate)[index]
37+
return UnsafeRawPointer(aggregate).load(
38+
fromByteOffset: index * strideof(T.self), as: T.self)
3839
}
3940

4041
%{

stdlib/public/core/Character.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public struct Character :
183183
}
184184
else {
185185
if let native = s._core.nativeBuffer,
186-
native.start == UnsafeMutablePointer(s._core._baseAddress!) {
186+
native.start == s._core._baseAddress! {
187187
_representation = .large(native._storage)
188188
return
189189
}

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,11 @@ internal func _stdlib_NSObject_isEqual(_ lhs: AnyObject, _ rhs: AnyObject) -> Bo
265265
/// Like `UnsafeMutablePointer<Unmanaged<AnyObject>>`, or `id
266266
/// __unsafe_unretained *` in Objective-C ARC.
267267
internal struct _UnmanagedAnyObjectArray {
268-
/// Underlying pointer, Unmanaged to escape reference counting.
269-
internal var value: UnsafeMutablePointer<Unmanaged<AnyObject>>
268+
/// Underlying pointer.
269+
internal var value: UnsafeMutableRawPointer
270270

271271
internal init(_ up: UnsafeMutablePointer<AnyObject>) {
272-
self.value = UnsafeMutablePointer(up)
272+
self.value = UnsafeMutableRawPointer(up)
273273
}
274274

275275
internal init?(_ up: UnsafeMutablePointer<AnyObject>?) {
@@ -279,10 +279,16 @@ internal struct _UnmanagedAnyObjectArray {
279279

280280
internal subscript(i: Int) -> AnyObject {
281281
get {
282-
return value[i].takeUnretainedValue()
282+
let unmanaged = value.load(
283+
fromByteOffset: i * strideof(AnyObject.self),
284+
as: Unmanaged<AnyObject>.self)
285+
return unmanaged.takeUnretainedValue()
283286
}
284287
nonmutating set(newValue) {
285-
value[i] = Unmanaged.passUnretained(newValue)
288+
let unmanaged = Unmanaged.passUnretained(newValue)
289+
value.storeBytes(of: unmanaged,
290+
toByteOffset: i * strideof(AnyObject.self),
291+
as: Unmanaged<AnyObject>.self)
286292
}
287293
}
288294
}

stdlib/public/core/Runtime.swift.gyb

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,21 @@ import SwiftShims
2020
// Atomics
2121
//===----------------------------------------------------------------------===//
2222

23+
public typealias _PointerToPointer = UnsafeMutablePointer<UnsafeRawPointer?>
24+
2325
@_transparent
2426
public // @testable
25-
func _stdlib_atomicCompareExchangeStrongPtrImpl(
26-
object target: UnsafeMutablePointer<UnsafeMutableRawPointer?>,
27-
expected: UnsafeMutablePointer<UnsafeMutableRawPointer?>,
28-
desired: UnsafeMutableRawPointer?) -> Bool {
27+
func _stdlib_atomicCompareExchangeStrongPtr(
28+
object target: _PointerToPointer,
29+
expected: _PointerToPointer,
30+
desired: UnsafeRawPointer?) -> Bool {
2931

3032
// We use Builtin.Word here because Builtin.RawPointer can't be nil.
3133
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Word(
3234
target._rawValue,
3335
UInt(bitPattern: expected.pointee)._builtinWordValue,
3436
UInt(bitPattern: desired)._builtinWordValue)
35-
expected.pointee = UnsafeMutableRawPointer(bitPattern: Int(oldValue))
37+
expected.pointee = UnsafeRawPointer(bitPattern: Int(oldValue))
3638
return Bool(won)
3739
}
3840

@@ -70,23 +72,23 @@ func _stdlib_atomicCompareExchangeStrongPtr<T>(
7072
object target: UnsafeMutablePointer<UnsafeMutablePointer<T>${optional}>,
7173
expected: UnsafeMutablePointer<UnsafeMutablePointer<T>${optional}>,
7274
desired: UnsafeMutablePointer<T>${optional}) -> Bool {
73-
return _stdlib_atomicCompareExchangeStrongPtrImpl(
74-
object: UnsafeMutablePointer(target),
75-
expected: UnsafeMutablePointer(expected),
76-
desired: UnsafeMutablePointer(desired))
75+
return _stdlib_atomicCompareExchangeStrongPtr(
76+
object: unsafeBitCast(target, to: _PointerToPointer.self),
77+
expected: unsafeBitCast(expected, to: _PointerToPointer.self),
78+
desired: unsafeBitCast(desired, to: Optional<UnsafeRawPointer>.self))
7779
}
78-
% end
80+
% end # optional
7981

8082
@_transparent
8183
@discardableResult
8284
public // @testable
8385
func _stdlib_atomicInitializeARCRef(
8486
object target: UnsafeMutablePointer<AnyObject?>,
8587
desired: AnyObject) -> Bool {
86-
var expected: UnsafeMutableRawPointer? = nil
88+
var expected: UnsafeRawPointer? = nil
8789
let desiredPtr = Unmanaged.passRetained(desired).toOpaque()
88-
let wonRace = _stdlib_atomicCompareExchangeStrongPtrImpl(
89-
object: UnsafeMutablePointer(target),
90+
let wonRace = _stdlib_atomicCompareExchangeStrongPtr(
91+
object: unsafeBitCast(target, to: _PointerToPointer.self),
9092
expected: &expected,
9193
desired: desiredPtr)
9294
if !wonRace {

stdlib/public/core/String.swift

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ extension String : _ExpressibleByBuiltinUTF16StringLiteral {
400400
) {
401401
self = String(
402402
_StringCore(
403-
baseAddress: OpaquePointer(start),
403+
baseAddress: UnsafeMutableRawPointer(start),
404404
count: Int(utf16CodeUnitCount),
405405
elementShift: 1,
406406
hasCocoaBuffer: false,
@@ -418,7 +418,7 @@ extension String : _ExpressibleByBuiltinStringLiteral {
418418
if Bool(isASCII) {
419419
self = String(
420420
_StringCore(
421-
baseAddress: OpaquePointer(start),
421+
baseAddress: UnsafeMutableRawPointer(start),
422422
count: Int(utf8CodeUnitCount),
423423
elementShift: 0,
424424
hasCocoaBuffer: false,
@@ -699,13 +699,15 @@ extension String : Hashable {
699699
}
700700
#else
701701
if self._core.isASCII {
702-
return _swift_stdlib_unicode_hash_ascii(
703-
UnsafeMutablePointer<Int8>(_core.startASCII),
704-
Int32(_core.count))
702+
return _core.startASCII.withMemoryRebound(
703+
to: CChar.self, capacity: _core.count) {
704+
_swift_stdlib_unicode_hash_ascii($0, Int32(_core.count))
705+
}
705706
} else {
706-
return _swift_stdlib_unicode_hash(
707-
UnsafeMutablePointer<UInt16>(_core.startUTF16),
708-
Int32(_core.count))
707+
return _core.startUTF16.withMemoryRebound(
708+
to: UInt16.self, capacity: _core.count) {
709+
_swift_stdlib_unicode_hash($0, Int32(_core.count))
710+
}
709711
}
710712
#endif
711713
}
@@ -821,7 +823,8 @@ internal func _nativeUnicodeLowercaseString(_ str: String) -> String {
821823
capacity: str._core.count, initialSize: str._core.count, elementWidth: 2)
822824

823825
// Try to write it out to the same length.
824-
let dest = UnsafeMutablePointer<UTF16.CodeUnit>(buffer.start)
826+
let dest = buffer.start.bindMemory(
827+
to: UTF16.CodeUnit.self, capacity: str._core.count)
825828
let z = _swift_stdlib_unicode_strToLower(
826829
dest, Int32(str._core.count),
827830
str._core.startUTF16, Int32(str._core.count))
@@ -831,7 +834,8 @@ internal func _nativeUnicodeLowercaseString(_ str: String) -> String {
831834
if correctSize != str._core.count {
832835
buffer = _StringBuffer(
833836
capacity: correctSize, initialSize: correctSize, elementWidth: 2)
834-
let dest = UnsafeMutablePointer<UTF16.CodeUnit>(buffer.start)
837+
let dest = buffer.start.bindMemory(
838+
to: UTF16.CodeUnit.self, capacity: str._core.count)
835839
_swift_stdlib_unicode_strToLower(
836840
dest, Int32(correctSize), str._core.startUTF16, Int32(str._core.count))
837841
}
@@ -844,7 +848,8 @@ internal func _nativeUnicodeUppercaseString(_ str: String) -> String {
844848
capacity: str._core.count, initialSize: str._core.count, elementWidth: 2)
845849

846850
// Try to write it out to the same length.
847-
let dest = UnsafeMutablePointer<UTF16.CodeUnit>(buffer.start)
851+
let dest = buffer.start.bindMemory(
852+
to: UTF16.CodeUnit.self, capacity: str._core.count)
848853
let z = _swift_stdlib_unicode_strToUpper(
849854
dest, Int32(str._core.count),
850855
str._core.startUTF16, Int32(str._core.count))
@@ -854,7 +859,8 @@ internal func _nativeUnicodeUppercaseString(_ str: String) -> String {
854859
if correctSize != str._core.count {
855860
buffer = _StringBuffer(
856861
capacity: correctSize, initialSize: correctSize, elementWidth: 2)
857-
let dest = UnsafeMutablePointer<UTF16.CodeUnit>(buffer.start)
862+
let dest = buffer.start.bindMemory(
863+
to: UTF16.CodeUnit.self, capacity: str._core.count)
858864
_swift_stdlib_unicode_strToUpper(
859865
dest, Int32(correctSize), str._core.startUTF16, Int32(str._core.count))
860866
}
@@ -904,7 +910,7 @@ extension String {
904910
let source = self._core.startASCII
905911
let buffer = _StringBuffer(
906912
capacity: count, initialSize: count, elementWidth: 1)
907-
let dest = UnsafeMutablePointer<UInt8>(buffer.start)
913+
let dest = buffer.start
908914
for i in 0..<count {
909915
// For each character in the string, we lookup if it should be shifted
910916
// in our ascii table, then we return 0x20 if it should, 0x0 if not.
@@ -923,7 +929,8 @@ extension String {
923929
// Since we are left with either 0x0 or 0x20, we can safely truncate to
924930
// a UInt8 and add to our ASCII value (this will not overflow numbers in
925931
// the ASCII range).
926-
dest[i] = value &+ UInt8(truncatingBitPattern: add)
932+
dest.storeBytes(of: value &+ UInt8(truncatingBitPattern: add),
933+
toByteOffset: i, as: UInt8.self)
927934
}
928935
return String(_storage: buffer)
929936
}
@@ -953,15 +960,16 @@ extension String {
953960
let source = self._core.startASCII
954961
let buffer = _StringBuffer(
955962
capacity: count, initialSize: count, elementWidth: 1)
956-
let dest = UnsafeMutablePointer<UInt8>(buffer.start)
963+
let dest = buffer.start
957964
for i in 0..<count {
958965
// See the comment above in lowercaseString.
959966
let value = source[i]
960967
let isLower =
961968
_asciiLowerCaseTable >>
962969
UInt64(((value &- 1) & 0b0111_1111) >> 1)
963970
let add = (isLower & 0x1) << 5
964-
dest[i] = value &- UInt8(truncatingBitPattern: add)
971+
dest.storeBytes(of: value &- UInt8(truncatingBitPattern: add),
972+
toByteOffset: i, as: UInt8.self)
965973
}
966974
return String(_storage: buffer)
967975
}

stdlib/public/core/StringBridge.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func _cocoaStringToSwiftString_NonASCII(
5454
let start = _stdlib_binary_CFStringGetCharactersPtr(cfImmutableValue)
5555

5656
return String(_StringCore(
57-
baseAddress: OpaquePointer(start),
57+
baseAddress: start,
5858
count: length,
5959
elementShift: 1,
6060
hasCocoaBuffer: true,
@@ -81,7 +81,7 @@ internal func _cocoaStringToContiguous(
8181

8282
_swift_stdlib_CFStringGetCharacters(
8383
source, _swift_shims_CFRange(location: startIndex, length: count),
84-
UnsafeMutablePointer<_swift_shims_UniChar>(buffer.start))
84+
buffer.start.assumingMemoryBound(to: _swift_shims_UniChar.self))
8585

8686
return buffer
8787
}
@@ -163,13 +163,13 @@ extension String {
163163

164164
// start will hold the base pointer of contiguous storage, if it
165165
// is found.
166-
var start: OpaquePointer?
166+
var start: UnsafeMutableRawPointer?
167167
let isUTF16 = (nulTerminatedASCII == nil)
168168
if isUTF16 {
169169
let utf16Buf = _swift_stdlib_CFStringGetCharactersPtr(cfImmutableValue)
170-
start = OpaquePointer(utf16Buf)
170+
start = UnsafeMutableRawPointer(mutating: utf16Buf)
171171
} else {
172-
start = OpaquePointer(nulTerminatedASCII)
172+
start = UnsafeMutableRawPointer(mutating: nulTerminatedASCII)
173173
}
174174

175175
self._core = _StringCore(

stdlib/public/core/StringBuffer.swift

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct _StringBufferIVars {
1919
}
2020

2121
internal init(
22-
_usedEnd: UnsafeMutablePointer<_RawByte>,
22+
_usedEnd: UnsafeMutableRawPointer,
2323
byteCapacity: Int,
2424
elementWidth: Int
2525
) {
@@ -31,7 +31,7 @@ struct _StringBufferIVars {
3131

3232
// This stored property should be stored at offset zero. We perform atomic
3333
// operations on it using _HeapBuffer's pointer.
34-
var usedEnd: UnsafeMutablePointer<_RawByte>?
34+
var usedEnd: UnsafeMutableRawPointer?
3535

3636
var capacityAndElementShift: Int
3737
var byteCapacity: Int {
@@ -78,6 +78,14 @@ public struct _StringBuffer {
7878
_StringBufferIVars(_elementWidth: elementWidth),
7979
(capacity + capacityBump + divRound) >> divRound
8080
)
81+
// This conditional branch should fold away during code gen.
82+
if elementShift == 0 {
83+
start.bindMemory(to: UTF8.CodeUnit.self, capacity: initialSize)
84+
}
85+
else {
86+
start.bindMemory(to: UTF16.CodeUnit.self, capacity: initialSize)
87+
}
88+
8189
self.usedEnd = start + (initialSize << elementShift)
8290
_storage.value.capacityAndElementShift
8391
= ((_storage._capacity() - capacityBump) << 1) + elementShift
@@ -107,7 +115,7 @@ public struct _StringBuffer {
107115
elementWidth: isAscii ? 1 : 2)
108116

109117
if isAscii {
110-
var p = UnsafeMutablePointer<UTF8.CodeUnit>(result.start)
118+
var p = result.start.assumingMemoryBound(to: UTF8.CodeUnit.self)
111119
let sink: (UTF32.CodeUnit) -> Void = {
112120
p.pointee = UTF8.CodeUnit($0)
113121
p += 1
@@ -137,12 +145,12 @@ public struct _StringBuffer {
137145

138146
/// A pointer to the start of this buffer's data area.
139147
public // @testable
140-
var start: UnsafeMutablePointer<_RawByte> {
141-
return UnsafeMutablePointer(_storage.baseAddress)
148+
var start: UnsafeMutableRawPointer {
149+
return UnsafeMutableRawPointer(_storage.baseAddress)
142150
}
143151

144152
/// A past-the-end pointer for this buffer's stored data.
145-
var usedEnd: UnsafeMutablePointer<_RawByte> {
153+
var usedEnd: UnsafeMutableRawPointer {
146154
get {
147155
return _storage.value.usedEnd!
148156
}
@@ -156,7 +164,7 @@ public struct _StringBuffer {
156164
}
157165

158166
/// A past-the-end pointer for this buffer's available storage.
159-
var capacityEnd: UnsafeMutablePointer<_RawByte> {
167+
var capacityEnd: UnsafeMutableRawPointer {
160168
return start + _storage.value.byteCapacity
161169
}
162170

@@ -181,11 +189,11 @@ public struct _StringBuffer {
181189
// two separate phases. Operations with one-phase growth should use
182190
// "grow()," below.
183191
func hasCapacity(
184-
_ cap: Int, forSubRange r: Range<UnsafePointer<_RawByte>>
192+
_ cap: Int, forSubRange r: Range<UnsafeRawPointer>
185193
) -> Bool {
186194
// The substring to be grown could be pointing in the middle of this
187195
// _StringBuffer.
188-
let offset = (r.lowerBound - UnsafePointer(start)) >> elementShift
196+
let offset = (r.lowerBound - UnsafeRawPointer(start)) >> elementShift
189197
return cap + offset <= capacity
190198
}
191199

@@ -202,13 +210,14 @@ public struct _StringBuffer {
202210
@inline(__always)
203211
@discardableResult
204212
mutating func grow(
205-
oldBounds bounds: Range<UnsafePointer<_RawByte>>, newUsedCount: Int
213+
oldBounds bounds: Range<UnsafeRawPointer>, newUsedCount: Int
206214
) -> Bool {
207215
var newUsedCount = newUsedCount
208216
// The substring to be grown could be pointing in the middle of this
209217
// _StringBuffer. Adjust the size so that it covers the imaginary
210218
// substring from the start of the buffer to `oldUsedEnd`.
211-
newUsedCount += (bounds.lowerBound - UnsafePointer(start)) >> elementShift
219+
newUsedCount
220+
+= (bounds.lowerBound - UnsafeRawPointer(start)) >> elementShift
212221

213222
if _slowPath(newUsedCount > capacity) {
214223
return false
@@ -230,11 +239,14 @@ public struct _StringBuffer {
230239
// usedEnd = newUsedEnd
231240
// return true
232241
// }
233-
let usedEndPhysicalPtr =
234-
UnsafeMutablePointer<UnsafeMutablePointer<_RawByte>>(_storage._value)
235-
var expected = UnsafeMutablePointer<_RawByte>(bounds.upperBound)
242+
243+
// &StringBufferIVars.usedEnd
244+
let usedEndPhysicalPtr = _PointerToPointer(_storage._value)
245+
// Create a temp var to hold the exchanged `expected` value.
246+
var expected : UnsafeRawPointer? = bounds.upperBound
236247
if _stdlib_atomicCompareExchangeStrongPtr(
237-
object: usedEndPhysicalPtr, expected: &expected, desired: newUsedEnd) {
248+
object: usedEndPhysicalPtr, expected: &expected,
249+
desired: UnsafeRawPointer(newUsedEnd)) {
238250
return true
239251
}
240252

0 commit comments

Comments
 (0)