Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 4 additions & 26 deletions stdlib/public/runtime/SwiftObject.mm
Original file line number Diff line number Diff line change
Expand Up @@ -677,43 +677,21 @@ static bool isBridgeObjectTaggedPointer(void *object) {
return (void*)(uintptr_t(object) & ~unTaggedNonNativeBridgeObjectBits);
}

#if SWIFT_OBJC_INTEROP
#if __arm64__
// Marking this as noinline allows swift_bridgeObjectRetain to avoid emitting
// a stack frame for the swift_retain path on ARM64. It makes for worse codegen
// on x86-64, though, so limit it to ARM64.
SWIFT_NOINLINE
#endif
static void *objcRetainAndReturn(void *object) {
auto const objectRef = toPlainObject_unTagged_bridgeObject(object);
objc_retain(static_cast<id>(objectRef));
return object;
}
#endif

void *swift::swift_bridgeObjectRetain(void *object) {
#if SWIFT_OBJC_INTEROP
if (isObjCTaggedPointer(object) || isBridgeObjectTaggedPointer(object))
return object;
#endif

auto const objectRef = toPlainObject_unTagged_bridgeObject(object);

#if SWIFT_OBJC_INTEROP
if (!isNonNative_unTagged_bridgeObject(object)) {
return swift_retain(static_cast<HeapObject *>(objectRef));
swift_retain(static_cast<HeapObject *>(objectRef));
return object;
}

// Put the call to objc_retain in a separate function, tail-called here. This
// allows the fast path of swift_bridgeObjectRetain to avoid creating a stack
// frame on ARM64. We can't directly tail-call objc_retain, because
// swift_bridgeObjectRetain returns the pointer with objectPointerIsObjCBit
// set, so we have to make a non-tail call and then return the value with the
// bit set.
SWIFT_MUSTTAIL return objcRetainAndReturn(object);
objc_retain(static_cast<id>(objectRef));
return object;
#else
// No tail call here. When !SWIFT_OBJC_INTEROP, the value of objectRef may be
// different from that of object, e.g. on Linux ARM64.
swift_retain(static_cast<HeapObject *>(objectRef));
return object;
#endif
Expand Down