@@ -76,7 +76,9 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
76
76
resultSelfValue = selfValue;
77
77
}
78
78
79
-
79
+ // / A distributed actor resigns its identity as it is deallocated.
80
+ // / This way the transport knows it must not deliver any more messages to it,
81
+ // / and can remove it from its (weak) lookup tables.
80
82
if (cd->isDistributedActor ()) {
81
83
SILBasicBlock *continueBB = createBasicBlock ();
82
84
injectDistributedActorDestructorLifecycleCall (dd, selfValue, continueBB);
@@ -109,113 +111,6 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
109
111
B.createReturn (returnLoc, resultSelfValue);
110
112
}
111
113
112
- void SILGenFunction::injectDistributedActorDestructorLifecycleCall (
113
- DestructorDecl *dd, SILValue selfValue, SILBasicBlock *continueBB) {
114
- ASTContext &ctx = getASTContext ();
115
-
116
- auto cd = cast<ClassDecl>(dd->getDeclContext ());
117
- assert (cd->isDistributedActor () &&
118
- " only distributed actors have transport lifecycle hooks in deinit" );
119
-
120
- RegularLocation Loc (dd);
121
- if (dd->isImplicit ())
122
- Loc.markAutoGenerated ();
123
-
124
- auto selfDecl = dd->getImplicitSelfDecl ();
125
- auto selfManagedValue = ManagedValue::forUnmanaged (selfValue);
126
- auto selfType = selfDecl->getType ();
127
-
128
- // ==== locate: self.id
129
- auto idVarDeclRefs = cd->lookupDirect (ctx.Id_id );
130
- assert (idVarDeclRefs.size () == 1 );
131
- auto *idVarDeclRef = dyn_cast<VarDecl>(idVarDeclRefs.front ());
132
- assert (idVarDeclRef);
133
- auto idRef =
134
- B.createRefElementAddr (Loc, selfValue, idVarDeclRef,
135
- getLoweredType (idVarDeclRef->getType ()));
136
-
137
- // ==== locate: self.actorTransport
138
- auto transportVarDeclRefs = cd->lookupDirect (ctx.Id_actorTransport );
139
- assert (transportVarDeclRefs.size () == 1 );
140
- auto *transportVarDeclRef = dyn_cast<VarDecl>(transportVarDeclRefs.front ());
141
- auto transportRef =
142
- B.createRefElementAddr (Loc, selfValue, transportVarDeclRef,
143
- getLoweredType (transportVarDeclRef->getType ()));
144
-
145
- // locate: self.transport.resignIdentity(...)
146
- auto *transportDecl = ctx.getActorTransportDecl ();
147
- auto resignFnDecls = transportDecl->lookupDirect (ctx.Id_resignIdentity );
148
- assert (resignFnDecls.size () == 1 );
149
- auto *resignFnDecl = resignFnDecls.front ();
150
- auto resignFnRef = SILDeclRef (resignFnDecl);
151
-
152
- // we only transport.resignIdentity if we are a local actor,
153
- // and thus the address was created by transport.assignIdentity.
154
- auto isRemoteBB = createBasicBlock ();
155
- auto isLocalBB = createBasicBlock ();
156
-
157
- // if __isRemoteActor(self) {
158
- // ...
159
- // } else {
160
- // ...
161
- // }
162
- {
163
- FuncDecl *isRemoteFn = ctx.getIsRemoteDistributedActor ();
164
- assert (isRemoteFn && " Could not find 'is remote' function, is the "
165
- " '_Distributed' module available?" );
166
-
167
- ManagedValue selfAnyObject =
168
- B.createInitExistentialRef (Loc, getLoweredType (ctx.getAnyObjectType ()),
169
- CanType (selfType), selfManagedValue, {});
170
- auto result = emitApplyOfLibraryIntrinsic (
171
- Loc, isRemoteFn, SubstitutionMap (), {selfAnyObject}, SGFContext ());
172
-
173
- SILValue isRemoteResult =
174
- std::move (result).forwardAsSingleValue (*this , Loc);
175
- SILValue isRemoteResultUnwrapped =
176
- emitUnwrapIntegerResult (Loc, isRemoteResult);
177
-
178
- B.createCondBranch (Loc, isRemoteResultUnwrapped, isRemoteBB, isLocalBB);
179
- }
180
-
181
- // if remote
182
- // === <noop>
183
- {
184
- B.emitBlock (isRemoteBB);
185
- // noop, remote actors don't do anything in their deinit
186
- B.createBranch (Loc, continueBB);
187
- }
188
-
189
- // if local
190
- // === self.transport.resignIdentity(self.address)
191
- {
192
- B.emitBlock (isLocalBB);
193
-
194
- auto openedTransport =
195
- OpenedArchetypeType::get (transportVarDeclRef->getType ());
196
- auto transportAddr = B.createOpenExistentialAddr (
197
- Loc, /* operand=*/ transportRef, getLoweredType (openedTransport),
198
- OpenedExistentialAccess::Immutable);
199
-
200
- auto resignFnType = SGM.M .Types .getConstantFunctionType (
201
- TypeExpansionContext::minimal (), resignFnRef);
202
-
203
- auto witness = B.createWitnessMethod (
204
- Loc, openedTransport, ProtocolConformanceRef (transportDecl),
205
- resignFnRef, SILType::getPrimitiveObjectType (resignFnType));
206
-
207
- auto subs = SubstitutionMap::getProtocolSubstitutions (
208
- transportDecl, openedTransport, ProtocolConformanceRef (transportDecl));
209
-
210
- SmallVector<SILValue, 2 > params;
211
- params.push_back (idRef);
212
- params.push_back (transportAddr); // self for the call, as last param
213
-
214
- B.createApply (Loc, witness, subs, params);
215
- B.createBranch (Loc, continueBB);
216
- }
217
- }
218
-
219
114
void SILGenFunction::emitDeallocatingDestructor (DestructorDecl *dd) {
220
115
MagicFunctionName = DeclName (SGM.M .getASTContext ().getIdentifier (" deinit" ));
221
116
0 commit comments