@@ -238,29 +238,14 @@ struct RefCountBitOffsets;
238
238
// 32-bit out of line
239
239
template <>
240
240
struct RefCountBitOffsets <8 > {
241
- /*
242
- The bottom 32 bits (on 64 bit architectures, fewer on 32 bit) of the refcount
243
- field are effectively a union of two different configurations:
244
-
245
- ---Normal case---
246
- Bit 0: Does this object need to call out to the ObjC runtime for deallocation
247
- Bits 1-31: Unowned refcount
248
-
249
- ---Immortal case---
250
- All bits set, the object does not deallocate or have a refcount
251
- */
252
- static const size_t PureSwiftDeallocShift = 0 ;
253
- static const size_t PureSwiftDeallocBitCount = 1 ;
254
- static const uint64_t PureSwiftDeallocMask = maskForField(PureSwiftDealloc);
255
-
256
- static const size_t UnownedRefCountShift = shiftAfterField(PureSwiftDealloc);
241
+ static const size_t IsImmortalShift = 0 ;
242
+ static const size_t IsImmortalBitCount = 1 ;
243
+ static const uint64_t IsImmortalMask = maskForField(IsImmortal);
244
+
245
+ static const size_t UnownedRefCountShift = shiftAfterField(IsImmortal);
257
246
static const size_t UnownedRefCountBitCount = 31 ;
258
247
static const uint64_t UnownedRefCountMask = maskForField(UnownedRefCount);
259
248
260
- static const size_t IsImmortalShift = 0 ; // overlaps PureSwiftDealloc and UnownedRefCount
261
- static const size_t IsImmortalBitCount = 32 ;
262
- static const uint64_t IsImmortalMask = maskForField(IsImmortal);
263
-
264
249
static const size_t IsDeinitingShift = shiftAfterField(UnownedRefCount);
265
250
static const size_t IsDeinitingBitCount = 1 ;
266
251
static const uint64_t IsDeinitingMask = maskForField(IsDeiniting);
@@ -286,18 +271,14 @@ struct RefCountBitOffsets<8> {
286
271
// 32-bit inline
287
272
template <>
288
273
struct RefCountBitOffsets <4 > {
289
- static const size_t PureSwiftDeallocShift = 0 ;
290
- static const size_t PureSwiftDeallocBitCount = 1 ;
291
- static const uint32_t PureSwiftDeallocMask = maskForField(PureSwiftDealloc );
274
+ static const size_t IsImmortalShift = 0 ;
275
+ static const size_t IsImmortalBitCount = 1 ;
276
+ static const uint64_t IsImmortalMask = maskForField(IsImmortal );
292
277
293
- static const size_t UnownedRefCountShift = shiftAfterField(PureSwiftDealloc );
278
+ static const size_t UnownedRefCountShift = shiftAfterField(IsImmortal );
294
279
static const size_t UnownedRefCountBitCount = 7 ;
295
280
static const uint32_t UnownedRefCountMask = maskForField(UnownedRefCount);
296
281
297
- static const size_t IsImmortalShift = 0 ; // overlaps PureSwiftDealloc and UnownedRefCount
298
- static const size_t IsImmortalBitCount = 8 ;
299
- static const uint32_t IsImmortalMask = maskForField(IsImmortal);
300
-
301
282
static const size_t IsDeinitingShift = shiftAfterField(UnownedRefCount);
302
283
static const size_t IsDeinitingBitCount = 1 ;
303
284
static const uint32_t IsDeinitingMask = maskForField(IsDeiniting);
@@ -388,56 +369,33 @@ class RefCountBitsT {
388
369
enum Immortal_t { Immortal };
389
370
390
371
LLVM_ATTRIBUTE_ALWAYS_INLINE
391
- bool isImmortal (bool checkSlowRCBit) const {
392
- if (checkSlowRCBit) {
393
- return (getField (IsImmortal) == Offsets::IsImmortalMask) &&
394
- bool (getField (UseSlowRC));
395
- } else {
396
- return (getField (IsImmortal) == Offsets::IsImmortalMask);
397
- }
398
- }
399
-
400
- LLVM_ATTRIBUTE_ALWAYS_INLINE
401
- bool isOverflowingUnownedRefCount (uint32_t oldValue, uint32_t inc) const {
402
- auto newValue = getUnownedRefCount ();
403
- return newValue != oldValue + inc ||
404
- newValue == Offsets::UnownedRefCountMask;
372
+ bool isImmortal () const {
373
+ return bool (getField (IsImmortal));
405
374
}
406
375
407
376
LLVM_ATTRIBUTE_ALWAYS_INLINE
408
377
void setIsImmortal (bool value) {
409
- assert (value);
410
- setField (IsImmortal, Offsets::IsImmortalMask);
378
+ setField (IsImmortal, value);
411
379
setField (UseSlowRC, value);
412
380
}
413
381
414
- LLVM_ATTRIBUTE_ALWAYS_INLINE
415
- bool pureSwiftDeallocation () const {
416
- return bool (getField (PureSwiftDealloc)) && !bool (getField (UseSlowRC));
417
- }
418
-
419
- LLVM_ATTRIBUTE_ALWAYS_INLINE
420
- void setPureSwiftDeallocation (bool value) {
421
- setField (PureSwiftDealloc, value);
422
- }
423
-
424
382
LLVM_ATTRIBUTE_ALWAYS_INLINE
425
383
RefCountBitsT () = default;
426
384
427
385
LLVM_ATTRIBUTE_ALWAYS_INLINE
428
386
constexpr
429
387
RefCountBitsT (uint32_t strongExtraCount, uint32_t unownedCount)
430
388
: bits((BitsType(strongExtraCount) << Offsets::StrongExtraRefCountShift) |
431
- (BitsType(1 ) << Offsets::PureSwiftDeallocShift) |
432
389
(BitsType(unownedCount) << Offsets::UnownedRefCountShift))
433
390
{ }
434
391
435
392
LLVM_ATTRIBUTE_ALWAYS_INLINE
436
393
constexpr
437
394
RefCountBitsT (Immortal_t immortal)
438
- : bits((BitsType(2 ) << Offsets::StrongExtraRefCountShift) |
439
- (BitsType(Offsets::IsImmortalMask)) |
440
- (BitsType(1 ) << Offsets::UseSlowRCShift))
395
+ : bits((BitsType(2 ) << Offsets::StrongExtraRefCountShift) |
396
+ (BitsType(2 ) << Offsets::UnownedRefCountShift) |
397
+ (BitsType(1 ) << Offsets::IsImmortalShift) |
398
+ (BitsType(1 ) << Offsets::UseSlowRCShift))
441
399
{ }
442
400
443
401
LLVM_ATTRIBUTE_ALWAYS_INLINE
@@ -475,7 +433,7 @@ class RefCountBitsT {
475
433
476
434
LLVM_ATTRIBUTE_ALWAYS_INLINE
477
435
bool hasSideTable () const {
478
- bool hasSide = getUseSlowRC () && !isImmortal (false );
436
+ bool hasSide = getUseSlowRC () && !isImmortal ();
479
437
480
438
// Side table refcount must not point to another side table.
481
439
assert ((refcountIsInline || !hasSide) &&
@@ -565,7 +523,7 @@ class RefCountBitsT {
565
523
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE
566
524
bool decrementStrongExtraRefCount (uint32_t dec) {
567
525
#ifndef NDEBUG
568
- if (!hasSideTable () && !isImmortal (false )) {
526
+ if (!hasSideTable () && !isImmortal ()) {
569
527
// Can't check these assertions with side table present.
570
528
571
529
if (getIsDeiniting ())
@@ -600,7 +558,7 @@ class RefCountBitsT {
600
558
static_assert (Offsets::UnownedRefCountBitCount +
601
559
Offsets::IsDeinitingBitCount +
602
560
Offsets::StrongExtraRefCountBitCount +
603
- Offsets::PureSwiftDeallocBitCount +
561
+ Offsets::IsImmortalBitCount +
604
562
Offsets::UseSlowRCBitCount == sizeof (bits)*8 ,
605
563
" inspect isUniquelyReferenced after adding fields" );
606
564
@@ -757,7 +715,7 @@ class RefCounts {
757
715
758
716
void setIsImmortal (bool immortal) {
759
717
auto oldbits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
760
- if (oldbits.isImmortal (true )) {
718
+ if (oldbits.isImmortal ()) {
761
719
return ;
762
720
}
763
721
RefCountBits newbits;
@@ -767,28 +725,7 @@ class RefCounts {
767
725
} while (!refCounts.compare_exchange_weak (oldbits, newbits,
768
726
std::memory_order_relaxed));
769
727
}
770
-
771
- void setPureSwiftDeallocation (bool nonobjc) {
772
- auto oldbits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
773
- // Immortal and no objc complications share a bit, so don't let setting
774
- // the complications one clear the immmortal one
775
- if (oldbits.isImmortal (true ) || oldbits.pureSwiftDeallocation () == nonobjc){
776
- assert (!oldbits.hasSideTable ());
777
- return ;
778
- }
779
- RefCountBits newbits;
780
- do {
781
- newbits = oldbits;
782
- newbits.setPureSwiftDeallocation (nonobjc);
783
- } while (!refCounts.compare_exchange_weak (oldbits, newbits,
784
- std::memory_order_relaxed));
785
- }
786
-
787
- bool getPureSwiftDeallocation () {
788
- auto bits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
789
- return bits.pureSwiftDeallocation ();
790
- }
791
-
728
+
792
729
// Initialize from another refcount bits.
793
730
// Only inline -> out-of-line is allowed (used for new side table entries).
794
731
void init (InlineRefCountBits newBits) {
@@ -803,7 +740,7 @@ class RefCounts {
803
740
newbits = oldbits;
804
741
bool fast = newbits.incrementStrongExtraRefCount (inc);
805
742
if (SWIFT_UNLIKELY (!fast)) {
806
- if (oldbits.isImmortal (false ))
743
+ if (oldbits.isImmortal ())
807
744
return ;
808
745
return incrementSlow (oldbits, inc);
809
746
}
@@ -816,7 +753,7 @@ class RefCounts {
816
753
auto newbits = oldbits;
817
754
bool fast = newbits.incrementStrongExtraRefCount (inc);
818
755
if (SWIFT_UNLIKELY (!fast)) {
819
- if (oldbits.isImmortal (false ))
756
+ if (oldbits.isImmortal ())
820
757
return ;
821
758
return incrementNonAtomicSlow (oldbits, inc);
822
759
}
@@ -834,7 +771,7 @@ class RefCounts {
834
771
newbits = oldbits;
835
772
bool fast = newbits.incrementStrongExtraRefCount (1 );
836
773
if (SWIFT_UNLIKELY (!fast)) {
837
- if (oldbits.isImmortal (false ))
774
+ if (oldbits.isImmortal ())
838
775
return true ;
839
776
return tryIncrementSlow (oldbits);
840
777
}
@@ -851,7 +788,7 @@ class RefCounts {
851
788
auto newbits = oldbits;
852
789
bool fast = newbits.incrementStrongExtraRefCount (1 );
853
790
if (SWIFT_UNLIKELY (!fast)) {
854
- if (oldbits.isImmortal (false ))
791
+ if (oldbits.isImmortal ())
855
792
return true ;
856
793
return tryIncrementNonAtomicSlow (oldbits);
857
794
}
@@ -887,7 +824,7 @@ class RefCounts {
887
824
// Precondition: the reference count must be 1
888
825
void decrementFromOneNonAtomic () {
889
826
auto bits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
890
- if (bits.isImmortal (true )) {
827
+ if (bits.isImmortal ()) {
891
828
return ;
892
829
}
893
830
if (bits.hasSideTable ())
@@ -985,7 +922,7 @@ class RefCounts {
985
922
// Decrement completed normally. New refcount is not zero.
986
923
deinitNow = false ;
987
924
}
988
- else if (oldbits.isImmortal (false )) {
925
+ else if (oldbits.isImmortal ()) {
989
926
return false ;
990
927
} else if (oldbits.hasSideTable ()) {
991
928
// Decrement failed because we're on some other slow path.
@@ -1024,7 +961,7 @@ class RefCounts {
1024
961
// Decrement completed normally. New refcount is not zero.
1025
962
deinitNow = false ;
1026
963
}
1027
- else if (oldbits.isImmortal (false )) {
964
+ else if (oldbits.isImmortal ()) {
1028
965
return false ;
1029
966
}
1030
967
else if (oldbits.hasSideTable ()) {
@@ -1064,7 +1001,7 @@ class RefCounts {
1064
1001
bool fast =
1065
1002
newbits.decrementStrongExtraRefCount (dec);
1066
1003
if (SWIFT_UNLIKELY (!fast)) {
1067
- if (oldbits.isImmortal (false )) {
1004
+ if (oldbits.isImmortal ()) {
1068
1005
return false ;
1069
1006
}
1070
1007
// Slow paths include side table; deinit; underflow
@@ -1088,7 +1025,7 @@ class RefCounts {
1088
1025
// Increment the unowned reference count.
1089
1026
void incrementUnowned (uint32_t inc) {
1090
1027
auto oldbits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
1091
- if (oldbits.isImmortal (true ))
1028
+ if (oldbits.isImmortal ())
1092
1029
return ;
1093
1030
RefCountBits newbits;
1094
1031
do {
@@ -1100,7 +1037,7 @@ class RefCounts {
1100
1037
uint32_t oldValue = newbits.incrementUnownedRefCount (inc);
1101
1038
1102
1039
// Check overflow and use the side table on overflow.
1103
- if (newbits.isOverflowingUnownedRefCount ( oldValue, inc) )
1040
+ if (newbits.getUnownedRefCount () != oldValue + inc)
1104
1041
return incrementUnownedSlow (inc);
1105
1042
1106
1043
} while (!refCounts.compare_exchange_weak (oldbits, newbits,
@@ -1109,7 +1046,7 @@ class RefCounts {
1109
1046
1110
1047
void incrementUnownedNonAtomic (uint32_t inc) {
1111
1048
auto oldbits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
1112
- if (oldbits.isImmortal (true ))
1049
+ if (oldbits.isImmortal ())
1113
1050
return ;
1114
1051
if (oldbits.hasSideTable ())
1115
1052
return oldbits.getSideTable ()->incrementUnownedNonAtomic (inc);
@@ -1119,7 +1056,7 @@ class RefCounts {
1119
1056
uint32_t oldValue = newbits.incrementUnownedRefCount (inc);
1120
1057
1121
1058
// Check overflow and use the side table on overflow.
1122
- if (newbits.isOverflowingUnownedRefCount ( oldValue, inc) )
1059
+ if (newbits.getUnownedRefCount () != oldValue + inc)
1123
1060
return incrementUnownedSlow (inc);
1124
1061
1125
1062
refCounts.store (newbits, std::memory_order_relaxed);
@@ -1129,7 +1066,7 @@ class RefCounts {
1129
1066
// Return true if the caller should free the object.
1130
1067
bool decrementUnownedShouldFree (uint32_t dec) {
1131
1068
auto oldbits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
1132
- if (oldbits.isImmortal (true ))
1069
+ if (oldbits.isImmortal ())
1133
1070
return false ;
1134
1071
RefCountBits newbits;
1135
1072
@@ -1157,7 +1094,7 @@ class RefCounts {
1157
1094
1158
1095
bool decrementUnownedShouldFreeNonAtomic (uint32_t dec) {
1159
1096
auto oldbits = refCounts.load (SWIFT_MEMORY_ORDER_CONSUME);
1160
- if (oldbits.isImmortal (true ))
1097
+ if (oldbits.isImmortal ())
1161
1098
return false ;
1162
1099
if (oldbits.hasSideTable ())
1163
1100
return oldbits.getSideTable ()->decrementUnownedShouldFreeNonAtomic (dec);
@@ -1446,7 +1383,7 @@ inline bool RefCounts<InlineRefCountBits>::doDecrementNonAtomic(uint32_t dec) {
1446
1383
auto newbits = oldbits;
1447
1384
bool fast = newbits.decrementStrongExtraRefCount (dec);
1448
1385
if (!fast) {
1449
- if (oldbits.isImmortal (false )) {
1386
+ if (oldbits.isImmortal ()) {
1450
1387
return false ;
1451
1388
}
1452
1389
return doDecrementNonAtomicSlow<performDeinit>(oldbits, dec);
0 commit comments