Skip to content

Struct interface dispatch still allocating for ref generics #9947

@stephentoub

Description

@stephentoub

dotnet/coreclr#14698 helped to avoid allocations when invoking methods on structs cast to interfaces, but it appears it didn't completely address it.

This code:
https://github.com/dotnet/coreclr/blob/8758f76b4e5ba6733e4f3184293414fc9182d06f/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs#L392-L398
takes advantage of this feature, and with a repro like:

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        for (int i = 0; i < 100; i++)
        {
            await new ValueTask<int>(Task.Delay(1).ContinueWith(_ => default(int))).ConfigureAwait(false);
        }
    }
}

it successfully avoids the allocation, but change the ints in the above to strings, and it starts allocating boxes for the interface:

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        for (int i = 0; i < 100; i++)
        {
            await new ValueTask<string>(Task.Delay(1).ContinueWith(_ => default(string))).ConfigureAwait(false);
        }
    }
}

@AndyAyersMS, could you take a look?

We either need to fix this for 2.1 (if you can that would be excellent), or in 2.1 I need to change the async method builder code to work a different way, as we can't have this allocation happening per await.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMItenet-performancePerformance related issue

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions