mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge remote-tracking branch 'origin/main' into rebranch
This commit is contained in:
@@ -113,6 +113,7 @@ target_compile_options(swift_Concurrency PRIVATE
|
|||||||
# NOTE: do not remove until `IsolatedAny` is on by default in all supported
|
# NOTE: do not remove until `IsolatedAny` is on by default in all supported
|
||||||
# compilers.
|
# compilers.
|
||||||
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature IsolatedAny>"
|
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature IsolatedAny>"
|
||||||
|
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-enable-experimental-feature Extern>"
|
||||||
# NOTE: enable the async frame pointer on Darwin to faciliate debugging.
|
# NOTE: enable the async frame pointer on Darwin to faciliate debugging.
|
||||||
$<$<AND:$<PLATFORM_ID:Darwin>,$<COMPILE_LANGUAGE:C,CXX>>:-fswift-async-fp=always>
|
$<$<AND:$<PLATFORM_ID:Darwin>,$<COMPILE_LANGUAGE:C,CXX>>:-fswift-async-fp=always>
|
||||||
"$<$<AND:$<PLATFORM_ID:Darwin>,$<COMPILE_LANGUAGE:Swift>>:SHELL:-Xfrontend -swift-async-frame-pointer=always>"
|
"$<$<AND:$<PLATFORM_ID:Darwin>,$<COMPILE_LANGUAGE:Swift>>:SHELL:-Xfrontend -swift-async-frame-pointer=always>"
|
||||||
|
|||||||
@@ -2396,13 +2396,25 @@ FUNCTION(TaskSwitchFunc,
|
|||||||
// size_t flags);
|
// size_t flags);
|
||||||
FUNCTION(DeinitOnExecutorFunc,
|
FUNCTION(DeinitOnExecutorFunc,
|
||||||
_Concurrency, swift_task_deinitOnExecutor, SwiftCC,
|
_Concurrency, swift_task_deinitOnExecutor, SwiftCC,
|
||||||
ConcurrencyAvailability,
|
IsolatedDeinitAvailability,
|
||||||
RETURNS(VoidTy),
|
RETURNS(VoidTy),
|
||||||
ARGS(Int8PtrTy, Int8PtrTy, ExecutorFirstTy, ExecutorSecondTy, SizeTy),
|
ARGS(Int8PtrTy, Int8PtrTy, ExecutorFirstTy, ExecutorSecondTy, SizeTy),
|
||||||
ATTRS(NoUnwind),
|
ATTRS(NoUnwind),
|
||||||
EFFECT(RuntimeEffect::Concurrency),
|
EFFECT(RuntimeEffect::Concurrency),
|
||||||
UNKNOWN_MEMEFFECTS)
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
|
// void swift_task_deinitOnExecutorMainActorBackDeploy(void *object,
|
||||||
|
// DeinitWorkFunction *work,
|
||||||
|
// SerialExecutorRef newExecutor,
|
||||||
|
// size_t flags);
|
||||||
|
FUNCTION(DeinitOnExecutorMainActorBackDeployFunc,
|
||||||
|
_Concurrency, deinitOnExecutorMainActorBackDeploy, SwiftCC,
|
||||||
|
ConcurrencyAvailability,
|
||||||
|
RETURNS(VoidTy),
|
||||||
|
ARGS(Int8PtrTy, Int8PtrTy, ExecutorFirstTy, ExecutorSecondTy, SizeTy),
|
||||||
|
ATTRS(NoUnwind),
|
||||||
|
EFFECT(RuntimeEffect::Concurrency),
|
||||||
|
UNKNOWN_MEMEFFECTS)
|
||||||
|
|
||||||
// AsyncTask *swift_continuation_init(AsyncContext *continuationContext,
|
// AsyncTask *swift_continuation_init(AsyncContext *continuationContext,
|
||||||
// AsyncContinuationFlags);
|
// AsyncContinuationFlags);
|
||||||
|
|||||||
@@ -982,6 +982,14 @@ namespace RuntimeConstants {
|
|||||||
return RuntimeAvailability::AlwaysAvailable;
|
return RuntimeAvailability::AlwaysAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RuntimeAvailability IsolatedDeinitAvailability(ASTContext &context) {
|
||||||
|
auto featureAvailability = context.getIsolatedDeinitAvailability();
|
||||||
|
if (!isDeploymentAvailabilityContainedIn(context, featureAvailability)) {
|
||||||
|
return RuntimeAvailability::ConditionallyAvailable;
|
||||||
|
}
|
||||||
|
return RuntimeAvailability::AlwaysAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
RuntimeAvailability
|
RuntimeAvailability
|
||||||
MultiPayloadEnumTagSinglePayloadAvailability(ASTContext &context) {
|
MultiPayloadEnumTagSinglePayloadAvailability(ASTContext &context) {
|
||||||
auto featureAvailability = context.getMultiPayloadEnumTagSinglePayload();
|
auto featureAvailability = context.getMultiPayloadEnumTagSinglePayload();
|
||||||
|
|||||||
@@ -462,6 +462,15 @@ FuncDecl *SILGenModule::getDeinitOnExecutor() {
|
|||||||
return lookupConcurrencyIntrinsic(getASTContext(), "_deinitOnExecutor");
|
return lookupConcurrencyIntrinsic(getASTContext(), "_deinitOnExecutor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FuncDecl *SILGenModule::getDeinitOnExecutorMainActorBackDeploy() {
|
||||||
|
auto found = lookupConcurrencyIntrinsic(getASTContext(),
|
||||||
|
"_deinitOnExecutorMainActorBackDeploy");
|
||||||
|
if (found)
|
||||||
|
return found;
|
||||||
|
|
||||||
|
return getDeinitOnExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
FuncDecl *SILGenModule::getCreateExecutors() {
|
FuncDecl *SILGenModule::getCreateExecutors() {
|
||||||
return lookupConcurrencyIntrinsic(getASTContext(), "_createExecutors");
|
return lookupConcurrencyIntrinsic(getASTContext(), "_createExecutors");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -557,6 +557,8 @@ public:
|
|||||||
FuncDecl *getSwiftJobRun();
|
FuncDecl *getSwiftJobRun();
|
||||||
/// Retrieve the _Concurrency._deinitOnExecutor intrinsic.
|
/// Retrieve the _Concurrency._deinitOnExecutor intrinsic.
|
||||||
FuncDecl *getDeinitOnExecutor();
|
FuncDecl *getDeinitOnExecutor();
|
||||||
|
/// Retrieve the _Concurrency._deinitOnExecutorMainActorBackDeploy intrinsic.
|
||||||
|
FuncDecl *getDeinitOnExecutorMainActorBackDeploy();
|
||||||
// Retrieve the _SwiftConcurrencyShims.exit intrinsic.
|
// Retrieve the _SwiftConcurrencyShims.exit intrinsic.
|
||||||
FuncDecl *getExit();
|
FuncDecl *getExit();
|
||||||
|
|
||||||
|
|||||||
@@ -339,6 +339,17 @@ void SILGenFunction::emitDeallocatingMoveOnlyDestructor(DestructorDecl *dd) {
|
|||||||
B.createReturn(loc, emitEmptyTuple(loc));
|
B.createReturn(loc, emitEmptyTuple(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determine whether the availability for the body the given destructor predates the introduction of
|
||||||
|
/// support for isolated deinit.
|
||||||
|
static bool availabilityPredatesIsolatedDeinit(DestructorDecl *dd) {
|
||||||
|
ASTContext &ctx = dd->getASTContext();
|
||||||
|
if (ctx.LangOpts.DisableAvailabilityChecking)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto deploymentAvailability = AvailabilityRange::forDeploymentTarget(ctx);
|
||||||
|
return !deploymentAvailability.isContainedIn(ctx.getIsolatedDeinitAvailability());
|
||||||
|
}
|
||||||
|
|
||||||
void SILGenFunction::emitIsolatingDestructor(DestructorDecl *dd) {
|
void SILGenFunction::emitIsolatingDestructor(DestructorDecl *dd) {
|
||||||
MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit"));
|
MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit"));
|
||||||
|
|
||||||
@@ -372,8 +383,15 @@ void SILGenFunction::emitIsolatingDestructor(DestructorDecl *dd) {
|
|||||||
executor = B.createExtractExecutor(loc, actor);
|
executor = B.createExtractExecutor(loc, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine whether we need the main-actor back-deployment version of
|
||||||
|
// this function.
|
||||||
|
bool useMainActorBackDeploy =
|
||||||
|
ai.isMainActor() && availabilityPredatesIsolatedDeinit(dd);
|
||||||
|
|
||||||
// Get deinitOnExecutor
|
// Get deinitOnExecutor
|
||||||
FuncDecl *swiftDeinitOnExecutorDecl = SGM.getDeinitOnExecutor();
|
FuncDecl *swiftDeinitOnExecutorDecl =
|
||||||
|
useMainActorBackDeploy ? SGM.getDeinitOnExecutorMainActorBackDeploy()
|
||||||
|
: SGM.getDeinitOnExecutor();
|
||||||
if (!swiftDeinitOnExecutorDecl) {
|
if (!swiftDeinitOnExecutorDecl) {
|
||||||
dd->diagnose(diag::missing_deinit_on_executor_function);
|
dd->diagnose(diag::missing_deinit_on_executor_function);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -123,15 +123,17 @@ public:
|
|||||||
diagnoseAndRemoveAttr(attr, diag::isolated_deinit_on_value_type);
|
diagnoseAndRemoveAttr(attr, diag::isolated_deinit_on_value_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
TypeChecker::checkAvailability(
|
if (!getActorIsolation(nominal).isMainActor()) {
|
||||||
attr->getRange(), C.getIsolatedDeinitAvailability(),
|
TypeChecker::checkAvailability(
|
||||||
D->getDeclContext(),
|
attr->getRange(), C.getIsolatedDeinitAvailability(),
|
||||||
[&](AvailabilityDomain domain, AvailabilityRange range) {
|
D->getDeclContext(),
|
||||||
return diagnoseAndRemoveAttr(
|
[&](AvailabilityDomain domain, AvailabilityRange range) {
|
||||||
attr, diag::isolated_deinit_unavailable, domain, range);
|
return diagnoseAndRemoveAttr(
|
||||||
});
|
attr, diag::isolated_deinit_unavailable, domain, range);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS
|
|||||||
list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS "-strict-memory-safety")
|
list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS "-strict-memory-safety")
|
||||||
list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS "-enable-experimental-feature" "AllowUnsafeAttribute")
|
list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS "-enable-experimental-feature" "AllowUnsafeAttribute")
|
||||||
|
|
||||||
|
list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS "-enable-experimental-feature" "Extern")
|
||||||
|
|
||||||
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS
|
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS
|
||||||
"-D__STDC_WANT_LIB_EXT1__=1")
|
"-D__STDC_WANT_LIB_EXT1__=1")
|
||||||
|
|
||||||
|
|||||||
@@ -162,6 +162,39 @@ extension MainActor {
|
|||||||
try assumeIsolated(operation, file: file, line: line)
|
try assumeIsolated(operation, file: file, line: line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS)
|
||||||
|
@_extern(c, "pthread_main_np")
|
||||||
|
@usableFromInline
|
||||||
|
internal func pthread_main_np() -> CInt
|
||||||
|
|
||||||
|
@available(SwiftStdlib 5.1, *)
|
||||||
|
@_alwaysEmitIntoClient
|
||||||
|
@_silgen_name("swift_task_deinitOnExecutorMainActorBackDeploy")
|
||||||
|
public func _deinitOnExecutorMainActorBackDeploy(
|
||||||
|
_ object: __owned AnyObject,
|
||||||
|
_ work: @convention(thin) (__owned AnyObject) -> Void,
|
||||||
|
_ executor: Builtin.Executor,
|
||||||
|
_ flags: Builtin.Word) {
|
||||||
|
if #available(macOS 15.4, iOS 18.4, watchOS 11.4, tvOS 18.4, visionOS 2.4, *) {
|
||||||
|
// On new-enough platforms, use the runtime functionality, which allocates
|
||||||
|
// the task more efficiently.
|
||||||
|
_deinitOnExecutor(object, work, executor, flags)
|
||||||
|
} else if pthread_main_np() == 1 {
|
||||||
|
// Using "main thread" as a proxy for "main actor", immediately destroy
|
||||||
|
// the object.
|
||||||
|
work(consume object)
|
||||||
|
} else {
|
||||||
|
// Steal the local object so that the reference count stays at 1 even when
|
||||||
|
// the object is captured.
|
||||||
|
var stolenObject: AnyObject? = consume object
|
||||||
|
Task.detached { @MainActor in
|
||||||
|
work(stolenObject.take()!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
#endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
|
||||||
|
|
||||||
#endif // !$Embedded
|
#endif // !$Embedded
|
||||||
|
|||||||
15
test/Concurrency/deinit_isolation_backdeploy.swift
Normal file
15
test/Concurrency/deinit_isolation_backdeploy.swift
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck %s
|
||||||
|
|
||||||
|
// REQUIRES: concurrency
|
||||||
|
// REQUIRES: OS=macosx
|
||||||
|
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class C {
|
||||||
|
// CHECK-LABEL: sil hidden [ossa] @$s27deinit_isolation_backdeploy1CCfD : $@convention(method) (@owned C) -> ()
|
||||||
|
// CHECK: function_ref @swift_task_deinitOnExecutorMainActorBackDeploy
|
||||||
|
isolated deinit { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure this function is available
|
||||||
|
// CHECK: sil hidden_external [serialized] [available 12.0.0] @swift_task_deinitOnExecutorMainActorBackDeploy : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor, Builtin.Word) -> ()
|
||||||
@@ -13,11 +13,24 @@ class NotSendable {}
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@globalActor
|
||||||
|
actor SomeGlobalActor {
|
||||||
|
static let shared = SomeGlobalActor()
|
||||||
|
}
|
||||||
|
|
||||||
// expected-note@+1{{add '@available' attribute to enclosing class}}
|
// expected-note@+1{{add '@available' attribute to enclosing class}}
|
||||||
@MainActor class C2 {
|
@SomeGlobalActor class C2 {
|
||||||
var x: Int = 0
|
var x: Int = 0
|
||||||
|
|
||||||
isolated deinit { // expected-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
|
isolated deinit { // expected-error{{isolated deinit is only available in macOS 15.4.0 or newer}}
|
||||||
print(x)
|
print(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor class C3 {
|
||||||
|
var x: Int = 0
|
||||||
|
|
||||||
|
isolated deinit { // okay, this back-deploys
|
||||||
|
print(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -128,6 +128,8 @@ Func withThrowingTaskGroup(of:returning:body:) has parameter 2 type change from
|
|||||||
Func withTaskGroup(of:returning:body:) has been renamed to Func withTaskGroup(of:returning:isolation:body:)
|
Func withTaskGroup(of:returning:body:) has been renamed to Func withTaskGroup(of:returning:isolation:body:)
|
||||||
Func withTaskGroup(of:returning:body:) has mangled name changing from '_Concurrency.withTaskGroup<A, B where A: Swift.Sendable>(of: A.Type, returning: B.Type, body: (inout Swift.TaskGroup<A>) async -> B) async -> B' to '_Concurrency.withTaskGroup<A, B where A: Swift.Sendable>(of: A.Type, returning: B.Type, isolation: isolated Swift.Optional<Swift.Actor>, body: (inout Swift.TaskGroup<A>) async -> B) async -> B'
|
Func withTaskGroup(of:returning:body:) has mangled name changing from '_Concurrency.withTaskGroup<A, B where A: Swift.Sendable>(of: A.Type, returning: B.Type, body: (inout Swift.TaskGroup<A>) async -> B) async -> B' to '_Concurrency.withTaskGroup<A, B where A: Swift.Sendable>(of: A.Type, returning: B.Type, isolation: isolated Swift.Optional<Swift.Actor>, body: (inout Swift.TaskGroup<A>) async -> B) async -> B'
|
||||||
|
|
||||||
|
Func pthread_main_np() is a new API without '@available'
|
||||||
|
|
||||||
// *** DO NOT DISABLE OR XFAIL THIS TEST. *** (See comment above.)
|
// *** DO NOT DISABLE OR XFAIL THIS TEST. *** (See comment above.)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user