Skip to content

5.9: [ClosureSpecializer] Don't release trivial noescape apply argument twice. #66285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

nate-chandler
Copy link
Contributor

Description: Analogous to #66274 but for apply instead of try_apply.

ClosureSpecializer creates releases for the closure passed as an parameter to a apply that is specialized. These releases are created in (1) ClosureSpecCloner::populateCloned and (2) rewriteApplyInst, depending on the effective ownership of the closure: in (1) they are inserted for closures passed without an increment of the retain count (done e.g. for closures passed as an @guaranteed parameter); in (2) they are inserted for closures passed with an increment of the retain count (done e.g. for closures passed as an @owned parameter).

Among the closures that are passed without an increment of the retain count are those which are noescape (SILFunctionType::isTrivialNoEscape). That is true even when the closure is passed as an @owned parameter. The condition of (1) under which releases are added for the closure correctly included consideration of the isTrivialNoEscape predicate of the closure's type; consequently that code inserts releases in both of the apply's destination blocks. The condition of (2) under which releases were added for the closure incorrectly failed to consider the isTrivialNoEscape predicate; consequently, that code also inserted releases in both of the destination blocks. The result was adding two releases in each destination block, one of each of which was an overrelease.

The fix is just to consider the isTrivialNoEscape predicate in (2).
Risk: Low. The patch adds a predicate to the bailout condition of (2) that complements an existing use of the same predicate in the condition of (1).
Scope: Narrow. This only affects releases for noescape closures passed as owned arguments to applys which are specialized.
Original PR: #66275
Reviewed By: Arnold Schwaigofer ( @aschwaighofer )
Testing: Added test that previously inserted double release is no longer present.
Resolves: rdar://110115795

When a specialization is created, in the original function, releases are
added in two different places:
(1) `ClosureSpecCloner::populateCloned`
(2) `rewriteApplyInst`

In the former, releases are added for closures which are guaranteed or
trivial noescape (but with owned convention).
In the latter, releases are added for closures that are owned.

Previously, when emitting releases at (2), whether the closure was
trivial noescape wasn't considered.  The result was inserting the
releases twice, an overrelease.

Here, fix (2) to recognize trivial noescape as not +1.

rdar://110115795
@nate-chandler nate-chandler requested a review from a team as a code owner June 1, 2023 20:35
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler nate-chandler merged commit 72612a2 into swiftlang:release/5.9 Jun 2, 2023
@nate-chandler nate-chandler deleted the cherrypick/release/5.9/rdar110115795 branch June 2, 2023 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants