18
18
#define SWIFT_ABI_EXECUTOR_H
19
19
20
20
#include < inttypes.h>
21
+ #include " swift/ABI/Actor.h"
21
22
#include " swift/ABI/HeapObject.h"
22
23
#include " swift/Runtime/Casting.h"
23
24
@@ -31,79 +32,89 @@ class Job;
31
32
SWIFT_EXPORT_FROM (swift_Concurrency)
32
33
Metadata* MainActorMetadata;
33
34
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.
36
45
class 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;
41
48
42
- constexpr ExecutorRef (uintptr_t value) : Value(value) {}
49
+ constexpr ExecutorRef (HeapObject *identity, uintptr_t implementation)
50
+ : Identity(identity), Implementation(implementation) {}
43
51
44
52
public:
45
53
// / A generic execution environment. When running in a generic
46
54
// / environment, it's presumed to be okay to switch synchronously
47
55
// / to an actor. As an executor request, this represents a request
48
56
// / to drop whatever the current actor is.
49
57
constexpr static ExecutorRef generic () {
50
- return ExecutorRef (0 );
58
+ return ExecutorRef (nullptr , 0 );
51
59
}
52
60
53
61
// / FIXME: only exists for the quick-and-dirty MainActor implementation.
54
62
// / NOTE: I didn't go with Executor::forMainActor(DefaultActor*) because
55
63
// / __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);
58
71
}
59
72
60
73
// / Given a pointer to a default actor, return an executor reference
61
74
// / for it.
62
75
static ExecutorRef forDefaultActor (DefaultActor *actor) {
63
76
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;
65
82
}
66
83
67
84
// / Is this the generic executor reference?
68
85
bool isGeneric () const {
69
- return Value == 0 ;
86
+ return Identity == 0 ;
70
87
}
71
88
72
89
// / FIXME: only exists for the quick-and-dirty MainActor implementation.
73
90
bool isMainExecutor () const {
74
- if (Value == ExecutorRef::mainExecutor (). Value )
91
+ if (Identity == getMainActorIdentity () )
75
92
return true ;
76
93
77
- HeapObject *heapObj = reinterpret_cast <HeapObject*>(Value & ~PointerMask);
78
-
79
- if (heapObj == nullptr || MainActorMetadata == nullptr )
94
+ if (Identity == nullptr || MainActorMetadata == nullptr )
80
95
return false ;
81
96
82
- Metadata const * metadata = swift_getObjectType (heapObj );
97
+ Metadata const * metadata = swift_getObjectType (Identity );
83
98
return metadata == MainActorMetadata;
84
99
}
85
100
86
101
// / Is this a default-actor executor reference?
87
102
bool isDefaultActor () const {
88
- return Value & IsDefaultActor ;
103
+ return Implementation & unsigned (ExecutorRefFlags::DefaultActor) ;
89
104
}
90
105
DefaultActor *getDefaultActor () const {
91
106
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);
97
108
}
98
109
99
110
// / Do we have to do any work to start running as the requested
100
111
// / executor?
101
112
bool mustSwitchToRun (ExecutorRef newExecutor) const {
102
- return * this != newExecutor;
113
+ return Identity != newExecutor. Identity ;
103
114
}
104
115
105
116
bool operator ==(ExecutorRef other) const {
106
- return Value == other.Value
117
+ return Identity == other.Identity
107
118
// / FIXME: only exists for the quick-and-dirty MainActor implementation.
108
119
|| (isMainExecutor () && other.isMainExecutor ());
109
120
}
0 commit comments