File tree 5 files changed +51
-7
lines changed 5 files changed +51
-7
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
@@ -1737,7 +1748,11 @@ extension Array {
1737
1748
@lifetime ( & self )
1738
1749
@_alwaysEmitIntoClient
1739
1750
mutating get {
1751
+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
1752
+ _makeMutableAndUniqueUnchecked ( )
1753
+ #else
1740
1754
_makeMutableAndUnique ( )
1755
+ #endif
1741
1756
// LifetimeDependence analysis inserts call to Builtin.endCOWMutation.
1742
1757
let pointer = unsafe _buffer . firstElementAddress
1743
1758
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 @@ -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