Skip to content

Avoid redundant marshaller copy by introducing FromManagedValue method #69031

@jkotas

Description

@jkotas

The source generated interop for string marshaling have unnecessary stack copies of the marshaller.

Proposal

Introduce FromManagedValue method on the string marshallers and use it to initialize the marshaller instead of the constructor.

Details

        [LibraryImport("...", StringMarshalling = StringMarshalling.Utf8)]
        public static partial void TestTest(string s);

The source generated interop for this simple method that takes utf8 string looks like this:

        public static partial void TestTest(string s)
        {
            byte* __s_gen_native = default;
            //
            // Setup
            //
            global::System.Runtime.InteropServices.Marshalling.Utf8StringMarshaller __s_gen_native__marshaller = default;
            try
            {
                //
                // Marshal
                //
                byte* __s_gen_native__marshaller__stackptr = stackalloc byte[256];
                __s_gen_native__marshaller = new(s, new System.Span<byte>(__s_gen_native__marshaller__stackptr, 256));
                __s_gen_native = __s_gen_native__marshaller.ToNativeValue();
                __PInvoke__(__s_gen_native);
            }
            finally
            {
                //
                // Cleanup
                //
                __s_gen_native__marshaller.FreeNative();
            }
...

__s_gen_native__marshaller = new(s, new System.Span<byte>(__s_gen_native__marshaller__stackptr, 256)); is the problematic line. The JIT has to create a temporary stack copy of the marshaller, invoke the constructor on this temporary copy, and then copy this temporary on-stack over the local variable.

My proposal is to change this line to __s_gen_native__marshaller.FromManagedValue(s, new System.Span<byte>(__s_gen_native__marshaller__stackptr, 256)); that will avoid the unnecessary on-stack copies.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions