Skip to content
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

JIT: Add support for SwiftSelf<T> in Swift calling convention #103576

Merged
merged 1 commit into from
Jun 18, 2024

Conversation

jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented Jun 17, 2024

This adds support to allow SwiftSelf with a frozen struct as T. Swift allows enregistration of 'self' in these cases, but the 'self' must still be passed in the dedicated context register when the frozen struct is not enregistered, which makes this support necessary to handle as part of the calling convention.

A few notes:

  • If T is not a value class we BADCODE
  • If the signature includes SwiftSelf<T>, then it must be the first argument of the signature, which matches how 'self' gets enregistered on the Swift side, otherwise we BADCODE
  • There is no support for reverse pinvokes for SwiftSelf<T>. That's because the context passed to function pointers is always a pointer, so I do not see any use case for this in reverse pinvokes.
  • Some care must be taken since SwiftSelf<T> is a generic struct whose layout generally is not going to match T without tail padding (until we get something like [API Proposal]: New attribute for interop-specific struct concerns #100896).

This adds support to allow SwiftSelf<T> with a frozen struct as T. Swift
allows enregistration of 'self' in these cases, but the 'self' must
still be passed in the dedicated context register when the frozen struct
is not enregistered, which makes this support necessary to handle as
part of the calling convention.

A few notes:
- If `T` is not a value class we `BADCODE`
- If the signature includes `SwiftSelf<T>`, then it must be the first
  argument of the signature, which matches how 'self' gets enregistered
  on the Swift side, otherwise we `BADCODE`
- There is not support for reverse pinvokes for `SwiftSelf<T>`. That's
  because the context passed to function pointers is always a pointer,
  so I do not see any use case for this in reverse pinvokes.
- Some care must be taken since `SwiftSelf<T>` is a generic struct whose
  layout generally is not going to match `T` without tail padding (until
  we get something like dotnet#100896).
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @amanasifkhalid

FYI @jkurdek @kotlarmilos @matouskozak

Copy link
Member

@amanasifkhalid amanasifkhalid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

If the signature includes SwiftSelf, then it must be the first argument of the signature, which matches how 'self' gets enregistered on the Swift side, otherwise we BADCODE

Is this codified in the API proposal? It seems odd that we enforce this for SwiftSelf<T> but not for SwiftSelf, nor do we enforce any ordering constraints for SwiftError, SwiftIndirectResult, etc.

@jakobbotsch
Copy link
Member Author

Is this codified in the API proposal? It seems odd that we enforce this for SwiftSelf<T> but not for SwiftSelf, nor do we enforce any ordering constraints for SwiftError, SwiftIndirectResult, etc.

I agree it's a bit odd. If we decide we do not want this constraint then we can do the reordering within the JIT relatively easily, but I suspect having this constraint is going to make things easier for Mono as well.

SwiftSelf<T> differs from the other cases in that when it is enregistered it takes up registers that other parameters would otherwise use. In the other cases you mention the Swift calling convention uses a register that does not participate in the normal calling convention, so the exact point where it gets classified does not matter ABI wise.

Documenting exact expected positions for all the special types seems like goodness to me. It would make sure that different libraries end up with compatible signatures for the same Swift calls. Not sure if that matters or not, but seems like a good thing.

@jakobbotsch jakobbotsch merged commit 84874d8 into dotnet:main Jun 18, 2024
110 of 113 checks passed
@jakobbotsch jakobbotsch deleted the swift-SwiftSelfOfT branch June 18, 2024 07:16
@github-actions github-actions bot locked and limited conversation to collaborators Jul 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants