Skip to content

Commit dea3b59

Browse files
authored
Merge pull request #76250 from ktoso/wip-experimental-isolated-deinit
2 parents 762e789 + 45b97f1 commit dea3b59

File tree

88 files changed

+4180
-512
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+4180
-512
lines changed

docs/ABI/Mangling.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ Entities
365365
entity-spec ::= 'fP' // property wrapper backing initializer
366366
entity-spec ::= 'fW' // property wrapper init from projected value
367367
entity-spec ::= 'fD' // deallocating destructor; untyped
368+
entity-spec ::= 'fZ' // isolated deallocating destructor; untyped
368369
entity-spec ::= 'fd' // non-deallocating destructor; untyped
369370
entity-spec ::= 'fE' // ivar destroyer; untyped
370371
entity-spec ::= 'fe' // ivar initializer; untyped

include/swift/ABI/Executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ using ThrowingTaskFutureWaitContinuationFunction =
295295
SWIFT_CC(swiftasync)
296296
void (SWIFT_ASYNC_CONTEXT AsyncContext *, SWIFT_CONTEXT void *);
297297

298+
using DeinitWorkFunction = SWIFT_CC(swift) void(void *);
298299

299300
template <class AsyncSignature>
300301
class AsyncFunctionPointer;

include/swift/ABI/MetadataValues.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2584,7 +2584,8 @@ enum class JobKind : size_t {
25842584
DefaultActorInline = First_Reserved,
25852585
DefaultActorSeparate,
25862586
DefaultActorOverride,
2587-
NullaryContinuation
2587+
NullaryContinuation,
2588+
IsolatedDeinit,
25882589
};
25892590

25902591
/// The priority of a job. Higher priorities are larger values.

include/swift/AST/ASTMangler.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ class RootProtocolConformance;
3434

3535
namespace Mangle {
3636

37+
enum class DestructorKind {
38+
NonDeallocating,
39+
Deallocating,
40+
IsolatedDeallocating
41+
};
42+
3743
/// The mangler for AST declarations.
3844
class ASTMangler : public Mangler {
3945
protected:
@@ -202,7 +208,7 @@ class ASTMangler : public Mangler {
202208
SymbolKind SKind = SymbolKind::Default);
203209

204210
std::string mangleDestructorEntity(const DestructorDecl *decl,
205-
bool isDeallocating,
211+
DestructorKind kind,
206212
SymbolKind SKind = SymbolKind::Default);
207213

208214
std::string mangleConstructorEntity(const ConstructorDecl *ctor,
@@ -697,8 +703,8 @@ class ASTMangler : public Mangler {
697703
bool tryAppendStandardSubstitution(const GenericTypeDecl *type);
698704

699705
void appendConstructorEntity(const ConstructorDecl *ctor, bool isAllocating);
700-
701-
void appendDestructorEntity(const DestructorDecl *decl, bool isDeallocating);
706+
707+
void appendDestructorEntity(const DestructorDecl *decl, DestructorKind kind);
702708

703709
/// \param accessorKindCode The code to describe the accessor and addressor
704710
/// kind. Usually retrieved using getCodeForAccessorKind.

include/swift/AST/Decl.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
13691369
std::optional<std::pair<CustomAttr *, NominalTypeDecl *>>
13701370
getGlobalActorAttr() const;
13711371

1372+
/// Determine whether there is an explicit isolation attribute
1373+
/// of any kind.
1374+
bool hasExplicitIsolationAttribute() const;
1375+
13721376
/// If an alternative module name is specified for this decl, e.g. using
13731377
/// @_originalDefinedIn attribute, this function returns this module name.
13741378
StringRef getAlternateModuleName() const;
@@ -3053,6 +3057,10 @@ class ValueDecl : public Decl {
30533057
/// Retrieve the declaration that this declaration overrides, if any.
30543058
ValueDecl *getOverriddenDecl() const;
30553059

3060+
/// Retrieve the declaration that this declaration overrides, including super
3061+
/// deinit.
3062+
ValueDecl *getOverriddenDeclOrSuperDeinit() const;
3063+
30563064
/// Retrieve the declarations that this declaration overrides, if any.
30573065
llvm::TinyPtrVector<ValueDecl *> getOverriddenDecls() const;
30583066

@@ -8854,6 +8862,10 @@ class DestructorDecl : public AbstractFunctionDecl {
88548862
/// Retrieve the Objective-C selector for destructors.
88558863
ObjCSelector getObjCSelector() const;
88568864

8865+
/// Retrieves destructor decl from the superclass, or nil if there is no
8866+
/// superclass
8867+
DestructorDecl *getSuperDeinit() const;
8868+
88578869
static bool classof(const Decl *D) {
88588870
return D->getKind() == DeclKind::Destructor;
88598871
}

include/swift/AST/DeclAttr.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,14 +434,17 @@ SIMPLE_DECL_ATTR(rethrows, Rethrows,
434434
CONTEXTUAL_SIMPLE_DECL_ATTR(indirect, Indirect,
435435
DeclModifier | OnEnum | OnEnumElement | ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove,
436436
60)
437+
CONTEXTUAL_SIMPLE_DECL_ATTR(isolated, Isolated,
438+
DeclModifier | OnDestructor | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
439+
103)
437440
CONTEXTUAL_SIMPLE_DECL_ATTR(async, Async,
438441
DeclModifier | OnVar | OnFunc | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
439442
106)
440443
SIMPLE_DECL_ATTR(reasync, Reasync,
441444
OnFunc | OnConstructor | RejectByParser | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
442445
109)
443446
CONTEXTUAL_DECL_ATTR(nonisolated, Nonisolated,
444-
DeclModifier | OnFunc | OnConstructor | OnVar | OnSubscript | OnProtocol | OnExtension | OnClass | OnStruct | OnEnum | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove,
447+
DeclModifier | OnFunc | OnConstructor | OnDestructor | OnVar | OnSubscript | OnProtocol | OnExtension | OnClass | OnStruct | OnEnum | ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove,
445448
112)
446449
CONTEXTUAL_SIMPLE_DECL_ATTR(distributed, DistributedActor,
447450
DeclModifier | OnClass | OnFunc | OnAccessor | OnVar | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,

include/swift/AST/DiagnosticsSema.def

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5916,9 +5916,12 @@ ERROR(global_actor_not_usable_from_inline,none,
59165916
NOTE(move_global_actor_attr_to_storage_decl,none,
59175917
"move global actor attribute to %kind0", (const ValueDecl *))
59185918

5919-
ERROR(actor_isolation_multiple_attr,none,
5919+
ERROR(actor_isolation_multiple_attr_2,none,
59205920
"%kind0 has multiple actor-isolation attributes ('%1' and '%2')",
59215921
(const Decl *, StringRef, StringRef))
5922+
ERROR(actor_isolation_multiple_attr_3,none,
5923+
"%0 %1 has multiple actor-isolation attributes ('%2', '%3' and '%4')",
5924+
(const Decl *, StringRef, StringRef, StringRef))
59225925
ERROR(actor_isolation_override_mismatch,none,
59235926
"%0 %kind1 has different actor isolation from %2 overridden declaration",
59245927
(ActorIsolation, const ValueDecl *, ActorIsolation))
@@ -5936,6 +5939,16 @@ ERROR(async_unavailable_decl,none,
59365939
"%kindbase0 is unavailable from asynchronous contexts%select{|; %1}1",
59375940
(const ValueDecl *, StringRef))
59385941

5942+
ERROR(isolated_deinit_no_isolation,none,
5943+
"deinit is marked isolated, but containing class %0 is not isolated to an actor",
5944+
(DeclName))
5945+
ERROR(isolated_deinit_on_value_type,none,
5946+
"only classes and actors can have isolated deinit",
5947+
())
5948+
ERROR(isolated_deinit_experimental,none,
5949+
"'isolated' deinit requires frontend flag -enable-experimental-feature IsolatedDeinit "
5950+
"to enable the usage of this language feature", ())
5951+
59395952
//------------------------------------------------------------------------------
59405953
// MARK: String Processing
59415954
//------------------------------------------------------------------------------

include/swift/AST/PrintOptions.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class DeclContext;
3737
class Type;
3838
class ModuleDecl;
3939
enum class DeclAttrKind : unsigned;
40+
class DeclAttribute;
41+
class CustomAttr;
4042
class SynthesizedExtensionAnalyzer;
4143
struct PrintOptions;
4244
class SILPrintContext;
@@ -342,6 +344,10 @@ struct PrintOptions {
342344
/// Suppress emitting @available(*, noasync)
343345
bool SuppressNoAsyncAvailabilityAttr = false;
344346

347+
/// Suppress emitting isolated or async deinit, and emit open containing class
348+
/// as public
349+
bool SuppressIsolatedDeinit = false;
350+
345351
/// Whether to print the \c{/*not inherited*/} comment on factory initializers.
346352
bool PrintFactoryInitializerComment = true;
347353

@@ -399,6 +405,8 @@ struct PrintOptions {
399405
DeclAttrKind::FixedLayout, DeclAttrKind::ShowInInterface,
400406
};
401407

408+
std::vector<CustomAttr *> ExcludeCustomAttrList = {};
409+
402410
/// List of attribute kinds that should be printed exclusively.
403411
/// Empty means allow all.
404412
std::vector<AnyAttrKind> ExclusiveAttrList;
@@ -630,6 +638,8 @@ struct PrintOptions {
630638
return false;
631639
}
632640

641+
bool excludeAttr(const DeclAttribute *DA) const;
642+
633643
/// Retrieve the set of options for verbose printing to users.
634644
static PrintOptions printVerbose() {
635645
PrintOptions result;
@@ -684,7 +694,8 @@ struct PrintOptions {
684694
result.SkipPrivateSystemDecls = true;
685695
result.SkipUnderscoredSystemProtocols = true;
686696
result.SkipUnsafeCXXMethods = true;
687-
result.SkipDeinit = true;
697+
result.SkipDeinit = false; // Deinit may have isolation attributes, which
698+
// are part of the interface
688699
result.EmptyLineBetweenDecls = true;
689700
result.CascadeDocComment = true;
690701
result.ShouldQualifyNestedDeclarations =

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,9 @@ EXPERIMENTAL_FEATURE(WarnUnsafe, true)
411411
/// Import unsafe C and C++ constructs as @unsafe.
412412
EXPERIMENTAL_FEATURE(SafeInterop, true)
413413

414+
// isolated deinit
415+
EXPERIMENTAL_FEATURE(IsolatedDeinit, true)
416+
414417
// Enable values in generic signatures, e.g. <let N: Int>
415418
EXPERIMENTAL_FEATURE(ValueGenerics, true)
416419

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ NODE(InfixOperator)
153153
CONTEXT_NODE(Initializer)
154154
CONTEXT_NODE(InitAccessor)
155155
NODE(Isolated)
156+
CONTEXT_NODE(IsolatedDeallocator)
156157
NODE(Sending)
157158
NODE(IsolatedAnyFunctionType)
158159
NODE(SendingResultFunctionType)

include/swift/Runtime/Concurrency.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,11 @@ swift_task_createNullaryContinuationJob(
605605
size_t priority,
606606
AsyncTask *continuation);
607607

608+
SWIFT_EXPORT_FROM(swift_Concurrency)
609+
SWIFT_CC(swift)
610+
void swift_task_deinitOnExecutor(void *object, DeinitWorkFunction *work,
611+
SerialExecutorRef newExecutor, size_t flags);
612+
608613
/// Report error about attempting to bind a task-local value from an illegal context.
609614
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
610615
void swift_task_reportIllegalTaskLocalBindingWithinWithTaskGroup(

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2278,7 +2278,7 @@ FUNCTION(GetTypeByMangledNameInContextInMetadataState2,
22782278
EFFECT(MetaData),
22792279
MEMEFFECTS(ArgMemOnly))
22802280

2281-
// AsyncTask *swift_task_getCurrent();s
2281+
// AsyncTask *swift_task_getCurrent();
22822282
FUNCTION(GetCurrentTask,
22832283
swift_task_getCurrent, SwiftCC,
22842284
ConcurrencyAvailability,
@@ -2347,6 +2347,20 @@ FUNCTION(TaskSwitchFunc,
23472347
ATTRS(NoUnwind),
23482348
EFFECT(Concurrency),
23492349
UNKNOWN_MEMEFFECTS)
2350+
2351+
// void swift_task_deinitOnExecutor(void *object,
2352+
// DeinitWorkFunction *work,
2353+
// SerialExecutorRef newExecutor,
2354+
// size_t flags);
2355+
FUNCTION(DeinitOnExecutorFunc,
2356+
swift_task_deinitOnExecutor, SwiftCC,
2357+
ConcurrencyAvailability,
2358+
RETURNS(VoidTy),
2359+
ARGS(Int8PtrTy, Int8PtrTy, ExecutorFirstTy, ExecutorSecondTy, SizeTy),
2360+
ATTRS(NoUnwind),
2361+
EFFECT(Concurrency),
2362+
UNKNOWN_MEMEFFECTS)
2363+
23502364

23512365
// AsyncTask *swift_continuation_init(AsyncContext *continuationContext,
23522366
// AsyncContinuationFlags);

include/swift/SIL/SILDeclRef.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,23 @@ struct SILDeclRef {
111111
/// Initializer - this constant references the initializing constructor
112112
/// entry point of the class ConstructorDecl in loc.
113113
Initializer,
114-
114+
115115
/// EnumElement - this constant references the injection function for
116116
/// an EnumElementDecl.
117117
EnumElement,
118-
118+
119119
/// Destroyer - this constant references the destroying destructor for the
120120
/// DestructorDecl in loc.
121121
Destroyer,
122122

123123
/// Deallocator - this constant references the deallocating
124124
/// destructor for the DestructorDecl in loc.
125125
Deallocator,
126-
126+
127+
/// Deallocator - this constant references the isolated deallocating
128+
/// destructor for the DestructorDecl in loc.
129+
IsolatedDeallocator,
130+
127131
/// GlobalAccessor - this constant references the lazy-initializing
128132
/// accessor for the global VarDecl in loc.
129133
GlobalAccessor,
@@ -339,7 +343,8 @@ struct SILDeclRef {
339343
}
340344
/// True if the SILDeclRef references a destructor entry point.
341345
bool isDestructor() const {
342-
return kind == Kind::Destroyer || kind == Kind::Deallocator;
346+
return kind == Kind::Destroyer || kind == Kind::Deallocator ||
347+
kind == Kind::IsolatedDeallocator;
343348
}
344349
/// True if the SILDeclRef references an enum entry point.
345350
bool isEnumElement() const {

include/swift/SIL/SILModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,9 @@ namespace Lowering {
11201120
/// Determine whether the given class will be allocated/deallocated using the
11211121
/// Objective-C runtime, i.e., +alloc and -dealloc.
11221122
LLVM_LIBRARY_VISIBILITY bool usesObjCAllocator(ClassDecl *theClass);
1123+
/// Determine if isolating destructor is needed.
1124+
LLVM_LIBRARY_VISIBILITY bool needsIsolatingDestructor(DestructorDecl *dd);
1125+
11231126
} // namespace Lowering
11241127
} // namespace swift
11251128

lib/AST/ASTMangler.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ std::string ASTMangler::mangleEntity(const ValueDecl *decl, SymbolKind SKind) {
133133
}
134134

135135
std::string ASTMangler::mangleDestructorEntity(const DestructorDecl *decl,
136-
bool isDeallocating,
136+
DestructorKind kind,
137137
SymbolKind SKind) {
138138
llvm::SaveAndRestore X(AllowInverses, inversesAllowed(decl));
139139
beginMangling();
140-
appendDestructorEntity(decl, isDeallocating);
140+
appendDestructorEntity(decl, kind);
141141
appendSymbolKind(SKind);
142142
return finalize();
143143
}
@@ -834,7 +834,7 @@ void ASTMangler::appendAnyDecl(const ValueDecl *Decl) {
834834
if (auto Ctor = dyn_cast<ConstructorDecl>(Decl)) {
835835
appendConstructorEntity(Ctor, /*isAllocating=*/false);
836836
} else if (auto Dtor = dyn_cast<DestructorDecl>(Decl)) {
837-
appendDestructorEntity(Dtor, /*isDeallocating=*/false);
837+
appendDestructorEntity(Dtor, DestructorKind::NonDeallocating);
838838
} else if (auto GTD = dyn_cast<GenericTypeDecl>(Decl)) {
839839
appendAnyGenericType(GTD);
840840
} else if (isa<AssociatedTypeDecl>(Decl)) {
@@ -936,7 +936,7 @@ std::string ASTMangler::mangleHasSymbolQuery(const ValueDecl *Decl) {
936936
if (auto Ctor = dyn_cast<ConstructorDecl>(Decl)) {
937937
appendConstructorEntity(Ctor, /*isAllocating=*/false);
938938
} else if (auto Dtor = dyn_cast<DestructorDecl>(Decl)) {
939-
appendDestructorEntity(Dtor, /*isDeallocating=*/false);
939+
appendDestructorEntity(Dtor, DestructorKind::NonDeallocating);
940940
} else if (auto GTD = dyn_cast<GenericTypeDecl>(Decl)) {
941941
appendAnyGenericType(GTD);
942942
} else if (isa<AssociatedTypeDecl>(Decl)) {
@@ -2457,8 +2457,8 @@ void ASTMangler::appendContext(const DeclContext *ctx,
24572457
}
24582458

24592459
if (auto dtor = dyn_cast<DestructorDecl>(fn))
2460-
return appendDestructorEntity(dtor, /*deallocating*/ false);
2461-
2460+
return appendDestructorEntity(dtor, DestructorKind::NonDeallocating);
2461+
24622462
return appendEntity(fn);
24632463
}
24642464

@@ -3940,10 +3940,20 @@ void ASTMangler::appendConstructorEntity(const ConstructorDecl *ctor,
39403940
}
39413941

39423942
void ASTMangler::appendDestructorEntity(const DestructorDecl *dtor,
3943-
bool isDeallocating) {
3943+
DestructorKind kind) {
39443944
BaseEntitySignature base(dtor);
39453945
appendContextOf(dtor, base);
3946-
appendOperator(isDeallocating ? "fD" : "fd");
3946+
switch (kind) {
3947+
case DestructorKind::NonDeallocating:
3948+
appendOperator("fd");
3949+
break;
3950+
case DestructorKind::Deallocating:
3951+
appendOperator("fD");
3952+
break;
3953+
case DestructorKind::IsolatedDeallocating:
3954+
appendOperator("fZ");
3955+
break;
3956+
}
39473957
}
39483958

39493959
void ASTMangler::appendAccessorEntity(StringRef accessorKindCode,

0 commit comments

Comments
 (0)