1818#define SWIFT_ABI_EXECUTOR_H
1919
2020#include < inttypes.h>
21+ #include " swift/ABI/Actor.h"
2122#include " swift/ABI/HeapObject.h"
2223#include " swift/Runtime/Casting.h"
2324
@@ -31,79 +32,89 @@ class Job;
3132SWIFT_EXPORT_FROM (swift_Concurrency)
3233Metadata* MainActorMetadata;
3334
34- // / An ExecutorRef isn't necessarily just a pointer to an executor
35- // / object; it may have other bits set.
35+ // / An unmanaged reference to an executor.
36+ // /
37+ // / The representation is two words: identity and implementation.
38+ // / The identity word is a reference to the executor object; for
39+ // / default actors, this is the actor object. The implementation
40+ // / word describes how the executor works; it carries a witness table
41+ // / as well as a small number of bits indicating various special
42+ // / implementation properties. As an exception to both of these
43+ // / rules, a null identity represents a generic executor and
44+ // / implies a null implementation word.
3645class ExecutorRef {
37- static constexpr uintptr_t IsDefaultActor = 1 ;
38- static constexpr uintptr_t PointerMask = 7 ;
39-
40- uintptr_t Value;
46+ HeapObject *Identity; // Not necessarily Swift reference-countable
47+ uintptr_t Implementation;
4148
42- constexpr ExecutorRef (uintptr_t value) : Value(value) {}
49+ constexpr ExecutorRef (HeapObject *identity, uintptr_t implementation)
50+ : Identity(identity), Implementation(implementation) {}
4351
4452public:
4553 // / A generic execution environment. When running in a generic
4654 // / environment, it's presumed to be okay to switch synchronously
4755 // / to an actor. As an executor request, this represents a request
4856 // / to drop whatever the current actor is.
4957 constexpr static ExecutorRef generic () {
50- return ExecutorRef (0 );
58+ return ExecutorRef (nullptr , 0 );
5159 }
5260
5361 // / FIXME: only exists for the quick-and-dirty MainActor implementation.
5462 // / NOTE: I didn't go with Executor::forMainActor(DefaultActor*) because
5563 // / __swift_run_job_main_executor can't take more than one argument.
56- constexpr static ExecutorRef mainExecutor () {
57- return ExecutorRef (2 );
64+ static ExecutorRef mainExecutor () {
65+ auto identity = getMainActorIdentity ();
66+ return ExecutorRef (identity, 0 );
67+ }
68+ static HeapObject *getMainActorIdentity () {
69+ return reinterpret_cast <HeapObject*>(
70+ ExecutorRefFlags::MainActorIdentity);
5871 }
5972
6073 // / Given a pointer to a default actor, return an executor reference
6174 // / for it.
6275 static ExecutorRef forDefaultActor (DefaultActor *actor) {
6376 assert (actor);
64- return ExecutorRef (reinterpret_cast <uintptr_t >(actor) | IsDefaultActor);
77+ return ExecutorRef (actor, unsigned (ExecutorRefFlags::DefaultActor));
78+ }
79+
80+ HeapObject *getIdentity () const {
81+ return Identity;
6582 }
6683
6784 // / Is this the generic executor reference?
6885 bool isGeneric () const {
69- return Value == 0 ;
86+ return Identity == 0 ;
7087 }
7188
7289 // / FIXME: only exists for the quick-and-dirty MainActor implementation.
7390 bool isMainExecutor () const {
74- if (Value == ExecutorRef::mainExecutor (). Value )
91+ if (Identity == getMainActorIdentity () )
7592 return true ;
7693
77- HeapObject *heapObj = reinterpret_cast <HeapObject*>(Value & ~PointerMask);
78-
79- if (heapObj == nullptr || MainActorMetadata == nullptr )
94+ if (Identity == nullptr || MainActorMetadata == nullptr )
8095 return false ;
8196
82- Metadata const * metadata = swift_getObjectType (heapObj );
97+ Metadata const * metadata = swift_getObjectType (Identity );
8398 return metadata == MainActorMetadata;
8499 }
85100
86101 // / Is this a default-actor executor reference?
87102 bool isDefaultActor () const {
88- return Value & IsDefaultActor ;
103+ return Implementation & unsigned (ExecutorRefFlags::DefaultActor) ;
89104 }
90105 DefaultActor *getDefaultActor () const {
91106 assert (isDefaultActor ());
92- return reinterpret_cast <DefaultActor*>(Value & ~PointerMask);
93- }
94-
95- uintptr_t getRawValue () const {
96- return Value;
107+ return reinterpret_cast <DefaultActor*>(Identity);
97108 }
98109
99110 // / Do we have to do any work to start running as the requested
100111 // / executor?
101112 bool mustSwitchToRun (ExecutorRef newExecutor) const {
102- return * this != newExecutor;
113+ return Identity != newExecutor. Identity ;
103114 }
104115
105116 bool operator ==(ExecutorRef other) const {
106- return Value == other.Value
117+ return Identity == other.Identity
107118 // / FIXME: only exists for the quick-and-dirty MainActor implementation.
108119 || (isMainExecutor () && other.isMainExecutor ());
109120 }
0 commit comments