From: Andrew Au Date: Tue, 17 Nov 2020 18:36:47 +0000 (-0800) Subject: Optimize HelloWorld usage (#44711) X-Git-Tag: submit/tizen/20210909.063632~4579 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e5c7168eaebbbbf4cea6473eee87f7c49edbeb10;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Optimize HelloWorld usage (#44711) --- diff --git a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index f0e8431..e2e888c 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -47,6 +47,36 @@ namespace ILCompiler.Reflection.ReadyToRun } } + public class ReadyToRunAssembly + { + private ReadyToRunReader _reader; + internal List _availableTypes; + internal List _methods; + + internal ReadyToRunAssembly(ReadyToRunReader reader) + { + _reader = reader; + } + + public IReadOnlyList AvailableTypes + { + get + { + _reader.EnsureAvailableTypes(); + return _availableTypes; + } + } + + public IReadOnlyList Methods + { + get + { + _reader.EnsureMethods(); + return _methods; + } + } + } + public sealed class ReadyToRunReader { private const string SystemModuleName = "System.Private.CoreLib"; @@ -73,6 +103,7 @@ namespace ILCompiler.Reflection.ReadyToRun private int _readyToRunHeaderRVA; private ReadyToRunHeader _readyToRunHeader; private List _readyToRunAssemblyHeaders; + private List _readyToRunAssemblies; // DebugInfo private Dictionary _runtimeFunctionIdToDebugOffset; @@ -86,16 +117,12 @@ namespace ILCompiler.Reflection.ReadyToRun private Dictionary _runtimeFunctionToEHInfo; // Methods - private Dictionary> _methods; private List _instanceMethods; // ImportSections private List _importSections; private Dictionary _importSignatures; - // AvailableType - private Dictionary> _availableTypes; - // CompilerIdentifier private string _compilerIdentifier; @@ -228,15 +255,12 @@ namespace ILCompiler.Reflection.ReadyToRun } } - /// - /// The runtime functions and method signatures of each method - /// - public Dictionary> Methods + public IReadOnlyList ReadyToRunAssemblies { get { - EnsureMethods(); - return _methods; + EnsureHeader(); + return _readyToRunAssemblies; } } @@ -253,20 +277,6 @@ namespace ILCompiler.Reflection.ReadyToRun } /// - /// The available types from READYTORUN_SECTION_AVAILABLE_TYPES - /// - public Dictionary> AvailableTypes - { - - get - { - EnsureAvailableTypes(); - return _availableTypes; - } - - } - - /// /// The compiler identifier string from READYTORUN_SECTION_COMPILER_IDENTIFIER /// public string CompilerIdentifier @@ -411,14 +421,14 @@ namespace ILCompiler.Reflection.ReadyToRun } } - private void EnsureMethods() + internal void EnsureMethods() { - if (_methods != null) + EnsureHeader(); + if (_readyToRunAssemblies[0]._methods != null) { return; } - _methods = new Dictionary>(); _instanceMethods = new List(); if (ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.RuntimeFunctions, out ReadyToRunSection runtimeFunctionSection)) @@ -443,13 +453,10 @@ namespace ILCompiler.Reflection.ReadyToRun if (_runtimeFunctionToMethod == null) { _runtimeFunctionToMethod = new Dictionary(); - foreach (var section in _methods) + foreach (var method in Methods) { - foreach (var method in section.Value) - { - if (!_runtimeFunctionToMethod.ContainsKey(method.EntryPointRuntimeFunctionId)) - _runtimeFunctionToMethod.Add(method.EntryPointRuntimeFunctionId, method); - } + if (!_runtimeFunctionToMethod.ContainsKey(method.EntryPointRuntimeFunctionId)) + _runtimeFunctionToMethod.Add(method.EntryPointRuntimeFunctionId, method); } } } @@ -555,10 +562,15 @@ namespace ILCompiler.Reflection.ReadyToRun int r2rHeaderOffset = GetOffset(_readyToRunHeaderRVA); _readyToRunHeader = new ReadyToRunHeader(Image, _readyToRunHeaderRVA, r2rHeaderOffset); + _readyToRunAssemblies = new List(); if (_composite) { ParseComponentAssemblies(); } + else + { + _readyToRunAssemblies.Add(new ReadyToRunAssembly(this)); + } } private void EnsureDebugInfo() @@ -693,6 +705,8 @@ namespace ILCompiler.Reflection.ReadyToRun /// Set to true for each runtime function index representing a method entrypoint private void ParseMethodDefEntrypointsSection(ReadyToRunSection section, IAssemblyMetadata componentReader, bool[] isEntryPoint) { + int assemblyIndex = GetAssemblyIndex(section); + _readyToRunAssemblies[assemblyIndex]._methods = new List(); int methodDefEntryPointsOffset = GetOffset(section.RelativeVirtualAddress); NativeArray methodEntryPoints = new NativeArray(Image, (uint)methodDefEntryPointsOffset); uint nMethodEntryPoints = methodEntryPoints.GetCount(); @@ -713,12 +727,7 @@ namespace ILCompiler.Reflection.ReadyToRun throw new BadImageFormatException("EntryPointRuntimeFunctionId out of bounds"); } isEntryPoint[method.EntryPointRuntimeFunctionId] = true; - if (!_methods.TryGetValue(section, out List sectionMethods)) - { - sectionMethods = new List(); - _methods.Add(section, sectionMethods); - } - sectionMethods.Add(method); + _readyToRunAssemblies[assemblyIndex]._methods.Add(method); } } } @@ -746,7 +755,7 @@ namespace ILCompiler.Reflection.ReadyToRun GetRuntimeFunctionIndexFromOffset(offset, out runtimeFunctionId, out fixupOffset); ReadyToRunMethod r2rMethod = _runtimeFunctionToMethod[runtimeFunctionId]; var customMethod = provider.GetMethodFromMethodDef(metadataReader.MetadataReader, MetadataTokens.MethodDefinitionHandle((int)rid), default(TType)); - + if (!Object.ReferenceEquals(customMethod, null) && !foundMethods.ContainsKey(customMethod)) foundMethods.Add(customMethod, r2rMethod); } @@ -865,20 +874,23 @@ namespace ILCompiler.Reflection.ReadyToRun { isEntryPoint[method.EntryPointRuntimeFunctionId] = true; } - if (!Methods.TryGetValue(instMethodEntryPointSection, out List sectionMethods)) - { - sectionMethods = new List(); - Methods.Add(instMethodEntryPointSection, sectionMethods); - } - sectionMethods.Add(method); _instanceMethods.Add(new InstanceMethod(curParser.LowHashcode, method)); curParser = allEntriesEnum.GetNext(); } } + public IEnumerable Methods + { + get + { + EnsureMethods(); + return _readyToRunAssemblies.SelectMany(assembly => assembly.Methods).Concat(_instanceMethods.Select(im => im.Method)); + } + } + private void CountRuntimeFunctions(bool[] isEntryPoint) { - foreach (ReadyToRunMethod method in Methods.Values.SelectMany(sectionMethods => sectionMethods)) + foreach (ReadyToRunMethod method in Methods) { int runtimeFunctionId = method.EntryPointRuntimeFunctionId; if (runtimeFunctionId == -1) @@ -895,20 +907,41 @@ namespace ILCompiler.Reflection.ReadyToRun } } + public int GetAssemblyIndex(ReadyToRunSection section) + { + EnsureHeader(); + if (_composite) + { + for (int assemblyIndex = 0; assemblyIndex < _readyToRunAssemblyHeaders.Count; assemblyIndex++) + { + ReadyToRunSection toMatch; + if (_readyToRunAssemblyHeaders[assemblyIndex].Sections.TryGetValue(section.Type, out toMatch) && section.RelativeVirtualAddress == toMatch.RelativeVirtualAddress) + { + return assemblyIndex; + } + } + return -1; + } + else + { + return 0; + } + } + /// /// Iterates through a native hashtable to get all RIDs /// - private void EnsureAvailableTypes() + internal void EnsureAvailableTypes() { - if (_availableTypes != null) + EnsureHeader(); + if (_readyToRunAssemblies[0]._availableTypes != null) { return; } - _availableTypes = new Dictionary>(); ReadyToRunSection availableTypesSection; if (ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.AvailableTypes, out availableTypesSection)) { - ParseAvailableTypesSection(availableTypesSection, GetGlobalMetadata()); + ParseAvailableTypesSection(0, availableTypesSection, GetGlobalMetadata()); } else if (_readyToRunAssemblyHeaders != null) { @@ -917,7 +950,7 @@ namespace ILCompiler.Reflection.ReadyToRun if (_readyToRunAssemblyHeaders[assemblyIndex].Sections.TryGetValue( ReadyToRunSectionType.AvailableTypes, out availableTypesSection)) { - ParseAvailableTypesSection(availableTypesSection, OpenReferenceAssembly(assemblyIndex + 1)); + ParseAvailableTypesSection(assemblyIndex, availableTypesSection, OpenReferenceAssembly(assemblyIndex + 1)); } } } @@ -928,8 +961,9 @@ namespace ILCompiler.Reflection.ReadyToRun /// as available types are stored separately for each component assembly of the composite R2R executable. /// /// - private void ParseAvailableTypesSection(ReadyToRunSection availableTypesSection, IAssemblyMetadata metadataReader) + private void ParseAvailableTypesSection(int assemblyIndex, ReadyToRunSection availableTypesSection, IAssemblyMetadata metadataReader) { + _readyToRunAssemblies[assemblyIndex]._availableTypes = new List(); int availableTypesOffset = GetOffset(availableTypesSection.RelativeVirtualAddress); NativeParser parser = new NativeParser(Image, (uint)availableTypesOffset); NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size)); @@ -946,23 +980,14 @@ namespace ILCompiler.Reflection.ReadyToRun { ExportedTypeHandle exportedTypeHandle = MetadataTokens.ExportedTypeHandle((int)rid); string exportedTypeName = GetExportedTypeFullName(metadataReader.MetadataReader, exportedTypeHandle); - if (!AvailableTypes.TryGetValue(availableTypesSection, out List sectionTypes)) - { - sectionTypes = new List(); - AvailableTypes.Add(availableTypesSection, sectionTypes); - } - sectionTypes.Add("exported " + exportedTypeName); + + _readyToRunAssemblies[assemblyIndex]._availableTypes.Add("exported " + exportedTypeName); } else { TypeDefinitionHandle typeDefHandle = MetadataTokens.TypeDefinitionHandle((int)rid); string typeDefName = MetadataNameFormatter.FormatHandle(metadataReader.MetadataReader, typeDefHandle); - if (!AvailableTypes.TryGetValue(availableTypesSection, out List sectionTypes)) - { - sectionTypes = new List(); - AvailableTypes.Add(availableTypesSection, sectionTypes); - } - sectionTypes.Add(typeDefName); + _readyToRunAssemblies[assemblyIndex]._availableTypes.Add(typeDefName); } curParser = allEntriesEnum.GetNext(); @@ -1012,6 +1037,7 @@ namespace ILCompiler.Reflection.ReadyToRun ReadyToRunCoreHeader assemblyHeader = new ReadyToRunCoreHeader(Image, ref headerOffset); _readyToRunAssemblyHeaders.Add(assemblyHeader); + _readyToRunAssemblies.Add(new ReadyToRunAssembly(this)); } } diff --git a/src/coreclr/src/tools/r2rdump/R2RDiff.cs b/src/coreclr/src/tools/r2rdump/R2RDiff.cs index 25e6dd9..ff660a9 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDiff.cs +++ b/src/coreclr/src/tools/r2rdump/R2RDiff.cs @@ -90,13 +90,28 @@ namespace R2RDump } } + private bool TryGetMethods(ReadyToRunReader reader, ReadyToRunSection section, out IReadOnlyList methods) + { + int assemblyIndex = reader.GetAssemblyIndex(section); + if (assemblyIndex == -1) + { + methods = null; + return false; + } + else + { + methods = reader.ReadyToRunAssemblies[assemblyIndex].Methods; + return true; + } + } + private void DiffMethodsForModule(ReadyToRunSection leftSection, ReadyToRunSection rightSection) { - if (!_leftDumper.Reader.Methods.TryGetValue(leftSection, out List leftSectionMethods)) + if (!TryGetMethods(_leftDumper.Reader, leftSection, out IReadOnlyList leftSectionMethods)) { leftSectionMethods = new List(); } - if (!_rightDumper.Reader.Methods.TryGetValue(rightSection, out List rightSectionMethods)) + if (!TryGetMethods(_rightDumper.Reader, rightSection, out IReadOnlyList rightSectionMethods)) { rightSectionMethods = new List(); } @@ -290,7 +305,7 @@ namespace R2RDump { Dictionary methodMap = new Dictionary(); - if (reader.Methods.TryGetValue(section, out List sectionMethods)) + if (TryGetMethods(reader, section, out IReadOnlyList sectionMethods)) { foreach (ReadyToRunMethod method in sectionMethods) { @@ -309,7 +324,7 @@ namespace R2RDump /// Set of common signatures of methods to dump private void DumpCommonMethods(Dumper dumper, ReadyToRunSection section, Dictionary signatureFilter) { - if (dumper.Reader.Methods.TryGetValue(section, out List sectionMethods)) + if (!TryGetMethods(dumper.Reader, section, out IReadOnlyList sectionMethods)) { IEnumerable filteredMethods = sectionMethods .Where(method => signatureFilter.ContainsKey(method.SignatureString)) diff --git a/src/coreclr/src/tools/r2rdump/R2RDump.cs b/src/coreclr/src/tools/r2rdump/R2RDump.cs index fa21ad4..d2909a6 100644 --- a/src/coreclr/src/tools/r2rdump/R2RDump.cs +++ b/src/coreclr/src/tools/r2rdump/R2RDump.cs @@ -176,7 +176,7 @@ namespace R2RDump public IEnumerable NormalizedMethods() { - IEnumerable methods = _r2r.Methods.Values.SelectMany(sectionMethods => sectionMethods); + IEnumerable methods = _r2r.Methods; if (_options.Normalize) { methods = methods.OrderBy((m) => m.SignatureString); @@ -492,7 +492,7 @@ namespace R2RDump public IList FindMethod(ReadyToRunReader r2r, string query, bool exact) { List res = new List(); - foreach (ReadyToRunMethod method in r2r.Methods.Values.SelectMany(sectionMethods => sectionMethods)) + foreach (ReadyToRunMethod method in r2r.Methods) { if (Match(method, query, exact)) { @@ -529,7 +529,7 @@ namespace R2RDump /// The name or value to search for public RuntimeFunction FindRuntimeFunction(ReadyToRunReader r2r, int rtfQuery) { - foreach (ReadyToRunMethod m in r2r.Methods.Values.SelectMany(sectionMethods => sectionMethods)) + foreach (ReadyToRunMethod m in r2r.Methods) { foreach (RuntimeFunction rtf in m.RuntimeFunctions) { diff --git a/src/coreclr/src/tools/r2rdump/TextDumper.cs b/src/coreclr/src/tools/r2rdump/TextDumper.cs index ea60e1d..f03b65e 100644 --- a/src/coreclr/src/tools/r2rdump/TextDumper.cs +++ b/src/coreclr/src/tools/r2rdump/TextDumper.cs @@ -133,7 +133,7 @@ namespace R2RDump internal override void DumpAllMethods() { WriteDivider("R2R Methods"); - _writer.WriteLine($"{_r2r.Methods.Sum(kvp => kvp.Value.Count)} methods"); + _writer.WriteLine($"{_r2r.Methods.Count()} methods"); SkipLine(); foreach (ReadyToRunMethod method in NormalizedMethods()) { @@ -303,10 +303,11 @@ namespace R2RDump _writer.WriteLine(availableTypes.ToString()); } - if (_r2r.AvailableTypes.TryGetValue(section, out List sectionTypes)) + int assemblyIndex1 = _r2r.GetAssemblyIndex(section); + if (assemblyIndex1 != -1) { _writer.WriteLine(); - foreach (string name in sectionTypes) + foreach (string name in _r2r.ReadyToRunAssemblies[assemblyIndex1].AvailableTypes) { _writer.WriteLine(name); } @@ -319,10 +320,11 @@ namespace R2RDump _writer.Write(methodEntryPoints.ToString()); } - if (_r2r.Methods.TryGetValue(section, out List sectionMethods)) + int assemblyIndex2 = _r2r.GetAssemblyIndex(section); + if (assemblyIndex2 != -1) { _writer.WriteLine(); - foreach (ReadyToRunMethod method in sectionMethods) + foreach (ReadyToRunMethod method in _r2r.ReadyToRunAssemblies[assemblyIndex2].Methods) { _writer.WriteLine($@"{MetadataTokens.GetToken(method.MethodHandle):X8}: {method.SignatureString}"); }