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

Code before:
                    methodHandle = MetadataTokens.MemberReferenceHandle(rid);
                }
                else
                {
                    methodHandle = MetadataTokens.MethodDefinitionHandle(rid);
                }
                string[] methodTypeArgs = null;
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_MethodInstantiation) != 0)
                {
                    uint typeArgCount = decoder.ReadUInt();
                    methodTypeArgs = new string[typeArgCount];
                    for (int typeArgIndex = 0; typeArgIndex < typeArgCount; typeArgIndex++)
                    {
                        methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignatureNoEmit();
                    }
                }

                string constrainedType = null;
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0)
                {
                    constrainedType = decoder.ReadTypeSignatureNoEmit();
                }

                int runtimeFunctionId;
                int? fixupOffset;
                GetRuntimeFunctionIndexFromOffset((int)decoder.Offset, out runtimeFunctionId, out fixupOffset);
                ReadyToRunMethod method = new ReadyToRunMethod(
                    this,
                    mdReader,
                    methodHandle,
                    runtimeFunctionId,
                    owningType,
                    constrainedType,
                    methodTypeArgs,
                    fixupOffset);
                if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < isEntryPoint.Length)
                {
                    isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                }
                _instanceMethods.Add(new InstanceMethod(curParser.LowHashcode, method));
                curParser = allEntriesEnum.GetNext();
            }
        }

        public IEnumerable<ReadyToRunMethod> Methods
        {
            get
            {
                EnsureMethods();
                return _readyToRunAssemblies.SelectMany(assembly => assembly.Methods).Concat(_instanceMethods.Select(im => im.Method));
            }

Review comment (refactor):
The prefix strings ([UNBOX]/
/[ASYNC]) are now duplicated here, but similar formatting already exists in ReadyToRunSignature.SignatureDecoder.TextTypeProvider.GetMethodWithFlags. Consider centralizing the prefix mapping (or reusing the existing helper) to prevent the two locations from drifting if more variants are added.
```suggestion
            static string[] GetSignaturePrefixes(uint flags)
            {
                List<string> prefixes = [];
                if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_UnboxingStub) != 0)
                {
                    prefixes.Add("[UNBOX]");
                }
                if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0)
                {
                    prefixes.Add("
");
                }
                if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_AsyncVariant) != 0)
                {
                    prefixes.Add("[ASYNC]");
                }

                return prefixes.ToArray();
            }

            string[] signaturePrefixes = GetSignaturePrefixes(methodFlags);

            return new DecodedMethodSignature(owningType, methodHandle, methodTypeArgs, constrainedType, signaturePrefixes);
```

Code after:
                {
                    methodTypeArgs[typeArgIndex] = decoder.ReadTypeSignatureNoEmit();
                }
            }

            string constrainedType = null;
            if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_Constrained) != 0)
            {
                constrainedType = decoder.ReadTypeSignatureNoEmit();
            }

            List<string> signaturePrefixes = [];
            if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_UnboxingStub) != 0)
            {
                signaturePrefixes.Add("[UNBOX]");
            }
            if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0)
            {
                signaturePrefixes.Add("
");
            }
            if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_AsyncVariant) != 0)
            {
                signaturePrefixes.Add("[ASYNC]");
            }

            return new DecodedMethodSignature(owningType, methodHandle, methodTypeArgs, constrainedType, signaturePrefixes.ToArray());
        }

        /// <summary>
        /// Initialize generic method instances with argument types and runtime function indices from InstanceMethodEntrypoints
        /// </summary>
        private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint)
        {
            if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.InstanceMethodEntryPoints, out ReadyToRunSection instMethodEntryPointSection))
            {
                return;
            }
            int instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
            NativeParser parser = new NativeParser(ImageReader, (uint)instMethodEntryPointsOffset);
            NativeHashtable instMethodEntryPoints = new NativeHashtable(ImageReader, parser, (uint)(instMethodEntryPointsOffset + instMethodEntryPointSection.Size));
            NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
            NativeParser curParser = allEntriesEnum.GetNext();
            while (!curParser.IsNull())
            {
                IAssemblyMetadata mdReader = GetGlobalMetadata();
                SignatureFormattingOptions dummyOptions = new SignatureFormattingOptions();
                SignatureDecoder decoder = new SignatureDecoder(_assemblyResolver, dummyOptions, mdReader?.MetadataReader, this, (int)curParser.Offset);

                var sig = DecodeMethodSignature(ref mdReader, ref decoder);

                int runtimeFunctionId;