Skip to content

Commit facc0ca

Browse files
Expanded test for SIL for distributed actor deinit, added isolated cases
1 parent f78c7f0 commit facc0ca

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
@@ -7,13 +7,23 @@
77
// FIXME(distributed): test fails on optimized build: OSS - Swift (Tools Opt+No Assert, Stdlib Opt+DebInfo, Test Simulator) - macOS
88
// REQUIRES: radar97074020
99

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

1318
typealias DefaultDistributedActorSystem = FakeActorSystem
1419

1520
final class SomeClass: Sendable {}
1621

22+
@inline(never)
23+
private nonisolated func doIt() {}
24+
25+
// MARK: - Distributed actor with nonisolated deinit
26+
1727
distributed actor MyDistActor {
1828
let localOnlyField: SomeClass
1929

@@ -23,7 +33,7 @@ distributed actor MyDistActor {
2333
}
2434
}
2535

26-
// MARK: distributed actor check
36+
// MARK: Destroying deinit
2737

2838
// CHECK-LABEL: // MyDistActor.deinit
2939
// CHECK-NEXT: sil hidden{{.*}} @$s14default_deinit11MyDistActorCfd : $@convention(method) (@guaranteed MyDistActor) -> @owned Builtin.NativeObject {
@@ -62,6 +72,14 @@ distributed actor MyDistActor {
6272

6373
// CHECK: } // end sil function '$s14default_deinit11MyDistActorCfd'
6474

75+
// MARK: Isolated deallocating deinit
76+
77+
// ===== -----------------------------------------------------------------------
78+
// CHECK-NOT: MyDistActor.__isolated_deallocating_deinit
79+
// CHECK-NOT: @$s14default_deinit11MyDistActorCfZ
80+
81+
// MARK: Deallocating deinit
82+
6583
// ===== -----------------------------------------------------------------------
6684
// CHECK-LABEL: MyDistActor.__deallocating_deinit
6785
// CHECK-NEXT: sil hidden @$s14default_deinit11MyDistActorCfD : $@convention(method) (@owned MyDistActor) -> () {
@@ -116,12 +134,133 @@ distributed actor MyDistActor {
116134

117135
// ===== -----------------------------------------------------------------------
118136

137+
// MARK: - Distributed actor with isolated deinit
119138

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

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

126265
@available(macOS 12, *)
127266
actor SimpleActor {
@@ -131,9 +270,11 @@ actor SimpleActor {
131270
}
132271
}
133272

134-
// additionally, we add basic coverage for a non-distributed actor's deinit
273+
// MARK: Destroying deinit
135274

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

0 commit comments

Comments
 (0)