Skip to content

Commit 9fd712b

Browse files
authored
Merge pull request #63531 from etcwilde/ewilde/fix-backdeploy-compat56-crash
[5.8] Fix backdeploy compat-56 ABI
2 parents 62b24df + 5605221 commit 9fd712b

File tree

15 files changed

+196
-54
lines changed

15 files changed

+196
-54
lines changed

lib/ASTGen/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ if (SWIFT_SWIFT_PARSER)
3232
Sources/ASTGen/Types.swift
3333
)
3434

35+
# The compat56 library is not available during a stage-0 compiler build.
36+
# Once we have proper stage tracking, we should turn this on for stages that
37+
# are guaranteed to have the compatibility libraries.
38+
target_compile_options(swiftASTGen PRIVATE
39+
$<$<COMPILE_LANGUAGE:Swift>:-runtime-compatibility-version>
40+
$<$<COMPILE_LANGUAGE:Swift>:none>)
41+
3542
# Set the appropriate target triple.
3643
if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS)
3744
set(DEPLOYMENT_VERSION "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}")

stdlib/public/BackDeployConcurrency/Actor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,7 @@ void DefaultActorImpl::giveUpThread(RunningJobInfo runner) {
12281228
}
12291229

12301230
#define LOG_STATE_TRANSITION \
1231-
SWIFT_TASK_DEBUG_LOG("actor %p transitioned from %zx to %zx (%s)\n", this, \
1231+
SWIFT_TASK_DEBUG_LOG("actor %p transitioned from %zx to %zx (%s)", this, \
12321232
oldState.Flags.getOpaqueValue(), \
12331233
newState.Flags.getOpaqueValue(), __FUNCTION__)
12341234
LOG_STATE_TRANSITION;

stdlib/public/BackDeployConcurrency/TaskGroup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T)
479479
// ==== add / attachChild ------------------------------------------------------
480480

