Skip to content

Commit 8e3201c

Browse files
Expanded test for SIL for distributed actor deinit, added isolated cases
1 parent 336c64f commit 8e3201c

File tree

1 file changed

+226
-7
lines changed

1 file changed

+226
-7
lines changed

test/Distributed/SIL/distributed_actor_default_deinit_sil.swift

Lines changed: 226 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@
44
// REQUIRES: concurrency
55
// REQUIRES: distributed
66

7+
// This test checks that we resign the identity for local deallocations,
8+
// destroy only the correct stored properties whether remote or local, and also
9+
// destroy the executor. It checks that remote actor proxies are not isolated.
10+
// Additionally, we add basic coverage for a non-distributed actor's deinit.
11+
712
import Distributed
813
import FakeDistributedActorSystems
914

1015
typealias DefaultDistributedActorSystem = FakeActorSystem
1116

1217
final class SomeClass: Sendable {}
1318

19+
@inline(never)
20+
private nonisolated func doIt() {}
21+
22+
// MARK: - Distributed actor with nonisolated deinit
23+
1424
distributed actor MyDistActor {
1525
let localOnlyField: SomeClass
1626

@@ -20,7 +30,7 @@ distributed actor MyDistActor {
2030
}
2131
}
2232

23-
// MARK: distributed actor check
33+
// MARK: Destroying deinit
2434

