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

Code before:
                    break;

                case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER:
                    id = ReadyToRunHelper.ReversePInvokeEnter;
                    break;

                case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT:
                    id = ReadyToRunHelper.ReversePInvokeExit;
                    break;

                case CorInfoHelpFunc.CORINFO_HELP_INITCLASS:
                case CorInfoHelpFunc.CORINFO_HELP_INITINSTCLASS:
                case CorInfoHelpFunc.CORINFO_HELP_GETSYNCFROMCLASSHANDLE:
                case CorInfoHelpFunc.CORINFO_HELP_GETCLASSFROMMETHODPARAM:
                case CorInfoHelpFunc.CORINFO_HELP_THROW_ARGUMENTEXCEPTION:
                case CorInfoHelpFunc.CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION:
                case CorInfoHelpFunc.CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED:
                case CorInfoHelpFunc.CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL:
                case CorInfoHelpFunc.CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL:
                case CorInfoHelpFunc.CORINFO_HELP_GETREFANY:
                case CorInfoHelpFunc.CORINFO_HELP_NEW_MDARR_RARE:
                // For Vector256.Create and similar cases
                case CorInfoHelpFunc.CORINFO_HELP_THROW_NOT_IMPLEMENTED:
                // For x86 tailcall where helper is required we need runtime JIT.
                case CorInfoHelpFunc.CORINFO_HELP_TAILCALL:
                // DirectOnThreadLocalData helper should not be used in R2R compilation
                case CorInfoHelpFunc.CORINFO_HELP_GETDIRECTONTHREADLOCALDATA_NONGCTHREADSTATIC_BASE:
                    throw new RequiresRuntimeJitException(ftnNum.ToString());

                default:
                    throw new NotImplementedException(ftnNum.ToString());
            }

            return _compilation.NodeFactory.GetReadyToRunHelperCell(id);
        }

        private void getFunctionEntryPoint(CORINFO_METHOD_STRUCT_* ftn, ref CORINFO_CONST_LOOKUP pResult, CORINFO_ACCESS_FLAGS accessFlags)
        {
            throw new RequiresRuntimeJitException(HandleToObject(ftn).ToString());
        }

        private bool canTailCall(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* declaredCalleeHnd, CORINFO_METHOD_STRUCT_* exactCalleeHnd, bool fIsTailPrefix)
        {
            if (!fIsTailPrefix)
            {
                MethodDesc caller = HandleToObject(callerHnd);

                // Do not tailcall out of the entry point as it results in a confusing debugger experience.
                if (caller is EcmaMethod em && em.Module.EntryPoint == caller)
                {
                    return false;

Review comment (refactor):
The comment "DirectOnThreadLocalData helper should not be used in R2R compilation" could be more precise. The helper is intentionally excluded from R2R compilation but will be used at runtime during ReadyToRun fixup resolution. Consider clarifying: "DirectOnThreadLocalData helper is used at runtime during R2R fixup resolution, not during R2R compilation".
```suggestion
                // DirectOnThreadLocalData helper is used at runtime during R2R fixup resolution, not during R2R compilation
```

Code after:
                    break;

                case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER:
                    id = ReadyToRunHelper.ReversePInvokeEnter;
                    break;

                case CorInfoHelpFunc.CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT:
                    id = ReadyToRunHelper.ReversePInvokeExit;
                    break;

                case CorInfoHelpFunc.CORINFO_HELP_INITCLASS:
                case CorInfoHelpFunc.CORINFO_HELP_INITINSTCLASS:
                case CorInfoHelpFunc.CORINFO_HELP_GETSYNCFROMCLASSHANDLE:
                case CorInfoHelpFunc.CORINFO_HELP_GETCLASSFROMMETHODPARAM:
                case CorInfoHelpFunc.CORINFO_HELP_THROW_ARGUMENTEXCEPTION:
                case CorInfoHelpFunc.CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION:
                case CorInfoHelpFunc.CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED:
                case CorInfoHelpFunc.CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL:
                case CorInfoHelpFunc.CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL:
                case CorInfoHelpFunc.CORINFO_HELP_GETREFANY:
                case CorInfoHelpFunc.CORINFO_HELP_NEW_MDARR_RARE:
                // For Vector256.Create and similar cases
                case CorInfoHelpFunc.CORINFO_HELP_THROW_NOT_IMPLEMENTED:
                // For x86 tailcall where helper is required we need runtime JIT.
                case CorInfoHelpFunc.CORINFO_HELP_TAILCALL:
                // DirectOnThreadLocalData helper is used at runtime during R2R fixup resolution, not during R2R compilation
                case CorInfoHelpFunc.CORINFO_HELP_GETDIRECTONTHREADLOCALDATA_NONGCTHREADSTATIC_BASE:
                    throw new RequiresRuntimeJitException(ftnNum.ToString());

                default:
                    throw new NotImplementedException(ftnNum.ToString());
            }

            return _compilation.NodeFactory.GetReadyToRunHelperCell(id);
        }

        private void getFunctionEntryPoint(CORINFO_METHOD_STRUCT_* ftn, ref CORINFO_CONST_LOOKUP pResult, CORINFO_ACCESS_FLAGS accessFlags)
        {
            throw new RequiresRuntimeJitException(HandleToObject(ftn).ToString());
        }

        private bool canTailCall(CORINFO_METHOD_STRUCT_* callerHnd, CORINFO_METHOD_STRUCT_* declaredCalleeHnd, CORINFO_METHOD_STRUCT_* exactCalleeHnd, bool fIsTailPrefix)
        {
            if (!fIsTailPrefix)
            {
                MethodDesc caller = HandleToObject(callerHnd);

                // Do not tailcall out of the entry point as it results in a confusing debugger experience.
                if (caller is EcmaMethod em && em.Module.EntryPoint == caller)
                {
                    return false;