Skip to content

Pay for an allocation/assignments of a capture class regardless of whether it's used #20777

@davkean

Description

@davkean

Version: Csc.exe 2.3.0.61907 (ee1637c)

Given:

    class Program
    {
        private void Capture(bool value)
        {
            if (value)
            {
                Method(() => value.ToString());
            }
        }

        private void Method(Action action)
        {
        }
    }

The following is the code gen:

.method private hidebysig instance void  Capture(bool 'value') cil managed
{
  // Code size       46 (0x2e)
  .maxstack  3
  .locals init ([0] class ConsoleApp65.Program/'<>c__DisplayClass1_0' 'CS$<>8__locals0',
           [1] bool V_1)
  IL_0000:  newobj     instance void ConsoleApp65.Program/'<>c__DisplayClass1_0'::.ctor()
  IL_0005:  stloc.0
  IL_0006:  ldloc.0
  IL_0007:  ldarg.1
  IL_0008:  stfld      bool ConsoleApp65.Program/'<>c__DisplayClass1_0'::'value'
  IL_000d:  nop
  IL_000e:  ldloc.0
  IL_000f:  ldfld      bool ConsoleApp65.Program/'<>c__DisplayClass1_0'::'value'
  IL_0014:  stloc.1
  IL_0015:  ldloc.1
  IL_0016:  brfalse.s  IL_002d
  IL_0018:  nop
  IL_0019:  ldarg.0
  IL_001a:  ldloc.0
  IL_001b:  ldftn      instance void ConsoleApp65.Program/'<>c__DisplayClass1_0'::'<Capture>b__0'()
  IL_0021:  newobj     instance void [mscorlib]System.Action::.ctor(object,
                                                                    native int)
  IL_0026:  call       instance void ConsoleApp65.Program::Method(class [mscorlib]System.Action)
  IL_002b:  nop
  IL_002c:  nop
  IL_002d:  ret
} // end of method Program::Capture

Notice that you pay for the creation/assignment of the capture class regardless of the branch in the method. This results in unexpected allocations, such as: #20775

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions