@@ -4880,51 +4880,88 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
4880
4880
}
4881
4881
#endif
4882
4882
4883
- /// Ensure this we hold a unique reference to a native buffer
4884
- /// having at least `minimumCapacity` elements.
4883
+ /// Return true if self is native.
4885
4884
@_inlineable // FIXME(sil-serialize-all)
4886
4885
@_versioned // FIXME(sil-serialize-all)
4887
- internal mutating func ensureUniqueNativeBuffer(_ minimumCapacity: Int)
4888
- -> (reallocated: Bool, capacityChanged: Bool) {
4886
+ internal var _isNative : Bool {
4887
+ #if _runtime(_ObjC)
4889
4888
switch self {
4890
4889
case .native:
4891
- let oldCapacity = asNative.capacity
4892
- if isUniquelyReferenced() && oldCapacity >= minimumCapacity {
4893
- return (reallocated: false, capacityChanged: false)
4894
- }
4890
+ return true
4891
+ case .cocoa:
4892
+ return false
4893
+ }
4894
+ #else
4895
+ return true
4896
+ #endif
4897
+ }
4895
4898
4896
- let oldNativeBuffer = asNative
4897
- var newNativeBuffer = NativeBuffer(minimumCapacity: minimumCapacity)
4898
- let newCapacity = newNativeBuffer.capacity
4899
- for i in 0..<oldCapacity {
4900
- if oldNativeBuffer.isInitializedEntry(at: i) {
4901
- if oldCapacity == newCapacity {
4902
- let key = oldNativeBuffer.key(at: i)
4899
+ @inline(__always)
4900
+ @_inlineable // FIXME(sil-serialize-all)
4901
+ @_versioned // FIXME(sil-serialize-all)
4902
+ internal mutating func ensureUniqueNativeBufferNative(_ minimumCapacity: Int)
4903
+ -> (reallocated: Bool, capacityChanged: Bool) {
4904
+ let oldCapacity = asNative.capacity
4905
+ if oldCapacity >= minimumCapacity && isUniquelyReferenced() {
4906
+ return (reallocated: false, capacityChanged: false)
4907
+ }
4908
+
4909
+ let oldNativeBuffer = asNative
4910
+ var newNativeBuffer = NativeBuffer(minimumCapacity: minimumCapacity)
4911
+ let newCapacity = newNativeBuffer.capacity
4912
+ for i in 0..<oldCapacity {
4913
+ if oldNativeBuffer.isInitializedEntry(at: i) {
4914
+ if oldCapacity == newCapacity {
4915
+ let key = oldNativeBuffer.key(at: i)
4903
4916
%if Self == 'Set':
4904
- newNativeBuffer.initializeKey(key, at: i)
4917
+ newNativeBuffer.initializeKey(key, at: i)
4905
4918
%elif Self == 'Dictionary':
4906
- let value = oldNativeBuffer.value(at: i)
4907
- newNativeBuffer.initializeKey(key, value: value , at: i)
4919
+ let value = oldNativeBuffer.value(at: i)
4920
+ newNativeBuffer.initializeKey(key, value: value , at: i)
4908
4921
%end
4909
- } else {
4910
- let key = oldNativeBuffer.key(at: i)
4922
+ } else {
4923
+ let key = oldNativeBuffer.key(at: i)
4911
4924
%if Self == 'Set':
4912
- newNativeBuffer.unsafeAddNew(key: key)
4925
+ newNativeBuffer.unsafeAddNew(key: key)
4913
4926
%elif Self == 'Dictionary':
4914
- newNativeBuffer.unsafeAddNew(
4915
- key: key,
4916
- value: oldNativeBuffer.value(at: i))
4927
+ newNativeBuffer.unsafeAddNew(
4928
+ key: key,
4929
+ value: oldNativeBuffer.value(at: i))
4917
4930
%end
4918
- }
4919
4931
}
4920
4932
}
4921
- newNativeBuffer.count = oldNativeBuffer.count
4933
+ }
4934
+ newNativeBuffer.count = oldNativeBuffer.count
4922
4935
4923
- self = .native(newNativeBuffer)
4924
- return (reallocated: true,
4925
- capacityChanged: oldCapacity != newNativeBuffer.capacity)
4936
+ self = .native(newNativeBuffer)
4937
+ return (reallocated: true,
4938
+ capacityChanged: oldCapacity != newNativeBuffer.capacity)
4939
+ }
4926
4940
4941
+ /// Ensure this we hold a unique reference to a native buffer
4942
+ /// having at least `minimumCapacity` elements.
4943
+ @_inlineable // FIXME(sil-serialize-all)
4944
+ @_versioned // FIXME(sil-serialize-all)
4945
+ internal mutating func ensureUniqueNativeBuffer(_ minimumCapacity: Int)
4946
+ -> (reallocated: Bool, capacityChanged: Bool) {
4927
4947
#if _runtime(_ObjC)
4948
+ // This is a performance optimization that was put in to ensure that we did
4949
+ // not make a copy of self to call _isNative over the entire if region
4950
+ // causing at -Onone the uniqueness check to fail. This code used to be:
4951
+ //
4952
+ // if _isNative {
4953
+ // return ensureUniqueNativeBufferNative(minimumCapacity)
4954
+ // }
4955
+ //
4956
+ // SR-6437
4957
+ let n = _isNative
4958
+ if n {
4959
+ return ensureUniqueNativeBufferNative(minimumCapacity)
4960
+ }
4961
+
4962
+ switch self {
4963
+ case .native:
4964
+ fatalError("This should have been handled earlier")
4928
4965
case .cocoa(let cocoaBuffer):
4929
4966
let cocoa${Self} = cocoaBuffer.cocoa${Self}
4930
4967
var newNativeBuffer = NativeBuffer(minimumCapacity: minimumCapacity)
@@ -4948,8 +4985,10 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
4948
4985
4949
4986
self = .native(newNativeBuffer)
4950
4987
return (reallocated: true, capacityChanged: true)
4951
- #endif
4952
4988
}
4989
+ #else
4990
+ return ensureUniqueNativeBufferNative(minimumCapacity)
4991
+ #endif
4953
4992
}
4954
4993
4955
4994
#if _runtime(_ObjC)
@@ -5236,8 +5275,17 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
5236
5275
@_inlineable // FIXME(sil-serialize-all)
5237
5276
@_versioned // FIXME(sil-serialize-all)
5238
5277
internal mutating func nativePointerToValue(at i: Index)
5239
- -> UnsafeMutablePointer<Value> {
5240
- _ = ensureUniqueNativeBuffer(asNative.capacity)
5278
+ -> UnsafeMutablePointer<Value> {
5279
+ // This is a performance optimization that was put in to ensure that we did
5280
+ // not make a copy of self to call asNative.capacity over
5281
+ // ensureUniqueNativeBefore causing at -Onone the uniqueness check to
5282
+ // fail. This code used to be:
5283
+ //
5284
+ // _ = ensureUniqueNativeBuffer(capacity)
5285
+ //
5286
+ // SR-6437
5287
+ let capacity = asNative.capacity
5288
+ _ = ensureUniqueNativeBuffer(capacity)
5241
5289
return asNative.values + i._nativeIndex.offset
5242
5290
}
5243
5291
@@ -5391,7 +5439,16 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
5391
5439
var (i, found) = asNative._find(key, startBucket: asNative._bucket(key))
5392
5440
5393
5441
if found {
5394
- _ = ensureUniqueNativeBuffer(asNative.capacity)
5442
+ // This is a performance optimization that was put in to ensure that we
5443
+ // did not make a copy of self to call asNative.capacity over
5444
+ // ensureUniqueNativeBefore causing at -Onone the uniqueness check to
5445
+ // fail. This code used to be:
5446
+ //
5447
+ // _ = ensureUniqueNativeBuffer(asNative.capacity)
5448
+ //
5449
+ // SR-6437
5450
+ let capacity = asNative.capacity
5451
+ _ = ensureUniqueNativeBuffer(capacity)
5395
5452
do {
5396
5453
let newValue = try combine(asNative.value(at: i.offset), value)
5397
5454
asNative.setKey(key, value: newValue, at: i.offset)
@@ -5545,8 +5602,17 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
5545
5602
return nil
5546
5603
}
5547
5604
5605
+ // This is a performance optimization that was put in to ensure that we
5606
+ // did not make a copy of self to call asNative.capacity over
5607
+ // ensureUniqueNativeBefore causing at -Onone the uniqueness check to
5608
+ // fail. This code used to be:
5609
+ //
5610
+ // _ = ensureUniqueNativeBuffer(asNative.capacity)
5611
+ //
5612
+ // SR-6437
5613
+ let capacity = asNative.capacity
5548
5614
let (_, capacityChanged) =
5549
- ensureUniqueNativeBuffer(asNative. capacity)
5615
+ ensureUniqueNativeBuffer(capacity)
5550
5616
let nativeBuffer = asNative
5551
5617
if capacityChanged {
5552
5618
idealBucket = nativeBuffer._bucket(key)
@@ -5568,10 +5634,18 @@ internal enum _Variant${Self}Buffer<${TypeParametersDecl}> : _HashBuffer {
5568
5634
internal mutating func nativeRemove(
5569
5635
at nativeIndex: NativeIndex
5570
5636
) -> SequenceElement {
5571
-
5637
+ // This is a performance optimization that was put in to ensure that we did
5638
+ // not make a copy of self to call asNative.capacity over
5639
+ // ensureUniqueNativeBefore causing at -Onone the uniqueness check to
5640
+ // fail. This code used to be:
5641
+ //
5642
+ // _ = ensureUniqueNativeBuffer(asNative.capacity)
5643
+ //
5644
+ // SR-6437
5645
+ let capacity = asNative.capacity
5572
5646
// The provided index should be valid, so we will always mutating the
5573
5647
// set buffer. Request unique buffer.
5574
- _ = ensureUniqueNativeBuffer(asNative. capacity)
5648
+ _ = ensureUniqueNativeBuffer(capacity)
5575
5649
let nativeBuffer = asNative
5576
5650
5577
5651
let result = nativeBuffer.assertingGet(nativeIndex)
0 commit comments