2535
// CHECK-LABEL: // MyDistActor.deinit
2636
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject {
@@ -59,6 +69,14 @@ distributed actor MyDistActor {
5969

6070
// CHECK: } // end sil function '$s14default_deinit11MyDistActorCfd'
6171

72+
// MARK: Isolated deallocating deinit
73+
74+
// ===== -----------------------------------------------------------------------
75+
// CHECK-NOT: MyDistActor.__isolated_deallocating_deinit
76+
// CHECK-NOT: @$s14default_deinit11MyDistActorCfZ
77+
78+
// MARK: Deallocating deinit
79+
6280
// ===== -----------------------------------------------------------------------
6381
// CHECK-LABEL: MyDistActor.__deallocating_deinit
6482
// CHECK-NEXT: sil hidden @$s14default_deinit11MyDistActorCfD : $@convention(method) (@owned MyDistActor) -> () {
@@ -113,12 +131,133 @@ distributed actor MyDistActor {
113131

114132
// ===== -----------------------------------------------------------------------
115133

134+
// MARK: - Distributed actor with isolated deinit
116135

117-
// This test checks that we resign the identity for local deallocations,
118-
// destroy only the correct stored properties whether remote or local, and also
119-
// destroy the executor.
136+
distributed actor MyDistActorIsolated {
137+
let localOnlyField: SomeClass
138+
139+
init(system: FakeActorSystem) {
140+
self.actorSystem = system
141+
self.localOnlyField = SomeClass()
142+
}
143+
144+
deinit {
145+
doIt()
146+
}
147+
}
148+
149+
// MARK: Destroying deinit
150+
151+
// CHECK-LABEL: // MyDistActorIsolated.deinit
152+
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19MyDistActorIsolatedCfd : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject {
153+
// CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated):
154+
155+
// Resign the ID by calling actorSystem.resignID, before we destroy properties:
156+
// CHECK: [[ID_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id
157+
// CHECK: [[SYS_REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem
158+
// CHECK: [[ID_LOAD:%[0-9]+]] = load [[ID_REF]] : $*ActorAddress
159+
// CHECK: [[SYS_LOAD:%[0-9]+]] = load [[SYS_REF]] : $*FakeActorSystem
160+
// CHECK: [[FN_REF:%[0-9]+]] = function_ref @$s27FakeDistributedActorSystems0aC6SystemV8resignIDyyAA0C7AddressVF : $@convention(method) (@guaranteed ActorAddress, @guaranteed FakeActorSystem) -> ()
161+
// CHECK: [[DROP:%[0-9]+]] = apply [[FN_REF]]([[ID_LOAD]], [[SYS_LOAD]]) : $@convention(method) (@guaranteed ActorAddress, @guaranteed FakeActorSystem) -> ()
162+
// CHECK: [[DROP:%[0-9]+]] = tuple ()
163+
164+
// Destroy implicit Distributed Actor field: id
165+
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id
166+
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*ActorAddress
167+
// CHECK: destroy_addr [[ACCESS]] : $*ActorAddress
168+
// CHECK: end_access [[ACCESS]] : $*ActorAddress
169+
170+
// Destroy implicit Distributed Actor field: actorSystem
171+
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem
172+
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*FakeActorSystem
173+
// CHECK: destroy_addr [[ACCESS]] : $*FakeActorSystem
174+
// CHECK: end_access [[ACCESS]] : $*FakeActorSystem
175+
176+
// Destroy local fields:
177+
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.localOnlyField
178+
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*SomeClass
179+
// CHECK: destroy_addr [[ACCESS]] : $*SomeClass
180+
// CHECK: end_access [[ACCESS]] : $*SomeClass
181+
182+
// CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActorIsolated) : $()
183+
// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]] : $MyDistActorIsolated to $Builtin.NativeObject
184+
// CHECK: return [[CAST]] : $Builtin.NativeObject
185+
186+
// CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfd'
187+
188+
// MARK: Isolated deallocating deinit
189+
190+
// ===== -----------------------------------------------------------------------
191+
// CHECK-LABEL: MyDistActorIsolated.__isolated_deallocating_deinit
192+
// CHECK-NEXT: sil hidden @$s14default_deinit19MyDistActorIsolatedCfZ : $@convention(thin) (@owned MyDistActorIsolated) -> () {
193+
// CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated):
194+
// CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit19MyDistActorIsolatedCfd : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject
195+
// CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed MyDistActorIsolated) -> @owned Builtin.NativeObject
196+
// CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $MyDistActorIsolated
197+
// CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $MyDistActorIsolated
198+
// CHECK: [[RESULT:%[0-9]+]] = tuple ()
199+
// CHECK: return [[RESULT]] : $()
200+
// CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfZ'
201+
202+
// MARK: Deallocating deinit
203+
204+
// ===== -----------------------------------------------------------------------
205+
// CHECK-LABEL: MyDistActorIsolated.__deallocating_deinit
206+
// CHECK-NEXT: sil hidden @$s14default_deinit19MyDistActorIsolatedCfD : $@convention(method) (@owned MyDistActorIsolated) -> () {
207+
// CHECK: bb0([[SELF:%[0-9]+]] : $MyDistActorIsolated):
208+
// CHECK: [[EXI_SELF:%[0-9]+]] = init_existential_ref [[SELF]] : $MyDistActorIsolated : $MyDistActorIsolated, $AnyObject
209+
// CHECK: [[IS_REMOTE_FN:%[0-9]+]] = function_ref @swift_distributed_actor_is_remote : $@convention(thin) (@guaranteed AnyObject) -> Bool
210+
// CHECK: [[IS_REMOTE:%[0-9]+]] = apply [[IS_REMOTE_FN]]([[EXI_SELF]])
211+
// CHECK: [[RAW_BOOL:%[0-9]+]] = struct_extract [[IS_REMOTE]] : $Bool, #Bool._value
212+
// CHECK: cond_br [[RAW_BOOL]], [[REMOTE_ACTOR_DEINIT_BB:bb[0-9]+]], [[LOCAL_ACTOR_DEINIT_BB:bb[0-9]+]]
213+
214+
// ===== -----------------------------------------------------------------------
215+
// CHECK: // localActorDeinitBB
216+
// CHECK: [[LOCAL_ACTOR_DEINIT_BB]]:
217+
// CHECK: [[ISOLATED_REF:%[0-9]+]] = function_ref @$s14default_deinit19MyDistActorIsolatedCfZ : $@convention(thin) (@owned MyDistActorIsolated) -> ()
218+
// CHECK: [[EXECUTOR:%[0-9]+]] = extract_executor [[SELF]] : $MyDistActorIsolated
219+
// CHECK: [[PERFORM_REF:%[0-9]+]] = function_ref @swift_task_performOnExecutor : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
220+
// CHECK: [[SELF_AS_ANY_OBJECT:%[0-9]+]] = unchecked_bitwise_cast [[SELF]] : $MyDistActorIsolated to $AnyObject
221+
// CHECK: [[ISOLATED_CASTED:%[0-9]+]] = convert_function [[ISOLATED_REF]] : $@convention(thin) (@owned MyDistActorIsolated) -> () to $@convention(thin) (@owned AnyObject) -> ()
222+
// CHECK: [[DROP:%[0-9]+]] = apply [[PERFORM_REF]]([[SELF_AS_ANY_OBJECT]], [[ISOLATED_CASTED]], [[EXECUTOR]]) : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
223+
// CHECK: br [[FINISH_DEINIT_BB:bb[0-9]+]]
224+
225+
// ===== -----------------------------------------------------------------------
226+
// CHECK: // finishDeinitBB
227+
// CHECK: [[FINISH_DEINIT_BB]]:
228+
// CHECK: [[RESULT:%[0-9]+]] = tuple ()
229+
// CHECK: return [[RESULT]] : $()
120230

121-
// MARK: local actor check
231+
// ===== -----------------------------------------------------------------------
232+
// CHECK: // remoteActorDeinitBB
233+
// CHECK: [[REMOTE_ACTOR_DEINIT_BB]]:
234+
235+
// Even just the remote deinit branch must destroy the ID
236+
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.id
237+
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*ActorAddress
238+
// CHECK: destroy_addr [[ACCESS]] : $*ActorAddress
239+
// CHECK: end_access [[ACCESS]] : $*ActorAddress
240+
241+
// As well as the actor system:
242+
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $MyDistActorIsolated, #MyDistActorIsolated.actorSystem
243+
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]] : $*FakeActorSystem
244+
// CHECK: destroy_addr [[ACCESS]] : $*FakeActorSystem
245+
// CHECK: end_access [[ACCESS]] : $*FakeActorSystem
246+
247+
// Destroy default actor implementation
248+
// CHECK: [[BUILTIN:%[0-9]+]] = builtin "destroyDefaultActor"([[SELF]] : $MyDistActorIsolated) : $()
249+
250+
// And deallocate the proxy
251+
// CHECK: dealloc_ref [[SELF]] : $MyDistActorIsolated
252+
253+
// Return
254+
// CHECK: br [[FINISH_DEINIT_BB]]
255+
256+
// CHECK: } // end sil function '$s14default_deinit19MyDistActorIsolatedCfD'
257+
258+
// ===== -----------------------------------------------------------------------
259+
260+
// MARK: - Local actor with nonisolated deinit
122261

123262
@available(macOS 12, *)
124263
actor SimpleActor {
@@ -128,9 +267,11 @@ actor SimpleActor {
128267
}
129268
}
130269

131-
// additionally, we add basic coverage for a non-distributed actor's deinit
270+
// MARK: Destroying deinit
132271

133-
// CHECK-LABEL: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject {
272+
// ===== -----------------------------------------------------------------------
273+
// CHECK-LABEL: // SimpleActor.deinit
274+
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject {
134275
// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActor):
135276
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SimpleActor, #SimpleActor.someField
136277
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]]
@@ -140,3 +281,81 @@ actor SimpleActor {
140281
// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]]
141282
// CHECK: return [[CAST]] : $Builtin.NativeObject
142283
// CHECK: } // end sil function '$s14default_deinit11SimpleActorCfd'
284+
285+
// MARK: Isolated deallocating deinit
286+
287+
// ===== -----------------------------------------------------------------------
288+
// CHECK-NOT: SimpleActor.__isolated_deallocating_deinit
289+
// CHECK-NOT: @$s14default_deinit11SimpleActorCfZ
290+
291+
// MARK: Deallocating deinit
292+
293+
// ===== -----------------------------------------------------------------------
294+
// CHECK-LABEL: // SimpleActor.__deallocating_deinit
295+
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11SimpleActorCfD : $@convention(method) (@owned SimpleActor) -> () {
296+
// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActor):
297+
// CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit11SimpleActorCfd : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject
298+
// CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed SimpleActor) -> @owned Builtin.NativeObject
299+
// CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $SimpleActor
300+
// CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $SimpleActor
301+
// CHECK: [[RESULT:%[0-9]+]] = tuple ()
302+
// CHECK: return [[RESULT]] : $()
303+
// CHECK: } // end sil function '$s14default_deinit11SimpleActorCfD'
304+
305+
// MARK: - Local actor with nonisolated deinit
306+
307+
@available(macOS 12, *)
308+
actor SimpleActorIsolated {
309+
let someField: SomeClass
310+
init() {
311+
self.someField = SomeClass()
312+
}
313+
deinit {
314+
doIt()
315+
}
316+
}
317+
318+
// MARK: Destroying deinit
319+
320+
// ===== -----------------------------------------------------------------------
321+
// CHECK-LABEL: // SimpleActorIsolated.deinit
322+
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfd : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject {
323+
// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated):
324+
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $SimpleActorIsolated, #SimpleActorIsolated.someField
325+
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [deinit] [static] [[REF]]
326+
// CHECK: destroy_addr [[ACCESS]] : $*SomeClass
327+
// CHECK: end_access [[ACCESS]]
328+
// CHECK: builtin "destroyDefaultActor"([[SELF]] : $SimpleActorIsolated)
329+
// CHECK: [[CAST:%[0-9]+]] = unchecked_ref_cast [[SELF]]
330+
// CHECK: return [[CAST]] : $Builtin.NativeObject
331+
// CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfd'
332+
333+
// MARK: Isolated deallocating deinit
334+
335+
// ===== -----------------------------------------------------------------------
336+
// CHECK-LABEL: // SimpleActorIsolated.__isolated_deallocating_deinit
337+
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfZ : $@convention(thin) (@owned SimpleActorIsolated) -> () {
338+
// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated):
339+
// CHECK: [[DESTROYER_REF:%[0-9]+]] = function_ref @$s14default_deinit19SimpleActorIsolatedCfd : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject
340+
// CHECK: [[UNTYPED_DESTOY_RESULT:%[0-9]+]] = apply [[DESTROYER_REF]]([[SELF]]) : $@convention(method) (@guaranteed SimpleActorIsolated) -> @owned Builtin.NativeObject
341+
// CHECK: [[TYPED_DESTOY_RESULT:%[0-9]+]] = unchecked_ref_cast [[UNTYPED_DESTOY_RESULT]] : $Builtin.NativeObject to $SimpleActorIsolated
342+
// CHECK: dealloc_ref [[TYPED_DESTOY_RESULT]] : $SimpleActorIsolated
343+
// CHECK: [[RESULT:%[0-9]+]] = tuple ()
344+
// CHECK: return [[RESULT]] : $()
345+
// CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfZ'
346+
347+
// MARK: Deallocating deinit
348+
349+
// ===== -----------------------------------------------------------------------
350+
// CHECK-LABEL: // SimpleActorIsolated.__deallocating_deinit
351+
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit19SimpleActorIsolatedCfD : $@convention(method) (@owned SimpleActorIsolated) -> () {
352+
// CHECK: bb0([[SELF:%[0-9]+]] : $SimpleActorIsolated):
353+
// CHECK: [[ISOLATED_REF:%[0-9]+]] = function_ref @$s14default_deinit19SimpleActorIsolatedCfZ : $@convention(thin) (@owned SimpleActorIsolated) -> ()
354+
// CHECK: [[EXECUTOR:%[0-9]+]] = extract_executor [[SELF]] : $SimpleActorIsolated
355+
// CHECK: [[PERFORM_REF:%[0-9]+]] = function_ref @swift_task_performOnExecutor : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
356+
// CHECK: [[SELF_AS_ANY_OBJECT:%[0-9]+]] = unchecked_bitwise_cast [[SELF]] : $SimpleActorIsolated to $AnyObject
357+
// CHECK: [[ISOLATED_CASTED:%[0-9]+]] = convert_function [[ISOLATED_REF]] : $@convention(thin) (@owned SimpleActorIsolated) -> () to $@convention(thin) (@owned AnyObject) -> ()
358+
// CHECK: [[DROP:%[0-9]+]] = apply [[PERFORM_REF]]([[SELF_AS_ANY_OBJECT]], [[ISOLATED_CASTED]], [[EXECUTOR]]) : $@convention(thin) (@owned AnyObject, @convention(thin) (@owned AnyObject) -> (), Builtin.Executor) -> ()
359+
// CHECK: [[RESULT:%[0-9]+]] = tuple ()
360+
// CHECK: return [[RESULT]] : $()
361+
// CHECK: } // end sil function '$s14default_deinit19SimpleActorIsolatedCfD'

0 commit comments

Comments
 (0)