Commit Graph

209 Commits

Author SHA1 Message Date
Konrad `ktoso` Malawski
7e0a3eba13 [Distributed] Implementing calling transport in resolve and assigning id/transp 2021-08-12 14:08:58 +09:00
Kavon Farvardin
d4c71943bd [distributed] working on runtime allocation function 2021-08-12 14:05:31 +09:00
Alastair Houghton
ad147308af Merge pull request #38309 from al45tair/problem/47902425
[Runtime] Add ObjC support to isKnownUniquelyReferenced.
2021-08-02 17:39:49 +01:00
Alastair Houghton
abec55f432 [Runtime] Add ObjC support to isKnownUniquelyReferenced.
Add code to support detecting uniquely referenced Objective-C and Core
Foundation objects.

rdar://47902425
rdar://66805490
2021-07-29 16:29:48 +01:00
Joe Groff
fc67ba57f2 Merge pull request #37938 from jckarter/async-let-multi-suspend
Handle multiple awaits and suspend-on-exit for async let tasks.
2021-07-23 07:36:54 -07:00
Joe Groff
439edbce1f Handle multiple awaits and suspend-on-exit for async let tasks.
Change the code generation patterns for `async let` bindings to use an ABI based on the following
functions:

- `swift_asyncLet_begin`, which starts an `async let` child task, but which additionally
  now associates the `async let` with a caller-owned buffer to receive the result of the task.
  This is intended to allow the task to emplace its result in caller-owned memory, allowing the
  child task to be deallocated after completion without invalidating the result buffer.
- `swift_asyncLet_get[_throwing]`, which replaces `swift_asyncLet_wait[_throwing]`. Instead of
  returning a copy of the value, this entry point concerns itself with populating the local buffer.
  If the buffer hasn't been populated, then it awaits completion of the task and emplaces the
  result in the buffer; otherwise, it simply returns. The caller can then read the result out of
  its owned memory. These entry points are intended to be used before every read from the
  `async let` binding, after which point the local buffer is guaranteed to contain an initialized
  value.
- `swift_asyncLet_finish`, which replaces `swift_asyncLet_end`. Unlike `_end`, this variant
  is async and will suspend the parent task after cancelling the child to ensure it finishes
  before cleaning up. The local buffer will also be deinitialized if necessary. This is intended
  to be used on exit from an `async let` scope, to handle cleaning up the local buffer if necessary
  as well as cancelling, awaiting, and deallocating the child task.
- `swift_asyncLet_consume[_throwing]`, which combines `get` and `finish`. This will await completion
  of the task, leaving the result value in the result buffer (or propagating the error, if it
  throws), while destroying and deallocating the child task. This is intended as an optimization
  for reading `async let` variables that are read exactly once by their parent task.

To avoid an epoch break with existing swiftinterfaces and ABI clients, the old builtins and entry
points are kept intact for now, but SILGen now only generates code using the new interface.

This new interface fixes several issues with the old async let codegen, including use-after-free
crashes if the `async let` was never awaited, and the inability to read from an `async let` variable
more than once.

