Skip to content

Commit 1de88a3

Browse files
author
Itai Ferber
committed
Refine inlinability of _Representation
1 parent 123b067 commit 1de88a3

File tree

1 file changed

+25
-22
lines changed

1 file changed

+25
-22
lines changed

stdlib/public/Darwin/Foundation/Data.swift

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import Darwin
1717
#elseif os(Linux)
1818
import Glibc
1919

20-
@inlinable
20+
@inlinable // This is inlinable as it is trivially computable.
2121
fileprivate func malloc_good_size(_ size: Int) -> Int {
2222
return size
2323
}
@@ -1233,6 +1233,8 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
12331233
}
12341234
}
12351235

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.)
12361238
@usableFromInline
12371239
@_frozen
12381240
internal enum _Representation {
@@ -1241,7 +1243,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
12411243
case slice(InlineSlice)
12421244
case large(LargeSlice)
12431245

1244-
@inlinable
1246+
@inlinable // This is @inlinable as a trivial initializer.
12451247
init(_ buffer: UnsafeRawBufferPointer) {
12461248
if buffer.count == 0 {
12471249
self = .empty
@@ -1254,7 +1256,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
12541256
}
12551257
}
12561258

1257-
@inlinable
1259+
@inlinable // This is @inlinable as a trivial initializer.
12581260
init(_ buffer: UnsafeRawBufferPointer, owner: AnyObject) {
12591261
if buffer.count == 0 {
12601262
self = .empty
@@ -1273,7 +1275,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
12731275
}
12741276
}
12751277

1276-
@inlinable
1278+
@inlinable // This is @inlinable as a trivial initializer.
12771279
init(capacity: Int) {
12781280
if capacity == 0 {
12791281
self = .empty
@@ -1286,7 +1288,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
12861288
}
12871289
}
12881290

1289-
@inlinable
1291+
@inlinable // This is @inlinable as a trivial initializer.
12901292
init(count: Int) {
12911293
if count == 0 {
12921294
self = .empty
@@ -1299,7 +1301,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
12991301
}
13001302
}
13011303

1302-
@inlinable
1304+
@inlinable // This is @inlinable as a trivial initializer.
13031305
init(_ storage: _DataStorage, count: Int) {
13041306
if count == 0 {
13051307
self = .empty
@@ -1312,7 +1314,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
13121314
}
13131315
}
13141316

1315-
@inlinable
1317+
@usableFromInline // This is not @inlinable as it is a non-trivial, non-generic function.
13161318
mutating func reserveCapacity(_ minimumCapacity: Int) {
13171319
guard minimumCapacity > 0 else { return }
13181320
switch self {
@@ -1355,7 +1357,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
13551357
}
13561358
}
13571359

1358-
@inlinable
1360+
@inlinable // This is @inlinable as reasonably small.
13591361
var count: Int {
13601362
get {
13611363
switch self {
@@ -1366,6 +1368,8 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
13661368
}
13671369
}
13681370
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.
13691373
@inline(__always)
13701374
func apply(_ representation: inout _Representation, _ newValue: Int) -> _Representation? {
13711375
switch representation {
@@ -1430,7 +1434,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14301434
}
14311435
}
14321436

1433-
@inlinable
1437+
@inlinable // This is @inlinable as a generic, trivially forwarding function.
14341438
func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
14351439
switch self {
14361440
case .empty:
@@ -1445,7 +1449,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14451449
}
14461450
}
14471451

1448-
@inlinable
1452+
@inlinable // This is @inlinable as a generic, trivially forwarding function.
14491453
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
14501454
switch self {
14511455
case .empty:
@@ -1465,7 +1469,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14651469
}
14661470
}
14671471

1468-
@inlinable
1472+
@inlinable // This is @inlinable as a generic, trivially forwarding function.
14691473
func withInteriorPointerReference<T>(_ work: (NSData) throws -> T) rethrows -> T {
14701474
switch self {
14711475
case .empty:
@@ -1481,7 +1485,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14811485
}
14821486
}
14831487

1484-
@inlinable
1488+
@usableFromInline // This is not @inlinable as it is a non-trivial, non-generic function.
14851489
func enumerateBytes(_ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Index, _ stop: inout Bool) -> Void) {
14861490
switch self {
14871491
case .empty:
@@ -1499,7 +1503,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14991503
}
15001504
}
15011505

1502-
@inlinable
1506+
@inlinable // This is @inlinable as reasonably small.
15031507
mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
15041508
switch self {
15051509
case .empty:
@@ -1535,7 +1539,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
15351539
}
15361540
}
15371541

1538-
@inlinable
1542+
@inlinable // This is @inlinable as reasonably small.
15391543
mutating func resetBytes(in range: Range<Index>) {
15401544
switch self {
15411545
case .empty:
@@ -1553,7 +1557,6 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
15531557
}
15541558
break
15551559
case .inline(var inline):
1556-
15571560
if inline.count < range.upperBound {
15581561
if InlineSlice.canStore(count: range.upperBound) {
15591562
var slice = InlineSlice(inline)
@@ -1588,7 +1591,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
15881591
}
15891592
}
15901593

1591-
@inlinable
1594+
@usableFromInline // This is not @inlinable as it is a non-trivial, non-generic function.
15921595
mutating func replaceSubrange(_ subrange: Range<Index>, with bytes: UnsafeRawPointer?, count cnt: Int) {
15931596
switch self {
15941597
case .empty:
@@ -1671,7 +1674,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
16711674
}
16721675
}
16731676

1674-
@inlinable
1677+
@inlinable // This is @inlinable as trivially forwarding.
16751678
subscript(index: Index) -> UInt8 {
16761679
get {
16771680
switch self {
@@ -1699,7 +1702,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
16991702
}
17001703
}
17011704

1702-
@inlinable
1705+
@inlinable // This is @inlinable as reasonably small.
17031706
subscript(bounds: Range<Index>) -> Data {
17041707
get {
17051708
switch self {
@@ -1749,7 +1752,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
17491752
}
17501753
}
17511754

1752-
@inlinable
1755+
@inlinable // This is @inlinable as trivially forwarding.
17531756
var startIndex: Int {
17541757
switch self {
17551758
case .empty: return 0
@@ -1759,7 +1762,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
17591762
}
17601763
}
17611764

1762-
@inlinable
1765+
@inlinable // This is @inlinable as trivially forwarding.
17631766
var endIndex: Int {
17641767
switch self {
17651768
case .empty: return 0
@@ -1769,7 +1772,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
17691772
}
17701773
}
17711774

1772-
@inlinable
1775+
@inlinable // This is @inlinable as trivially forwarding.
17731776
func bridgedReference() -> NSData {
17741777
switch self {
17751778
case .empty: return NSData()
@@ -1784,7 +1787,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
17841787
}
17851788
}
17861789

1787-
@inlinable
1790+
@inlinable // This is @inlinable as trivially forwarding.
17881791
func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
17891792
switch self {
17901793
case .empty:

0 commit comments

Comments
 (0)