Skip to content

Commit f4afaff

Browse files
committed
(162698092) Micro Optimization: Elide overflow checking in Data.bytes
1 parent e4ef061 commit f4afaff

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

Sources/FoundationEssentials/Data/Data.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ internal final class __DataStorage : @unchecked Sendable {
207207

208208
@inlinable // This is @inlinable as trivially computable.
209209
var mutableBytes: UnsafeMutableRawPointer? {
210-
return _bytes?.advanced(by: -_offset)
210+
return _bytes?.advanced(by: _offset &* -1) // _offset is guaranteed to be non-negative, so it can never overflow when negating
211211
}
212212

213213
@inlinable
@@ -955,7 +955,8 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
955955
@inlinable // This is @inlinable as trivially computable.
956956
var count: Int {
957957
get {
958-
return Int(slice.upperBound - slice.lowerBound)
958+
// The upper bound is guaranteed to be greater than or equal to the lower bound, and the lower bound must be non-negative so subtraction can never overflow
959+
return Int(slice.upperBound &- slice.lowerBound)
959960
}
960961
set(newValue) {
961962
assert(newValue < HalfInt.max)
@@ -1112,7 +1113,8 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
11121113

11131114
@inlinable @inline(__always) // This is @inlinable as trivially computable.
11141115
var count: Int {
1115-
return range.upperBound - range.lowerBound
1116+
// The upper bound is guaranteed to be greater than or equal to the lower bound, and the lower bound must be non-negative so subtraction can never overflow
1117+
return range.upperBound &- range.lowerBound
11161118
}
11171119

11181120
@inlinable @inline(__always) // This is @inlinable as a trivial initializer.
@@ -2214,10 +2216,10 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
22142216
switch _representation {
22152217
case .empty:
22162218
buffer = UnsafeRawBufferPointer(start: nil, count: 0)
2217-
case .inline:
2219+
case .inline(let inline):
22182220
buffer = unsafe UnsafeRawBufferPointer(
22192221
start: UnsafeRawPointer(Builtin.addressOfBorrow(self)),
2220-
count: _representation.count
2222+
count: inline.count
22212223
)
22222224
case .large(let slice):
22232225
buffer = unsafe UnsafeRawBufferPointer(
@@ -2252,10 +2254,10 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
22522254
switch _representation {
22532255
case .empty:
22542256
buffer = UnsafeMutableRawBufferPointer(start: nil, count: 0)
2255-
case .inline:
2257+
case .inline(let inline):
22562258
buffer = unsafe UnsafeMutableRawBufferPointer(
22572259
start: UnsafeMutableRawPointer(Builtin.addressOfBorrow(self)),
2258-
count: _representation.count
2260+
count: inline.count
22592261
)
22602262
case .large(var slice):
22612263
// Clear _representation during the unique check to avoid double counting the reference, and assign the mutated slice back to _representation afterwards
@@ -2293,10 +2295,10 @@ public struct Data : Equatable, Hashable, RandomAccessCollection, MutableCollect
22932295
switch _representation {
22942296
case .empty:
22952297
buffer = UnsafeMutableRawBufferPointer(start: nil, count: 0)
2296-
case .inline:
2298+
case .inline(let inline):
22972299
buffer = unsafe UnsafeMutableRawBufferPointer(
22982300
start: UnsafeMutableRawPointer(Builtin.addressOfBorrow(self)),
2299-
count: _representation.count
2301+
count: inline.count
23002302
)
23012303
case .large(var slice):
23022304
// Clear _representation during the unique check to avoid double counting the reference, and assign the mutated slice back to _representation afterwards

0 commit comments

Comments
 (0)