481481
void TaskGroup::addChildTask(AsyncTask *child) {
482-
SWIFT_TASK_DEBUG_LOG("attach child task = %p to group = %p", child, group);
482+
SWIFT_TASK_DEBUG_LOG("attach child task = %p to group = %p", child, this);
483483

484484
// The counterpart of this (detachChild) is performed by the group itself,
485485
// when it offers the completed (child) task's value to a waiting task -

stdlib/public/BackDeployConcurrency/TaskPrivate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace swift {
4747
#if 0
4848
#define SWIFT_TASK_DEBUG_LOG(fmt, ...) \
4949
fprintf(stderr, "[%lu] [%s:%d](%s) " fmt "\n", \
50-
(unsigned long)Thread::current()::platformThreadId(), \
50+
(unsigned long)Thread::current().platformThreadId(), \
5151
__FILE__, __LINE__, __FUNCTION__, \
5252
__VA_ARGS__)
5353
#else

stdlib/toolchain/Compatibility56/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ set(library_name "swiftCompatibility56")
22

33
include_directories("include/" "${SWIFT_STDLIB_SOURCE_DIR}")
44

5+
set(CMAKE_C_VISIBILITY_PRESET hidden)
6+
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
7+
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
8+
59
add_compile_definitions(SWIFT_COMPATIBILITY56)
610
add_swift_target_library("${library_name}" STATIC
711
Overrides.cpp

stdlib/toolchain/Compatibility56/Concurrency/Task.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ FutureFragment::Status AsyncTask::waitFuture(AsyncTask *waitingTask,
1515
TaskContinuationFunction *resumeFn,
1616
AsyncContext *callerContext,
1717
OpaqueValue *result) {
18+
SWIFT_TASK_DEBUG_LOG("compat 56 task task %p", this);
1819
using Status = FutureFragment::Status;
1920
using WaitQueueItem = FutureFragment::WaitQueueItem;
2021

stdlib/toolchain/Compatibility56/Overrides.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ struct ConcurrencyOverrideSection {
3939

4040
#undef OVERRIDE
4141

42+
__attribute__((visibility("hidden")))
4243
ConcurrencyOverrideSection Swift56ConcurrencyOverrides
4344
__attribute__((used, section("__DATA,__s_async_hook"))) = {
4445
.version = 0,
@@ -49,6 +50,7 @@ __attribute__((used, section("__DATA,__s_async_hook"))) = {
4950
.task_future_wait_throwing = swift56override_swift_task_future_wait_throwing,
5051
};
5152

53+
__attribute__((visibility("hidden")))
5254
RuntimeOverrideSection Swift56RuntimeOverrides
5355
__attribute__((used, section("__DATA,__swift56_hooks"))) = {
5456
.version = 0,

stdlib/toolchain/Compatibility56/include/Concurrency/Error.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
namespace swift {
2525

26+
__attribute__((visibility("hidden")))
2627
SWIFT_NORETURN void swift_Concurrency_fatalError(uint32_t flags, const char *format, ...);
2728

2829
} // namespace swift

stdlib/toolchain/Compatibility56/include/Concurrency/Task.h

Lines changed: 103 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_ABI_TASK_BACKDEPLOY56_H
1818
#define SWIFT_ABI_TASK_BACKDEPLOY56_H
1919

20+
#include "Concurrency/TaskLocal.h"
2021
#include "Executor.h"
2122
#include "swift/ABI/HeapObject.h"
2223
#include "swift/ABI/Metadata.h"
@@ -26,7 +27,7 @@
2627
#include "VoucherShims.h"
2728
#include "swift/Basic/STLExtras.h"
2829
#include <bitset>
29-
#include <queue>
30+
#include <queue> // TODO: remove and replace with our own mpsc
3031

3132
namespace swift {
3233
class AsyncTask;
@@ -275,13 +276,6 @@ class AsyncTask : public Job {
275276
void setTaskId();
276277
uint64_t getTaskId();
277278

278-
/// Get the task's resume function, for logging purposes only. This will
279-
/// attempt to see through the various adapters that are sometimes used, and
280-
/// failing that will return ResumeTask. The returned function pointer may
281-
/// have a different signature than ResumeTask, and it's only for identifying
282-
/// code associated with the task.
283-
const void *getResumeFunctionForLogging();
284-
285279
/// Given that we've already fully established the job context
286280
/// in the current thread, start running this task. To establish
287281
/// the job context correctly, call swift_job_run or
@@ -313,34 +307,44 @@ class AsyncTask : public Job {
313307
///
314308
/// Generally this should be done immediately after updating
315309
/// ActiveTask.
310+
__attribute__((visibility("hidden")))
316311
void flagAsRunning();
312+
__attribute__((visibility("hidden")))
317313
void flagAsRunning_slow();
318314

319-
/// Flag that this task is now suspended.
315+
/// Flag that this task is now suspended. This can update the
316+
/// priority stored in the job flags if the priority hsa been
317+
/// escalated. Generally this should be done immediately after
318+
/// clearing ActiveTask and immediately before enqueuing the task
319+
/// somewhere. TODO: record where the task is enqueued if
320+
/// possible.
321+
__attribute__((visibility("hidden")))
320322
void flagAsSuspended();
323+
__attribute__((visibility("hidden")))
321324
void flagAsSuspended_slow();
322325

323-
/// Flag that the task is to be enqueued on the provided executor and actually
324-
/// enqueue it
325-
void flagAsAndEnqueueOnExecutor(ExecutorRef newExecutor);
326-
327326
/// Flag that this task is now completed. This normally does not do anything
328327
/// but can be used to locally insert logging.
328+
__attribute__((visibility("hidden")))
329329
void flagAsCompleted();
330330

331331
/// Check whether this task has been cancelled.
332332
/// Checking this is, of course, inherently race-prone on its own.
333+
__attribute__((visibility("hidden")))
333334
bool isCancelled() const;
334335

335336
// ==== Task Local Values ----------------------------------------------------
336337

338+
__attribute__((visibility("hidden")))
337339
void localValuePush(const HeapObject *key,
338340
/* +1 */ OpaqueValue *value,
339341
const Metadata *valueType);
340342

343+
__attribute__((visibility("hidden")))
341344
OpaqueValue *localValueGet(const HeapObject *key);
342345

343346
/// Returns true if storage has still more bindings.
347+
__attribute__((visibility("hidden")))
344348
bool localValuePop();
345349

346350
// ==== Child Fragment -------------------------------------------------------
@@ -566,8 +570,9 @@ class AsyncTask : public Job {
566570
/// \c Executing, then \c waitingTask has been added to the
567571
/// wait queue and will be scheduled when the future completes. Otherwise,
568572
/// the future has completed and can be queried.
569-
/// The waiting task's async context will be initialized with the parameters if
573+
/// The waiting task's async context will be intialized with the parameters if
570574
/// the current's task state is executing.
575+
__attribute__((visibility("hidden")))
571576
FutureFragment::Status waitFuture(AsyncTask *waitingTask,
572577
AsyncContext *waitingTaskContext,
573578
TaskContinuationFunction *resumeFn,
@@ -614,6 +619,65 @@ inline void Job::runInFullyEstablishedContext() {
614619

615620
// ==== ------------------------------------------------------------------------
616621

622+
/// The Swift5.6 AsyncContextKind for the AsyncContext.
623+
/// Note that these were removed in Swift5.7
624+
/// (aca744b21165a20655502b563a6fa54c2c83efdf).
625+
/// Kinds of async context.
626+
enum class AsyncContextKind {
627+
/// An ordinary asynchronous function.
628+
Ordinary = 0,
629+
630+
/// A context which can yield to its caller.
631+
Yielding = 1,
632+
633+
/// A continuation context.
634+
Continuation = 2,
635+
636+
// Other kinds are reserved for interesting special
637+
// intermediate contexts.
638+
639+
// Kinds >= 192 are private to the implementation.
640+
First_Reserved = 192
641+
};
642+
643+
644+
/// The Swift5.6 AsyncContextFlags for the AsyncContext.
645+
/// Note that these were removed in Swift5.7
646+
/// (aca744b21165a20655502b563a6fa54c2c83efdf).
647+
/// Flags for async contexts.
648+
class AsyncContextFlags : public FlagSet<uint32_t> {
649+
public:
650+
enum {
651+
Kind = 0,
652+
Kind_width = 8,
653+
654+
CanThrow = 8,
655+
656+
// Kind-specific flags should grow down from 31.
657+
658+
Continuation_IsExecutorSwitchForced = 31,
659+
};
660+
661+
explicit AsyncContextFlags(uint32_t bits) : FlagSet(bits) {}
662+
constexpr AsyncContextFlags() {}
663+
AsyncContextFlags(AsyncContextKind kind) {
664+
setKind(kind);
665+
}
666+
667+
/// The kind of context this represents.
668+
FLAGSET_DEFINE_FIELD_ACCESSORS(Kind, Kind_width, AsyncContextKind,
669+
getKind, setKind)
670+
671+
/// Whether this context is permitted to throw.
672+
FLAGSET_DEFINE_FLAG_ACCESSORS(CanThrow, canThrow, setCanThrow)
673+
674+
/// See AsyncContinuationFlags::isExecutorSwitchForced.
675+
FLAGSET_DEFINE_FLAG_ACCESSORS(Continuation_IsExecutorSwitchForced,
676+
continuation_isExecutorSwitchForced,
677+
continuation_setIsExecutorSwitchForced)
678+
};
679+
680+
617681
/// An asynchronous context within a task. Generally contexts are
618682
/// allocated using the task-local stack alloc/dealloc operations, but
619683
/// there's no guarantee of that, and the ABI is designed to permit
@@ -634,9 +698,19 @@ class alignas(MaximumAlignment) AsyncContext {
634698
TaskContinuationFunction * __ptrauth_swift_async_context_resume
635699
ResumeParent;
636700

637-
AsyncContext(TaskContinuationFunction *resumeParent,
701+
/// Flags describing this context.
702+
///
703+
/// Note that this field is only 32 bits; any alignment padding
704+
/// following this on 64-bit platforms can be freely used by the
705+
/// function. If the function is a yielding function, that padding
706+
/// is of course interrupted by the YieldToParent field.
707+
AsyncContextFlags Flags;
708+
709+
AsyncContext(AsyncContextFlags flags,
710+
TaskContinuationFunction *resumeParent,
638711
AsyncContext *parent)
639-
: Parent(parent), ResumeParent(resumeParent) {}
712+
: Parent(parent), ResumeParent(resumeParent),
713+
Flags(flags) {}
640714

641715
AsyncContext(const AsyncContext &) = delete;
642716
AsyncContext &operator=(const AsyncContext &) = delete;
@@ -660,66 +734,48 @@ class YieldingAsyncContext : public AsyncContext {
660734
TaskContinuationFunction * __ptrauth_swift_async_context_yield
661735
YieldToParent;
662736

663-
YieldingAsyncContext(TaskContinuationFunction *resumeParent,
737+
YieldingAsyncContext(AsyncContextFlags flags,
738+
TaskContinuationFunction *resumeParent,
664739
TaskContinuationFunction *yieldToParent,
665740
AsyncContext *parent)
666-
: AsyncContext(resumeParent, parent),
741+
: AsyncContext(flags, resumeParent, parent),
667742
YieldToParent(yieldToParent) {}
743+
744+
static bool classof(const AsyncContext *context) {
745+
return context->Flags.getKind() == AsyncContextKind::Yielding;
746+
}
668747
};
669748

670749
/// An async context that can be resumed as a continuation.
671750
class ContinuationAsyncContext : public AsyncContext {
672751
public:
673-
class FlagsType : public FlagSet<size_t> {
674-
public:
675-
enum {
676-
CanThrow = 0,
677-
IsExecutorSwitchForced = 1,
678-
};
679-
680-
explicit FlagsType(size_t bits) : FlagSet(bits) {}
681-
constexpr FlagsType() {}
682-
683-
/// Whether this is a throwing continuation.
684-
FLAGSET_DEFINE_FLAG_ACCESSORS(CanThrow,
685-
canThrow,
686-
setCanThrow)
687-
688-
/// See AsyncContinuationFlags::isExecutorSwitchForced().
689-
FLAGSET_DEFINE_FLAG_ACCESSORS(IsExecutorSwitchForced,
690-
isExecutorSwitchForced,
691-
setIsExecutorSwitchForced)
692-
};
693-
694-
/// Flags for the continuation. Not public ABI.
695-
FlagsType Flags;
696-
697752
/// An atomic object used to ensure that a continuation is not
698753
/// scheduled immediately during a resume if it hasn't yet been
699-
/// awaited by the function which set it up. Not public ABI.
754+
/// awaited by the function which set it up.
700755
std::atomic<ContinuationStatus> AwaitSynchronization;
701756

702757
/// The error result value of the continuation.
703758
/// This should be null-initialized when setting up the continuation.
704759
/// Throwing resumers must overwrite this with a non-null value.
705-
/// Public ABI.
706760
SwiftError *ErrorResult;
707761

708762
/// A pointer to the normal result value of the continuation.
709763
/// Normal resumers must initialize this before resuming.
710-
/// Public ABI.
711764
OpaqueValue *NormalResult;
712765

713766
/// The executor that should be resumed to.
714-
/// Public ABI.
715767
ExecutorRef ResumeToExecutor;
716768

717769
void setErrorResult(SwiftError *error) {
718770
ErrorResult = error;
719771
}
720772

721773
bool isExecutorSwitchForced() const {
722-
return Flags.isExecutorSwitchForced();
774+
return Flags.continuation_isExecutorSwitchForced();
775+
}
776+
777+
static bool classof(const AsyncContext *context) {
778+
return context->Flags.getKind() == AsyncContextKind::Continuation;
723779
}
724780
};
725781

stdlib/toolchain/Compatibility56/include/Concurrency/TaskPrivate.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,25 @@
2929

3030
namespace swift {
3131

32+
#if 0
33+
using ThreadID = decltype(pthread_self());
34+
35+
inline ThreadID _swift_get_thread_id() {
36+
#if defined(_WIN32)
37+
return GetCurrentThreadId();
38+
#else
39+
return pthread_self();
40+
#endif
41+
}
42+
43+
#define SWIFT_TASK_DEBUG_LOG(fmt, ...) \
44+
fprintf(stderr, "[%lu] [%s:%d](%s) " fmt "\n", \
45+
(unsigned long)_swift_get_thread_id(), \
46+
__FILE__, __LINE__, __FUNCTION__, \
47+
__VA_ARGS__)
48+
#else
3249
#define SWIFT_TASK_DEBUG_LOG(fmt ...) (void)0
50+
#endif
3351

3452
/// Allocate task-local memory on behalf of a specific task,
3553
/// not necessarily the current one. Generally this should only be
@@ -91,18 +109,23 @@ class TaskFutureWaitAsyncContext : public AsyncContext {
91109

92110
/// Adopt the voucher stored in `task`. This removes the voucher from the task
93111
/// and adopts it on the current thread.
112+
__attribute__((visibility("hidden")))
94113
void adoptTaskVoucher(AsyncTask *task);
95114

96115
/// Restore the voucher for `task`. This un-adopts the current thread's voucher
97116
/// and stores it back into the task again.
117+
__attribute__((visibility("hidden")))
98118
void restoreTaskVoucher(AsyncTask *task);
99119

100120
/// release() establishes a happens-before relation with a preceding acquire()
101121
/// on the same address.
122+
__attribute__((visibility("hidden")))
102123
void _swift_tsan_acquire(void *addr);
124+
__attribute__((visibility("hidden")))
103125
void _swift_tsan_release(void *addr);
104126

105127
/// Clear the active task reference for the current thread.
128+
__attribute__((visibility("hidden")))
106129
AsyncTask *_swift_task_clearCurrent();
107130

108131
/// The current state of a task's status records.

0 commit comments

Comments
 (0)