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

[mono][swift-interop] Support for Swift struct lowering in callback returns #104949

Merged

Conversation

matouskozak
Copy link
Member

@matouskozak matouskozak commented Jul 16, 2024

Description

This PR adds support in Mono runtime for Swift @frozen struct lowering in function returns in reverse P/Invoke scenario. These changes are a follow-up to #104389 which introduced support for direct P/Invoke scenario and contains detailed description of the problem.

Implementation

The key implementation part was done in #104389. Same as in direct P/Invokes, the struct can be returned as a lowered sequence of primitives or by reference.

  1. Returned by lowered sequence:

    • The struct is disassembled inside mono_arch_emit_epilog where the lowered sequence of primitives is stored into dedicated return registers.
  2. Returned by reference:

    • On arm64, handled as regular ArgVtypeByRef with no extra changes.
    • On x64, handled as ArgValuetypeAddrInIReg with specific handling where we need to load the return buffer address passed by Swift caller from RAX reg. into vret_addr inside the mono_arch_emit_prolog

Verification

The changes are verified using the Interop/Swift/SwiftCallbackAbiStress runtime tests. The extended set of 2500 test cases was used locally to further verify the lowering support. The fullAOT functionality was only verified in local settings due to missing coverage on CI.


Contributes to #102077

Copy link
Member

@lambdageek lambdageek left a comment

Choose a reason for hiding this comment

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

looks ok

@lambdageek
Copy link
Member

/azp run runtime-ioslike

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@matouskozak
Copy link
Member Author

/azp run runtime-extra-platforms

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@jkurdek jkurdek left a comment

Choose a reason for hiding this comment

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

Thanks for finishing the reverse pinvokes interop story!

@@ -988,7 +988,8 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
/*
* We need to set this even when sig->pinvoke is FALSE, because the `cinfo` gets copied to the
* `cfg->arch` on the first pass. However, later in `amd64_handle_swift_return_buffer_reg` we
* condition the Swift return buffer handling only to P/Invoke calls.
* condition the Swift return buffer handling only to P/Invoke calls. This however can trigger
* a false positive in some scenarios where the Swift return buffer is not needed.
Copy link
Member

Choose a reason for hiding this comment

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

What are those false positive triggering scenarios?

Copy link
Member Author

Choose a reason for hiding this comment

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

Mostly cases where struct is large enough that it would normally (outside swiftcall) be returned by a reference but small enough that during swiftcall it is returned via registers.

src/mono/mono/mini/mini-arm64.c Outdated Show resolved Hide resolved
src/mono/mono/mini/mini-amd64.c Outdated Show resolved Hide resolved
@@ -2368,6 +2400,9 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
linfo->ret.storage = LLVMArgVtypeRetAddr;
linfo->vret_arg_index = cinfo->vret_arg_index;
break;
case ArgSwiftValuetypeLoweredRet:
linfo->ret.storage = LLVMArgNone; // LLVM compilation of pinvoke wrappers is not supported, see emit_method_inner in mini-llvm.c
Copy link
Member

Choose a reason for hiding this comment

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

Should it assert here?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, we can't assert here. See #104949 (comment).

@matouskozak matouskozak merged commit 833fbb8 into dotnet:main Jul 18, 2024
127 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Aug 18, 2024
@matouskozak matouskozak deleted the swift-interop/callbacks-struct-returns branch October 3, 2024 13:15
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants