Skip to content

Commit 01d470c

Browse files
committed
Simplify lifetime extension for async ObjC calls.
Since the clean-up is not unwind only, we can rely on the clean-ups to be emitted on both result and throw paths. This does slightly change when the hop_to_executor is emitted, in those paths, but that shouldn't matter. refactors solution for rdar://78982371
1 parent fa9889d commit 01d470c

File tree

4 files changed

+15
-22
lines changed

4 files changed

+15
-22
lines changed

lib/SILGen/ManagedValue.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,20 @@ ManagedValue ManagedValue::copy(SILGenFunction &SGF, SILLocation loc) const {
5858

5959
// Emit an unmanaged copy of this value
6060
// WARNING: Callers of this API should manage the cleanup of this value!
61-
ManagedValue ManagedValue::unmanagedCopy(SILGenFunction &SGF,
61+
SILValue ManagedValue::unmanagedCopy(SILGenFunction &SGF,
6262
SILLocation loc) const {
6363
auto &lowering = SGF.getTypeLowering(getType());
6464
if (lowering.isTrivial())
65-
return *this;
65+
return getValue();
6666

6767
if (getType().isObject()) {
6868
auto copy = SGF.B.emitCopyValueOperation(loc, getValue());
69-
return ManagedValue::forUnmanaged(copy);
69+
return copy;
7070
}
7171

7272
SILValue buf = SGF.emitTemporaryAllocation(loc, getType());
7373
SGF.B.createCopyAddr(loc, getValue(), buf, IsNotTake, IsInitialization);
74-
return ManagedValue::forUnmanaged(buf);
74+
return buf;
7575
}
7676

7777
/// Emit a copy of this value with independent ownership.

lib/SILGen/ManagedValue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class ManagedValue {
280280

281281
/// Returns an unmanaged copy of this value.
282282
/// WARNING: Callers of this API should manage the cleanup of this value!
283-
ManagedValue unmanagedCopy(SILGenFunction &SGF, SILLocation loc) const;
283+
SILValue unmanagedCopy(SILGenFunction &SGF, SILLocation loc) const;
284284

285285
/// Emit a copy of this value with independent ownership into the current
286286
/// formal evaluation scope.

lib/SILGen/SILGenApply.cpp

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4573,7 +4573,7 @@ RValue SILGenFunction::emitApply(
45734573
// generates `await_async_continuation`.
45744574
// Lifetime is extended by creating unmanaged copies here and by pushing the
45754575
// cleanups required just before the result plan is generated.
4576-
SmallVector<ManagedValue, 8> unmanagedCopies;
4576+
SmallVector<SILValue, 8> unmanagedCopies;
45774577
if (calleeTypeInfo.foreign.async) {
45784578
for (auto arg : args) {
45794579
if (arg.hasCleanup()) {
@@ -4660,29 +4660,22 @@ RValue SILGenFunction::emitApply(
46604660
*foreignError, calleeTypeInfo.foreign.async);
46614661
}
46624662

4663-
// For objc async calls, push cleanup to be used on throw paths in the result
4664-
// planner.
4665-
for (unsigned i : indices(unmanagedCopies)) {
4666-
SILValue value = unmanagedCopies[i].getValue();
4667-
Cleanups.pushCleanup<FixLifetimeDestroyCleanup>(value);
4668-
unmanagedCopies[i] = ManagedValue(value, Cleanups.getTopCleanup());
4663+
// For objc async calls, push cleanup to be used on
4664+
// both result and throw paths prior to finishing the result plan.
4665+
if (calleeTypeInfo.foreign.async) {
4666+
for (auto unmanagedCopy : unmanagedCopies) {
4667+
Cleanups.pushCleanup<FixLifetimeDestroyCleanup>(unmanagedCopy);
4668+
}
4669+
} else {
4670+
assert(unmanagedCopies.empty());
46694671
}
46704672

46714673
auto directResultsArray = makeArrayRef(directResults);
46724674
RValue result = resultPlan->finish(*this, loc, substResultType,
46734675
directResultsArray, bridgedForeignError);
46744676
assert(directResultsArray.empty() && "didn't claim all direct results");
46754677

4676-
// For objc async calls, generate cleanup on the resume path here and forward
4677-
// the previously pushed cleanups.
46784678
if (calleeTypeInfo.foreign.async) {
4679-
for (auto unmanagedCopy : unmanagedCopies) {
4680-
auto value = unmanagedCopy.forward(*this);
4681-
B.emitFixLifetime(loc, value);
4682-
B.emitDestroyOperation(loc, value);
4683-
}
4684-
4685-
// hop back to the current executor
46864679
breadcrumb.emit(*this, loc);
46874680
}
46884681

test/SILGen/objc_async.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,9 @@ func testSlowServerFromMain(slowServer: SlowServer) async throws {
195195
// CHECK: await_async_continuation [[CONT]] {{.*}}, resume [[RESUME:bb[0-9]+]]
196196
// CHECK: [[RESUME]]:
197197
// CHECK: [[RESULT:%.*]] = load [trivial] [[RESUME_BUF]]
198+
// CHECK: hop_to_executor %6 : $MainActor
198199
// CHECK: fix_lifetime [[COPY]]
199200
// CHECK: destroy_value [[COPY]]
200-
// CHECK: hop_to_executor %6 : $MainActor
201201
// CHECK: dealloc_stack [[RESUME_BUF]]
202202
let _: Int = await slowServer.doSomethingSlow("mail")
203203
}

0 commit comments

Comments
 (0)