@@ -17,7 +17,7 @@ import Darwin
17
17
#elseif os(Linux)
18
18
import Glibc
19
19
20
- @inlinable
20
+ @inlinable // This is inlinable as it is trivially computable.
21
21
fileprivate func malloc_good_size( _ size: Int ) -> Int {
22
22
return size
23
23
}
@@ -1233,6 +1233,8 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1233
1233
}
1234
1234
}
1235
1235
1236
+ // The actual storage for Data's various representations.
1237
+ // Inlinability strategy: almost everything should be inlinable as forwarding the underlying implementations. (Inlining can also help avoid retain-release traffic around pulling values out of enums.)
1236
1238
@usableFromInline
1237
1239
@_frozen
1238
1240
internal enum _Representation {
@@ -1241,7 +1243,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1241
1243
case slice( InlineSlice )
1242
1244
case large( LargeSlice )
1243
1245
1244
- @inlinable
1246
+ @inlinable // This is @inlinable as a trivial initializer.
1245
1247
init ( _ buffer: UnsafeRawBufferPointer ) {
1246
1248
if buffer. count == 0 {
1247
1249
self = . empty
@@ -1254,7 +1256,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1254
1256
}
1255
1257
}
1256
1258
1257
- @inlinable
1259
+ @inlinable // This is @inlinable as a trivial initializer.
1258
1260
init ( _ buffer: UnsafeRawBufferPointer , owner: AnyObject ) {
1259
1261
if buffer. count == 0 {
1260
1262
self = . empty
@@ -1273,7 +1275,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1273
1275
}
1274
1276
}
1275
1277
1276
- @inlinable
1278
+ @inlinable // This is @inlinable as a trivial initializer.
1277
1279
init ( capacity: Int ) {
1278
1280
if capacity == 0 {
1279
1281
self = . empty
@@ -1286,7 +1288,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1286
1288
}
1287
1289
}
1288
1290
1289
- @inlinable
1291
+ @inlinable // This is @inlinable as a trivial initializer.
1290
1292
init ( count: Int ) {
1291
1293
if count == 0 {
1292
1294
self = . empty
@@ -1299,7 +1301,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1299
1301
}
1300
1302
}
1301
1303
1302
- @inlinable
1304
+ @inlinable // This is @inlinable as a trivial initializer.
1303
1305
init ( _ storage: _DataStorage , count: Int ) {
1304
1306
if count == 0 {
1305
1307
self = . empty
@@ -1312,7 +1314,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1312
1314
}
1313
1315
}
1314
1316
1315
- @inlinable
1317
+ @usableFromInline // This is not @ inlinable as it is a non-trivial, non-generic function.
1316
1318
mutating func reserveCapacity( _ minimumCapacity: Int ) {
1317
1319
guard minimumCapacity > 0 else { return }
1318
1320
switch self {
@@ -1355,7 +1357,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1355
1357
}
1356
1358
}
1357
1359
1358
- @inlinable
1360
+ @inlinable // This is @inlinable as reasonably small.
1359
1361
var count : Int {
1360
1362
get {
1361
1363
switch self {
@@ -1366,6 +1368,8 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1366
1368
}
1367
1369
}
1368
1370
set ( newValue) {
1371
+ // HACK: The definition of this inline function takes an inout reference to self, giving the optimizer a unique referencing guarantee.
1372
+ // This allows us to avoid excessive retain-release traffic around modifying enum values, and inlining the function then avoids the additional frame.
1369
1373
@inline ( __always)
1370
1374
func apply( _ representation: inout _Representation , _ newValue: Int ) -> _Representation ? {
1371
1375
switch representation {
@@ -1430,7 +1434,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1430
1434
}
1431
1435
}
1432
1436
1433
- @inlinable
1437
+ @inlinable // This is @inlinable as a generic, trivially forwarding function.
1434
1438
func withUnsafeBytes< Result> ( _ apply: ( UnsafeRawBufferPointer ) throws -> Result ) rethrows -> Result {
1435
1439
switch self {
1436
1440
case . empty:
@@ -1445,7 +1449,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1445
1449
}
1446
1450
}
1447
1451
1448
- @inlinable
1452
+ @inlinable // This is @inlinable as a generic, trivially forwarding function.
1449
1453
mutating func withUnsafeMutableBytes< Result> ( _ apply: ( UnsafeMutableRawBufferPointer ) throws -> Result ) rethrows -> Result {
1450
1454
switch self {
1451
1455
case . empty:
@@ -1465,7 +1469,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1465
1469
}
1466
1470
}
1467
1471
1468
- @inlinable
1472
+ @inlinable // This is @inlinable as a generic, trivially forwarding function.
1469
1473
func withInteriorPointerReference< T> ( _ work: ( NSData ) throws -> T ) rethrows -> T {
1470
1474
switch self {
1471
1475
case . empty:
@@ -1481,7 +1485,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1481
1485
}
1482
1486
}
1483
1487
1484
- @inlinable
1488
+ @usableFromInline // This is not @ inlinable as it is a non-trivial, non-generic function.
1485
1489
func enumerateBytes( _ block: ( _ buffer: UnsafeBufferPointer < UInt8 > , _ byteIndex: Index , _ stop: inout Bool ) -> Void ) {
1486
1490
switch self {
1487
1491
case . empty:
@@ -1499,7 +1503,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1499
1503
}
1500
1504
}
1501
1505
1502
- @inlinable
1506
+ @inlinable // This is @inlinable as reasonably small.
1503
1507
mutating func append( contentsOf buffer: UnsafeRawBufferPointer ) {
1504
1508
switch self {
1505
1509
case . empty:
@@ -1535,7 +1539,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1535
1539
}
1536
1540
}
1537
1541
1538
- @inlinable
1542
+ @inlinable // This is @inlinable as reasonably small.
1539
1543
mutating func resetBytes( in range: Range < Index > ) {
1540
1544
switch self {
1541
1545
case . empty:
@@ -1553,7 +1557,6 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1553
1557
}
1554
1558
break
1555
1559
case . inline( var inline) :
1556
-
1557
1560
if inline. count < range. upperBound {
1558
1561
if InlineSlice . canStore ( count: range. upperBound) {
1559
1562
var slice = InlineSlice ( inline)
@@ -1588,7 +1591,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1588
1591
}
1589
1592
}
1590
1593
1591
- @inlinable
1594
+ @usableFromInline // This is not @ inlinable as it is a non-trivial, non-generic function.
1592
1595
mutating func replaceSubrange( _ subrange: Range < Index > , with bytes: UnsafeRawPointer ? , count cnt: Int ) {
1593
1596
switch self {
1594
1597
case . empty:
@@ -1671,7 +1674,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1671
1674
}
1672
1675
}
1673
1676
1674
- @inlinable
1677
+ @inlinable // This is @inlinable as trivially forwarding.
1675
1678
subscript( index: Index ) -> UInt8 {
1676
1679
get {
1677
1680
switch self {
@@ -1699,7 +1702,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1699
1702
}
1700
1703
}
1701
1704
1702
- @inlinable
1705
+ @inlinable // This is @inlinable as reasonably small.
1703
1706
subscript( bounds: Range < Index > ) -> Data {
1704
1707
get {
1705
1708
switch self {
@@ -1749,7 +1752,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1749
1752
}
1750
1753
}
1751
1754
1752
- @inlinable
1755
+ @inlinable // This is @inlinable as trivially forwarding.
1753
1756
var startIndex : Int {
1754
1757
switch self {
1755
1758
case . empty: return 0
@@ -1759,7 +1762,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1759
1762
}
1760
1763
}
1761
1764
1762
- @inlinable
1765
+ @inlinable // This is @inlinable as trivially forwarding.
1763
1766
var endIndex : Int {
1764
1767
switch self {
1765
1768
case . empty: return 0
@@ -1769,7 +1772,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1769
1772
}
1770
1773
}
1771
1774
1772
- @inlinable
1775
+ @inlinable // This is @inlinable as trivially forwarding.
1773
1776
func bridgedReference( ) -> NSData {
1774
1777
switch self {
1775
1778
case . empty: return NSData ( )
@@ -1784,7 +1787,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1784
1787
}
1785
1788
}
1786
1789
1787
- @inlinable
1790
+ @inlinable // This is @inlinable as trivially forwarding.
1788
1791
func copyBytes( to pointer: UnsafeMutableRawPointer , from range: Range < Int > ) {
1789
1792
switch self {
1790
1793
case . empty:
0 commit comments