Closed
Description
For delegates, we currently retain the context from the IL (similarly to how we used to do it for type-based GDV before #87847). For example:
[MethodImpl(MethodImplOptions.NoInlining)]
static int Foo(Func<int, int> test)
{
return test(3);
}
public static int Main()
{
for (int i = 0; i < 100; i++)
{
Foo(new Runtime_87597().Id<int>);
if (i >= 30)
{
Thread.Sleep(10);
}
}
return 100;
}
private T Id<T>(T val) => val;
results in
Importing BB01 (PC=000) of 'Runtime_87597:Foo(System.Func`2[int,int]):int'
[ 0] 0 (0x000) ldarg.0
[ 1] 1 (0x001) ldc.i4.3 3
[ 2] 2 (0x002) callvirt 0A000001
(Implicit Tail call: prefixFlags |= PREFIX_TAILCALL_IMPLICIT)
In Compiler::impImportCall: opcode is callvirt, kind=0, callRetType is int, structSize is 0
Considering guarded devirtualization at IL offset 2 (0x2)
Likely methods for call [000002] to method System.Func`2[int,int]:Invoke(int):int:this
1) 00007FFAF0A1B5E8 (Runtime_87597:Id[int](int):int:this) [likelihood:100%]
delegate call would invoke method Runtime_87597:Id[int](int):int:this
Marking call [000002] as guarded devirtualization candidate; will guess for method Runtime_87597:Id[int](int):int:this
info.compCompHnd->canTailCall returned false for call [000002]
CheckCanInline: fetching method info for inline candidate Id -- context 00007FFAF0A63C99
Class context: System.Func`2[int,int]
INLINER: during 'impMarkInlineCandidate for GDV' result 'CheckCanInline Success' reason 'CheckCanInline Success' for 'Runtime_87597:Foo(System.Func`2[int,int]):int' calling 'System.Func`2[int,int]:Invoke(int):int:this'
INLINER: during 'impMarkInlineCandidate for GDV' result 'CheckCanInline Success' reason 'CheckCanInline Success'
The Class context: System.Func`2[int,int]
is not right. This is presumably a correctness issue similar to #87847.