Skip to content

Commit ae1c984

Browse files
author
Greg Parker
authored
New refcount representation (swiftlang#5282)
New refcount representation and weak variable implementation. See SwiftShims/RefCount.h for details.
1 parent 60ae044 commit ae1c984

21 files changed

+2748
-760
lines changed

include/swift/ABI/System.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,36 @@
5656
/// ``pointer & SWIFT_ABI_XXX_OBJC_RESERVED_BITS_MASK == 0 &&
5757
/// pointer & SWIFT_ABI_XXX_SWIFT_SPARE_BITS_MASK != 0``.
5858

59+
// Weak references use a marker to tell when they are controlled by
60+
// the ObjC runtime and when they are controlled by the Swift runtime.
61+
// Non-ObjC platforms don't use this marker.
62+
#define SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_MASK 0
63+
#define SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_VALUE 0
64+
5965
/*********************************** i386 *************************************/
6066

6167
// Heap objects are pointer-aligned, so the low two bits are unused.
6268
#define SWIFT_ABI_I386_SWIFT_SPARE_BITS_MASK 0x00000003U
6369

70+
// ObjC weak reference discriminator is the LSB.
71+
#define SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_MASK \
72+
(SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK | \
73+
1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
74+
#define SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_VALUE \
75+
(1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
76+
6477
/*********************************** arm **************************************/
6578

6679
// Heap objects are pointer-aligned, so the low two bits are unused.
6780
#define SWIFT_ABI_ARM_SWIFT_SPARE_BITS_MASK 0x00000003U
6881

82+
// ObjC weak reference discriminator is the LSB.
83+
#define SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_MASK \
84+
(SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK | \
85+
1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
86+
#define SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_VALUE \
87+
(1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
88+
6989
/*********************************** x86-64 ***********************************/
7090

7191
/// Darwin reserves the low 4GB of address space.
@@ -79,6 +99,14 @@
7999
#define SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK 0x8000000000000001ULL
80100
#define SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS 1
81101

102+
// ObjC weak reference discriminator is the two bits
103+
// reserved for ObjC tagged pointers plus one more low bit.
104+
#define SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_MASK \
105+
(SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK | \
106+
1<<SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS)
107+
#define SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_VALUE \
108+
(1<<SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS)
109+
82110
/*********************************** arm64 ************************************/
83111

84112
/// Darwin reserves the low 4GB of address space.
@@ -92,6 +120,14 @@
92120
#define SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK 0x8000000000000000ULL
93121
#define SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS 0
94122

123+
// ObjC weak reference discriminator is the high bit
124+
// reserved for ObjC tagged pointers plus the LSB.
125+
#define SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_MASK \
126+
(SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK | \
127+
1<<SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS)
128+
#define SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_VALUE \
129+
(1<<SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS)
130+
95131
/*********************************** powerpc64 ********************************/
96132

97133
// Heap objects are pointer-aligned, so the low three bits are unused.

include/swift/Runtime/Debug.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include <llvm/Support/Compiler.h>
2121
#include <stdint.h>
2222
#include "swift/Runtime/Config.h"
23-
#include "swift/Runtime/Metadata.h"
2423
#include "swift/Runtime/Unreachable.h"
2524

2625
#ifdef SWIFT_HAVE_CRASHREPORTERCLIENT
@@ -63,6 +62,12 @@ static void CRSetCrashLogMessage(const char *) {}
6362

6463
namespace swift {
6564

65+
// Duplicated from Metadata.h. We want to use this header
66+
// in places that cannot themselves include Metadata.h.
67+
struct InProcess;
68+
template <typename Runtime> struct TargetMetadata;
69+
using Metadata = TargetMetadata<InProcess>;
70+
6671
// swift::crash() halts with a crash log message,
6772
// but otherwise tries not to disturb register state.
6873

@@ -87,11 +92,6 @@ static inline void _failCorruptType(const Metadata *type) {
8792
LLVM_ATTRIBUTE_NORETURN
8893
extern void
8994
fatalError(uint32_t flags, const char *format, ...);
90-
91-
struct InProcess;
92-
93-
template <typename Runtime> struct TargetMetadata;
94-
using Metadata = TargetMetadata<InProcess>;
9595

9696
// swift_dynamicCastFailure halts using fatalError()
9797
// with a description of a failed cast's types.
@@ -112,6 +112,14 @@ swift_dynamicCastFailure(const void *sourceType, const char *sourceName,
112112
SWIFT_RUNTIME_EXPORT
113113
void swift_reportError(uint32_t flags, const char *message);
114114

115+
// Halt due to an overflow in swift_retain().
116+
LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
117+
void swift_abortRetainOverflow();
118+
119+
// Halt due to reading an unowned reference to a dead object.
120+
LLVM_ATTRIBUTE_NORETURN LLVM_ATTRIBUTE_NOINLINE
121+
void swift_abortRetainUnowned(const void *object);
122+
115123
// namespace swift
116124
}
117125

include/swift/Runtime/HeapObject.h

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -219,18 +219,6 @@ SWIFT_RUNTIME_EXPORT
219219
void (*SWIFT_CC(RegisterPreservingCC) _swift_nonatomic_retain_n)(HeapObject *object,
220220
uint32_t n);
221221

222-
static inline void _swift_retain_inlined(HeapObject *object) {
223-
if (object) {
224-
object->refCount.increment();
225-
}
226-
}
227-
228-
static inline void _swift_nonatomic_retain_inlined(HeapObject *object) {
229-
if (object) {
230-
object->refCount.incrementNonAtomic();
231-
}
232-
}
233-
234222
/// Atomically increments the reference count of an object, unless it has
235223
/// already been destroyed. Returns nil if the object is dead.
236224
SWIFT_RT_ENTRY_VISIBILITY
@@ -512,22 +500,22 @@ struct UnownedReference {
512500
HeapObject *Value;
513501
};
514502

515-
/// Increment the weak/unowned retain count.
503+
/// Increment the unowned retain count.
516504
SWIFT_RT_ENTRY_VISIBILITY
517505
void swift_unownedRetain(HeapObject *value)
518506
SWIFT_CC(RegisterPreservingCC);
519507

520-
/// Decrement the weak/unowned retain count.
508+
/// Decrement the unowned retain count.
521509
SWIFT_RT_ENTRY_VISIBILITY
522510
void swift_unownedRelease(HeapObject *value)
523511
SWIFT_CC(RegisterPreservingCC);
524512

525-
/// Increment the weak/unowned retain count by n.
513+
/// Increment the unowned retain count by n.
526514
SWIFT_RT_ENTRY_VISIBILITY
527515
void swift_unownedRetain_n(HeapObject *value, int n)
528516
SWIFT_CC(RegisterPreservingCC);
529517

530-
/// Decrement the weak/unowned retain count by n.
518+
/// Decrement the unowned retain count by n.
531519
SWIFT_RT_ENTRY_VISIBILITY
532520
void swift_unownedRelease_n(HeapObject *value, int n)
533521
SWIFT_CC(RegisterPreservingCC);
@@ -540,7 +528,7 @@ void swift_unownedRetainStrong(HeapObject *value)
540528

541529
/// Increment the strong retain count of an object which may have been
542530
/// deallocated, aborting if it has been deallocated, and decrement its
543-
/// weak/unowned reference count.
531+
/// unowned reference count.
544532
SWIFT_RT_ENTRY_VISIBILITY
545533
void swift_unownedRetainStrongAndRelease(HeapObject *value)
546534
SWIFT_CC(RegisterPreservingCC);
@@ -614,16 +602,8 @@ static inline void swift_unownedTakeAssign(UnownedReference *dest,
614602
/****************************** WEAK REFERENCES ******************************/
615603
/*****************************************************************************/
616604

617-
/// A weak reference value object. This is ABI.
618-
struct WeakReference {
619-
uintptr_t Value;
620-
};
621-
622-
/// Return true if this is a native weak reference
623-
///
624-
/// \param ref - never null
625-
/// \return true if ref is a native weak reference
626-
bool isNativeSwiftWeakReference(WeakReference *ref);
605+
// Defined in Runtime/WeakReference.h
606+
class WeakReference;
627607

628608
/// Initialize a weak reference.
629609
///

include/swift/Runtime/Metadata.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ using TargetFarRelativeIndirectablePointer
136136
= typename Runtime::template FarRelativeIndirectablePointer<Pointee,Nullable>;
137137

138138
struct HeapObject;
139-
struct WeakReference;
139+
class WeakReference;
140140

141141
template <typename Runtime> struct TargetMetadata;
142142
using Metadata = TargetMetadata<InProcess>;
@@ -1832,17 +1832,6 @@ struct TargetObjCClassWrapperMetadata : public TargetMetadata<Runtime> {
18321832
using ObjCClassWrapperMetadata
18331833
= TargetObjCClassWrapperMetadata<InProcess>;
18341834

1835-
// FIXME: Workaround for rdar://problem/18889711. 'Consume' does not require
1836-
// a barrier on ARM64, but LLVM doesn't know that. Although 'relaxed'
1837-
// is formally UB by C++11 language rules, we should be OK because neither
1838-
// the processor model nor the optimizer can realistically reorder our uses
1839-
// of 'consume'.
1840-
#if __arm64__ || __arm__
1841-
# define SWIFT_MEMORY_ORDER_CONSUME (std::memory_order_relaxed)
1842-
#else
1843-
# define SWIFT_MEMORY_ORDER_CONSUME (std::memory_order_consume)
1844-
#endif
1845-
18461835
/// The structure of metadata for foreign types where the source
18471836
/// language doesn't provide any sort of more interesting metadata for
18481837
/// us to use.

stdlib/public/SwiftShims/HeapObject.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ typedef struct HeapMetadata HeapMetadata;
3131
// The members of the HeapObject header that are not shared by a
3232
// standard Objective-C instance
3333
#define SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS \
34-
StrongRefCount refCount; \
35-
WeakRefCount weakRefCount
34+
InlineRefCounts refCounts;
3635

3736
/// The Swift heap-object header.
3837
struct HeapObject {
@@ -48,8 +47,7 @@ struct HeapObject {
4847
// Initialize a HeapObject header as appropriate for a newly-allocated object.
4948
constexpr HeapObject(HeapMetadata const *newMetadata)
5049
: metadata(newMetadata)
51-
, refCount(StrongRefCount::Initialized)
52-
, weakRefCount(WeakRefCount::Initialized)
50+
, refCounts(InlineRefCounts::Initialized)
5351
{ }
5452
#endif
5553
};
@@ -59,6 +57,11 @@ static_assert(swift::IsTriviallyConstructible<HeapObject>::value,
5957
"HeapObject must be trivially initializable");
6058
static_assert(std::is_trivially_destructible<HeapObject>::value,
6159
"HeapObject must be trivially destructible");
60+
// FIXME: small header for 32-bit
61+
//static_assert(sizeof(HeapObject) == 2*sizeof(void*),
62+
// "HeapObject must be two pointers long");
63+
static_assert(alignof(HeapObject) == alignof(void*),
64+
"HeapObject must be pointer-aligned");
6265

6366
} // end namespace swift
6467
#endif

0 commit comments

Comments
 (0)