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

Code before:
                }
                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();
                }

                List<string> signaturePrefixes = [];
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_AsyncVariant) != 0)
                {
                    signaturePrefixes.Add("[Async]");
                }
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0)
                {
                    throw new NotImplementedException("Crossgen2 should not emit code for Instantiating stubs.");
                }
                if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_UnboxingStub) != 0)
                {
                    throw new NotImplementedException("Crossgen2 should not emit code for Unboxing stubs.");
                }

                GetPgoOffsetAndVersion(decoder.Offset, out int pgoFormatVersion, out int pgoOffset);

                PgoInfoKey key = new PgoInfoKey(mdReader, owningType, methodHandle, methodTypeArgs, signaturePrefixes.ToArray());
                PgoInfo info = new PgoInfo(key, this, pgoFormatVersion, Image, pgoOffset);

                // Since we do non-assembly qualified name based matching for generic instantiations, we can have conflicts.
                // This is rare, so the current strategy is to just ignore them. This will allow the tooling to work, although
                // the text output for PGO will be slightly wrong.
                if (!_pgoInfos.ContainsKey(key))
                    _pgoInfos.Add(key, info);
                curParser = allEntriesEnum.GetNext();
            }

            return;

            // Broken out into helper function in case we ever implement pgo data that isn't tied to a signature
            void GetPgoOffsetAndVersion(int offset, out int version, out int pgoDataOffset)
            {
                version = 0;

Review comment (suggestion):
This is not a fundamental limitation. It can be fixed anytime.

r2rdump should print what's in the file. It is not meant to be validating. I think we should dump these bits without throwing  exceptions.

Code after:
            }

            return;

            // Broken out into helper function in case we ever implement pgo data that isn't tied to a signature
            void GetPgoOffsetAndVersion(int offset, out int version, out int pgoDataOffset)
            {
                version = 0;
                // get the id of the entry point runtime function from the MethodEntryPoints NativeArray
                uint versionAndFlags = 0; // the RUNTIME_FUNCTIONS index
                offset = (int)ImageReader.DecodeUnsigned((uint)offset, ref versionAndFlags);

                switch (versionAndFlags & 3)
                {
                    case 3:
                        uint val = 0;
                        ImageReader.DecodeUnsigned((uint)offset, ref val);
                        offset -= (int)val;
                        break;
                    case 1:
                        // Offset already correct
                        break;
                    default:
                        throw new Exception("Invalid Pgo format");
                }

                version = (int)(versionAndFlags >> 2);
                pgoDataOffset = offset;
            }
        }

        private void CountRuntimeFunctions(bool[] isEntryPoint, IDictionary<int, int[]> dHotColdMap, int firstColdRuntimeFunction)
        {
            foreach (ReadyToRunMethod method in Methods)
            {
                int runtimeFunctionId = method.EntryPointRuntimeFunctionId;
                if (runtimeFunctionId == -1)
                {
                    continue;
                }
                int count = 0;
                int i = runtimeFunctionId;
                do
                {
                    count++;
                    i++;
                } while (i < isEntryPoint.Length && !isEntryPoint[i] && i < firstColdRuntimeFunction);

                if (dHotColdMap.ContainsKey(runtimeFunctionId))
                {
                    int coldSize = dHotColdMap[runtimeFunctionId].Length;