23
23
#include " swift/ABI/Metadata.h"
24
24
#include " swift/ABI/MetadataValues.h"
25
25
#include " swift/Runtime/Config.h"
26
+ #include " swift/Runtime/VoucherShims.h"
26
27
#include " swift/Basic/STLExtras.h"
27
28
#include " bitset"
28
29
#include " queue" // TODO: remove and replace with our own mpsc
@@ -72,7 +73,13 @@ class alignas(2 * alignof(void*)) Job :
72
73
// Derived classes can use this to store a Job Id.
73
74
uint32_t Id = 0 ;
74
75
75
- void *Reserved[2 ] = {};
76
+ // / The voucher associated with the job. Note: this is currently unused on
77
+ // / non-Darwin platforms, with stub implementations of the functions for
78
+ // / consistency.
79
+ voucher_t Voucher = nullptr ;
80
+
81
+ // / Reserved for future use.
82
+ void *Reserved = nullptr ;
76
83
77
84
// We use this union to avoid having to do a second indirect branch
78
85
// when resuming an asynchronous task, which we expect will be the
@@ -88,23 +95,32 @@ class alignas(2 * alignof(void*)) Job :
88
95
Job (JobFlags flags, JobInvokeFunction *invoke,
89
96
const HeapMetadata *metadata = &jobHeapMetadata)
90
97
: HeapObject (metadata), Flags (flags), RunJob (invoke) {
98
+ Voucher = voucher_copy ();
91
99
assert (!isAsyncTask () && " wrong constructor for a task" );
92
100
}
93
101
94
102
Job (JobFlags flags, TaskContinuationFunction *invoke,
95
- const HeapMetadata *metadata = &jobHeapMetadata)
103
+ const HeapMetadata *metadata = &jobHeapMetadata,
104
+ bool captureCurrentVoucher = true )
96
105
: HeapObject (metadata), Flags (flags), ResumeTask (invoke) {
106
+ if (captureCurrentVoucher)
107
+ Voucher = voucher_copy ();
97
108
assert (isAsyncTask () && " wrong constructor for a non-task job" );
98
109
}
99
110
100
111
// / Create a job with "immortal" reference counts.
101
112
// / Used for async let tasks.
102
113
Job (JobFlags flags, TaskContinuationFunction *invoke,
103
- const HeapMetadata *metadata, InlineRefCounts::Immortal_t immortal)
114
+ const HeapMetadata *metadata, InlineRefCounts::Immortal_t immortal,
115
+ bool captureCurrentVoucher = true )
104
116
: HeapObject (metadata, immortal), Flags (flags), ResumeTask (invoke) {
117
+ if (captureCurrentVoucher)
118
+ Voucher = voucher_copy ();
105
119
assert (isAsyncTask () && " wrong constructor for a non-task job" );
106
120
}
107
121
122
+ ~Job () { swift_voucher_release (Voucher); }
123
+
108
124
bool isAsyncTask () const {
109
125
return Flags.isAsyncTask ();
110
126
}
@@ -229,8 +245,9 @@ class AsyncTask : public Job {
229
245
// / Private.initialize separately.
230
246
AsyncTask (const HeapMetadata *metadata, JobFlags flags,
231
247
TaskContinuationFunction *run,
232
- AsyncContext *initialContext)
233
- : Job(flags, run, metadata),
248
+ AsyncContext *initialContext,
249
+ bool captureCurrentVoucher)
250
+ : Job(flags, run, metadata, captureCurrentVoucher),
234
251
ResumeContext (initialContext) {
235
252
assert (flags.isAsyncTask ());
236
253
Id = getNextTaskId ();
@@ -243,8 +260,9 @@ class AsyncTask : public Job {
243
260
AsyncTask (const HeapMetadata *metadata, InlineRefCounts::Immortal_t immortal,
244
261
JobFlags flags,
245
262
TaskContinuationFunction *run,
246
- AsyncContext *initialContext)
247
- : Job(flags, run, metadata, immortal),
263
+ AsyncContext *initialContext,
264
+ bool captureCurrentVoucher)
265
+ : Job(flags, run, metadata, immortal, captureCurrentVoucher),
248
266
ResumeContext(initialContext) {
249
267
assert (flags.isAsyncTask ());
250
268
Id = getNextTaskId ();
0 commit comments