Repository: dotnet/runtime
File: src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs (C#)

Code before:
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it has an non version resilient signature.");
                    return;
                }
                MethodIL methodIL = _compilation.GetMethodIL(MethodBeingCompiled);
                if (methodIL == null)
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because IL code could not be found for the method.");
                    return;
                }

                if (FunctionJustThrows(methodIL))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it always throws an exception");
                    return;
                }

                if (FunctionHasNonReferenceableTypedILCatchClause(methodIL, _compilation.NodeFactory.CompilationModuleGroup))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it has a non referenceable catch clause");
                    return;
                }

                if (MethodBeingCompiled.IsAsyncThunk())
                {
                    // The synthetic async thunks require references to methods/types that may not have existing methodRef entries in the version bubble.
                    // These references need to be added to the mutable module if they don't exist.
                    var requiredMutableModuleReferences = MethodBeingCompiled.IsAsyncVariant() ?
                        AsyncThunkILEmitter.GetRequiredReferencesForAsyncThunk(((AsyncMethodVariant)MethodBeingCompiled).Target)
                        : AsyncThunkILEmitter.GetRequiredReferencesForTaskReturningThunk(MethodBeingCompiled);
                    foreach (var entity in requiredMutableModuleReferences)
                    {
                        // If we have a reference to the method/type already, we're okay.
                        if (_compilation.NodeFactory.ManifestMetadataTable._mutableModule.TryGetExistingEntityHandle(entity) is null)
                        {
                            if (logger.IsVerbose)
                                logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` triggered recompilation.");
                            _compilation.PrepareForCompilationRetry(_methodCodeNode, null, requiredMutableModuleReferences);
                            codeGotPublished = true;
                            return;
                        }
                    }
                }

                if (MethodBeingCompiled.GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
                {
                    if ((methodIL.GetMethodILScopeDefinition() is IEcmaMethodIL && _compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && ecmaMethod.Module == ecmaMethod.Context.SystemModule) ||
                        (!_compilation.NodeFactory.CompilationModuleGroup.VersionsWithMethodBody(MethodBeingCompiled) &&
                            _compilation.NodeFactory.CompilationModuleGroup.CrossModuleInlineable(MethodBeingCompiled)))

Review comment (refactor):
If the async thunks are inlined, I believe we can encounter references for the managed helpers in methods that are not async thunks. We should not be limiting this to async thunks.



Code after:
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it is skipped.");
                    return;
                }

                if (MethodSignatureIsUnstable(MethodBeingCompiled.Signature, out var _))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it has an non version resilient signature.");
                    return;
                }
                MethodIL methodIL = _compilation.GetMethodIL(MethodBeingCompiled);
                if (methodIL == null)
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because IL code could not be found for the method.");
                    return;
                }

                if (FunctionJustThrows(methodIL))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it always throws an exception");
                    return;
                }

                if (FunctionHasNonReferenceableTypedILCatchClause(methodIL, _compilation.NodeFactory.CompilationModuleGroup))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it has a non referenceable catch clause");
                    return;
                }

                if (MethodBeingCompiled.GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
                {
                    if ((methodIL.GetMethodILScopeDefinition() is IEcmaMethodIL && _compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && ecmaMethod.Module == ecmaMethod.Context.SystemModule) ||
                        (!_compilation.NodeFactory.CompilationModuleGroup.VersionsWithMethodBody(MethodBeingCompiled) &&
                            _compilation.NodeFactory.CompilationModuleGroup.CrossModuleInlineable(MethodBeingCompiled)))
                    {
                        ISymbolNode ilBodyNode = _compilation.SymbolNodeFactory.CheckILBodyFixupSignature((EcmaMethod)MethodBeingCompiled.GetTypicalMethodDefinition());
                        AddPrecodeFixup(ilBodyNode);
                    }

                    // Harvest the method being compiled for the purpose of populating the type resolver
                    var resolver = _compilation.NodeFactory.Resolver;
                    if (_compilation.CompilationModuleGroup.VersionsWithModule(ecmaMethod.Module))
                    {
                        resolver.AddModuleTokenForMethod(MethodBeingCompiled, new ModuleToken(ecmaMethod.Module, ecmaMethod.Handle));
                    }
                    else
                    {
                        // Cross module optimization scenario. If we aren't able to come up with a token for the method being compiled, then force it to be