rdar://77855176
2021-07-22 10:19:31 -07:00
Konrad `ktoso` Malawski
73797800b4 [Distributed] introduce static resolve func, and fix static isolation on dist actors (#38530) 2021-07-22 08:00:54 +09:00
John McCall
3aa04db87b Track whether a task is actively running.
Tracking this as a single bit is actually largely uninteresting
to the runtime.  To handle priority escalation properly, we really
need to track this at a finer grain of detail: recording that the
task is running on a specific thread, enqueued on a specific actor,
or so on.  But starting by tracking a single bit is important for
two reasons:

- First, it's more realistic about the performance overheads of
  tasks: we're going to be doing this tracking eventually, and
  the cost of that tracking will be dominated by the atomic
  access, so doing that access now sets the baseline about right.

- Second, it ensures that we've actually got runtime involvement
  in all the right places to do this tracking.

A propos of the latter: there was no runtime involvement with
awaiting a continuation, which is a point at which the task
potentially transitions from running to suspended.  We must do
the tracking as part of this transition, rather than recognizing
in the run-loops that a task is still active and treating it as
having suspended, because the latter point potentially races with
the resumption of the task.  To do this, I've had to introduce
a runtime function, swift_continuation_await, to do this awaiting
rather than inlining the atomic operation on the continuation.

As part of doing this work, I've also fixed a bug where we failed
to load-acquire in swift_task_escalate before walking the task
status records to invoke escalation actions.

I've also fixed several places where the handling of task statuses
may have accidentally allowed the task to revert to uncancelled.
2021-07-14 20:24:01 -04:00
nate-chandler
5e0d0fb91b Merge pull request #36765 from nate-chandler/generic-metadata-prespecialization-components/generic-value-witnesses
[IRGen] Use generic value witnesses for prespecialized types.
2021-06-30 07:03:40 -07:00
Doug Gregor
d40fdb438c [IRGen] swift_getFunctionTypeMetadataGlobalActor has concurrency availability
Fixes rdar://79674106.
2021-06-28 14:14:39 -07:00
Nate Chandler
07ba7a6f3c [runtime] Exported multi payload enum witnesses.
When witness tables for enums are instantiated at runtime via

    swift::swift_initEnumMetadataMultiPayload

the witnesses

    getEnumTagSinglePayload
    storeEnumTagSinglePayload

are filled with swift_getMultiPayloadEnumTagSinglePayload (previously
getMultiPayloadEnumTagSinglePayload) and
swift_storeMultiPayloadEnumTagSinglePayload (previously
storeMultiPayloadEnumTagSinglePayload).  Concretely, that occurs when
instantiating the value witness table for a generic enum which has more
than one case with a payload, like Result<T>.  To enable the compiler to
do the same work, those functions need to be visible to it.

Here, those functions are made visible to the compiler.  Doing so
requires changing the way they are declared and adding them to
RuntimeFunctions.def which in turn requires the definition of some
functions to describe the availability of those functions.
2021-06-25 21:03:56 -07:00
Doug Gregor
e94c8271d0 Remove swift_task_create_async_let_future.
This is a small shim over `swift_task_create`. Use that instead.
2021-06-24 07:53:18 -07:00
Doug Gregor
76959b1d4f Remove CreateAsyncTaskGroupFuture and swift_task_create_group_future.
We've moved everything over to `CreateAsyncTask` now.
2021-06-24 07:53:18 -07:00
Doug Gregor
a61adace85 Remove CreateAsyncTaskFuture and swift_task_create_future.
We no longer need these entry points.
2021-06-24 07:53:18 -07:00
Doug Gregor
c7edfa3ba9 Centralize non-group task creation on swift_task_create[_f].
Introduce a builtin `createAsyncTask` that maps to `swift_task_create`,
and use that for the non-group task creation operations based on the
task-creation flags. `swift_task_create` and the thin function version
`swift_task_create_f` go through the dynamically-replaceable
`swift_task_create_common`, where all of the task creation logic is
present.

While here, move copying of task locals and the initial scheduling of
the task into `swift_task_create_common`, enabling by separate flags.
2021-06-24 07:53:17 -07:00
Doug Gregor
3727db2fe2 Create a separate set of task creation flags for swift_task_create.
The flags that are useful for task creation are a bit different from
the flags that go on a job. Create a separate flag set for task
creation and use that in the API for `swift_task_create`. For now,
have the callers do the remapping.
2021-06-24 07:53:17 -07:00
Konrad `ktoso` Malawski
8536100354 [Concurrency] introduce task options, and change ABI to accept them
introduce new options parameter to all task spawning

[Concurrency] ABI for asynclet start to accept options

[Concurrency] fix unittest usages of changed task creation ABI

[Concurrency] introduce constants for parameter indexes in ownership

[Concurrency] fix test/SILOptimizer/closure_lifetime_fixup_concurrency.swift
2021-06-21 13:03:50 +09:00
John McCall
ca62a79079 Use &_dispatch_main_q as the identity of the main actor.
I added Builtin.buildMainActorExecutor before, but because I never
implemented it correctly in IRGen, it's not okay to use it on old
versions, so I had to introduce a new feature only for it.

The shim dispatch queue class in the Concurrency runtime is rather
awful, but I couldn't think of a reasonable alternative without
just entirely hard-coding the witness table in the runtime.
It's not ABI, at least.
2021-06-17 05:04:30 -04:00
Arnold Schwaighofer
10e3d2e3af Change _wait(_throwing) ABIs to reduce code size
Changes the task, taskGroup, asyncLet wait funtion call ABIs.

To reduce code size pass the context parameters and resumption function
as arguments to the wait function.

This means that the suspend point does not need to store parent context
and resumption to the suspend point's context.

```
  void swift_task_future_wait_throwing(
    OpaqueValue * result,
    SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
    AsyncTask *task,
    ThrowingTaskFutureWaitContinuationFunction *resume,
    AsyncContext *callContext);
```

The runtime passes the caller context to the resume entry point saving
the load of the parent context in the resumption function.

This patch adds a `Metadata *` field to `GroupImpl`. The await entry
pointer no longer pass the metadata pointer and there is a path through
the runtime where the task future is no longer available.
2021-06-08 10:41:26 -07:00
Doug Gregor
ff24437b3b [IRGen] Emit calls to swift_getFunctionTypeMetadataGlobalActor as appropriate 2021-06-03 11:59:49 -07:00
Konrad `ktoso` Malawski
6008b32789 [Distributed] initial distributed support, fixed availability (#37650)
* [Distributed] Initial distributed checking

* [Distributed] initial types shapes and conform to DistributedActor

* [Distributed] Require Codable params and return types

* [Distributed] initial synthesis of fields and constructors

* [Distributed] Field and initializer synthesis

* [Distributed] Codable requirement on distributed funcs; also handle <T: Codable>

* [Distributed] handle generic type params which are Codable in dist func

[Distributed] conformsToProtocol after all

* [Distributed] Implement remote flag on actors

* Implement remote flag on actors

* add test

* actor initializer that sets remote flag

[Distributed] conformances getting there

* [Distributed] dont require async throws; cleanup compile tests

* [Distributed] do not synthesize default implicit init, only our special ones

* [Distributed] properly synth inits and properties; mark actorTransport as _distributedActorIndependent

Also:

- do not synthesize default init() initializer for dist actor

* [Distributed] init(transport:) designated and typechecking

* [Distributed] dist actor initializers MUST delegate to local-init

* [Distributed] check if any ctors in delegation call init(transport:)

* [Distributed] check init(transport:) delegation through many inits; ban invoking init(resolve:using:) explicitly

* [Distributed] disable IRGen test for now

* [Distributed] Rebase cleanups

* [Concurrent] transport and address are concurrent value

* [Distributed] introduce -enable-experimental-distributed flag

* rebase adjustments again

* rebase again...

* [Distributed] distributed functions are implicitly async+throws outside the actor

* [Distributed] implicitly throwing and async distributed funcs

* remove printlns

* add more checks to implicit function test

* [Distributed] resolve initializer now marks the isRemote actor flag

* [Distributed] distributedActor_destroy invoked instead, rather than before normal

* [Distributed] Generate distributed thunk for actors

* [distributed] typechecking for _remote_ functions existing, add tests for remote funcs

* adding one XFAIL'ed task & actor lifetime test

The `executor_deinit1` test fails 100% of the time
(from what I've seen) so I thought we could track
and see when/if someone happens to fix this bug.

Also, added extra coverage for #36298 via `executor_deinit2`

* Fix a memory issue with actors in the runtime system, by @phausler

* add new test that now passes because of patch by @phausler

See previous commit in this PR.
Test is based on one from rdar://74281361

* fix all tests that require the _remote_ function stubs

* Do not infer @actorIndependent onto `let` decls

* REVERT_ME: remove some tests that hacky workarounds will fail

* another flaky test, help build toolchain

* [Distributed] experimental distributed implies experimental concurrency

* [Distributed] Allow distributed function that are not marked async or throws

* [Distributed] make attrs SIMPLE to get serialization generated

* [Distributed] ActorAddress must be Hashable

* [Distributed] Implement transport.actorReady call in local init

* cleanup after rebase

* [Distributed] add availability attributes to all distributed actor code

* cleanup - this fixed some things

* fixing up

* fixing up

* [Distributed] introduce new Distributed module

* [Distributed] diagnose when missing 'import _Distributed'

* [Distributed] make all tests import the module

* more docs on address

* [Distributed] fixup merge issues

* cleanup: remove unnecessary code for now SIMPLE attribute

* fix: fix getActorIsolationOfContext

* [Distributed] cmake: depend on _concurrency module

* fixing tests...

* Revert "another flaky test, help build toolchain"

This reverts commit 83ae6654dd.

* remove xfail

* clenup some IR and SIL tests

* cleanup

* [Distributed] fix cmake test and ScanDependencies/can_import_with_map.swift

* [Distributed] fix flags/build tests

* cleanup: use isDistributed wherever possible

* [Distributed] don't import Dispatch in tests

* dont link distributed in stdlib unittest

* trying always append distributed module

* cleanups

* [Distributed] move all tests to Distributed/ directory

* [lit] try to fix lit test discovery

* [Distributed] update tests after diagnostics for implicit async changed

* [Distributed] Disable remote func tests on Windows for now

* Review cleanups

* [Distributed] fix typo, fixes Concurrency/actor_isolation_objc.swift

* [Distributed] attributes are DistributedOnly (only)

* cleanup

* [Distributed] cleanup: rely on DistributedOnly for guarding the keyword

* Update include/swift/AST/ActorIsolation.h

Co-authored-by: Doug Gregor <dgregor@apple.com>

* introduce isAnyThunk, minor cleanup

* wip

* [Distributed] move some type checking to TypeCheckDistributed.cpp

* [TypeCheckAttr] remove extra debug info

* [Distributed/AutoDiff] fix SILDeclRef creation which caused AutoDiff issue

* cleanups

* [lit] remove json import from lit test suite, not needed after all

* [Distributed] distributed functions only in DistributedActor protocols

* [Distributed] fix flag overlap & build setting

* [Distributed] Simplify noteIsolatedActorMember to not take bool distributed param

* [Distributed] make __isRemote not public

* [Distributed] Fix availability and remove actor class tests

* [actorIndependent] do not apply actorIndependent implicitly to values where it would be illegal to apply

* [Distributed] disable tests until issue fixed

Co-authored-by: Dario Rexin <drexin@apple.com>
Co-authored-by: Kavon Farvardin <kfarvardin@apple.com>
Co-authored-by: Doug Gregor <dgregor@apple.com>
2021-05-28 07:22:03 +09:00
Konrad `ktoso` Malawski
0c75bd2a39 Revert Initial distributed, some issues to be fixed first (#37556)
* Revert "[Distributed] disable tests until issue fixed"

This reverts commit 0a04278920.

* Revert "[Distributed] Initial `distributed` actors and functions and new module (#37109)"

This reverts commit 814ede0cf3.
2021-05-21 19:28:48 +09:00
Konrad `ktoso` Malawski
814ede0cf3 [Distributed] Initial distributed actors and functions and new module (#37109)
* [Distributed] Initial distributed checking

* [Distributed] initial types shapes and conform to DistributedActor

* [Distributed] Require Codable params and return types

* [Distributed] initial synthesis of fields and constructors

* [Distributed] Field and initializer synthesis

* [Distributed] Codable requirement on distributed funcs; also handle <T: Codable>

* [Distributed] handle generic type params which are Codable in dist func

[Distributed] conformsToProtocol after all

* [Distributed] Implement remote flag on actors

* Implement remote flag on actors

* add test

* actor initializer that sets remote flag

[Distributed] conformances getting there

* [Distributed] dont require async throws; cleanup compile tests

* [Distributed] do not synthesize default implicit init, only our special ones

* [Distributed] properly synth inits and properties; mark actorTransport as _distributedActorIndependent

Also:

- do not synthesize default init() initializer for dist actor

* [Distributed] init(transport:) designated and typechecking

* [Distributed] dist actor initializers MUST delegate to local-init

* [Distributed] check if any ctors in delegation call init(transport:)

* [Distributed] check init(transport:) delegation through many inits; ban invoking init(resolve:using:) explicitly

* [Distributed] disable IRGen test for now

* [Distributed] Rebase cleanups

* [Concurrent] transport and address are concurrent value

* [Distributed] introduce -enable-experimental-distributed flag

* rebase adjustments again

* rebase again...

* [Distributed] distributed functions are implicitly async+throws outside the actor

* [Distributed] implicitly throwing and async distributed funcs

* remove printlns

* add more checks to implicit function test

* [Distributed] resolve initializer now marks the isRemote actor flag

* [Distributed] distributedActor_destroy invoked instead, rather than before normal

* [Distributed] Generate distributed thunk for actors

* [distributed] typechecking for _remote_ functions existing, add tests for remote funcs

* adding one XFAIL'ed task & actor lifetime test

The `executor_deinit1` test fails 100% of the time
(from what I've seen) so I thought we could track
and see when/if someone happens to fix this bug.

Also, added extra coverage for #36298 via `executor_deinit2`

* Fix a memory issue with actors in the runtime system, by @phausler

* add new test that now passes because of patch by @phausler

See previous commit in this PR.
Test is based on one from rdar://74281361

* fix all tests that require the _remote_ function stubs

* Do not infer @actorIndependent onto `let` decls

* REVERT_ME: remove some tests that hacky workarounds will fail

* another flaky test, help build toolchain

* [Distributed] experimental distributed implies experimental concurrency

* [Distributed] Allow distributed function that are not marked async or throws

* [Distributed] make attrs SIMPLE to get serialization generated

* [Distributed] ActorAddress must be Hashable

* [Distributed] Implement transport.actorReady call in local init

* cleanup after rebase

* [Distributed] add availability attributes to all distributed actor code

* cleanup - this fixed some things

* fixing up

* fixing up

* [Distributed] introduce new Distributed module

* [Distributed] diagnose when missing 'import _Distributed'

* [Distributed] make all tests import the module

* more docs on address

* [Distributed] fixup merge issues

* cleanup: remove unnecessary code for now SIMPLE attribute

* fix: fix getActorIsolationOfContext

* [Distributed] cmake: depend on _concurrency module

* fixing tests...

* Revert "another flaky test, help build toolchain"

This reverts commit 83ae6654dd.

* remove xfail

* clenup some IR and SIL tests

* cleanup

* [Distributed] fix cmake test and ScanDependencies/can_import_with_map.swift

* [Distributed] fix flags/build tests

* cleanup: use isDistributed wherever possible

* [Distributed] don't import Dispatch in tests

* dont link distributed in stdlib unittest

* trying always append distributed module

* cleanups

* [Distributed] move all tests to Distributed/ directory

* [lit] try to fix lit test discovery

* [Distributed] update tests after diagnostics for implicit async changed

* [Distributed] Disable remote func tests on Windows for now

* Review cleanups

* [Distributed] fix typo, fixes Concurrency/actor_isolation_objc.swift

* [Distributed] attributes are DistributedOnly (only)

* cleanup

* [Distributed] cleanup: rely on DistributedOnly for guarding the keyword

* Update include/swift/AST/ActorIsolation.h

Co-authored-by: Doug Gregor <dgregor@apple.com>

* introduce isAnyThunk, minor cleanup

* wip

* [Distributed] move some type checking to TypeCheckDistributed.cpp

* [TypeCheckAttr] remove extra debug info

* [Distributed/AutoDiff] fix SILDeclRef creation which caused AutoDiff issue

* cleanups

* [lit] remove json import from lit test suite, not needed after all

* [Distributed] distributed functions only in DistributedActor protocols

* [Distributed] fix flag overlap & build setting

* [Distributed] Simplify noteIsolatedActorMember to not take bool distributed param

* [Distributed] make __isRemote not public

Co-authored-by: Dario Rexin <drexin@apple.com>
Co-authored-by: Kavon Farvardin <kfarvardin@apple.com>
Co-authored-by: Doug Gregor <dgregor@apple.com>
2021-05-21 09:12:29 +09:00
Erik Eckstein
93367ed587 concurrency: make the startAsyncLet closure no-escaping
The closure does not escape the startAsyncLet - endAsyncLet scope. Even though it's (potentially) running on a different thread.

The substantial change in the runtime is to not call swift_release on the closure context if it's a non-escaping closure.
2021-04-20 21:57:19 +02:00
Konrad `ktoso` Malawski
eed96d21bb [AsyncLet] remove runChild; it is now asyncLetStart 2021-04-19 10:06:23 +09:00
Konrad `ktoso` Malawski
d3c5ebc9b7 [AsyncLet] reimplemented with new ABI and builtins 2021-04-19 10:06:23 +09:00
Konrad `ktoso` Malawski
ba615029c7 [Concurrency] Store child record when async let child task spawned 2021-04-19 10:06:23 +09:00
John McCall
efeb818161 Clean up the TaskGroup ABI:
- stop storing the parent task in the TaskGroup at the .swift level
- make sure that swift_taskGroup_isCancelled is implied by the parent
  task being cancelled
- make the TaskGroup structs frozen
- make the withTaskGroup functions inlinable
- remove swift_taskGroup_create
- teach IRGen to allocate memory for the task group
- don't deallocate the task group in swift_taskGroup_destroy

To achieve the allocation change, introduce paired create/destroy builtins.

Furthermore, remove the _swiftRetain and _swiftRelease functions and
several calls to them.  Replace them with uses of the appropriate builtins.
I should probably change the builtins to return retained, since they're
working with a managed type, but I'll do that in a separate commit.
2021-04-09 03:06:31 -04:00
John McCall
0242d7572e Delay deallocation of default actors when they're currently running.
For ordinary memory-management reasons, this should only ever
happen when there will be no more uses of the actor outside of the
actor runtime.  The actor runtime, meanwhile, doesn't care about
anything except the default-actor control state of the actor.  So
we can just allow the rest of the actor to be destructed when it
isn't needed anymore, then destroy the actor state and deallocate
the object when we get around to switching off the executor.

This does assume that the task doesn't do anything which semantically
detects the executor it's on before switching off it, since doing so
might read a bogus executor.  However, we should only get an executor
in a zombie state like this when a hop has been removed or reordered,
and detection events should count as inhibiting that and forcing the
true executor to be switched to (and thus detected).

(But maybe lifetime optimization can make this happen?  Maybe we
need semantic detection to filter out zombie executors.)
2021-04-08 12:57:12 -04:00
John McCall
156264f8e8 Make ExecutorRef two words. 2021-04-08 12:57:12 -04:00
Richard Wei
d997526948 Fix function differentiability kind metadata and mangling. (#36601)
* Move differentiability kinds from target function type metadata to trailing objects so that we don't exhaust all remaining bits of function type metadata.
  * Differentiability kind is now stored in a tail-allocated word when function type flags say it's differentiable, located immediately after the normal function type metadata's contents (with proper alignment in between).
  * Add new runtime function `swift_getFunctionTypeMetadataDifferentiable` which handles differentiable function types.
* Fix mangling of different differentiability kinds in function types. Mangle it like `ConcurrentFunctionType` so that we can drop special cases for escaping functions.
    ```
    function-signature ::= params-type params-type async? sendable? throws? differentiable? // results and parameters
    ...
    differentiable ::= 'jf'                    // @differentiable(_forward) on function type
    differentiable ::= 'jr'                    // @differentiable(reverse) on function type
    differentiable ::= 'jd'                    // @differentiable on function type
    differentiable ::= 'jl'                    // @differentiable(_linear) on function type
    ```

Resolves rdar://75240064.
2021-03-30 09:59:06 -07:00
John McCall
98711fd628 Revise the continuation ABI.
The immediate desire is to minimize the set of ABI dependencies
on the layout of an ExecutorRef.  In addition to that, however,
I wanted to generally reduce the code size impact of an unsafe
continuation since it now requires accessing thread-local state,
and I wanted resumption to not have to create unnecessary type
metadata for the value type just to do the initialization.

Therefore, I've introduced a swift_continuation_init function
which handles the default initialization of a continuation
and returns a reference to the current task.  I've also moved
the initialization of the normal continuation result into the
caller (out of the runtime), and I've moved the resumption-side
cmpxchg into the runtime (and prior to the task being enqueued).
2021-03-28 12:58:16 -04:00
Joe Groff
79fb05b362 Concurrency: Hop back to the previous executor after actor calls.
Tasks shouldn't normally hog the actor context indefinitely after making a call that's bound to
that actor, since that prevents the actor from potentially taking on other jobs it needs to
be able to address. Set up SILGen so that it saves the current executor (using a new runtime
entry point) and hops back to it after every actor call, not only ones where the caller context
is also actor-bound.

The added executor hopping here also exposed a bug in the runtime implementation while processing
DefaultActor jobs, where if an actor job returned to the processing loop having already yielded
the thread back to a generic executor, we would still attempt to make the actor give up the thread
again, corrupting its state.

rdar://71905765
2021-03-18 11:47:50 -07:00
John McCall
6c879d6fd3 Change the async ABI to not pass the active task and executor.
Most of the async runtime functions have been changed to not
expect the task and executor to be passed in.  When knowing the
task and executor is necessary, there are runtime functions
available to recover them.

The biggest change I had to make to a runtime function signature
was to swift_task_switch, which has been altered to expect to be
passed the context and resumption function instead of requiring
the caller to park the task.  This has the pleasant consequence
of allowing the implementation to very quickly turn around when
it recognizes that the current executor is satisfactory.  It does
mean that on arm64e we have to sign the continuation function
pointer as an argument and then potentially resign it when
assigning into the task's resume slot.

rdar://70546948
2021-03-16 22:52:54 -04:00
Joe Groff
872afda50b Merge pull request #36298 from jckarter/created-task-closure-context-leak
SIL: Clean up ownership handling in `createAsyncTask` builtins.
2021-03-09 14:17:13 -08:00
Joe Groff
d9798c0868 Concurrency: Redo non-_f variants of swift_task_create to accept closures as is.
In their previous form, the non-`_f` variants of these entry points were unused, and IRGen
lowered the `createAsyncTask` builtins to use the `_f` variants with a large amount of caller-side
codegen to manually unpack closure values. Amid all this, it also failed to make anyone responsible
for releasing the closure context after the task completed, causing every task creation to leak.
Redo the `swift_task_create_*` entry points to accept the two words of an async closure value
directly, and unpack the closure to get its invocation entry point and initial context size
inside the runtime. (Also get rid of the non-future `swift_task_create` variant, since it's unused
and it's subtly different in a lot of hairy ways from the future forms. Better to add it later
when it's needed than to have a broken unexercised version now.)
2021-03-08 16:54:19 -08:00
Joe Groff
016496384e Concurrency: Remove currently-unused non-_f variants of swift_task_create
I'm about to replace these with new variations that correctly handle spawning a task with
a closure as its initial entry point, without leaking or requiring large amounts of caller-side
code generation.
2021-03-05 12:01:06 -08:00
Konrad `ktoso` Malawski
aedbbe615d [TaskGroup] Towards ABI stability of groups 2021-03-02 20:25:22 +09:00
Konrad `ktoso` Malawski
a226259d84 [Concurrency] TaskGroup moves out of AsyncTask, non escaping body 2021-02-22 13:26:27 +09:00
Arnold Schwaighofer
4373bdd6d0 Conditionally start using llvm::CallingConv::SwiftTail for async functions
This is conditional on UseAsyncLowering and in the future should also be
conditional on `clangTargetInfo.isSwiftAsyncCCSupported()` once that
support is merged.

Update tests to work either with swiftcc or swifttailcc.
2021-02-18 09:25:15 -08:00
Andrew Trick
29b9e51cb6 Remove ReadNone attribute from runtime functions
The Swift compiler incorrectly sets the LLVM "ReadNone" attribute when
declaring swift_getObjCClassFromObject and swift_projectBox. This
means that the LLVM ARC optimizer will hoist ARC "release" operations
above these runtime calls. Since the implementation of the calls reads
the object, this causes a use-after-free crash.

This problem is easy to reproduce with
swift_getObjCClassFromObject. It was only exposed recently because the
SIL optimizer now shrinks object lifetimes, making it easier for LLVM
optimizations to kick in. It is difficult to expose the problem with
swift_projectBox, but the bug/fix is still obvious.

Fixes rdar://73820091: Use-after free application crash.
2021-02-08 14:53:24 -08:00
John McCall
d874479290 Add builtins to initialize and destroy a default-actor member.
It would be more abstractly correct if this got DI support so
that we destroy the member if the constructor terminates
abnormally, but we can get to that later.
2020-12-10 19:18:53 -05:00
Erik Eckstein
4e296c0c5a IRGen: emit emit_hop_to_executor instructions.
This basically means to create a suspension point and call the swift_task_switch runtime function.

rdar://71099289
2020-12-03 12:42:41 +01:00
Richard Wei
de2dbe57ed [AutoDiff] Bump-pointer allocate pullback structs in loops. (#34886)
In derivatives of loops, no longer allocate boxes for indirect case payloads. Instead, use a custom pullback context in the runtime which contains a bump-pointer allocator.

When a function contains a differentiated loop, the closure context is a `Builtin.NativeObject`, which contains a `swift::AutoDiffLinearMapContext` and a tail-allocated top-level linear map struct (which represents the linear map struct that was previously directly partial-applied into the pullback). In branching trace enums, the payloads of previously indirect cases will be allocated by `swift::AutoDiffLinearMapContext::allocate` and stored as a `Builtin.RawPointer`.
2020-11-30 15:49:38 -08:00
Arnold Schwaighofer
fa54ff8568 IRGen: Fix lowering of Builtin.createAsyncTask and Builtin.createAsyncTaskFuture
Thick async functions store their async context size in the closure
context. Only if the closure context is nil can we assume the
partial_apply_forwarder function to be the address of an async function
pointer struct value.
2020-11-16 13:33:55 -08:00
Doug Gregor
069dfad638 [Concurrency] Add Builtin.createAsyncTaskFuture.
This new builtin allows the creation of a "future" task, which calls
down to swift_task_create_future to actually form the task.
2020-11-15 22:37:13 -08:00
Arnold Schwaighofer
32ecd350e9 Change swift_task_create_f to swift_task_create now that explosions are async function pointers 2020-11-13 07:32:33 -08:00
Doug Gregor
4c2c2f32e9 [Concurrency] Implement a builtin createAsyncTask() to create a new task.
`Builtin.createAsyncTask` takes flags, an optional parent task, and an
async/throwing function to execute, and passes it along to the
`swift_task_create_f` entry point to create a new (potentially child)
task, returning the new task and its initial context.
2020-11-07 23:05:04 -08:00
Doug Gregor
c291eb596b [Concurrency] Add cancelAsyncTask() builtin.
Implement a new builtin, `cancelAsyncTask()`, to cancel the given
asynchronous task. This lowers down to a call into the runtime
operation `swift_task_cancel()`.

Use this builtin to implement Task.Handle.cancel().
2020-11-05 13:50:17 -08:00
Nate Chandler
cda11b90a1 [Runtime] Add prespecialized-caching getGenericMetadata variant.
Add a new entry point for getting generic metadata which adds the
canonical metadata records attached to the nominal type descriptor to
the metadata cache.

Change the implementation of the primary entry-point
swift_getGenericMetadata to stop looking through canonical
prespecialized records.

Change the implementation of swift_getCanonicalSpecializedMetadata to
use the caching token attached to the nominal type descriptor to add
canonical prespecialized metadata records to the metadata cache only
once rather than using the cache variables to limit the number of times
the attempt was made.
2020-11-01 13:35:03 -08:00