Skip to content

Commit 03dd2a3

Browse files
author
Itai Ferber
committed
Annotate inlinability of InlineSlice
1 parent b1e4c56 commit 03dd2a3

File tree

1 file changed

+41
-38
lines changed

1 file changed

+41
-38
lines changed

stdlib/public/Darwin/Foundation/Data.swift

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -806,116 +806,119 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
806806
}
807807

808808
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
809-
@usableFromInline
810-
internal typealias HalfInt = Int32
809+
@usableFromInline internal typealias HalfInt = Int32
811810
#elseif arch(i386) || arch(arm)
812-
@usableFromInline
813-
internal typealias HalfInt = Int16
811+
@usableFromInline internal typealias HalfInt = Int16
814812
#endif
815813

814+
// A buffer of bytes too large to fit in an InlineData, but still small enough to fit a storage pointer + range in two words.
815+
// Inlinability strategy: everything here should be easily inlinable as large _DataStorage methods should not inline into here.
816816
@usableFromInline
817817
@_fixed_layout
818818
internal struct InlineSlice {
819819
// ***WARNING***
820820
// 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
821-
@usableFromInline
822-
var slice: Range<HalfInt>
823-
@usableFromInline
824-
var storage: _DataStorage
821+
@usableFromInline var slice: Range<HalfInt>
822+
@usableFromInline var storage: _DataStorage
825823

826-
@inlinable
824+
@inlinable // This is @inlinable as trivially computable.
827825
static func canStore(count: Int) -> Bool {
828826
return count < HalfInt.max
829827
}
830828

831-
@inlinable
829+
@inlinable // This is @inlinable as a convenience initializer.
832830
init(_ buffer: UnsafeRawBufferPointer) {
833831
assert(buffer.count < HalfInt.max)
834832
self.init(_DataStorage(bytes: buffer.baseAddress, length: buffer.count), count: buffer.count)
835833
}
836834

837-
@inlinable
835+
@inlinable // This is @inlinable as a convenience initializer.
838836
init(capacity: Int) {
839837
assert(capacity < HalfInt.max)
840838
self.init(_DataStorage(capacity: capacity), count: 0)
841839
}
842840

843-
@inlinable
841+
@inlinable // This is @inlinable as a convenience initializer.
844842
init(count: Int) {
845843
assert(count < HalfInt.max)
846844
self.init(_DataStorage(length: count), count: count)
847845
}
848846

849-
@inlinable
847+
@inlinable // This is @inlinable as a convenience initializer.
850848
init(_ inline: InlineData) {
851849
assert(inline.count < HalfInt.max)
852850
self.init(inline.withUnsafeBytes { return _DataStorage(bytes: $0.baseAddress, length: $0.count) }, count: inline.count)
853851
}
854852

855-
@inlinable
853+
@inlinable // This is @inlinable as a convenience initializer.
856854
init(_ inline: InlineData, range: Range<Int>) {
857855
assert(range.lowerBound < HalfInt.max)
858856
assert(range.upperBound < HalfInt.max)
859857
self.init(inline.withUnsafeBytes { return _DataStorage(bytes: $0.baseAddress, length: $0.count) }, range: range)
860858
}
861859

862-
@inlinable
860+
@inlinable // This is @inlinable as a convenience initializer.
863861
init(_ large: LargeSlice) {
864862
assert(large.range.lowerBound < HalfInt.max)
865863
assert(large.range.upperBound < HalfInt.max)
866864
self.init(large.storage, range: large.range)
867865
}
868866

869-
@inlinable
867+
@inlinable // This is @inlinable as a convenience initializer.
870868
init(_ large: LargeSlice, range: Range<Int>) {
871869
assert(range.lowerBound < HalfInt.max)
872870
assert(range.upperBound < HalfInt.max)
873871
self.init(large.storage, range: range)
874872
}
875873

876-
@inlinable
874+
@inlinable // This is @inlinable as a trivial initializer.
877875
init(_ storage: _DataStorage, count: Int) {
878876
assert(count < HalfInt.max)
879877
self.storage = storage
880878
slice = 0..<HalfInt(count)
881879
}
882880

883-
@inlinable
881+
@inlinable // This is @inlinable as a trivial initializer.
884882
init(_ storage: _DataStorage, range: Range<Int>) {
885883
assert(range.lowerBound < HalfInt.max)
886884
assert(range.upperBound < HalfInt.max)
887885
self.storage = storage
888886
slice = HalfInt(range.lowerBound)..<HalfInt(range.upperBound)
889887
}
890888

891-
@inlinable
889+
@inlinable // This is @inlinable as trivially computable (and inlining may help avoid retain-release traffic).
892890
mutating func ensureUniqueReference() {
893891
if !isKnownUniquelyReferenced(&storage) {
894892
storage = storage.mutableCopy(self.range)
895893
}
896894
}
897895

898-
@inlinable
899-
var startIndex: Int { return numericCast(slice.lowerBound) }
900-
@inlinable
901-
var endIndex: Int { return numericCast(slice.upperBound) }
896+
@inlinable // This is @inlinable as trivially computable.
897+
var startIndex: Int {
898+
return Int(slice.lowerBound)
899+
}
902900

903-
@inlinable
901+
@inlinable // This is @inlinable as trivially computable.
902+
var endIndex: Int {
903+
return Int(slice.upperBound)
904+
}
905+
906+
@inlinable // This is @inlinable as trivially computable.
904907
var capacity: Int {
905908
return storage.capacity
906909
}
907910

908-
@inlinable
911+
@inlinable // This is @inlinable as trivially computable (and inlining may help avoid retain-release traffic).
909912
mutating func reserveCapacity(_ minimumCapacity: Int) {
910913
ensureUniqueReference()
911914
// the current capacity can be zero (representing externally owned buffer), and count can be greater than the capacity
912915
storage.ensureUniqueBufferReference(growingTo: Swift.max(minimumCapacity, count))
913916
}
914917

915-
@inlinable
918+
@inlinable // This is @inlinable as trivially computable.
916919
var count: Int {
917920
get {
918-
return numericCast(slice.upperBound - slice.lowerBound)
921+
return Int(slice.upperBound - slice.lowerBound)
919922
}
920923
set(newValue) {
921924
assert(newValue < HalfInt.max)
@@ -925,10 +928,10 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
925928
}
926929
}
927930

928-
@inlinable
931+
@inlinable // This is @inlinable as trivially computable.
929932
var range: Range<Int> {
930933
get {
931-
return numericCast(slice.lowerBound)..<numericCast(slice.upperBound)
934+
return Int(slice.lowerBound)..<Int(slice.upperBound)
932935
}
933936
set(newValue) {
934937
assert(newValue.lowerBound < HalfInt.max)
@@ -937,26 +940,26 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
937940
}
938941
}
939942

940-
@inlinable
943+
@inlinable // This is @inlinable as a generic, trivially forwarding function.
941944
func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
942945
return try storage.withUnsafeBytes(in: range, apply: apply)
943946
}
944947

