Skip to content

Commit b1e4c56

Browse files
author
Itai Ferber
committed
Refine inlinability of InlineData
1 parent 6482c34 commit b1e4c56

File tree

1 file changed

+40
-44
lines changed

1 file changed

+40
-44
lines changed

stdlib/public/Darwin/Foundation/Data.swift

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -612,36 +612,28 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
612612
public typealias Index = Int
613613
public typealias Indices = Range<Int>
614614

615+
// A small inline buffer of bytes suitable for stack-allocation of small data.
616+
// Inlinability strategy: everything here should be inlined for direct operation on the stack wherever possible.
615617
@usableFromInline
616618
@_fixed_layout
617619
internal struct InlineData {
618620
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
619-
@usableFromInline
620-
typealias Buffer = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
621-
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) //len //enum
622-
@usableFromInline
623-
var bytes: Buffer
621+
@usableFromInline typealias Buffer = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
622+
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) //len //enum
623+
@usableFromInline var bytes: Buffer
624624
#elseif arch(i386) || arch(arm)
625-
@usableFromInline
626-
typealias Buffer = (UInt8, UInt8, UInt8, UInt8,
627-
UInt8, UInt8) //len //enum
628-
@usableFromInline
629-
var bytes: Buffer
625+
@usableFromInline typealias Buffer = (UInt8, UInt8, UInt8, UInt8,
626+
UInt8, UInt8) //len //enum
627+
@usableFromInline var bytes: Buffer
630628
#endif
631-
@usableFromInline
632-
var length: UInt8
629+
@usableFromInline var length: UInt8
633630

634-
@inlinable
631+
@inlinable // This is @inlinable as trivially computable.
635632
static func canStore(count: Int) -> Bool {
636633
return count <= MemoryLayout<Buffer>.size
637634
}
638635

639-
@inlinable
640-
init() {
641-
self.init(count: 0)
642-
}
643-
644-
@inlinable
636+
@inlinable // This is @inlinable as a convenience initializer.
645637
init(_ srcBuffer: UnsafeRawBufferPointer) {
646638
self.init(count: srcBuffer.count)
647639
if srcBuffer.count > 0 {
@@ -651,19 +643,18 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
651643
}
652644
}
653645

654-
@inlinable
655-
init(count: Int) {
646+
@inlinable // This is @inlinable as a trivial initializer.
647+
init(count: Int = 0) {
656648
assert(count <= MemoryLayout<Buffer>.size)
657649
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
658650
bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0))
659651
#elseif arch(i386) || arch(arm)
660-
bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0),
661-
UInt8(0), UInt8(0))
652+
bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0))
662653
#endif
663654
length = UInt8(count)
664655
}
665656

666-
@inlinable
657+
@inlinable // This is @inlinable as a convenience initializer.
667658
init(_ slice: InlineSlice, count: Int) {
668659
self.init(count: count)
669660
Swift.withUnsafeMutableBytes(of: &bytes) { dstBuffer in
@@ -673,7 +664,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
673664
}
674665
}
675666

676-
@inlinable
667+
@inlinable // This is @inlinable as a convenience initializer.
677668
init(_ slice: LargeSlice, count: Int) {
678669
self.init(count: count)
679670
Swift.withUnsafeMutableBytes(of: &bytes) { dstBuffer in
@@ -683,57 +674,61 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
683674
}
684675
}
685676

686-
@inlinable
677+
@inlinable // This is @inlinable as trivially computable.
687678
var capacity: Int {
688679
return MemoryLayout<Buffer>.size
689680
}
690681

691-
@inlinable
682+
@inlinable // This is @inlinable as trivially computable.
692683
var count: Int {
693684
get {
694-
return numericCast(length)
685+
return Int(length)
695686
}
696687
set(newValue) {
697688
precondition(newValue <= MemoryLayout<Buffer>.size)
698689
length = UInt8(newValue)
699690
}
700691
}
701692

