diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index b319fa2be39418..47a8c243a2e9e6 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -1061,14 +1061,26 @@ GenTree* Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, else { assert(oper != GT_FTN_ADDR); - CORINFO_CONST_LOOKUP genericLookup; - info.compCompHnd->getReadyToRunHelper(&ldftnToken->m_token, &pLookup.lookupKind, - CORINFO_HELP_READYTORUN_GENERIC_HANDLE, info.compMethodHnd, - &genericLookup); - GenTree* ctxTree = getRuntimeContextTree(pLookup.lookupKind.runtimeLookupKind); - call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, thisPointer, - targetObjPointers, ctxTree); - call->setEntryPoint(genericLookup); + + if (pLookup.lookupKind.runtimeLookupKind != CORINFO_LOOKUP_NOT_SUPPORTED) + { + CORINFO_CONST_LOOKUP genericLookup; + info.compCompHnd->getReadyToRunHelper(&ldftnToken->m_token, &pLookup.lookupKind, + CORINFO_HELP_READYTORUN_GENERIC_HANDLE, + info.compMethodHnd, &genericLookup); + GenTree* ctxTree = getRuntimeContextTree(pLookup.lookupKind.runtimeLookupKind); + call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, thisPointer, + targetObjPointers, ctxTree); + call->setEntryPoint(genericLookup); + } + else + { + // Runtime does not support inlining of all shapes of runtime lookups + // Inlining has to be aborted in such a case + assert(compIsForInlining()); + compInlineResult->NoteFatal(InlineObservation::CALLSITE_GENERIC_DICTIONARY_LOOKUP); + JITDUMP("not optimized, generic inlining restriction\n"); + } } } else diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index c3ba433be4d3f2..89f33319c8120a 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -1005,6 +1005,10 @@ var_types Compiler::impImportCall(OPCODE opcode, // New inliner morph it in impImportCall. // This will allow us to inline the call to the delegate constructor. call = fgOptimizeDelegateConstructor(call->AsCall(), &exactContextHnd, ldftnInfo); + if (compDonotInline()) + { + return TYP_UNDEF; + } } if (!bIntrinsicImported) diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 2e4013c9081bb5..46e3b1af0e4628 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -436,10 +436,17 @@ private void getReadyToRunDelegateCtorHelper(ref CORINFO_RESOLVED_TOKEN pTargetM { pLookup.lookupKind.needsRuntimeLookup = true; - MethodDesc contextMethod = HandleToObject(callerHandle); - pLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(contextMethod); - pLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.DelegateCtor; - pLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(delegateInfo); + if (pTargetMethod.tokenContext != contextFromMethodBeingCompiled()) + { + pLookup.lookupKind.runtimeLookupKind = CORINFO_RUNTIME_LOOKUP_KIND.CORINFO_LOOKUP_NOT_SUPPORTED; + } + else + { + MethodDesc contextMethod = HandleToObject(callerHandle); + pLookup.lookupKind.runtimeLookupKind = GetGenericRuntimeLookupKind(contextMethod); + pLookup.lookupKind.runtimeLookupFlags = (ushort)ReadyToRunHelperId.DelegateCtor; + pLookup.lookupKind.runtimeLookupArgs = (void*)ObjectToHandle(delegateInfo); + } } else { diff --git a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs index f362c08d424649..5df11edec24563 100644 --- a/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs +++ b/src/tests/nativeaot/SmokeTests/UnitTests/Generics.cs @@ -56,6 +56,7 @@ internal static int Run() TestRecursionInFields.Run(); TestGvmLookupDependency.Run(); Test99198Regression.Run(); + Test102259Regression.Run(); TestInvokeMemberCornerCaseInGenerics.Run(); TestRefAny.Run(); TestNullableCasting.Run(); @@ -3555,6 +3556,26 @@ public static void Run() } } + class Test102259Regression + { + class Gen + { + static Func _theval; + + public static object TheFunc(object obj) => obj; + + static Gen() + { + _theval = typeof(Gen).GetMethod(nameof(TheFunc), BindingFlags.Public | BindingFlags.Static).CreateDelegate>().WithObjectTResult(); + } + } + + public static void Run() + { + new Gen(); + } + } + class TestInvokeMemberCornerCaseInGenerics { class Generic @@ -3601,3 +3622,16 @@ public static void Run() } } } + +static class Ext +{ + public static Func WithObjectTResult(this Func function) + { + return function.InvokeWithObjectTResult; + } + + private static object InvokeWithObjectTResult(this Func func, T arg) + { + return func(arg); + } +}