945-
@inlinable
948+
@inlinable // This is @inlinable as a generic, trivially forwarding function.
946949
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
947950
ensureUniqueReference()
948951
return try storage.withUnsafeMutableBytes(in: range, apply: apply)
949952
}
950953

951-
@inlinable
954+
@inlinable // This is @inlinable as reasonably small.
952955
mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
953956
assert(endIndex + buffer.count < HalfInt.max)
954957
ensureUniqueReference()
955958
storage.replaceBytes(in: NSRange(location: range.upperBound, length: storage.length - (range.upperBound - storage._offset)), with: buffer.baseAddress, length: buffer.count)
956-
slice = slice.lowerBound..<HalfInt(numericCast(slice.upperBound) + buffer.count)
959+
slice = slice.lowerBound..<HalfInt(Int(slice.upperBound) + buffer.count)
957960
}
958961

959-
@inlinable
962+
@inlinable // This is @inlinable as reasonably small.
960963
subscript(index: Index) -> UInt8 {
961964
get {
962965
assert(index < HalfInt.max)
@@ -973,12 +976,12 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
973976
}
974977
}
975978

976-
@inlinable
979+
@inlinable // This is @inlinable as trivially forwarding.
977980
func bridgedReference() -> NSData {
978981
return storage.bridgedReference(self.range)
979982
}
980983

981-
@inlinable
984+
@inlinable // This is @inlinable as reasonably small.
982985
mutating func resetBytes(in range: Range<Index>) {
983986
assert(range.lowerBound < HalfInt.max)
984987
assert(range.upperBound < HalfInt.max)
@@ -990,7 +993,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
990993
}
991994
}
992995

993-
@inlinable
996+
@inlinable // This is @inlinable as reasonably small.
994997
mutating func replaceSubrange(_ subrange: Range<Index>, with bytes: UnsafeRawPointer?, count cnt: Int) {
995998
precondition(startIndex <= subrange.lowerBound, "index \(subrange.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
996999
precondition(subrange.lowerBound <= endIndex, "index \(subrange.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
@@ -1005,7 +1008,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
10051008
slice = slice.lowerBound..<HalfInt(resultingUpper)
10061009
}
10071010

1008-
@inlinable
1011+
@inlinable // This is @inlinable as reasonably small.
10091012
func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
10101013
precondition(startIndex <= range.lowerBound, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
10111014
precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")

0 commit comments

Comments
 (0)