2323#include " swift/ABI/Metadata.h"
2424#include " swift/ABI/MetadataValues.h"
2525#include " swift/Runtime/Config.h"
26+ #include " swift/Runtime/VoucherShims.h"
2627#include " swift/Basic/STLExtras.h"
2728#include " bitset"
2829#include " queue" // TODO: remove and replace with our own mpsc
@@ -72,7 +73,13 @@ class alignas(2 * alignof(void*)) Job :
7273 // Derived classes can use this to store a Job Id.
7374 uint32_t Id = 0 ;
7475
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 ;
7683
7784 // We use this union to avoid having to do a second indirect branch
7885 // when resuming an asynchronous task, which we expect will be the
@@ -88,23 +95,32 @@ class alignas(2 * alignof(void*)) Job :
8895 Job (JobFlags flags, JobInvokeFunction *invoke,
8996 const HeapMetadata *metadata = &jobHeapMetadata)
9097 : HeapObject (metadata), Flags (flags), RunJob (invoke) {
98+ Voucher = voucher_copy ();
9199 assert (!isAsyncTask () && " wrong constructor for a task" );
92100 }
93101
94102 Job (JobFlags flags, TaskContinuationFunction *invoke,
95- const HeapMetadata *metadata = &jobHeapMetadata)
103+ const HeapMetadata *metadata = &jobHeapMetadata,
104+ bool captureCurrentVoucher = true )
96105 : HeapObject (metadata), Flags (flags), ResumeTask (invoke) {
106+ if (captureCurrentVoucher)
107+ Voucher = voucher_copy ();
97108 assert (isAsyncTask () && " wrong constructor for a non-task job" );
98109 }
99110
100111 // / Create a job with "immortal" reference counts.
101112 // / Used for async let tasks.
102113 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 )
104116 : HeapObject (metadata, immortal), Flags (flags), ResumeTask (invoke) {
117+ if (captureCurrentVoucher)
118+ Voucher = voucher_copy ();
105119 assert (isAsyncTask () && " wrong constructor for a non-task job" );
106120 }
107121
122+ ~Job () { swift_voucher_release (Voucher); }
123+
108124 bool isAsyncTask () const {
109125 return Flags.isAsyncTask ();
110126 }
@@ -229,8 +245,9 @@ class AsyncTask : public Job {
229245 // / Private.initialize separately.
230246 AsyncTask (const HeapMetadata *metadata, JobFlags flags,
231247 TaskContinuationFunction *run,
232- AsyncContext *initialContext)
233- : Job(flags, run, metadata),
248+ AsyncContext *initialContext,
249+ bool captureCurrentVoucher)
250+ : Job(flags, run, metadata, captureCurrentVoucher),
234251 ResumeContext (initialContext) {
235252 assert (flags.isAsyncTask ());
236253 Id = getNextTaskId ();
@@ -243,8 +260,9 @@ class AsyncTask : public Job {
243260 AsyncTask (const HeapMetadata *metadata, InlineRefCounts::Immortal_t immortal,
244261 JobFlags flags,
245262 TaskContinuationFunction *run,
246- AsyncContext *initialContext)
247- : Job(flags, run, metadata, immortal),
263+ AsyncContext *initialContext,
264+ bool captureCurrentVoucher)
265+ : Job(flags, run, metadata, immortal, captureCurrentVoucher),
248266 ResumeContext(initialContext) {
249267 assert (flags.isAsyncTask ());
250268 Id = getNextTaskId ();
0 commit comments