@@ -1029,70 +1029,78 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1029
1029
}
1030
1030
}
1031
1031
1032
+ // A reference wrapper around a Range<Int> for when the range of a data buffer is too large to whole in a single word.
1033
+ // Inlinability strategy: everything should be inlinable as trivial.
1032
1034
@usableFromInline
1033
1035
@_fixed_layout
1034
1036
internal final class RangeReference {
1035
- @usableFromInline
1036
- var range : Range < Int >
1037
+ @usableFromInline var range : Range < Int >
1037
1038
1038
- @inlinable
1039
- var lowerBound : Int { return range. lowerBound }
1039
+ @inlinable @inline ( __always) // This is @inlinable as trivially forwarding.
1040
+ var lowerBound : Int {
1041
+ return range. lowerBound
1042
+ }
1040
1043
1041
- @inlinable
1042
- var upperBound : Int { return range. upperBound }
1044
+ @inlinable @inline ( __always) // This is @inlinable as trivially forwarding.
1045
+ var upperBound : Int {
1046
+ return range. upperBound
1047
+ }
1043
1048
1044
- @inlinable
1045
- var count : Int { return range. upperBound - range. lowerBound }
1049
+ @inlinable @inline ( __always) // This is @inlinable as trivially computable.
1050
+ var count : Int {
1051
+ return range. upperBound - range. lowerBound
1052
+ }
1046
1053
1047
- @inlinable
1054
+ @inlinable @ inline ( __always ) // This is @inlinable as a trivial initializer.
1048
1055
init ( _ range: Range < Int > ) {
1049
1056
self . range = range
1050
1057
}
1051
1058
}
1052
1059
1060
+ // A buffer of bytes whose range is too large to fit in a signle word. Used alongside a RangeReference to make it fit into _Representation's two-word size.
1061
+ // Inlinability strategy: everything here should be easily inlinable as large _DataStorage methods should not inline into here.
1053
1062
@usableFromInline
1054
1063
@_fixed_layout
1055
1064
internal struct LargeSlice {
1056
1065
// ***WARNING***
1057
1066
// These ivars are specifically laid out so that they cause the enum _Representation to be 16 bytes on 64 bit platforms. This means we _MUST_ have the class type thing last
1058
- @usableFromInline
1059
- var slice : RangeReference
1060
- @usableFromInline
1061
- var storage : _DataStorage
1067
+ @usableFromInline var slice : RangeReference
1068
+ @usableFromInline var storage : _DataStorage
1062
1069
1063
- @inlinable
1070
+ @inlinable // This is @inlinable as a convenience initializer.
1064
1071
init ( _ buffer: UnsafeRawBufferPointer ) {
1065
1072
self . init ( _DataStorage ( bytes: buffer. baseAddress, length: buffer. count) , count: buffer. count)
1066
1073
}
1067
1074
1068
- @inlinable
1075
+ @inlinable // This is @inlinable as a convenience initializer.
1069
1076
init ( capacity: Int ) {
1070
1077
self . init ( _DataStorage ( capacity: capacity) , count: 0 )
1071
1078
}
1072
1079
1073
- @inlinable
1080
+ @inlinable // This is @inlinable as a convenience initializer.
1074
1081
init ( count: Int ) {
1075
1082
self . init ( _DataStorage ( length: count) , count: count)
1076
1083
}
1077
1084
1078
- @inlinable
1085
+ @inlinable // This is @inlinable as a convenience initializer.
1079
1086
init ( _ inline: InlineData ) {
1080
- self . init ( inline. withUnsafeBytes { return _DataStorage ( bytes: $0. baseAddress, length: $0. count) } , count: inline. count)
1087
+ let storage = inline. withUnsafeBytes { return _DataStorage ( bytes: $0. baseAddress, length: $0. count) }
1088
+ self . init ( storage, count: inline. count)
1081
1089
}
1082
1090
1083
- @inlinable
1091
+ @inlinable // This is @inlinable as a trivial initializer.
1084
1092
init ( _ slice: InlineSlice ) {
1085
1093
self . storage = slice. storage
1086
1094
self . slice = RangeReference ( slice. range)
1087
1095
}
1088
1096
1089
- @inlinable
1097
+ @inlinable // This is @inlinable as a trivial initializer.
1090
1098
init ( _ storage: _DataStorage , count: Int ) {
1091
1099
self . storage = storage
1092
- slice = RangeReference ( 0 ..< count)
1100
+ self . slice = RangeReference ( 0 ..< count)
1093
1101
}
1094
1102
1095
- @inlinable
1103
+ @inlinable // This is @inlinable as trivially computable (and inlining may help avoid retain-release traffic).
1096
1104
mutating func ensureUniqueReference( ) {
1097
1105
if !isKnownUniquelyReferenced( & storage) {
1098
1106
storage = storage. mutableCopy ( range)
@@ -1102,25 +1110,29 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1102
1110
}
1103
1111
}
1104
1112
1105
- @inlinable
1106
- var startIndex : Int { return slice. range. lowerBound }
1113
+ @inlinable // This is @inlinable as trivially forwarding.
1114
+ var startIndex : Int {
1115
+ return slice. range. lowerBound
1116
+ }
1107
1117
1108
- @inlinable
1109
- var endIndex : Int { return slice. range. upperBound }
1118
+ @inlinable // This is @inlinable as trivially forwarding.
1119
+ var endIndex : Int {
1120
+ return slice. range. upperBound
1121
+ }
1110
1122
1111
- @inlinable
1123
+ @inlinable // This is @inlinable as trivially forwarding.
1112
1124
var capacity : Int {
1113
1125
return storage. capacity
1114
1126
}
1115
1127
1116
- @inlinable
1128
+ @inlinable // This is @inlinable as trivially computable.
1117
1129
mutating func reserveCapacity( _ minimumCapacity: Int ) {
1118
1130
ensureUniqueReference ( )
1119
1131
// the current capacity can be zero (representing externally owned buffer), and count can be greater than the capacity
1120
1132
storage. ensureUniqueBufferReference ( growingTo: Swift . max ( minimumCapacity, count) )
1121
1133
}
1122
1134
1123
- @inlinable
1135
+ @inlinable // This is @inlinable as trivially computable.
1124
1136
var count : Int {
1125
1137
get {
1126
1138
return slice. count
@@ -1132,28 +1144,30 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1132
1144
}
1133
1145
}
1134
1146
1135
- @inlinable
1136
- var range : Range < Int > { return slice. range }
1147
+ @inlinable // This is @inlinable as it is trivially forwarding.
1148
+ var range : Range < Int > {
1149
+ return slice. range
1150
+ }
1137
1151
1138
- @inlinable
1152
+ @inlinable // This is @inlinable as a generic, trivially forwarding function.
1139
1153
func withUnsafeBytes< Result> ( _ apply: ( UnsafeRawBufferPointer ) throws -> Result ) rethrows -> Result {
1140
1154
return try storage. withUnsafeBytes ( in: range, apply: apply)
1141
1155
}
1142
1156
1143
- @inlinable
1157
+ @inlinable // This is @inlinable as a generic, trivially forwarding function.
1144
1158
mutating func withUnsafeMutableBytes< Result> ( _ apply: ( UnsafeMutableRawBufferPointer ) throws -> Result ) rethrows -> Result {
1145
1159
ensureUniqueReference ( )
1146
1160
return try storage. withUnsafeMutableBytes ( in: range, apply: apply)
1147
1161
}
1148
1162
1149
- @inlinable
1163
+ @inlinable // This is @inlinable as reasonably small.
1150
1164
mutating func append( contentsOf buffer: UnsafeRawBufferPointer ) {
1151
1165
ensureUniqueReference ( )
1152
1166
storage. replaceBytes ( in: NSRange ( location: range. upperBound, length: storage. length - ( range. upperBound - storage. _offset) ) , with: buffer. baseAddress, length: buffer. count)
1153
1167
slice. range = slice. range. lowerBound..< slice. range. upperBound + buffer. count
1154
1168
}
1155
1169
1156
- @inlinable
1170
+ @inlinable // This is @inlinable as trivially computable.
1157
1171
subscript( index: Index ) -> UInt8 {
1158
1172
get {
1159
1173
precondition ( startIndex <= index, " index \( index) is out of bounds of \( startIndex) ..< \( endIndex) " )
@@ -1168,12 +1182,12 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1168
1182
}
1169
1183
}
1170
1184
1171
- @inlinable
1185
+ @inlinable // This is @inlinable as trivially forwarding.
1172
1186
func bridgedReference( ) -> NSData {
1173
1187
return storage. bridgedReference ( self . range)
1174
1188
}
1175
1189
1176
- @inlinable
1190
+ @inlinable // This is @inlinable as reasonably small.
1177
1191
mutating func resetBytes( in range: Range < Int > ) {
1178
1192
precondition ( range. lowerBound <= endIndex, " index \( range. lowerBound) is out of bounds of \( startIndex) ..< \( endIndex) " )
1179
1193
ensureUniqueReference ( )
@@ -1183,7 +1197,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1183
1197
}
1184
1198
}
1185
1199
1186
- @inlinable
1200
+ @inlinable // This is @inlinable as reasonably small.
1187
1201
mutating func replaceSubrange( _ subrange: Range < Index > , with bytes: UnsafeRawPointer ? , count cnt: Int ) {
1188
1202
precondition ( startIndex <= subrange. lowerBound, " index \( subrange. lowerBound) is out of bounds of \( startIndex) ..< \( endIndex) " )
1189
1203
precondition ( subrange. lowerBound <= endIndex, " index \( subrange. lowerBound) is out of bounds of \( startIndex) ..< \( endIndex) " )
@@ -1198,7 +1212,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
1198
1212
slice. range = slice. range. lowerBound..< resultingUpper
1199
1213
}
1200
1214
1201
- @inlinable
1215
+ @inlinable // This is @inlinable as reasonably small.
1202
1216
func copyBytes( to pointer: UnsafeMutableRawPointer , from range: Range < Int > ) {
1203
1217
precondition ( startIndex <= range. lowerBound, " index \( range. lowerBound) is out of bounds of \( startIndex) ..< \( endIndex) " )
1204
1218
precondition ( range. lowerBound <= endIndex, " index \( range. lowerBound) is out of bounds of \( startIndex) ..< \( endIndex) " )
0 commit comments