File tree 5 files changed +52
-8
lines changed
5 files changed +52
-8
lines changed Original file line number Diff line number Diff line change @@ -355,6 +355,17 @@ extension Array {
355
355
}
356
356
}
357
357
358
+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
359
+ @inlinable
360
+ @_semantics ( " array.make_mutable " )
361
+ @_effects ( notEscaping self.** )
362
+ internal mutating func _makeMutableAndUniqueUnchecked( ) {
363
+ if _slowPath ( !_buffer. beginCOWMutationUnchecked ( ) ) {
364
+ _buffer = _buffer. _consumeAndCreateNew ( )
365
+ }
366
+ }
367
+ #endif
368
+
358
369
/// Marks the end of an Array mutation.
359
370
///
360
371
/// After a call to `_endMutation` the buffer must not be mutated until a call
@@ -1735,7 +1746,11 @@ extension Array {
1735
1746
@lifetime ( & self )
1736
1747
@_alwaysEmitIntoClient
1737
1748
mutating get {
1749
+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
1750
+ _makeMutableAndUniqueUnchecked ( )
1751
+ #else
1738
1752
_makeMutableAndUnique ( )
1753
+ #endif
1739
1754
// LifetimeDependence analysis inserts call to Builtin.endCOWMutation.
1740
1755
let pointer = unsafe _buffer . firstElementAddress
1741
1756
let count = _buffer. mutableCount
Original file line number Diff line number Diff line change @@ -135,7 +135,22 @@ extension _ArrayBuffer {
135
135
#endif
136
136
return isUnique
137
137
}
138
-
138
+
139
+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
140
+ @_alwaysEmitIntoClient
141
+ internal mutating func beginCOWMutationUnchecked( ) -> Bool {
142
+ let isUnique : Bool
143
+ if !_isClassOrObjCExistential( Element . self) {
144
+ isUnique = _storage. beginCOWMutationUnflaggedNative ( )
145
+ } else if !_storage. beginCOWMutationNative ( ) {
146
+ return false
147
+ } else {
148
+ isUnique = _isNative
149
+ }
150
+ return isUnique
151
+ }
152
+ #endif
153
+
139
154
/// Puts the buffer in an immutable state.
140
155
///
141
156
/// - Precondition: The buffer must be mutable or the empty array singleton.
Original file line number Diff line number Diff line change @@ -1305,10 +1305,12 @@ extension ArraySlice {
1305
1305
@lifetime ( & self )
1306
1306
@_alwaysEmitIntoClient
1307
1307
mutating get {
1308
+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
1309
+ _makeMutableAndUniqueUnchecked ( )
1310
+ #else
1308
1311
_makeMutableAndUnique ( )
1309
- // NOTE: We don't have the ability to schedule a call to
1310
- // ContiguousArrayBuffer.endCOWMutation().
1311
- // rdar://146785284 (lifetime analysis for end of mutation)
1312
+ #endif
1313
+ // LifetimeDependence analysis inserts call to Builtin.endCOWMutation.
1312
1314
let ( pointer, count) = unsafe ( _buffer. firstElementAddress, _buffer. count)
1313
1315
let span = unsafe MutableSpan( _unsafeStart: pointer, count: count)
1314
1316
return unsafe _override Lifetime ( span, mutating: & self )
Original file line number Diff line number Diff line change @@ -1247,10 +1247,12 @@ extension ContiguousArray {
1247
1247
@lifetime ( & self )
1248
1248
@_alwaysEmitIntoClient
1249
1249
mutating get {
1250
+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
1251
+ _makeMutableAndUniqueUnchecked ( )
1252
+ #else
1250
1253
_makeMutableAndUnique ( )
1251
- // NOTE: We don't have the ability to schedule a call to
1252
- // ContiguousArrayBuffer.endCOWMutation().
1253
- // rdar://146785284 (lifetime analysis for end of mutation)
1254
+ #endif
1255
+ // LifetimeDependence analysis inserts call to Builtin.endCOWMutation.
1254
1256
let pointer = unsafe _buffer . firstElementAddress
1255
1257
let count = _buffer. mutableCount
1256
1258
let span = unsafe MutableSpan( _unsafeStart: pointer, count: count)
Original file line number Diff line number Diff line change @@ -808,7 +808,7 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
808
808
/// - Warning: It's a requirement to call `beginCOWMutation` before the buffer
809
809
/// is mutated.
810
810
@_alwaysEmitIntoClient
811
- internal mutating func beginCOWMutation( ) -> Bool {
811
+ internal mutating func beginCOWMutation( checked : Bool = true ) -> Bool {
812
812
if Bool ( Builtin . beginCOWMutation ( & _storage) ) {
813
813
#if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
814
814
isImmutable = false
@@ -818,6 +818,16 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
818
818
return false ;
819
819
}
820
820
821
+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
822
+ @_alwaysEmitIntoClient
823
+ internal mutating func beginCOWMutationUnchecked( ) -> Bool {
824
+ if Bool ( Builtin . beginCOWMutation ( & _storage) ) {
825
+ return true
826
+ }
827
+ return false ;
828
+ }
829
+ #endif
830
+
821
831
/// Puts the buffer in an immutable state.
822
832
///
823
833
/// - Precondition: The buffer must be mutable or the empty array singleton.
You can’t perform that action at this time.
0 commit comments