702-
@inlinable
703-
var startIndex: Int { return 0 }
693+
@inlinable // This is @inlinable as trivially computable.
694+
var startIndex: Int {
695+
return 0
696+
}
704697

705-
@inlinable
706-
var endIndex: Int { return count }
698+
@inlinable // This is @inlinable as trivially computable.
699+
var endIndex: Int {
700+
return count
701+
}
707702

708-
@inlinable
703+
@inlinable // This is @inlinable as a generic, trivially forwarding function.
709704
func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
710-
let count: Int = numericCast(length)
705+
let count = Int(length)
711706
return try Swift.withUnsafeBytes(of: bytes) { (rawBuffer) throws -> Result in
712707
return try apply(UnsafeRawBufferPointer(start: rawBuffer.baseAddress, count: count))
713708
}
714709
}
715710

716-
@inlinable
711+
@inlinable // This is @inlinable as a generic, trivially forwarding function.
717712
mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
718-
let count: Int = numericCast(length)
713+
let count = Int(length)
719714
return try Swift.withUnsafeMutableBytes(of: &bytes) { (rawBuffer) throws -> Result in
720715
return try apply(UnsafeMutableRawBufferPointer(start: rawBuffer.baseAddress, count: count))
721716
}
722717
}
723718

724-
@inlinable
719+
@inlinable // This is @inlinable as trivially computable.
725720
mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
726721
guard buffer.count > 0 else { return }
727722
assert(count + buffer.count <= MemoryLayout<Buffer>.size)
728723
let cnt = count
729724
_ = Swift.withUnsafeMutableBytes(of: &bytes) { rawBuffer in
730725
rawBuffer.baseAddress?.advanced(by: cnt).copyMemory(from: buffer.baseAddress!, byteCount: buffer.count)
731726
}
732-
length += UInt8(buffer.count)
733727

728+
length += UInt8(buffer.count)
734729
}
735730

736-
@inlinable
731+
@inlinable // This is @inlinable as trivially computable.
737732
subscript(index: Index) -> UInt8 {
738733
get {
739734
assert(index <= MemoryLayout<Buffer>.size)
@@ -751,20 +746,21 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
751746
}
752747
}
753748

754-
@inlinable
749+
@inlinable // This is @inlinable as trivially computable.
755750
mutating func resetBytes(in range: Range<Index>) {
756751
assert(range.lowerBound <= MemoryLayout<Buffer>.size)
757752
assert(range.upperBound <= MemoryLayout<Buffer>.size)
758753
precondition(range.lowerBound <= length, "index \(range.lowerBound) is out of bounds of 0..<\(length)")
759754
if count < range.upperBound {
760755
count = range.upperBound
761756
}
762-
Swift.withUnsafeMutableBytes(of: &bytes) { rawBuffer in
763-
bzero(rawBuffer.baseAddress?.advanced(by: range.lowerBound), range.upperBound - range.lowerBound)
757+
758+
let _ = Swift.withUnsafeMutableBytes(of: &bytes) { rawBuffer in
759+
memset(rawBuffer.baseAddress?.advanced(by: range.lowerBound), 0, range.upperBound - range.lowerBound)
764760
}
765761
}
766762

767-
@inlinable
763+
@usableFromInline // This is not @inlinable as it is a non-trivial, non-generic function.
768764
mutating func replaceSubrange(_ subrange: Range<Index>, with replacementBytes: UnsafeRawPointer?, count replacementLength: Int) {
769765
assert(subrange.lowerBound <= MemoryLayout<Buffer>.size)
770766
assert(subrange.upperBound <= MemoryLayout<Buffer>.size)
@@ -788,7 +784,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
788784
count = resultingLength
789785
}
790786

791-
@inlinable
787+
@inlinable // This is @inlinable as trivially computable.
792788
func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
793789
precondition(startIndex <= range.lowerBound, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
794790
precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")

0 commit comments

Comments
 (0)