Skip to content

JNI Marshal Methods & [UnmanagedCallersOnly]? #956

Open
@jonpryor

Description

@jonpryor

Context: dotnet/runtime#65853

generator emits "JNI Marshal Methods", which are methods to be called by Java/JNI, which marshals parameters and return types in order to "forward" to virtual method overrides:

https://github.com/xamarin/java.interop/blob/1987829f96d58c3298fa1e3d86ef3cd0e12e6c31/tests/generator-Tests/expected.xaji/NormalMethods/Xamarin.Test.A.cs#L52-L56

As these methods are intended to only be called by Java, it would make sense to apply the UnmanagedCallersOnlyAttribute custom attribute to them. This wouldn't be immediately useful, but would permit future optimization opportunities.

Unfortunately, "just" adding [UnmanagedCallersOnly] to generator output is insufficient:

If you call GetFunctionPointerForDelegate on this delegate, you would end up doing the transition twice, so you'd end up in the right GC mode afterwards, but it might put the runtime into a weird state as it would transition from native to managed twice and then from managed to native twice.

which just sounds Bad™.

Thus, in order to use [UnmanagedCallersOnly], we would also need to:

  1. Stop using System.Reflection.Emit / JNINativeWrapper.CreateDelegate() entirely (which might halt this entire thought process), as [UnmanagedCallersOnly] can't be called by managed code.

  2. Turn JniNativeMethodRegistration.Marshaler into a "union", so that it can be either a Delegate or an `IntPtr.

    Can that even be done without breaking ABI?

  3. Update JNI marshal method lookup…somehow… so that the looked-up method uses RuntimeMethodHandle.GetFunctionPointer() to set JniNativeMethodRegistration.Marshaler-as-IntPtr instead of -as-Delegate. (Plus figure out how RegisterNativeMembers() is supposed to know when it should be using the Delegate codepath vs. the IntPtr codepath…)

Metadata

Metadata

Assignees

No one assigned

    Labels

    java-interopRuntime bridge between .NET and JavaproposalIssue raised for discussion, we do not even know if the change would be desirable yet

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions