Skip to content

Commit 8b93591

Browse files
committed
Experiment with avoiding stack frames in swift_retain and swift_bridgeObjectRetain
1 parent 8a95701 commit 8b93591

File tree

5 files changed

+26
-13
lines changed

5 files changed

+26
-13
lines changed

stdlib/public/SwiftShims/swift/shims/RefCount.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ class RefCounts {
703703
// Out-of-line slow paths.
704704

705705
SWIFT_NOINLINE
706-
void incrementSlow(RefCountBits oldbits, uint32_t inc) SWIFT_CC(PreserveMost);
706+
HeapObject *incrementSlow(RefCountBits oldbits, uint32_t inc) SWIFT_CC(PreserveMost);
707707

708708
SWIFT_NOINLINE
709709
void incrementNonAtomicSlow(RefCountBits oldbits, uint32_t inc);
@@ -800,13 +800,13 @@ class RefCounts {
800800

801801
// Increment the reference count.
802802
SWIFT_ALWAYS_INLINE
803-
void increment(uint32_t inc = 1) {
803+
HeapObject *increment(uint32_t inc = 1) {
804804
auto oldbits = refCounts.load(SWIFT_MEMORY_ORDER_CONSUME);
805805

806806
// constant propagation will remove this in swift_retain, it should only
807807
// be present in swift_retain_n
808808
if (inc != 1 && oldbits.isImmortal(true)) {
809-
return;
809+
return getHeapObject();
810810
}
811811

812812
RefCountBits newbits;
@@ -815,11 +815,12 @@ class RefCounts {
815815
bool fast = newbits.incrementStrongExtraRefCount(inc);
816816
if (SWIFT_UNLIKELY(!fast)) {
817817
if (oldbits.isImmortal(false))
818-
return;
818+
return getHeapObject();
819819
return incrementSlow(oldbits, inc);
820820
}
821821
} while (!refCounts.compare_exchange_weak(oldbits, newbits,
822822
std::memory_order_relaxed));
823+
return getHeapObject();
823824
}
824825

825826
SWIFT_ALWAYS_INLINE

stdlib/public/SwiftShims/swift/shims/Visibility.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@
109109
#define SWIFT_WEAK_IMPORT
110110
#endif
111111

112+
#if __has_attribute(musttail)
113+
#define SWIFT_MUSTTAIL __attribute__((musttail))
114+
#else
115+
#define SWIFT_MUSTTAIL
116+
#endif
117+
112118
// Define the appropriate attributes for sharing symbols across
113119
// image (executable / shared-library) boundaries.
114120
//

stdlib/public/runtime/HeapObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ SWIFT_ALWAYS_INLINE
343343
static HeapObject *_swift_retain_(HeapObject *object) {
344344
SWIFT_RT_TRACK_INVOCATION(object, swift_retain);
345345
if (isValidPointerForNativeRetain(object))
346-
object->refCounts.increment(1);
346+
return object->refCounts.increment(1);
347347
return object;
348348
}
349349

stdlib/public/runtime/RefCount.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
namespace swift {
1616

1717
template <typename RefCountBits>
18-
void RefCounts<RefCountBits>::incrementSlow(RefCountBits oldbits,
18+
HeapObject *RefCounts<RefCountBits>::incrementSlow(RefCountBits oldbits,
1919
uint32_t n) {
2020
if (oldbits.isImmortal(false)) {
21-
return;
21+
return getHeapObject();
2222
}
2323
else if (oldbits.hasSideTable()) {
2424
// Out-of-line slow path.
@@ -29,9 +29,10 @@ void RefCounts<RefCountBits>::incrementSlow(RefCountBits oldbits,
2929
// Retain count overflow.
3030
swift::swift_abortRetainOverflow();
3131
}
32+
return getHeapObject();
3233
}
33-
template void RefCounts<InlineRefCountBits>::incrementSlow(InlineRefCountBits oldbits, uint32_t n);
34-
template void RefCounts<SideTableRefCountBits>::incrementSlow(SideTableRefCountBits oldbits, uint32_t n);
34+
template HeapObject *RefCounts<InlineRefCountBits>::incrementSlow(InlineRefCountBits oldbits, uint32_t n);
35+
template HeapObject *RefCounts<SideTableRefCountBits>::incrementSlow(SideTableRefCountBits oldbits, uint32_t n);
3536

3637
template <typename RefCountBits>
3738
void RefCounts<RefCountBits>::incrementNonAtomicSlow(RefCountBits oldbits,

stdlib/public/runtime/SwiftObject.mm

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,13 @@ static bool isBridgeObjectTaggedPointer(void *object) {
574574
return (void*)(uintptr_t(object) & ~unTaggedNonNativeBridgeObjectBits);
575575
}
576576

577+
SWIFT_NOINLINE
578+
static void *objcRetainAndReturn(void *object) {
579+
auto const objectRef = toPlainObject_unTagged_bridgeObject(object);
580+
objc_retain(static_cast<id>(objectRef));
581+
return object;
582+
}
583+
577584
void *swift::swift_bridgeObjectRetain(void *object) {
578585
#if SWIFT_OBJC_INTEROP
579586
if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
@@ -584,11 +591,9 @@ static bool isBridgeObjectTaggedPointer(void *object) {
584591

585592
#if SWIFT_OBJC_INTEROP
586593
if (!isNonNative_unTagged_bridgeObject(object)) {
587-
swift_retain(static_cast<HeapObject *>(objectRef));
588-
return object;
594+
return swift_retain(static_cast<HeapObject *>(objectRef));
589595
}
590-
objc_retain(static_cast<id>(objectRef));
591-
return object;
596+
SWIFT_MUSTTAIL return objcRetainAndReturn(object);
592597
#else
593598
swift_retain(static_cast<HeapObject *>(objectRef));
594599
return object;

0 commit comments

Comments
 (0)