Skip to content

Commit 88e1aba

Browse files
committed
Revert "[Foundation] Fix potential backdeployment regression in append"
This reverts commit cdd9956.
1 parent 35159da commit 88e1aba

File tree

1 file changed

+67
-64
lines changed

1 file changed

+67
-64
lines changed

stdlib/public/Darwin/Foundation/Data.swift

Lines changed: 67 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,65 +1415,6 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14151415
}
14161416
}
14171417

1418-
@inlinable
1419-
@_alwaysEmitIntoClient
1420-
internal mutating func _truncateOrZeroExtend(toCount newCount: Int) {
1421-
switch self {
1422-
case .empty:
1423-
if newCount == 0 {
1424-
return
1425-
} else if InlineData.canStore(count: newCount) {
1426-
self = .inline(InlineData(count: newCount))
1427-
} else if InlineSlice.canStore(count: newCount) {
1428-
self = .slice(InlineSlice(count: newCount))
1429-
} else {
1430-
self = .large(LargeSlice(count: newCount))
1431-
}
1432-
case .inline(var inline):
1433-
if newCount == 0 {
1434-
self = .empty
1435-
} else if InlineData.canStore(count: newCount) {
1436-
guard inline.count != newCount else { return }
1437-
inline.count = newCount
1438-
self = .inline(inline)
1439-
} else if InlineSlice.canStore(count: newCount) {
1440-
var slice = InlineSlice(inline)
1441-
slice.count = newCount
1442-
self = .slice(slice)
1443-
} else {
1444-
var slice = LargeSlice(inline)
1445-
slice.count = newCount
1446-
self = .large(slice)
1447-
}
1448-
case .slice(var slice):
1449-
if newCount == 0 && slice.startIndex == 0 {
1450-
self = .empty
1451-
} else if slice.startIndex == 0 && InlineData.canStore(count: newCount) {
1452-
self = .inline(InlineData(slice, count: newCount))
1453-
} else if InlineSlice.canStore(count: newCount + slice.startIndex) {
1454-
guard slice.count != newCount else { return }
1455-
self = .empty // TODO: remove this when mgottesman lands optimizations
1456-
slice.count = newCount
1457-
self = .slice(slice)
1458-
} else {
1459-
var newSlice = LargeSlice(slice)
1460-
newSlice.count = newCount
1461-
self = .large(newSlice)
1462-
}
1463-
case .large(var slice):
1464-
if newCount == 0 && slice.startIndex == 0 {
1465-
self = .empty
1466-
} else if slice.startIndex == 0 && InlineData.canStore(count: newCount) {
1467-
self = .inline(InlineData(slice, count: newCount))
1468-
} else {
1469-
guard slice.count != newCount else { return }
1470-
self = .empty // TODO: remove this when mgottesman lands optimizations
1471-
slice.count = newCount
1472-
self = .large(slice)
1473-
}
1474-
}
1475-
}
1476-
14771418
@inlinable // This is @inlinable as reasonably small.
14781419
var count: Int {
14791420
get {
@@ -1485,7 +1426,69 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
14851426
}
14861427
}
14871428
set(newValue) {
1488-
_truncateOrZeroExtend(toCount: newValue)
1429+
// HACK: The definition of this inline function takes an inout reference to self, giving the optimizer a unique referencing guarantee.
1430+
// This allows us to avoid excessive retain-release traffic around modifying enum values, and inlining the function then avoids the additional frame.
1431+
@inline(__always)
1432+
func apply(_ representation: inout _Representation, _ newValue: Int) -> _Representation? {
1433+
switch representation {
1434+
case .empty:
1435+
if newValue == 0 {
1436+
return nil
1437+
} else if InlineData.canStore(count: newValue) {
1438+
return .inline(InlineData(count: newValue))
1439+
} else if InlineSlice.canStore(count: newValue) {
1440+
return .slice(InlineSlice(count: newValue))
1441+
} else {
1442+
return .large(LargeSlice(count: newValue))
1443+
}
1444+
case .inline(var inline):
1445+
if newValue == 0 {
1446+
return .empty
1447+
} else if InlineData.canStore(count: newValue) {
1448+
guard inline.count != newValue else { return nil }
1449+
inline.count = newValue
1450+
return .inline(inline)
1451+
} else if InlineSlice.canStore(count: newValue) {
1452+
var slice = InlineSlice(inline)
1453+
slice.count = newValue
1454+
return .slice(slice)
1455+
} else {
1456+
var slice = LargeSlice(inline)
1457+
slice.count = newValue
1458+
return .large(slice)
1459+
}
1460+
case .slice(var slice):
1461+
if newValue == 0 && slice.startIndex == 0 {
1462+
return .empty
1463+
} else if slice.startIndex == 0 && InlineData.canStore(count: newValue) {
1464+
return .inline(InlineData(slice, count: newValue))
1465+
} else if InlineSlice.canStore(count: newValue + slice.startIndex) {
1466+
guard slice.count != newValue else { return nil }
1467+
representation = .empty // TODO: remove this when mgottesman lands optimizations
1468+
slice.count = newValue
1469+
return .slice(slice)
1470+
} else {
1471+
var newSlice = LargeSlice(slice)
1472+
newSlice.count = newValue
1473+
return .large(newSlice)
1474+
}
1475+
case .large(var slice):
1476+
if newValue == 0 && slice.startIndex == 0 {
1477+
return .empty
1478+
} else if slice.startIndex == 0 && InlineData.canStore(count: newValue) {
1479+
return .inline(InlineData(slice, count: newValue))
1480+
} else {
1481+
guard slice.count != newValue else { return nil}
1482+
representation = .empty // TODO: remove this when mgottesman lands optimizations
1483+
slice.count = newValue
1484+
return .large(slice)
1485+
}
1486+
}
1487+
}
1488+
1489+
if let rep = apply(&self, newValue) {
1490+
self = rep
1491+
}
14891492
}
14901493
}
14911494

@@ -2385,16 +2388,16 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
23852388
// Copy as much as we can in one shot.
23862389
let underestimatedCount = elements.underestimatedCount
23872390
let originalCount = _representation.count
2388-
_representation._truncateOrZeroExtend(toCount: originalCount + underestimatedCount)
2389-
var (iter, copiedCount): (S.Iterator, Int) = _representation.withUnsafeMutableBytes { buffer in
2391+
_representation.count += underestimatedCount
2392+
var (iter, endIndex): (S.Iterator, Int) = _representation.withUnsafeMutableBytes { buffer in
23902393
let start = buffer.baseAddress!.assumingMemoryBound(to: UInt8.self) + originalCount
23912394
let b = UnsafeMutableBufferPointer(start: start, count: buffer.count - originalCount)
23922395
return elements._copyContents(initializing: b)
23932396
}
2394-
guard copiedCount == underestimatedCount else {
2397+
guard endIndex == underestimatedCount else {
23952398
// We can't trap here. We have to allow an underfilled buffer
23962399
// to emulate the previous implementation.
2397-
_representation._truncateOrZeroExtend(toCount: originalCount + copiedCount)
2400+
_representation.replaceSubrange(originalCount + endIndex ..< _representation.endIndex, with: nil, count: 0)
23982401
return
23992402
}
24002403

0 commit comments

Comments
 (0)