//===--- HeapObject.h - Swift Language Allocation ABI -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // Swift Allocation ABI // //===----------------------------------------------------------------------===// #ifndef SWIFT_RUNTIME_ALLOC_H #define SWIFT_RUNTIME_ALLOC_H #include #include #include "swift/Runtime/Config.h" // Bring in the definition of HeapObject #include "../../../stdlib/public/SwiftShims/HeapObject.h" namespace swift { struct Metadata; struct HeapMetadata; struct OpaqueValue; /// Allocates a new heap object. The returned memory is /// uninitialized outside of the heap-object header. The object /// has an initial retain count of 1, and its metadata is set to /// the given value. /// /// At some point "soon after return", it will become an /// invariant that metadata->getSize(returnValue) will equal /// requiredSize. /// /// Either aborts or throws a swift exception if the allocation fails. /// /// \param requiredSize - the required size of the allocation, /// including the header /// \param requiredAlignmentMask - the required alignment of the allocation; /// always one less than a power of 2 that's at least alignof(void*) /// \return never null /// /// POSSIBILITIES: The argument order is fair game. It may be useful /// to have a variant which guarantees zero-initialized memory. extern "C" HeapObject *swift_allocObject(HeapMetadata const *metadata, size_t requiredSize, size_t requiredAlignmentMask); /// Initializes the object header of a stack allocated object. /// /// \param metadata - the object's metadata which is stored in the header /// \param object - the pointer to the object's memory on the stack /// \returns the passed object pointer. extern "C" HeapObject *swift_initStackObject(HeapMetadata const *metadata, HeapObject *object); /// Performs verification that the lifetime of a stack allocated object has /// ended. It aborts if the reference counts of the object indicate that the /// object did escape to some other location. extern "C" void swift_verifyEndOfLifetime(HeapObject *object); /// A structure that's two pointers in size. /// /// C functions can use the TwoWordPair::Return type to return a value in /// two registers, compatible with Swift's calling convention for tuples /// and structs of two word-sized elements. template struct TwoWordPair { A first; B second; TwoWordPair() = default; TwoWordPair(A first, B second); // FIXME: rdar://16257592 arm codegen does't call swift_allocBox correctly. // Structs are returned indirectly on these platforms, but we want to return // in registers, so cram the result into an unsigned long long. // Use an enum class with implicit conversions so we don't dirty C callers // too much. #if __arm__ || __i386__ enum class Return : unsigned long long {}; operator Return() const { union { TwoWordPair value; Return mangled; } reinterpret = {*this}; return reinterpret.mangled; } /*implicit*/ TwoWordPair(Return r) { union { Return mangled; TwoWordPair value; } reinterpret = {r}; *this = reinterpret.value; } #else using Return = TwoWordPair; #endif }; template inline TwoWordPair::TwoWordPair(A first, B second) : first(first), second(second) { static_assert(sizeof(A) == sizeof(void*), "first type must be word-sized"); static_assert(sizeof(B) == sizeof(void*), "second type must be word-sized"); static_assert(alignof(TwoWordPair) == alignof(void*), "pair must be word-aligned"); } using BoxPair = TwoWordPair; /// Allocates a heap object that can contain a value of the given type. /// Returns a Box structure containing a HeapObject* pointer to the /// allocated object, and a pointer to the value inside the heap object. /// The value pointer points to an uninitialized buffer of size and alignment /// appropriate to store a value of the given type. /// The heap object has an initial retain count of 1, and its metadata is set /// such that destroying the heap object destroys the contained value. extern "C" BoxPair::Return swift_allocBox(Metadata const *type); // Allocate plain old memory. This is the generalized entry point // Never returns nil. The returned memory is uninitialized. // // An "alignment mask" is just the alignment (a power of 2) minus 1. extern "C" void *swift_slowAlloc(size_t bytes, size_t alignMask); // If the caller cannot promise to zero the object during destruction, // then call these corresponding APIs: extern "C" void swift_slowDealloc(void *ptr, size_t bytes, size_t alignMask); /// Atomically increments the retain count of an object. /// /// \param object - may be null, in which case this is a no-op /// /// POSSIBILITIES: We may end up wanting a bunch of different variants: /// - the general version which correctly handles null values, swift /// objects, and ObjC objects /// - a variant that assumes that its operand is a swift object /// - a variant that can safely use non-atomic operations /// - maybe a variant that can assume a non-null object /// It may also prove worthwhile to have this use a custom CC /// which preserves a larger set of registers. extern "C" void swift_retain(HeapObject *object); extern "C" void swift_retain_n(HeapObject *object, uint32_t n); static inline void _swift_retain_inlined(HeapObject *object) { if (object) { object->refCount.increment(); } } /// Atomically increments the reference count of an object, unless it has /// already been destroyed. Returns nil if the object is dead. extern "C" HeapObject *swift_tryRetain(HeapObject *object); /// Returns true if an object is in the process of being deallocated. extern "C" bool swift_isDeallocating(HeapObject *object); /// Attempts to atomically pin an object and increment its reference /// count. Returns nil if the object was already pinned. /// /// The standard protocol is that the caller is responsible for /// calling swift_unpin on the return value. /// /// The object reference may not be nil. extern "C" HeapObject *swift_tryPin(HeapObject *object); /// Given that an object is pinned, atomically unpin it and decrement /// the reference count. /// /// The object reference may be nil (to simplify the protocol). extern "C" void swift_unpin(HeapObject *object); /// Atomically decrements the retain count of an object. If the /// retain count reaches zero, the object is destroyed as follows: /// /// size_t allocSize = object->metadata->destroy(object); /// if (allocSize) swift_deallocObject(object, allocSize); /// /// \param object - may be null, in which case this is a no-op /// /// POSSIBILITIES: We may end up wanting a bunch of different variants: /// - the general version which correctly handles null values, swift /// objects, and ObjC objects /// - a variant that assumes that its operand is a swift object /// - a variant that can safely use non-atomic operations /// - maybe a variant that can assume a non-null object /// It's unlikely that a custom CC would be beneficial here. extern "C" void swift_release(HeapObject *object); /// Atomically decrements the retain count of an object n times. If the retain /// count reaches zero, the object is destroyed extern "C" void swift_release_n(HeapObject *object, uint32_t n); /// Is this pointer a non-null unique reference to an object /// that uses Swift reference counting? extern "C" bool swift_isUniquelyReferencedNonObjC(const void *); /// Is this non-null pointer a unique reference to an object /// that uses Swift reference counting? extern "C" bool swift_isUniquelyReferencedNonObjC_nonNull(const void *); /// Is this non-null pointer a reference to an object that uses Swift /// reference counting and is either uniquely referenced or pinned? extern "C" bool swift_isUniquelyReferencedOrPinnedNonObjC_nonNull(const void *); /// Is this non-null BridgeObject a unique reference to an object /// that uses Swift reference counting? extern "C" bool swift_isUniquelyReferencedNonObjC_nonNull_bridgeObject( uintptr_t bits); /// Is this non-null BridgeObject a unique or pinned reference to an /// object that uses Swift reference counting? extern "C" bool swift_isUniquelyReferencedOrPinnedNonObjC_nonNull_bridgeObject( uintptr_t bits); /// Is this native Swift pointer a non-null unique reference to /// an object? extern "C" bool swift_isUniquelyReferenced_native(const struct HeapObject *); /// Is this native Swift pointer a non-null unique or pinned reference /// to an object? extern "C" bool swift_isUniquelyReferencedOrPinned_native( const struct HeapObject *); /// Is this non-null native Swift pointer a unique reference to /// an object? extern "C" bool swift_isUniquelyReferenced_nonNull_native( const struct HeapObject *); /// Does this non-null native Swift pointer refer to an object that /// is either uniquely referenced or pinned? extern "C" bool swift_isUniquelyReferencedOrPinned_nonNull_native( const struct HeapObject *); /// Deallocate the given memory. /// /// It must have been returned by swift_allocObject and the strong reference /// must have the RC_DEALLOCATING_FLAG flag set, but otherwise the object is /// in an unknown state. /// /// \param object - never null /// \param allocatedSize - the allocated size of the object from the /// program's perspective, i.e. the value /// \param allocatedAlignMask - the alignment requirement that was passed /// to allocObject /// /// POSSIBILITIES: It may be useful to have a variant which /// requires the object to have been fully zeroed from offsets /// sizeof(SwiftHeapObject) to allocatedSize. extern "C" void swift_deallocObject(HeapObject *object, size_t allocatedSize, size_t allocatedAlignMask); /// Deallocate the given memory. /// /// It must have been returned by swift_allocObject, possibly used as an /// Objective-C class instance, and the strong reference must have the /// RC_DEALLOCATING_FLAG flag set, but otherwise the object is in an unknown /// state. /// /// \param object - never null /// \param allocatedSize - the allocated size of the object from the /// program's perspective, i.e. the value /// \param allocatedAlignMask - the alignment requirement that was passed /// to allocObject /// /// POSSIBILITIES: It may be useful to have a variant which /// requires the object to have been fully zeroed from offsets /// sizeof(SwiftHeapObject) to allocatedSize. extern "C" void swift_deallocClassInstance(HeapObject *object, size_t allocatedSize, size_t allocatedAlignMask); /// Deallocate the given memory after destroying instance variables. /// /// Destroys instance variables in classes more derived than the given metatype. /// /// It must have been returned by swift_allocObject, possibly used as an /// Objective-C class instance, and the strong reference must be equal to 1. /// /// \param object - may be null /// \param type - most derived class whose instance variables do not need to /// be destroyed /// \param allocatedSize - the allocated size of the object from the /// program's perspective, i.e. the value /// \param allocatedAlignMask - the alignment requirement that was passed /// to allocObject extern "C" void swift_deallocPartialClassInstance(HeapObject *object, const HeapMetadata *type, size_t allocatedSize, size_t allocatedAlignMask); /// Deallocate the given memory allocated by swift_allocBox; it was returned /// by swift_allocBox but is otherwise in an unknown state. The given Metadata /// pointer must be the same metadata pointer that was passed to swift_allocBox /// when the memory was allocated. extern "C" void swift_deallocBox(HeapObject *object); /// Project the value out of a box. `object` must have been allocated /// using `swift_allocBox`, or by the compiler using a statically-emitted /// box metadata object. extern "C" OpaqueValue *swift_projectBox(HeapObject *object); /// RAII object that wraps a Swift heap object and releases it upon /// destruction. class SwiftRAII { HeapObject *object; public: SwiftRAII(HeapObject *obj, bool AlreadyRetained) : object(obj) { if (!AlreadyRetained) swift_retain(obj); } ~SwiftRAII() { if (object) swift_release(object); } SwiftRAII(const SwiftRAII &other) { swift_retain(*other); object = *other; ; } SwiftRAII(SwiftRAII &&other) : object(*other) { other.object = nullptr; } SwiftRAII &operator=(const SwiftRAII &other) { if (object) swift_release(object); swift_retain(*other); object = *other; return *this; } SwiftRAII &operator=(SwiftRAII &&other) { if (object) swift_release(object); object = *other; other.object = nullptr; return *this; } HeapObject *operator *() const { return object; } }; /*****************************************************************************/ /**************************** UNOWNED REFERENCES *****************************/ /*****************************************************************************/ /// An unowned reference in memory. This is ABI. struct UnownedReference { HeapObject *Value; }; /// Increment the weak/unowned retain count. extern "C" void swift_unownedRetain(HeapObject *value); /// Decrement the weak/unowned retain count. extern "C" void swift_unownedRelease(HeapObject *value); /// Increment the weak/unowned retain count by n. extern "C" void swift_unownedRetain_n(HeapObject *value, int n); /// Decrement the weak/unowned retain count by n. extern "C" void swift_unownedRelease_n(HeapObject *value, int n); /// Increment the strong retain count of an object, aborting if it has /// been deallocated. extern "C" void swift_unownedRetainStrong(HeapObject *value); /// Increment the strong retain count of an object which may have been /// deallocated, aborting if it has been deallocated, and decrement its /// weak/unowned reference count. extern "C" void swift_unownedRetainStrongAndRelease(HeapObject *value); /// Aborts if the object has been deallocated. extern "C" void swift_unownedCheck(HeapObject *value); static inline void swift_unownedInit(UnownedReference *ref, HeapObject *value) { ref->Value = value; swift_unownedRetain(value); } static inline void swift_unownedAssign(UnownedReference *ref, HeapObject *value) { auto oldValue = ref->Value; if (value != oldValue) { swift_unownedRetain(value); ref->Value = value; swift_unownedRelease(oldValue); } } static inline HeapObject *swift_unownedLoadStrong(UnownedReference *ref) { auto value = ref->Value; swift_unownedRetainStrong(value); return value; } static inline void *swift_unownedTakeStrong(UnownedReference *ref) { auto value = ref->Value; swift_unownedRetainStrongAndRelease(value); return value; } static inline void swift_unownedDestroy(UnownedReference *ref) { swift_unownedRelease(ref->Value); } static inline void swift_unownedCopyInit(UnownedReference *dest, UnownedReference *src) { dest->Value = src->Value; swift_unownedRetain(dest->Value); } static inline void swift_unownedTakeInit(UnownedReference *dest, UnownedReference *src) { dest->Value = src->Value; } static inline void swift_unownedCopyAssign(UnownedReference *dest, UnownedReference *src) { auto newValue = src->Value; auto oldValue = dest->Value; if (newValue != oldValue) { dest->Value = newValue; swift_unownedRetain(newValue); swift_unownedRelease(oldValue); } } static inline void swift_unownedTakeAssign(UnownedReference *dest, UnownedReference *src) { auto newValue = src->Value; auto oldValue = dest->Value; dest->Value = newValue; swift_unownedRelease(oldValue); } /*****************************************************************************/ /****************************** WEAK REFERENCES ******************************/ /*****************************************************************************/ /// A weak reference value object. This is ABI. struct WeakReference { HeapObject *Value; }; /// Initialize a weak reference. /// /// \param ref - never null /// \param value - can be null extern "C" void swift_weakInit(WeakReference *ref, HeapObject *value); /// Assign a new value to a weak reference. /// /// \param ref - never null /// \param value - can be null extern "C" void swift_weakAssign(WeakReference *ref, HeapObject *value); /// Load a value from a weak reference. If the current value is a /// non-null object that has begun deallocation, returns null; /// otherwise, retains the object before returning. /// /// \param ref - never null /// \return can be null extern "C" HeapObject *swift_weakLoadStrong(WeakReference *ref); /// Load a value from a weak reference as if by swift_weakLoadStrong, /// but leaving the reference in an uninitialized state. /// /// \param ref - never null /// \return can be null extern "C" HeapObject *swift_weakTakeStrong(WeakReference *ref); /// Destroy a weak reference. /// /// \param ref - never null, but can refer to a null object extern "C" void swift_weakDestroy(WeakReference *ref); /// Copy initialize a weak reference. /// /// \param dest - never null, but can refer to a null object /// \param src - never null, but can refer to a null object extern "C" void swift_weakCopyInit(WeakReference *dest, WeakReference *src); /// Take initialize a weak reference. /// /// \param dest - never null, but can refer to a null object /// \param src - never null, but can refer to a null object extern "C" void swift_weakTakeInit(WeakReference *dest, WeakReference *src); /// Copy assign a weak reference. /// /// \param dest - never null, but can refer to a null object /// \param src - never null, but can refer to a null object extern "C" void swift_weakCopyAssign(WeakReference *dest, WeakReference *src); /// Take assign a weak reference. /// /// \param dest - never null, but can refer to a null object /// \param src - never null, but can refer to a null object extern "C" void swift_weakTakeAssign(WeakReference *dest, WeakReference *src); /*****************************************************************************/ /************************* OTHER REFERENCE-COUNTING **************************/ /*****************************************************************************/ extern "C" void *swift_bridgeObjectRetain(void *value); /// Increment the strong retain count of a bridged object by n. extern "C" void *swift_bridgeObjectRetain_n(void *value, int n); /*****************************************************************************/ /************************ UNKNOWN REFERENCE-COUNTING *************************/ /*****************************************************************************/ #if SWIFT_OBJC_INTEROP /// Increment the strong retain count of an object which might not be a native /// Swift object. extern "C" void swift_unknownRetain(void *value); /// Increment the strong retain count of an object which might not be a native /// Swift object by n. extern "C" void swift_unknownRetain_n(void *value, int n); #else static inline void swift_unknownRetain(void *value) { swift_retain(static_cast(value)); } static inline void swift_unknownRetain_n(void *value, int n) { swift_retain_n(static_cast(value), n); } #endif /* SWIFT_OBJC_INTEROP */ extern "C" void swift_bridgeObjectRelease(void *value); /// Decrement the strong retain count of a bridged object by n. extern "C" void swift_bridgeObjectRelease_n(void *value, int n); #if SWIFT_OBJC_INTEROP /// Decrement the strong retain count of an object which might not be a native /// Swift object. extern "C" void swift_unknownRelease(void *value); /// Decrement the strong retain count of an object which might not be a native /// Swift object by n. extern "C" void swift_unknownRelease_n(void *value, int n); #else static inline void swift_unknownRelease(void *value) { swift_release(static_cast(value)); } static inline void swift_unknownRelease_n(void *value, int n) { swift_release_n(static_cast(value), n); } #endif /* SWIFT_OBJC_INTEROP */ /*****************************************************************************/ /************************** UNKNOWN WEAK REFERENCES **************************/ /*****************************************************************************/ #if SWIFT_OBJC_INTEROP /// Initialize a weak reference. /// /// \param ref - never null /// \param value - not necessarily a native Swift object; can be null extern "C" void swift_unknownWeakInit(WeakReference *ref, void *value); #else static inline void swift_unknownWeakInit(WeakReference *ref, void *value) { swift_weakInit(ref, static_cast(value)); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Assign a new value to a weak reference. /// /// \param ref - never null /// \param value - not necessarily a native Swift object; can be null extern "C" void swift_unknownWeakAssign(WeakReference *ref, void *value); #else static inline void swift_unknownWeakAssign(WeakReference *ref, void *value) { swift_weakAssign(ref, static_cast(value)); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Load a value from a weak reference, much like swift_weakLoadStrong /// but without requiring the variable to refer to a native Swift object. /// /// \param ref - never null /// \return can be null extern "C" void *swift_unknownWeakLoadStrong(WeakReference *ref); #else static inline void swift_unknownWeakLoadStrong(WeakReference *ref) { swift_weakLoadStrong(ref); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Load a value from a weak reference as if by /// swift_unknownWeakLoadStrong, but leaving the reference in an /// uninitialized state. /// /// \param ref - never null /// \return can be null extern "C" void *swift_unknownWeakTakeStrong(WeakReference *ref); #else static inline void swift_unknownWeakTakeStrong(WeakReference *ref) { swift_weakTakeStrong(ref); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Destroy a weak reference variable that might not refer to a native /// Swift object. extern "C" void swift_unknownWeakDestroy(WeakReference *object); #else static inline void swift_unknownWeakDestroy(WeakReference *object) { swift_weakDestroy(object); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Copy-initialize a weak reference variable from one that might not /// refer to a native Swift object. extern "C" void swift_unknownWeakCopyInit(WeakReference *dest, WeakReference *src); #else static inline void swift_unknownWeakCopyInit(WeakReference *dest, WeakReference *src) { swift_weakCopyInit(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Take-initialize a weak reference variable from one that might not /// refer to a native Swift object. extern "C" void swift_unknownWeakTakeInit(WeakReference *dest, WeakReference *src); #else static inline void swift_unknownWeakTakeInit(WeakReference *dest, WeakReference *src) { swift_weakTakeInit(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Copy-assign a weak reference variable from another when either /// or both variables might not refer to a native Swift object. extern "C" void swift_unknownWeakCopyAssign(WeakReference *dest, WeakReference *src); #else static inline void swift_unknownWeakCopyAssign(WeakReference *dest, WeakReference *src) { swift_weakCopyAssign(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Take-assign a weak reference variable from another when either /// or both variables might not refer to a native Swift object. extern "C" void swift_unknownWeakTakeAssign(WeakReference *dest, WeakReference *src); #else static inline void swift_unknownWeakTakeAssign(WeakReference *dest, WeakReference *src) { swift_weakTakeAssign(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ /*****************************************************************************/ /************************ UNKNOWN UNOWNED REFERENCES *************************/ /*****************************************************************************/ #if SWIFT_OBJC_INTEROP /// Initialize an unowned reference to an object with unknown reference /// counting. extern "C" void swift_unknownUnownedInit(UnownedReference *ref, void *value); #else static inline void swift_unknownUnownedInit(UnownedReference *ref, void *value) { swift_unownedInit(ref, static_cast(value)); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Assign to an unowned reference holding an object with unknown reference /// counting. extern "C" void swift_unknownUnownedAssign(UnownedReference *ref, void *value); #else static inline void swift_unknownUnownedAssign(UnownedReference *ref, void *value) { swift_unownedAssign(ref, static_cast(value)); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Load from an unowned reference to an object with unknown reference /// counting. extern "C" void *swift_unknownUnownedLoadStrong(UnownedReference *ref); #else static inline void *swift_unknownUnownedLoadStrong(UnownedReference *ref) { return swift_unownedLoadStrong(ref); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Take from an unowned reference to an object with unknown reference /// counting. extern "C" void *swift_unknownUnownedTakeStrong(UnownedReference *ref); #else static inline void *swift_unknownUnownedTakeStrong(UnownedReference *ref) { return swift_unownedTakeStrong(ref); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Destroy an unowned reference to an object with unknown reference counting. extern "C" void swift_unknownUnownedDestroy(UnownedReference *ref); #else static inline void swift_unknownUnownedDestroy(UnownedReference *ref) { swift_unownedDestroy(ref); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Copy-initialize an unowned reference variable from one that might not /// refer to a native Swift object. extern "C" void swift_unknownUnownedCopyInit(UnownedReference *dest, UnownedReference *src); #else static inline void swift_unknownUnownedCopyInit(UnownedReference *dest, UnownedReference *src) { swift_unownedCopyInit(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Take-initialize an unowned reference variable from one that might not /// refer to a native Swift object. extern "C" void swift_unknownUnownedTakeInit(UnownedReference *dest, UnownedReference *src); #else static inline void swift_unknownUnownedTakeInit(UnownedReference *dest, UnownedReference *src) { swift_unownedTakeInit(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Copy-assign an unowned reference variable from another when either /// or both variables might not refer to a native Swift object. extern "C" void swift_unknownUnownedCopyAssign(UnownedReference *dest, UnownedReference *src); #else static inline void swift_unknownUnownedCopyAssign(UnownedReference *dest, UnownedReference *src) { swift_unownedCopyAssign(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ #if SWIFT_OBJC_INTEROP /// Take-assign an unowned reference variable from another when either /// or both variables might not refer to a native Swift object. extern "C" void swift_unknownUnownedTakeAssign(UnownedReference *dest, UnownedReference *src); #else static inline void swift_unknownUnownedTakeAssign(UnownedReference *dest, UnownedReference *src) { swift_unownedTakeAssign(dest, src); } #endif /* SWIFT_OBJC_INTEROP */ } // end namespace swift #endif /* SWIFT_RUNTIME_ALLOC_H */