Skip to content

[5.5] async function pointer support for Windows #40147

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

Merged
merged 3 commits into from
Nov 15, 2021

Conversation

compnerd
Copy link
Member

@compnerd compnerd commented Nov 12, 2021

I'm nominating this for Swift 5.5 on behalf of my team (XCTest) and the original PR author (@compnerd), since it supports Swift async test support. Our XCTest release manager @bcroom is out on vacation currently, but he approved this via Slack.

  • Explanation: This fixes an issue leading to linker failures with open async functions on Windows. For detailed summary of the problem, see the original PR (IRGen: initial pass to support async inheritance on Windows #39998). The motivation for bringing it back to 5.5 is that this is one PR of several which support async XCTests, since this problem was identified as a blocker to landing the Corelibs XCTest changes for Windows.

  • Scope: Limited. Affects code which has adopted async on Windows, and uses subclassing.

  • SR Issue: SR-15399

  • Risk: Low, only affecting PE/COFF (Windows), relatively new code which has adopted async, under narrow circumstances.

  • Testing: New unit tests are included, it passes existing tests and smoke tests as well. Change has been on main for 2 weeks without issue. Also resolves an existing XFAIL’ed test on Windows.

  • Reviewer: @aschwaighofer

With PE/COFF, one cannot reference a data symbol directly across the
binary module boundary.  Instead, the reference must be indirected
through the Import Address Table (IAT) to allow for position
independence.

When generating a reference to a AsyncFunctionPointer ({i8*, i32}), we
tag the pointer as being indirected by tagging bit 1 (with the
assumption that native alignment will ensure 4/8 byte alignment, freeing
the bottom 2 bits at least for bit-packing).  We tweak the
v-table/witness table emission such that all references to the
AsyncFunctionPointer are replaced with the linker synthetic import
symbol with the bit packing:

~~~
.quad __imp_$s1L1CC1yyYaKFTu+1
~~~

rather than

~~~
.quad $s1L1CC1yyYaKFTu
~~~

Upon access of the async function pointer reference, we open-code the
check for the following:

~~~
pointer = (pointer & 1) ? *(void **)(pointer & ~1) : pointer;
~~~

Thanks to @DougGregor for the discussion and the suggestion for the
pointer tagging.  Thanks to @aschwaighofer for pointers to the code that
I had missed.  Also, thanks to @SeanROlszewski for the original code
sample that led to the reduced test case.

Fixes: SR-15399
(cherry picked from commit 68bc33f)
Tweak test for macOS

(cherry picked from commit fee023c)
@compnerd compnerd requested a review from a team as a code owner November 12, 2021 01:15
@compnerd
Copy link
Member Author

@swift-ci please test

Make the test less restrictive.  The value of the select is not referenced, no need to match it.
@compnerd
Copy link
Member Author

@swift-ci please test

@compnerd
Copy link
Member Author

@swift-ci please test Windows platform

@compnerd
Copy link
Member Author

@compnerd
Copy link
Member Author

I'll try to do some more testing over the weekend.

@tkremenek
Copy link
Member

@compnerd is this OK to merge?

@compnerd
Copy link
Member Author

@tkremenek thanks, yes, this should be good to merge.

@compnerd compnerd merged commit 476f634 into swiftlang:release/5.5 Nov 15, 2021
@compnerd compnerd deleted the 5.5-async-function-protocol branch November 15, 2021 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants