Skip to content

Commit 0d67212

Browse files
committed
[Concurrency] Add an exported symbol on Darwin that contains the frame pointer flag bit for async frames.
The symbol is swift_async_extendedFramePointerFlags. Since the value doesn't need to be dynamically computed, we save a level of indirection by emitting a fake global variable whose address is the value we want, similar to objc_absolute_packed_isa_class_mask. This bit is mixed in to the frame pointer address stored on the stack to signal that a frame is an async frame. The compiler can emit code that ORs in the address of this symbol to apply the appropriate flag when it doesn't know the flag statically. rdar://80277146
1 parent 2f5660a commit 0d67212

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

include/swift/Runtime/Concurrency.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,18 @@ void swift_task_reportUnexpectedExecutor(
673673
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
674674
JobPriority swift_task_getCurrentThreadPriority(void);
675675

676+
#ifdef __APPLE__
677+
/// A magic symbol whose address is the mask to apply to a frame pointer to
678+
/// signal that it is an async frame. Do not try to read the actual value of
679+
/// this global, it will crash.
680+
///
681+
/// On ARM64_32, the address is only 32 bits, and therefore this value covers
682+
/// the top 32 bits of the in-memory frame pointer. On other 32-bit platforms,
683+
/// the bit is not used and the address is always 0.
684+
SWIFT_EXPORT_FROM(swift_Concurrency)
685+
struct { char c; } swift_async_extendedFramePointerFlags;
686+
#endif
687+
676688
}
677689

678690
#pragma clang diagnostic pop

stdlib/public/Concurrency/Task.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@
3434
#include <dlfcn.h>
3535
#endif
3636

37+
#ifdef __APPLE__
38+
#if __POINTER_WIDTH__ == 64
39+
asm("\n .globl _swift_async_extendedFramePointerFlags" \
40+
"\n _swift_async_extendedFramePointerFlags = 0x1000000000000000");
41+
#elif __ARM64_ARCH_8_32__
42+
asm("\n .globl _swift_async_extendedFramePointerFlags" \
43+
"\n _swift_async_extendedFramePointerFlags = 0x10000000");
44+
#else
45+
asm("\n .globl _swift_async_extendedFramePointerFlags" \
46+
"\n _swift_async_extendedFramePointerFlags = 0x0");
47+
#endif
48+
#endif // __APPLE__
49+
3750
using namespace swift;
3851
using FutureFragment = AsyncTask::FutureFragment;
3952
using TaskGroup = swift::TaskGroup;

0 commit comments

Comments
 (0)