diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs index 35557a1d8aae7b..6532f6c4be1647 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs @@ -34,7 +34,7 @@ public override ObjectNodeSection GetSection(NodeFactory factory) public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { - sb.Append("__readonlydata_" + nameMangler.GetMangledMethodName(_owningMethod)); + sb.Append("__readonlydata_"u8).Append(nameMangler.GetMangledMethodName(_owningMethod)); } public int Offset => 0; public override bool IsShareable => true; diff --git a/src/coreclr/tools/Common/Compiler/NameMangler.cs b/src/coreclr/tools/Common/Compiler/NameMangler.cs index 8e327e85ad88fd..91879a359e7ce4 100644 --- a/src/coreclr/tools/Common/Compiler/NameMangler.cs +++ b/src/coreclr/tools/Common/Compiler/NameMangler.cs @@ -23,7 +23,7 @@ public NameMangler(NodeMangler nodeMangler) public NodeMangler NodeMangler { get; private set; } #endif - public abstract string CompilationUnitPrefix { get; set; } + public abstract Utf8String CompilationUnitPrefix { get; set; } public abstract Utf8String SanitizeName(Utf8String s); diff --git a/src/coreclr/tools/Common/Compiler/NativeAotNameMangler.cs b/src/coreclr/tools/Common/Compiler/NativeAotNameMangler.cs index 2f00a4fb19b360..427ee9e1e9c499 100644 --- a/src/coreclr/tools/Common/Compiler/NativeAotNameMangler.cs +++ b/src/coreclr/tools/Common/Compiler/NativeAotNameMangler.cs @@ -22,13 +22,13 @@ public NativeAotNameMangler(NodeMangler nodeMangler) : base(nodeMangler) } #endif - private string _compilationUnitPrefix; + private Utf8String _compilationUnitPrefix; - public override string CompilationUnitPrefix + public override Utf8String CompilationUnitPrefix { get { - Debug.Assert(_compilationUnitPrefix != null); + Debug.Assert(!_compilationUnitPrefix.IsNull); return _compilationUnitPrefix; } set { _compilationUnitPrefix = SanitizeNameWithHash(value); } @@ -170,6 +170,31 @@ private string SanitizeNameWithHash(string literal) return mangledName; } + private Utf8String SanitizeNameWithHash(Utf8String literal) + { + Utf8String mangledName = SanitizeName(literal); + + if (mangledName.Length > 30) + mangledName = new Utf8String(mangledName.AsSpan().Slice(0, 30).ToArray()); + + if (!mangledName.AsSpan().SequenceEqual(literal.AsSpan())) + { + byte[] hash; + lock (this) + { + // Use SHA256 hash here to provide a high degree of uniqueness to symbol names without requiring them to be long + // This hash function provides an exceedingly high likelihood that no two strings will be given equal symbol names + // This is not considered used for security purpose; however collisions would be highly unfortunate as they will cause compilation + // failure. + hash = SHA256.HashData(literal.AsSpan()); + } + + mangledName += "_" + Convert.ToHexString(hash); + } + + return mangledName; + } + /// /// Dictionary given a mangled name for a given /// diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/CoffObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/CoffObjectWriter.cs index 11bc8b65729570..dda356a81abd5a 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/CoffObjectWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/CoffObjectWriter.cs @@ -14,6 +14,7 @@ using System.Text; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; +using Internal.Text; using Internal.TypeSystem; using static ILCompiler.DependencyAnalysis.RelocType; using static ILCompiler.ObjectWriter.CoffObjectWriter.CoffRelocationType; @@ -46,16 +47,16 @@ namespace ILCompiler.ObjectWriter /// internal partial class CoffObjectWriter : ObjectWriter { - protected sealed record SectionDefinition(CoffSectionHeader Header, Stream Stream, List Relocations, string ComdatName, string SymbolName); + protected sealed record SectionDefinition(CoffSectionHeader Header, Stream Stream, List Relocations, Utf8String ComdatName, Utf8String SymbolName); protected readonly Machine _machine; protected readonly List _sections = new(); // Symbol table private readonly List _symbols = new(); - private readonly Dictionary _symbolNameToIndex = new(StringComparer.Ordinal); + private readonly Dictionary _symbolNameToIndex = new(); private readonly Dictionary _sectionNumberToComdatAuxRecord = new(); - private readonly HashSet _referencedMethods = new(); + private readonly HashSet _referencedMethods = new(); private static readonly ObjectNodeSection GfidsSection = new ObjectNodeSection(".gfids$y", SectionType.ReadOnly); private static readonly ObjectNodeSection DebugTypesSection = new ObjectNodeSection(".debug$T", SectionType.ReadOnly); @@ -76,7 +77,7 @@ public CoffObjectWriter(NodeFactory factory, ObjectWritingOptions options, Outpu }; } - private protected override void CreateSection(ObjectNodeSection section, string comdatName, string symbolName, int sectionIndex, Stream sectionStream) + private protected override void CreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName, int sectionIndex, Stream sectionStream) { var sectionHeader = new CoffSectionHeader { @@ -108,7 +109,7 @@ private protected override void CreateSection(ObjectNodeSection section, string SectionCharacteristics.MemDiscardable; } - if (comdatName is not null) + if (!comdatName.IsNull) { sectionHeader.SectionCharacteristics |= SectionCharacteristics.LinkerComdat; @@ -140,7 +141,7 @@ private protected override void CreateSection(ObjectNodeSection section, string }); _symbols.Add(auxRecord); - if (symbolName is not null) + if (!symbolName.IsNull) { _symbolNameToIndex.Add(symbolName, (uint)_symbols.Count); _symbols.Add(new CoffSymbol @@ -186,7 +187,7 @@ protected internal override unsafe void EmitRelocation( long offset, Span data, RelocType relocType, - string symbolName, + Utf8String symbolName, long addend) { if (relocType is IMAGE_REL_BASED_RELPTR32) @@ -206,14 +207,14 @@ protected internal override unsafe void EmitRelocation( base.EmitRelocation(sectionIndex, offset, data, relocType, symbolName, 0); } - private protected override void EmitReferencedMethod(string symbolName) + private protected override void EmitReferencedMethod(Utf8String symbolName) { _referencedMethods.Add(symbolName); } private protected override void EmitSymbolTable( - IDictionary definedSymbols, - SortedSet undefinedSymbols) + IDictionary definedSymbols, + SortedSet undefinedSymbols) { Feat00Flags feat00Flags = _machine is Machine.I386 ? Feat00Flags.SafeSEH : 0; @@ -734,7 +735,7 @@ private enum CoffSymbolClass : byte private sealed class CoffSymbol : CoffSymbolRecord { - public string Name { get; set; } + public Utf8String Name { get; set; } public uint Value { get; set; } public uint SectionIndex { get; set; } public ushort Type { get; set; } @@ -763,13 +764,12 @@ public override void Write(Stream stream, CoffStringTable stringTable, bool isBi { Span buffer = stackalloc byte[isBigObj ? BigObjSize : RegularSize]; - int nameBytes = Encoding.UTF8.GetByteCount(Name); - if (nameBytes <= NameSize) + if (Name.Length <= NameSize) { - Encoding.UTF8.GetBytes(Name, buffer); - if (nameBytes < NameSize) + Name.AsSpan().CopyTo(buffer); + if (Name.Length < NameSize) { - buffer.Slice(nameBytes, 8 - nameBytes).Clear(); + buffer.Slice(Name.Length, 8 - Name.Length).Clear(); } } else @@ -853,7 +853,7 @@ protected sealed class CoffStringTable : StringTableBuilder { public new uint Size => (uint)(base.Size + 4); - public new uint GetStringOffset(string text) + public new uint GetStringOffset(Utf8String text) { return base.GetStringOffset(text) + 4; } diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/ElfObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/ElfObjectWriter.cs index 8adb40bec10943..a36c366bc12cdc 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/ElfObjectWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/ElfObjectWriter.cs @@ -10,6 +10,7 @@ using System.Reflection; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; +using Internal.Text; using Internal.TypeSystem; using static ILCompiler.DependencyAnalysis.RelocType; using static ILCompiler.ObjectWriter.EabiNative; @@ -40,10 +41,10 @@ internal sealed partial class ElfObjectWriter : UnixObjectWriter private readonly List _sections = new(); private readonly List _symbols = new(); private uint _localSymbolCount; - private readonly Dictionary _comdatNameToElfSection = new(StringComparer.Ordinal); + private readonly Dictionary _comdatNameToElfSection = new(); // Symbol table - private readonly Dictionary _symbolNameToIndex = new(); + private readonly Dictionary _symbolNameToIndex = new(); private static readonly ObjectNodeSection ArmAttributesSection = new ObjectNodeSection(".ARM.attributes", SectionType.ReadOnly); private static readonly ObjectNodeSection ArmTextThunkSection = new ObjectNodeSection(".text.thunks", SectionType.Executable); @@ -69,7 +70,7 @@ public ElfObjectWriter(NodeFactory factory, ObjectWritingOptions options) _symbols.Add(new ElfSymbol {}); } - private protected override void CreateSection(ObjectNodeSection section, string comdatName, string symbolName, int sectionIndex, Stream sectionStream) + private protected override void CreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName, int sectionIndex, Stream sectionStream) { string sectionName = section.Name == "rdata" ? ".rodata" : @@ -114,7 +115,7 @@ private protected override void CreateSection(ObjectNodeSection section, string }; } - if (comdatName is not null) + if (!comdatName.IsNull) { flags |= SHF_GROUP; if (!_comdatNameToElfSection.TryGetValue(comdatName, out groupSection)) @@ -154,7 +155,7 @@ private protected override void CreateSection(ObjectNodeSection section, string }); // Emit section symbol into symbol table (for COMDAT the defining symbol is section symbol) - if (comdatName is null) + if (comdatName.IsNull) { _symbolNameToIndex[sectionName] = (uint)_symbols.Count; _symbols.Add(new ElfSymbol @@ -174,7 +175,7 @@ private protected override void CreateSection(ObjectNodeSection section, string }); } - base.CreateSection(section, comdatName, symbolName ?? sectionName, sectionIndex, sectionStream); + base.CreateSection(section, comdatName, symbolName.IsNull ? sectionName : symbolName, sectionIndex, sectionStream); } protected internal override void UpdateSectionAlignment(int sectionIndex, int alignment) @@ -188,7 +189,7 @@ protected internal override unsafe void EmitRelocation( long offset, Span data, RelocType relocType, - string symbolName, + Utf8String symbolName, long addend) { fixed (byte *pData = data) @@ -265,11 +266,11 @@ protected internal override unsafe void EmitRelocation( private static string GetRiscV64SymbolNameForPcrelRelocation(int sectionIndex, long offset) => $".Lpcrel_hi{sectionIndex}_{offset:x}"; private protected override void EmitSymbolTable( - IDictionary definedSymbols, - SortedSet undefinedSymbols) + IDictionary definedSymbols, + SortedSet undefinedSymbols) { List sortedSymbols = new(definedSymbols.Count + undefinedSymbols.Count); - foreach ((string name, SymbolDefinition definition) in definedSymbols) + foreach ((Utf8String name, SymbolDefinition definition) in definedSymbols) { var section = _sections[definition.SectionIndex]; var type = @@ -290,7 +291,7 @@ private protected override void EmitSymbolTable( int thunkSectionIndex = useArmThunks ? GetOrCreateSection(ArmTextThunkSection).SectionIndex : 0; int thunkSymbolsIndex = 0; - foreach (string externSymbol in undefinedSymbols) + foreach (Utf8String externSymbol in undefinedSymbols) { if (!_symbolNameToIndex.ContainsKey(externSymbol)) { @@ -316,7 +317,7 @@ private protected override void EmitSymbolTable( } } - sortedSymbols.Sort((symA, symB) => string.CompareOrdinal(symA.Name, symB.Name)); + sortedSymbols.Sort((symA, symB) => Comparer.Default.Compare(symA.Name, symB.Name)); _localSymbolCount = (uint)_symbols.Count; _symbols.AddRange(sortedSymbols); uint symbolIndex = _localSymbolCount; @@ -337,7 +338,7 @@ private protected override void EmitSymbolTable( Span relocationEntry = stackalloc byte[8]; var relocationStream = new MemoryStream(8 * undefinedSymbols.Count); _sections[thunkSectionWriter.SectionIndex].RelocationStream = relocationStream; - foreach (string externSymbol in undefinedSymbols) + foreach (Utf8String externSymbol in undefinedSymbols) { if (_symbolNameToIndex.TryGetValue($"{externSymbol}$thunk", out uint thunkSymbolIndex)) { @@ -356,7 +357,7 @@ private protected override void EmitSymbolTable( } // Update group sections links - foreach ((string comdatName, ElfSectionDefinition groupSection) in _comdatNameToElfSection) + foreach ((Utf8String comdatName, ElfSectionDefinition groupSection) in _comdatNameToElfSection) { groupSection.SectionHeader.Info = (uint)_symbolNameToIndex[comdatName]; } @@ -669,7 +670,7 @@ private void EmitObjectFile(Stream outputFileStream) // Reserve all symbol names foreach (var symbol in _symbols) { - if (symbol.Name is not null) + if (!symbol.Name.IsNull) { _stringTable.ReserveString(symbol.Name); } @@ -1039,7 +1040,7 @@ public void Write(Stream stream) private sealed class ElfSymbol { - public string Name { get; init; } + public Utf8String Name { get; init; } public ulong Value { get; init; } public ulong Size { get; init; } public ElfSectionDefinition Section { get; init; } @@ -1062,7 +1063,7 @@ public void Write(Stream stream, ElfStringTable stringTable) (ushort)SHN_XINDEX : (Section is not null ? (ushort)Section.SectionIndex : (ushort)0u); - BinaryPrimitives.WriteUInt32LittleEndian(buffer, Name is not null ? stringTable.GetStringOffset(Name) : 0); + BinaryPrimitives.WriteUInt32LittleEndian(buffer, !Name.IsNull ? stringTable.GetStringOffset(Name) : 0); if (typeof(TSize) == typeof(uint)) { TSize.CreateChecked(Value).WriteLittleEndian(buffer.Slice(4)); diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/MachObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/MachObjectWriter.cs index 46ea1a542bedaa..ef8ee1bf507fe6 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/MachObjectWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/MachObjectWriter.cs @@ -12,6 +12,7 @@ using System.Text; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; +using Internal.Text; using Internal.TypeSystem; using static ILCompiler.DependencyAnalysis.RelocType; using static ILCompiler.ObjectWriter.MachNative; @@ -62,10 +63,10 @@ internal sealed partial class MachObjectWriter : UnixObjectWriter private readonly List _sections = new(); // Symbol table - private readonly Dictionary _symbolNameToIndex = new(); + private readonly Dictionary _symbolNameToIndex = new(); private readonly List _symbolTable = new(); private readonly MachDynamicLinkEditSymbolTable _dySymbolTable = new(); - private readonly Dictionary _rangeSymbols = new(); + private readonly Dictionary _rangeSymbols = new(); /// /// Base symbol to use for relocations. @@ -316,7 +317,7 @@ private protected override void EmitObjectFile(Stream outputFileStream) stringTable.Write(outputFileStream); } - private protected override void CreateSection(ObjectNodeSection section, string comdatName, string symbolName, int sectionIndex, Stream sectionStream) + private protected override void CreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName, int sectionIndex, Stream sectionStream) { string segmentName = section.Name switch { @@ -374,7 +375,7 @@ private protected override void CreateSection(ObjectNodeSection section, string _sections.Add(machSection); - base.CreateSection(section, comdatName, symbolName ?? $"lsection{sectionIndex}", sectionIndex, sectionStream); + base.CreateSection(section, comdatName, symbolName.IsNull ? $"lsection{sectionIndex}" : symbolName, sectionIndex, sectionStream); } protected internal override void UpdateSectionAlignment(int sectionIndex, int alignment) @@ -384,7 +385,7 @@ protected internal override void UpdateSectionAlignment(int sectionIndex, int al machSection.Log2Alignment = Math.Max(machSection.Log2Alignment, (uint)BitOperations.Log2((uint)alignment)); } - private protected override void EmitSymbolRangeDefinition(string rangeNodeName, string startSymbolName, string endSymbolName, SymbolDefinition endSymbol) + private protected override void EmitSymbolRangeDefinition(Utf8String rangeNodeName, Utf8String startSymbolName, Utf8String endSymbolName, SymbolDefinition endSymbol) { // Mach has a few characteristics that make range symbols more difficult to emit: // - Emitting two symbols in the same location is not well supported by the Apple linker. @@ -399,13 +400,13 @@ protected internal override unsafe void EmitRelocation( long offset, Span data, RelocType relocType, - string symbolName, + Utf8String symbolName, long addend) { // We don't emit the range node name into the image as it overlaps with another symbol. // For relocs to it, instead target the start symbol. // For the "symbol size" reloc, we'll handle it later when we emit relocations in the Mach format. - if (_rangeSymbols.TryGetValue(symbolName, out (string StartNode, string, int Size) range)) + if (_rangeSymbols.TryGetValue(symbolName, out (Utf8String StartNode, Utf8String, int Size) range)) { if (relocType == RelocType.IMAGE_REL_SYMBOL_SIZE) { @@ -425,7 +426,7 @@ protected internal override unsafe void EmitRelocation( _sections[sectionIndex].IsDwarfSection) { // DWARF section to DWARF section relocation - if (symbolName.StartsWith('.')) + if (symbolName.AsSpan().StartsWith((byte)'.')) { switch (relocType) { @@ -504,8 +505,8 @@ protected internal override unsafe void EmitRelocation( } private protected override void EmitSymbolTable( - IDictionary definedSymbols, - SortedSet undefinedSymbols) + IDictionary definedSymbols, + SortedSet undefinedSymbols) { // We already emitted symbols for all non-debug sections in EmitSectionsAndLayout, // these symbols are local and we need to account for them. @@ -515,7 +516,7 @@ private protected override void EmitSymbolTable( // Sort and insert all defined symbols var sortedDefinedSymbols = new List(definedSymbols.Count); - foreach ((string name, SymbolDefinition definition) in definedSymbols) + foreach ((Utf8String name, SymbolDefinition definition) in definedSymbols) { MachSection section = _sections[definition.SectionIndex]; // Sections in our object file should not be altered during native linking as the runtime @@ -530,7 +531,7 @@ private protected override void EmitSymbolTable( Type = (byte)(N_SECT | N_EXT | (definition.Global ? 0 : N_PEXT)), }); } - sortedDefinedSymbols.Sort((symA, symB) => string.CompareOrdinal(symA.Name, symB.Name)); + sortedDefinedSymbols.Sort((symA, symB) => Comparer.Default.Compare(symA.Name, symB.Name)); foreach (MachSymbol definedSymbol in sortedDefinedSymbols) { _symbolTable.Add(definedSymbol); @@ -549,7 +550,7 @@ private protected override void EmitSymbolTable( undefinedSymbols.Add(_baseSymbolName); } - foreach (string externSymbol in undefinedSymbols) + foreach (Utf8String externSymbol in undefinedSymbols) { if (!_symbolNameToIndex.ContainsKey(externSymbol)) { @@ -597,10 +598,10 @@ private void EmitRelocationsX64(int sectionIndex, List reloc foreach (SymbolicRelocation symbolicRelocation in relocationList) { if (symbolicRelocation.Type == RelocType.IMAGE_REL_SYMBOL_SIZE - && _rangeSymbols.TryGetValue(symbolicRelocation.SymbolName, out (string, string, int) range)) + && _rangeSymbols.TryGetValue(symbolicRelocation.SymbolName, out (Utf8String, Utf8String, int) range)) { // Represent as X86_64_RELOC_SUBTRACTOR + X86_64_RELOC_UNSIGNED. - (string StartNode, string EndNode, int Size) = range; + (Utf8String StartNode, Utf8String EndNode, int Size) = range; uint startSymbolIndex = _symbolNameToIndex[StartNode]; uint endSymbolIndex = _symbolNameToIndex[EndNode]; sectionRelocations.Add( @@ -724,10 +725,10 @@ private void EmitRelocationsArm64(int sectionIndex, List rel foreach (SymbolicRelocation symbolicRelocation in relocationList) { if (symbolicRelocation.Type == RelocType.IMAGE_REL_SYMBOL_SIZE - && _rangeSymbols.TryGetValue(symbolicRelocation.SymbolName, out (string, string, int) range)) + && _rangeSymbols.TryGetValue(symbolicRelocation.SymbolName, out (Utf8String, Utf8String, int) range)) { // Represent as ARM64_RELOC_SUBTRACTOR + ARM64_RELOC_UNSIGNED. - (string StartNode, string EndNode, _) = range; + (Utf8String StartNode, Utf8String EndNode, _) = range; uint startSymbolIndex = _symbolNameToIndex[StartNode]; uint endSymbolIndex = _symbolNameToIndex[EndNode]; sectionRelocations.Add( @@ -879,11 +880,11 @@ private void EmitRelocationsArm64(int sectionIndex, List rel } } - partial void EmitCompactUnwindTable(IDictionary definedSymbols); + partial void EmitCompactUnwindTable(IDictionary definedSymbols); - private protected override string ExternCName(string name) => "_" + name; + private protected override Utf8String ExternCName(Utf8String name) => Utf8String.Concat("_"u8, name.AsSpan()); - private static bool IsSectionSymbolName(string symbolName) => symbolName.StartsWith('l'); + private static bool IsSectionSymbolName(Utf8String symbolName) => symbolName.AsSpan().StartsWith((byte)'l'); private struct MachHeader64 { @@ -1033,7 +1034,7 @@ public void Write(Stream stream) private sealed class MachSymbol { - public string Name { get; init; } = string.Empty; + public Utf8String Name { get; init; } = string.Empty; public byte Type { get; init; } public MachSection Section { get; init; } public ushort Descriptor { get; init; } diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs index ce8347cd072975..7c362f411cec95 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs @@ -21,7 +21,7 @@ namespace ILCompiler.ObjectWriter public abstract partial class ObjectWriter { private protected sealed record SymbolDefinition(int SectionIndex, long Value, int Size = 0, bool Global = false); - protected sealed record SymbolicRelocation(long Offset, RelocType Type, string SymbolName, long Addend = 0); + protected sealed record SymbolicRelocation(long Offset, RelocType Type, Utf8String SymbolName, long Addend = 0); private sealed record BlockToRelocate(int SectionIndex, long Offset, byte[] Data, Relocation[] Relocations); private protected sealed record ChecksumsToCalculate(int SectionIndex, long Offset, Relocation[] ChecksumRelocations); @@ -29,8 +29,9 @@ private protected sealed record ChecksumsToCalculate(int SectionIndex, long Offs private protected readonly ObjectWritingOptions _options; private protected readonly OutputInfoBuilder _outputInfoBuilder; private readonly bool _isSingleFileCompilation; + protected readonly Utf8StringBuilder _utf8StringBuilder = new(); - private readonly Dictionary _mangledNameMap = new(); + private readonly Dictionary _mangledNameMap = new(); private readonly byte _insPaddingByte; @@ -41,7 +42,7 @@ private protected sealed record ChecksumsToCalculate(int SectionIndex, long Offs private protected readonly List _outputSectionLayout = []; // Symbol table - private readonly Dictionary _definedSymbols = new(StringComparer.Ordinal); + private readonly Dictionary _definedSymbols = new(); private protected ObjectWriter(NodeFactory factory, ObjectWritingOptions options, OutputInfoBuilder outputInfoBuilder = null) { @@ -60,10 +61,13 @@ private protected ObjectWriter(NodeFactory factory, ObjectWritingOptions options } private protected virtual bool UsesSubsectionsViaSymbols => false; - private protected abstract void CreateSection(ObjectNodeSection section, string comdatName, string symbolName, int sectionIndex, Stream sectionStream); + private protected abstract void CreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName, int sectionIndex, Stream sectionStream); protected internal abstract void UpdateSectionAlignment(int sectionIndex, int alignment); + private protected SectionWriter GetOrCreateSection(ObjectNodeSection section) + => GetOrCreateSection(section, default, default); + /// /// Get or creates an object file section. /// @@ -78,19 +82,19 @@ private protected ObjectWriter(NodeFactory factory, ObjectWritingOptions options /// For associated sections, such as exception or debugging information, the /// will be different. /// - private protected SectionWriter GetOrCreateSection(ObjectNodeSection section, string comdatName = null, string symbolName = null) + private protected SectionWriter GetOrCreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName) { int sectionIndex; SectionData sectionData; - if (comdatName is not null || !_sectionNameToSectionIndex.TryGetValue(section.Name, out sectionIndex)) + if (!comdatName.IsNull || !_sectionNameToSectionIndex.TryGetValue(section.Name, out sectionIndex)) { sectionData = new SectionData(section.Type == SectionType.Executable ? _insPaddingByte : (byte)0); sectionIndex = _sectionIndexToData.Count; CreateSection(section, comdatName, symbolName, sectionIndex, sectionData.GetReadStream()); _sectionIndexToData.Add(sectionData); _sectionIndexToRelocations.Add(new()); - if (comdatName is null) + if (comdatName.IsNull) { _sectionNameToSectionIndex.Add(section.Name, sectionIndex); } @@ -140,7 +144,7 @@ private unsafe void EmitOrResolveRelocation( long offset, Span data, RelocType relocType, - string symbolName, + Utf8String symbolName, long addend) { if (!UsesSubsectionsViaSymbols && @@ -217,7 +221,7 @@ protected internal virtual void EmitRelocation( long offset, Span data, RelocType relocType, - string symbolName, + Utf8String symbolName, long addend) { _sectionIndexToRelocations[sectionIndex].Add(new SymbolicRelocation(offset, relocType, symbolName, addend)); @@ -228,7 +232,7 @@ private protected bool SectionHasRelocations(int sectionIndex) return _sectionIndexToRelocations[sectionIndex].Count > 0; } - private protected virtual void EmitReferencedMethod(string symbolName) { } + private protected virtual void EmitReferencedMethod(Utf8String symbolName) { } /// /// Emit symbolic relocations into object file as format specific @@ -250,7 +254,7 @@ private protected virtual void EmitReferencedMethod(string symbolName) { } /// protected internal void EmitSymbolDefinition( int sectionIndex, - string symbolName, + Utf8String symbolName, long offset = 0, int size = 0, bool global = false) @@ -264,18 +268,19 @@ protected internal void EmitSymbolDefinition( /// Emit symbolic definitions into object file symbols. /// private protected abstract void EmitSymbolTable( - IDictionary definedSymbols, - SortedSet undefinedSymbols); + IDictionary definedSymbols, + SortedSet undefinedSymbols); - private protected virtual string ExternCName(string name) => name; + private protected virtual Utf8String ExternCName(Utf8String name) => name; - private protected string GetMangledName(ISymbolNode symbolNode) + private protected Utf8String GetMangledName(ISymbolNode symbolNode) { - string symbolName; + Utf8String symbolName; if (!_mangledNameMap.TryGetValue(symbolNode, out symbolName)) { - symbolName = ExternCName(symbolNode.GetMangledName(_nodeFactory.NameMangler)); + symbolNode.AppendMangledName(_nodeFactory.NameMangler, _utf8StringBuilder.Clear()); + symbolName = ExternCName(_utf8StringBuilder.ToUtf8String()); _mangledNameMap.Add(symbolNode, symbolName); } @@ -290,9 +295,9 @@ private protected virtual void EmitSectionsAndLayout() partial void EmitDebugInfo(IReadOnlyCollection nodes, Logger logger); - private SortedSet GetUndefinedSymbols() + private SortedSet GetUndefinedSymbols() { - SortedSet undefinedSymbolSet = new SortedSet(StringComparer.Ordinal); + SortedSet undefinedSymbolSet = new SortedSet(); foreach (var relocationList in _sectionIndexToRelocations) foreach (var symbolicRelocation in relocationList) { @@ -371,7 +376,7 @@ public void EmitObject(Stream outputFileStream, IReadOnlyCollection nodes, NodeFactory factory, ObjectWritingOptions options, IObjectDumper dumper, Logger logger) { @@ -669,6 +675,13 @@ public static void EmitObject(string objectFilePath, IReadOnlyCollection FormatUtf8Int(Span buffer, int number) + { + bool b = number.TryFormat(buffer, out int bytesWritten); + Debug.Assert(b); + return buffer.Slice(0, bytesWritten); + } + private struct ProgressReporter { private readonly Logger _logger; diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/OutputInfoBuilder.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/OutputInfoBuilder.cs index f99e03b7ebdad0..83bf11db428039 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/OutputInfoBuilder.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/OutputInfoBuilder.cs @@ -13,6 +13,7 @@ using ILCompiler.DependencyAnalysisFramework; using ILCompiler.Diagnostics; using Internal.JitInterface; +using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; @@ -47,9 +48,9 @@ public int Compare([AllowNull] OutputItem x, [AllowNull] OutputItem y) /// /// Item name /// - public readonly string Name; + public readonly Utf8String Name; - public OutputItem(int sectionIndex, ulong offset, string name) + public OutputItem(int sectionIndex, ulong offset, Utf8String name) { SectionIndex = sectionIndex; Offset = offset; @@ -93,7 +94,7 @@ public void AddRelocation() /// public sealed class OutputSymbol : OutputItem { - public OutputSymbol(int sectionIndex, ulong offset, string name) + public OutputSymbol(int sectionIndex, ulong offset, Utf8String name) : base(sectionIndex, offset, name) { } @@ -171,7 +172,7 @@ public void Sort() public bool FindSymbol(OutputItem item, out int index) { - index = _symbols.BinarySearch(new OutputSymbol(item.SectionIndex, item.Offset, name: null), OutputItem.Comparer.Instance); + index = _symbols.BinarySearch(new OutputSymbol(item.SectionIndex, item.Offset, name: default), OutputItem.Comparer.Instance); bool result = (index >= 0 && index < _symbols.Count && OutputItem.Comparer.Instance.Compare(_symbols[index], item) == 0); if (!result) { diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/PEObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/PEObjectWriter.cs index e31468b3813054..5243d2e214c685 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/PEObjectWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/PEObjectWriter.cs @@ -13,6 +13,7 @@ using System.Security.Cryptography; using System.Text; using ILCompiler.DependencyAnalysis; +using Internal.Text; using Internal.TypeSystem; namespace ILCompiler.ObjectWriter @@ -80,7 +81,7 @@ internal sealed class PEObjectWriter : CoffObjectWriter // Base relocation (.reloc) bookkeeping private readonly SortedDictionary> _baseRelocMap = new(); - private Dictionary _definedSymbols = []; + private Dictionary _definedSymbols = []; private HashSet _exportedSymbolNames = new(); private long _coffHeaderOffset; @@ -101,10 +102,10 @@ public void AddExportedSymbol(string symbol) } } - private protected override void CreateSection(ObjectNodeSection section, string comdatName, string symbolName, int sectionIndex, Stream sectionStream) + private protected override void CreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName, int sectionIndex, Stream sectionStream) { // COMDAT sections are not supported in PE files - base.CreateSection(section, comdatName: null, symbolName, sectionIndex, sectionStream); + base.CreateSection(section, comdatName: default, symbolName, sectionIndex, sectionStream); if (_requestedSectionAlignment != 0) { @@ -339,7 +340,7 @@ private enum ImageDirectoryEntry Reserved = 15, } - private protected override void EmitSymbolTable(IDictionary definedSymbols, SortedSet undefinedSymbols) + private protected override void EmitSymbolTable(IDictionary definedSymbols, SortedSet undefinedSymbols) { if (undefinedSymbols.Count > 0) { @@ -347,7 +348,7 @@ private protected override void EmitSymbolTable(IDictionary(definedSymbols); + _definedSymbols = new Dictionary(definedSymbols); } private protected override void EmitSectionsAndLayout() diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/SectionWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/SectionWriter.cs index 2378830f5e094a..03920b49bd2bad 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/SectionWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/SectionWriter.cs @@ -45,7 +45,7 @@ public readonly void EmitRelocation( long relativeOffset, Span data, RelocType relocType, - string symbolName, + Utf8String symbolName, long addend) { _objectWriter.EmitRelocation( @@ -58,7 +58,7 @@ public readonly void EmitRelocation( } public readonly void EmitSymbolDefinition( - string symbolName, + Utf8String symbolName, long relativeOffset = 0, int size = 0, bool global = false) @@ -73,7 +73,7 @@ public readonly void EmitSymbolDefinition( public readonly void EmitSymbolReference( RelocType relocType, - string symbolName, + Utf8String symbolName, long addend = 0) { IBufferWriter bufferWriter = _sectionData.BufferWriter; diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/StringTableBuilder.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/StringTableBuilder.cs index 0c6d1831dd4eb8..db5a9a9406e004 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/StringTableBuilder.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/StringTableBuilder.cs @@ -8,14 +8,15 @@ using System.IO; using System.Text; using System.Linq; +using Internal.Text; namespace ILCompiler.ObjectWriter { internal class StringTableBuilder { private readonly MemoryStream _stream = new(); - private readonly SortedSet _reservedStrings = new(StringComparer.Ordinal); - private Dictionary _stringToOffset = new(StringComparer.Ordinal); + private readonly SortedSet _reservedStrings = new(); + private Dictionary _stringToOffset = new(); public void Write(Stream stream) { @@ -32,9 +33,9 @@ public uint Size } } - public void ReserveString(string text) + public void ReserveString(Utf8String text) { - if (text is object && !_stringToOffset.ContainsKey(text)) + if (!text.IsNull && !_stringToOffset.ContainsKey(text)) { _reservedStrings.Add(text); } @@ -42,21 +43,21 @@ public void ReserveString(string text) private void FlushReservedStrings() { - string[] reservedStrings = _reservedStrings.ToArray(); + Utf8String[] reservedStrings = _reservedStrings.ToArray(); // Pre-sort the string based on their matching suffix MultiKeySort(reservedStrings, 0); // Add the strings to string table - string lastText = null; + Utf8String lastText = default; for (int i = 0; i < reservedStrings.Length; i++) { var text = reservedStrings[i]; uint index; - if (lastText is not null && lastText.EndsWith(text, StringComparison.Ordinal)) + if (!lastText.IsNull && lastText.AsSpan().EndsWith(text.AsSpan())) { // Suffix matches the last symbol - index = (uint)(_stream.Length - Encoding.UTF8.GetByteCount(text) - 1); + index = (uint)(_stream.Length - text.Length - 1); _stringToOffset.Add(text, index); } else @@ -68,15 +69,15 @@ private void FlushReservedStrings() _reservedStrings.Clear(); - static char TailCharacter(string str, int pos) + static byte TailCharacter(Utf8String str, int pos) { int index = str.Length - pos - 1; if ((uint)index < str.Length) - return str[index]; - return '\0'; + return str.AsSpan()[index]; + return 0; } - static void MultiKeySort(Span input, int pos) + static void MultiKeySort(Span input, int pos) { if (!MultiKeySortSmallInput(input, pos)) { @@ -84,14 +85,14 @@ static void MultiKeySort(Span input, int pos) } } - static void MultiKeySortLargeInput(Span input, int pos) + static void MultiKeySortLargeInput(Span input, int pos) { tailcall: - char pivot = TailCharacter(input[0], pos); + byte pivot = TailCharacter(input[0], pos); int l = 0, h = input.Length; for (int i = 1; i < h;) { - char c = TailCharacter(input[i], pos); + byte c = TailCharacter(input[i], pos); if (c > pivot) { (input[l], input[i]) = (input[i], input[l]); @@ -123,7 +124,7 @@ static void MultiKeySortLargeInput(Span input, int pos) } } - static bool MultiKeySortSmallInput(Span input, int pos) + static bool MultiKeySortSmallInput(Span input, int pos) { if (input.Length <= 1) return true; @@ -133,14 +134,14 @@ static bool MultiKeySortSmallInput(Span input, int pos) { while (true) { - char c0 = TailCharacter(input[0], pos); - char c1 = TailCharacter(input[1], pos); + byte c0 = TailCharacter(input[0], pos); + byte c1 = TailCharacter(input[1], pos); if (c0 < c1) { (input[0], input[1]) = (input[1], input[0]); break; } - else if (c0 > c1 || c0 == (char)0) + else if (c0 > c1 || c0 == 0) { break; } @@ -153,21 +154,18 @@ static bool MultiKeySortSmallInput(Span input, int pos) } } - private uint CreateIndex(string text) + private uint CreateIndex(Utf8String text) { uint offset = (uint)_stream.Position; - int reservedBytes = Encoding.UTF8.GetByteCount(text) + 1; - byte[] buffer = ArrayPool.Shared.Rent(reservedBytes); - var span = new Span(buffer, 0, reservedBytes); - Encoding.UTF8.GetBytes(text, span); - span[reservedBytes - 1] = 0; - _stream.Write(span); - ArrayPool.Shared.Return(buffer); + + _stream.Write(text.AsSpan()); + _stream.WriteByte(0); + _stringToOffset[text] = offset; return offset; } - public uint GetStringOffset(string text) + public uint GetStringOffset(Utf8String text) { if (_reservedStrings.Count > 0) { diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/UnixObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/UnixObjectWriter.cs index 3d0a80050e2412..8aba39808e321c 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/UnixObjectWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/UnixObjectWriter.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Buffers.Binary; using ILCompiler.DependencyAnalysis; +using Internal.Text; using Internal.TypeSystem; using Debug = System.Diagnostics.Debug; @@ -19,7 +20,7 @@ namespace ILCompiler.ObjectWriter /// internal abstract partial class UnixObjectWriter : ObjectWriter { - private sealed record UnixSectionDefinition(string SymbolName, Stream SectionStream); + private sealed record UnixSectionDefinition(Utf8String SymbolName, Stream SectionStream); private readonly List _sections = new(); private static readonly ObjectNodeSection LsdaSection = new ObjectNodeSection(".dotnet_eh_table", SectionType.ReadOnly); @@ -30,12 +31,12 @@ protected UnixObjectWriter(NodeFactory factory, ObjectWritingOptions options, Ou { } - private protected override void CreateSection(ObjectNodeSection section, string comdatName, string symbolName, int sectionIndex, Stream sectionStream) + private protected override void CreateSection(ObjectNodeSection section, Utf8String comdatName, Utf8String symbolName, int sectionIndex, Stream sectionStream) { if (section.Type != SectionType.Debug && section != LsdaSection && section != EhFrameSection && - (comdatName is null || Equals(comdatName, symbolName))) + (comdatName.IsNull || Equals(comdatName, symbolName))) { // Record code and data sections that can be referenced from debugging information _sections.Add(new UnixSectionDefinition(symbolName, sectionStream)); diff --git a/src/coreclr/tools/Common/Internal/Text/Utf8String.cs b/src/coreclr/tools/Common/Internal/Text/Utf8String.cs index 5ade766c61d35f..4c8d902809040c 100644 --- a/src/coreclr/tools/Common/Internal/Text/Utf8String.cs +++ b/src/coreclr/tools/Common/Internal/Text/Utf8String.cs @@ -11,6 +11,8 @@ namespace Internal.Text { private readonly byte[] _value; + public bool IsNull => _value == null; + public Utf8String(byte[] underlyingArray) { _value = underlyingArray; @@ -102,5 +104,43 @@ public static Utf8String Concat(params ReadOnlySpan strings) return new Utf8String(result); } + + public static Utf8String Concat(ReadOnlySpan s1, ReadOnlySpan s2) + { + var result = new byte[s1.Length + s2.Length]; + s1.CopyTo(result); + s2.CopyTo(result.AsSpan(s1.Length)); + return new Utf8String(result); + } + + public static Utf8String Concat(ReadOnlySpan s1, ReadOnlySpan s2, ReadOnlySpan s3) + { + var result = new byte[s1.Length + s2.Length + s3.Length]; + s1.CopyTo(result); + s2.CopyTo(result.AsSpan(s1.Length)); + s3.CopyTo(result.AsSpan(s1.Length + s2.Length)); + return new Utf8String(result); + } + + public static Utf8String Concat(ReadOnlySpan s1, ReadOnlySpan s2, ReadOnlySpan s3, ReadOnlySpan s4) + { + var result = new byte[s1.Length + s2.Length + s3.Length + s4.Length]; + s1.CopyTo(result); + s2.CopyTo(result.AsSpan(s1.Length)); + s3.CopyTo(result.AsSpan(s1.Length + s2.Length)); + s4.CopyTo(result.AsSpan(s1.Length + s2.Length + s3.Length)); + return new Utf8String(result); + } + + public static Utf8String Concat(ReadOnlySpan s1, ReadOnlySpan s2, ReadOnlySpan s3, ReadOnlySpan s4, ReadOnlySpan s5) + { + var result = new byte[s1.Length + s2.Length + s3.Length + s4.Length + s5.Length]; + s1.CopyTo(result); + s2.CopyTo(result.AsSpan(s1.Length)); + s3.CopyTo(result.AsSpan(s1.Length + s2.Length)); + s4.CopyTo(result.AsSpan(s1.Length + s2.Length + s3.Length)); + s5.CopyTo(result.AsSpan(s1.Length + s2.Length + s3.Length + s4.Length)); + return new Utf8String(result); + } } } diff --git a/src/coreclr/tools/Common/TypeSystem/TypesDebugInfoWriter/TypesDebugInfoWriter.cs b/src/coreclr/tools/Common/TypeSystem/TypesDebugInfoWriter/TypesDebugInfoWriter.cs index 27ad49899a31a1..b792e754e33066 100644 --- a/src/coreclr/tools/Common/TypeSystem/TypesDebugInfoWriter/TypesDebugInfoWriter.cs +++ b/src/coreclr/tools/Common/TypeSystem/TypesDebugInfoWriter/TypesDebugInfoWriter.cs @@ -32,7 +32,7 @@ uint GetCompleteClassTypeIndex(ClassTypeDescriptor classTypeDescriptor, ClassFie public struct EnumRecordTypeDescriptor { public ulong Value; - public string Name; + public Utf8String Name; } [StructLayout(LayoutKind.Sequential)] @@ -57,13 +57,13 @@ public struct DataFieldDescriptor { public uint FieldTypeIndex; public ulong Offset; - public string Name; + public Utf8String Name; } [StructLayout(LayoutKind.Sequential)] public struct StaticDataFieldDescriptor { - public string StaticDataName; + public Utf8String StaticDataName; public ulong StaticOffset; public int IsStaticDataInObject; } @@ -109,6 +109,6 @@ public struct MemberFunctionIdTypeDescriptor { public uint MemberFunction; public uint ParentClass; - public string Name; + public Utf8String Name; } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index 423d845f8a4760..8ecdb7b7c0d5c3 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -229,11 +229,6 @@ public override bool InterestingForDynamicDependencyAnalysis public override bool StaticDependenciesAreComputed => true; - public static string GetMangledName(TypeDesc type, NameMangler nameMangler) - { - return nameMangler.NodeMangler.MethodTable(type); - } - public virtual void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append(nameMangler.NodeMangler.MethodTable(_type)); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs index bf645650170c38..0d848dabd5b128 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs @@ -39,7 +39,7 @@ public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) public int Offset => 0; public MetadataType Type => _type; - public static string GetMangledName(TypeDesc type, NameMangler nameMangler) + public static Utf8String GetMangledName(TypeDesc type, NameMangler nameMangler) { return nameMangler.NodeMangler.GCStatics(type); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodExceptionHandlingInfoNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodExceptionHandlingInfoNode.cs index 1b1bd06d72de2d..d8705af7f7b1ce 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodExceptionHandlingInfoNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodExceptionHandlingInfoNode.cs @@ -30,7 +30,7 @@ public override ObjectNodeSection GetSection(NodeFactory factory) => _owningMeth public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { - sb.Append("__ehinfo_" + nameMangler.GetMangledMethodName(_owningMethod)); + sb.Append("__ehinfo_"u8).Append(nameMangler.GetMangledMethodName(_owningMethod)); } public int Offset => 0; public override bool IsShareable => true; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs index 68fb7ddfc6b2db..215e62af76874b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -273,15 +273,15 @@ private void CreateNodeCaches() return new FieldRvaDataNode(key); }); - _externFunctionSymbols = new NodeCache((string name) => + _externFunctionSymbols = new NodeCache((Utf8String name) => { return new ExternFunctionSymbolNode(name); }); - _externIndirectFunctionSymbols = new NodeCache((string name) => + _externIndirectFunctionSymbols = new NodeCache((Utf8String name) => { return new ExternFunctionSymbolNode(name, isIndirection: true); }); - _externDataSymbols = new NodeCache((string name) => + _externDataSymbols = new NodeCache((Utf8String name) => { return new ExternDataSymbolNode(name); }); @@ -972,30 +972,30 @@ internal ISymbolNode GenericVariance(GenericVarianceDetails details) return _genericVariances.GetOrAdd(details); } - private NodeCache _externFunctionSymbols; + private NodeCache _externFunctionSymbols; - public ISortableSymbolNode ExternFunctionSymbol(string name) + public ISortableSymbolNode ExternFunctionSymbol(Utf8String name) { return _externFunctionSymbols.GetOrAdd(name); } - private NodeCache _externIndirectFunctionSymbols; + private NodeCache _externIndirectFunctionSymbols; - public ISortableSymbolNode ExternIndirectFunctionSymbol(string name) + public ISortableSymbolNode ExternIndirectFunctionSymbol(Utf8String name) { return _externIndirectFunctionSymbols.GetOrAdd(name); } - private NodeCache _externDataSymbols; + private NodeCache _externDataSymbols; - public ISortableSymbolNode ExternDataSymbol(string name) + public ISortableSymbolNode ExternDataSymbol(Utf8String name) { return _externDataSymbols.GetOrAdd(name); } - public ISortableSymbolNode ExternVariable(string name) + public ISortableSymbolNode ExternVariable(Utf8String name) { - string mangledName = NameMangler.NodeMangler.ExternVariable(name); + Utf8String mangledName = NameMangler.NodeMangler.ExternVariable(name); return _externDataSymbols.GetOrAdd(mangledName); } @@ -1563,12 +1563,12 @@ public AnalysisCharacteristicNode AnalysisCharacteristic(string ch) /// Returns alternative symbol name that object writer should produce for given symbols /// in addition to the regular one. /// - public string GetSymbolAlternateName(ISymbolNode node, out bool isHidden) + public Utf8String GetSymbolAlternateName(ISymbolNode node, out bool isHidden) { if (!NodeAliases.TryGetValue(node, out var value)) { isHidden = false; - return null; + return default; } isHidden = value.Hidden; @@ -1595,7 +1595,7 @@ public string GetSymbolAlternateName(ISymbolNode node, out bool isHidden) public ReadyToRunHeaderNode ReadyToRunHeader; - public Dictionary NodeAliases = new Dictionary(); + public Dictionary NodeAliases = new Dictionary(); protected internal TypeManagerIndirectionNode TypeManagerIndirection = new TypeManagerIndirectionNode(); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs index e03cad4f078dfe..9cc8edccb96717 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs @@ -71,7 +71,7 @@ protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory) } } - public static string GetMangledName(TypeDesc type, NameMangler nameMangler) + public static Utf8String GetMangledName(TypeDesc type, NameMangler nameMangler) { return nameMangler.NodeMangler.NonGCStatics(type); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs index f0b9fbf532457e..2d994f76ec054c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/SealedVTableNode.cs @@ -34,7 +34,7 @@ public SealedVTableNode(TypeDesc type) public virtual void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { - sb.Append(nameMangler.CompilationUnitPrefix + "__SealedVTable_" + nameMangler.NodeMangler.MethodTable(_type)); + sb.Append(nameMangler.CompilationUnitPrefix).Append("__SealedVTable_"u8).Append(nameMangler.NodeMangler.MethodTable(_type)); } int ISymbolNode.Offset => 0; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs index f024dd24e13458..26526a19f508b3 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs @@ -37,7 +37,7 @@ protected override void OnMarked(NodeFactory factory) factory.ThreadStaticsRegion.AddEmbeddedObject(this); } - public static string GetMangledName(TypeDesc type, NameMangler nameMangler) + public static Utf8String GetMangledName(TypeDesc type, NameMangler nameMangler) { return nameMangler.NodeMangler.ThreadStatics(type); } @@ -48,7 +48,7 @@ public static string GetMangledName(TypeDesc type, NameMangler nameMangler) public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { - string mangledName = _type == null ? "_inlinedThreadStatics" : GetMangledName(_type, nameMangler); + Utf8String mangledName = _type == null ? "_inlinedThreadStatics" : GetMangledName(_type, nameMangler); sb.Append(mangledName); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/UnboxingStubNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/UnboxingStubNode.cs index bf7eeaea29e917..f3c764057b80fc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/UnboxingStubNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/UnboxingStubNode.cs @@ -41,9 +41,9 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde sb.Append("unbox_"u8).Append(nameMangler.GetMangledMethodName(Method)); } - public static string GetMangledName(NameMangler nameMangler, MethodDesc method) + public static Utf8String GetMangledName(NameMangler nameMangler, MethodDesc method) { - return "unbox_" + nameMangler.GetMangledMethodName(method); + return Utf8String.Concat("unbox_"u8, nameMangler.GetMangledMethodName(method).AsSpan()); } protected override string GetName(NodeFactory factory) => this.GetMangledName(factory.NameMangler); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs index 74bdcbdac01c8e..8896d68dac3f62 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Internal.Text; using Internal.TypeSystem; namespace ILCompiler @@ -10,7 +11,8 @@ namespace ILCompiler /// public interface IRootingServiceProvider { - void AddCompilationRoot(MethodDesc method, string reason, string exportName = null, bool exportHidden = false); + void AddCompilationRoot(MethodDesc method, string reason) => AddCompilationRoot(method, reason, default); + void AddCompilationRoot(MethodDesc method, string reason, Utf8String exportName, bool exportHidden = false); void AddCompilationRoot(TypeDesc type, string reason); void AddReflectionRoot(TypeDesc type, string reason); void AddReflectionRoot(MethodDesc method, string reason); @@ -19,7 +21,7 @@ public interface IRootingServiceProvider void RootGCStaticBaseForType(TypeDesc type, string reason); void RootNonGCStaticBaseForType(TypeDesc type, string reason); void RootModuleMetadata(ModuleDesc module, string reason); - void RootReadOnlyDataBlob(byte[] data, int alignment, string reason, string exportName, bool exportHidden); + void RootReadOnlyDataBlob(byte[] data, int alignment, string reason, Utf8String exportName, bool exportHidden); void RootDelegateMarshallingData(DefType type, string reason); void RootStructMarshallingData(DefType type, string reason); void AddCompilationRoot(object o, string reason); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs index bcf71ddab35b1d..5c42fc88f68062 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/NodeMangler.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Internal.Text; using Internal.TypeSystem; namespace ILCompiler @@ -14,19 +15,19 @@ public abstract class NodeMangler { public NameMangler NameMangler; - protected const string GenericDictionaryNamePrefix = "__GenericDict_"; + protected static readonly Utf8String GenericDictionaryNamePrefix = new Utf8String("__GenericDict_"); // Mangled name of boxed version of a type - public abstract string MangledBoxedTypeName(TypeDesc type); + public abstract Utf8String MangledBoxedTypeName(TypeDesc type); - public abstract string MethodTable(TypeDesc type); - public abstract string GCStatics(TypeDesc type); - public abstract string NonGCStatics(TypeDesc type); - public abstract string ThreadStatics(TypeDesc type); - public abstract string ThreadStaticsIndex(TypeDesc type); - public abstract string TypeGenericDictionary(TypeDesc type); - public abstract string MethodGenericDictionary(MethodDesc method); - public abstract string ExternMethod(string unmangledName, MethodDesc method); - public abstract string ExternVariable(string unmangledName); + public abstract Utf8String MethodTable(TypeDesc type); + public abstract Utf8String GCStatics(TypeDesc type); + public abstract Utf8String NonGCStatics(TypeDesc type); + public abstract Utf8String ThreadStatics(TypeDesc type); + public abstract Utf8String ThreadStaticsIndex(TypeDesc type); + public abstract Utf8String TypeGenericDictionary(TypeDesc type); + public abstract Utf8String MethodGenericDictionary(MethodDesc method); + public abstract Utf8String ExternMethod(Utf8String unmangledName, MethodDesc method); + public abstract Utf8String ExternVariable(Utf8String unmangledName); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs index 7c8a0bbc7ae32c..9092b870f818da 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectDataInterner.cs @@ -69,7 +69,7 @@ private void EnsureMap(NodeFactory factory) // Bodies that are visible from outside should not be folded because we don't know // if they're address taken. - if (factory.GetSymbolAlternateName(body, out _) != null) + if (!factory.GetSymbolAlternateName(body, out _).IsNull) continue; var key = new MethodInternKey(body, factory); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CodeView/CodeViewSymbolsBuilder.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CodeView/CodeViewSymbolsBuilder.cs index 132b97a0e99aa3..2ca792fd6645a1 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CodeView/CodeViewSymbolsBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CodeView/CodeViewSymbolsBuilder.cs @@ -112,7 +112,7 @@ private CodeViewRegister GetCVRegNum(uint regNum) } public void EmitSubprogramInfo( - string methodName, + Utf8String methodName, int methodPCLength, uint methodTypeIndex, IEnumerable<(DebugVarInfoMetadata, uint)> debugVars, @@ -220,7 +220,7 @@ public void EmitSubprogramInfo( public void EmitLineInfo( CodeViewFileTableBuilder fileTableBuilder, - string methodName, + Utf8String methodName, int methodPCLength, IEnumerable sequencePoints) { @@ -300,7 +300,7 @@ private sealed class SubsectionWriter : IDisposable private readonly SectionWriter _sectionWriter; internal uint _size; internal readonly List _data = new(); - internal readonly List<(uint, RelocType, string)> _relocations = new(); + internal readonly List<(uint, RelocType, Utf8String)> _relocations = new(); public SubsectionWriter(DebugSymbolsSubsectionType kind, SectionWriter sectionWriter) { @@ -416,7 +416,7 @@ public void Write(string value) public void EmitSymbolReference( RelocType relocType, - string symbolName, + Utf8String symbolName, int addend = 0) { _subsectionWriter._relocations.Add(( diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CoffObjectWriter.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CoffObjectWriter.Aot.cs index 78f0dad8ed5284..ebc36125afe188 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CoffObjectWriter.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/CoffObjectWriter.Aot.cs @@ -14,6 +14,7 @@ using System.Text; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; +using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.TypesDebugInfo; using static ILCompiler.DependencyAnalysis.RelocType; @@ -66,7 +67,7 @@ private protected override void CreateEhSections() private protected override void EmitUnwindInfo( SectionWriter sectionWriter, INodeWithCodeInfo nodeWithCodeInfo, - string currentSymbolName) + Utf8String currentSymbolName) { if (nodeWithCodeInfo.FrameInfos is FrameInfo[] frameInfos && nodeWithCodeInfo is ISymbolDefinitionNode) @@ -75,6 +76,8 @@ private protected override void EmitUnwindInfo( SectionWriter pdataSectionWriter; bool shareSymbol = ShouldShareSymbol((ObjectNode)nodeWithCodeInfo); + Span i_str = stackalloc byte[16]; + for (int i = 0; i < frameInfos.Length; i++) { FrameInfo frameInfo = frameInfos[i]; @@ -83,13 +86,17 @@ private protected override void EmitUnwindInfo( int end = frameInfo.EndOffset; byte[] blob = frameInfo.BlobData; - string unwindSymbolName = $"_unwind{i}{currentSymbolName}"; + _utf8StringBuilder.Clear() + .Append("_unwind"u8) + .Append(FormatUtf8Int(i_str, i)) + .Append(currentSymbolName); + Utf8String unwindSymbolName = _utf8StringBuilder.ToUtf8String(); if (shareSymbol) { // Produce an associative COMDAT symbol. xdataSectionWriter = GetOrCreateSection(ObjectNodeSection.XDataSection, currentSymbolName, unwindSymbolName); - pdataSectionWriter = GetOrCreateSection(ObjectNodeSection.PDataSection, currentSymbolName, null); + pdataSectionWriter = GetOrCreateSection(ObjectNodeSection.PDataSection, currentSymbolName, default); } else { @@ -179,7 +186,7 @@ private protected override ITypesDebugInfoWriter CreateDebugInfoBuilder() private protected override void EmitDebugFunctionInfo( uint methodTypeIndex, - string methodName, + Utf8String methodName, SymbolDefinition methodSymbol, INodeWithDebugInfo debugNode, bool hasSequencePoints) @@ -196,7 +203,7 @@ private protected override void EmitDebugFunctionInfo( { // If the method is emitted in COMDAT section then we need to create an // associated COMDAT section for the debugging symbols. - var sectionWriter = GetOrCreateSection(DebugSymbolSection, methodName, null); + var sectionWriter = GetOrCreateSection(DebugSymbolSection, methodName, default); debugSymbolsBuilder = new CodeViewSymbolsBuilder(_nodeFactory.Target.Architecture, sectionWriter); } else @@ -222,7 +229,7 @@ private protected override void EmitDebugFunctionInfo( } private protected override void EmitDebugThunkInfo( - string methodName, + Utf8String methodName, SymbolDefinition methodSymbol, INodeWithDebugInfo debugNode) { @@ -235,7 +242,7 @@ private protected override void EmitDebugThunkInfo( { // If the method is emitted in COMDAT section then we need to create an // associated COMDAT section for the debugging symbols. - var sectionWriter = GetOrCreateSection(DebugSymbolSection, methodName, null); + var sectionWriter = GetOrCreateSection(DebugSymbolSection, methodName, default); debugSymbolsBuilder = new CodeViewSymbolsBuilder(_nodeFactory.Target.Architecture, sectionWriter); } else @@ -250,7 +257,7 @@ private protected override void EmitDebugThunkInfo( debugNode.GetNativeSequencePoints()); } - private protected override void EmitDebugSections(IDictionary definedSymbols) + private protected override void EmitDebugSections(IDictionary definedSymbols) { _debugSymbolsBuilder.WriteUserDefinedTypes(_debugTypesBuilder.UserDefinedTypes); _debugFileTableBuilder.Write(_debugSymbolSectionWriter); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfBuilder.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfBuilder.cs index 4dcccbdd32fc41..0f63ef910c893c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfBuilder.cs @@ -17,9 +17,9 @@ namespace ILCompiler.ObjectWriter { internal sealed class DwarfBuilder : ITypesDebugInfoWriter { - private record struct SectionInfo(string SectionSymbolName, ulong Size); + private record struct SectionInfo(Utf8String SectionSymbolName, ulong Size); private record struct MemberFunctionTypeInfo(MemberFunctionTypeDescriptor MemberDescriptor, uint[] ArgumentTypes, bool IsStatic); - public delegate (string SectionSymbolName, long Address) ResolveStaticVariable(string name); + public delegate (Utf8String SectionSymbolName, long Address) ResolveStaticVariable(Utf8String name); private readonly NameMangler _nameMangler; private readonly TargetArchitecture _architecture; @@ -201,8 +201,8 @@ public void WriteInfoTable( foreach (DwarfStaticVariableInfo staticField in _staticFields) { - (string sectionSymbolName, long address) = resolveStaticVariable(staticField.Name); - if (sectionSymbolName is not null) + (Utf8String sectionSymbolName, long address) = resolveStaticVariable(staticField.Name); + if (!sectionSymbolName.IsNull) { staticField.Dump(dwarfInfoWriter, sectionSymbolName, address); } @@ -429,8 +429,8 @@ public Utf8String GetMangledName(TypeDesc type) } public void EmitSubprogramInfo( - string methodName, - string sectionSymbolName, + Utf8String methodName, + Utf8String sectionSymbolName, long methodAddress, int methodPCLength, uint methodTypeIndex, @@ -456,7 +456,7 @@ public void EmitSubprogramInfo( public void EmitLineInfo( int sectionIndex, - string sectionSymbolName, + Utf8String sectionSymbolName, long methodAddress, IEnumerable sequencePoints) { @@ -493,7 +493,7 @@ public void EmitLineInfo( } } - public void EmitSectionInfo(string sectionSymbolName, ulong size) + public void EmitSectionInfo(Utf8String sectionSymbolName, ulong size) { _sections.Add(new SectionInfo(sectionSymbolName, size)); } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfEhFrame.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfEhFrame.cs index 3e207ffe296129..bc4d835eacac4e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfEhFrame.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfEhFrame.cs @@ -171,9 +171,9 @@ private uint AddressSize(byte encoding) } } - private void WriteAddress(byte encoding, string symbolName, long symbolOffset = 0) + private void WriteAddress(byte encoding, Utf8String symbolName, long symbolOffset = 0) { - if (symbolName != null) + if (!symbolName.IsNull) { RelocType relocationType = encoding switch { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs index f405fddde48a6b..4c1444c179a701 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfFde.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Diagnostics; using System.Buffers; +using System.Diagnostics; + +using Internal.Text; + using static ILCompiler.ObjectWriter.DwarfNative; namespace ILCompiler.ObjectWriter @@ -12,20 +15,20 @@ internal readonly struct DwarfFde { public readonly DwarfCie Cie; public readonly byte[] Instructions; - public readonly string PcStartSymbolName; + public readonly Utf8String PcStartSymbolName; public readonly long PcStartSymbolOffset; public readonly ulong PcLength; - public readonly string LsdaSymbolName; - public readonly string PersonalitySymbolName; + public readonly Utf8String LsdaSymbolName; + public readonly Utf8String PersonalitySymbolName; public DwarfFde( DwarfCie cie, byte[] blobData, - string pcStartSymbolName, + Utf8String pcStartSymbolName, long pcStartSymbolOffset, ulong pcLength, - string lsdaSymbolName, - string personalitySymbolName) + Utf8String lsdaSymbolName, + Utf8String personalitySymbolName) { Cie = cie; Instructions = CfiCodeToInstructions(cie, blobData); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfo.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfo.cs index fa02122c9a8793..4ce33dbbe5d815 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfo.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfo.cs @@ -7,6 +7,7 @@ using System.Linq; using ILCompiler.DependencyAnalysis; using Internal.JitInterface; +using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.TypesDebugInfo; using static ILCompiler.ObjectWriter.DwarfNative; @@ -194,15 +195,15 @@ public override void Dump(DwarfInfoWriter writer) internal sealed class DwarfMemberFunction { - public string Name { get; private set; } - public string LinkageName { get; set; } + public Utf8String Name { get; private set; } + public Utf8String LinkageName { get; set; } public MemberFunctionTypeDescriptor Descriptor { get; private set; } public uint[] ArgumentTypes { get; private set; } public bool IsStatic { get; private set; } public long InfoOffset { get; set; } public DwarfMemberFunction( - string name, + Utf8String name, MemberFunctionTypeDescriptor descriptor, uint[] argumentTypes, bool isStatic) @@ -360,7 +361,7 @@ public override void Dump(DwarfInfoWriter writer) internal sealed class DwarfSubprogramInfo : DwarfInfo { - private readonly string _sectionSymbolName; + private readonly Utf8String _sectionSymbolName; private readonly long _methodAddress; private readonly int _methodSize; private readonly DwarfMemberFunction _memberFunction; @@ -370,7 +371,7 @@ internal sealed class DwarfSubprogramInfo : DwarfInfo private readonly bool _hasChildren; public DwarfSubprogramInfo( - string sectionSymbolName, + Utf8String sectionSymbolName, long methodAddress, int methodSize, DwarfMemberFunction memberFunction, @@ -553,14 +554,14 @@ internal sealed class DwarfStaticVariableInfo private readonly StaticDataFieldDescriptor _descriptor; public long InfoOffset { get; set; } - public string Name => _descriptor.StaticDataName; + public Utf8String Name => _descriptor.StaticDataName; public DwarfStaticVariableInfo(StaticDataFieldDescriptor descriptor) { _descriptor = descriptor; } - public void Dump(DwarfInfoWriter writer, string sectionSymbolName, long address) + public void Dump(DwarfInfoWriter writer, Utf8String sectionSymbolName, long address) { writer.WriteStartDIE(DwarfAbbrev.VariableStatic); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfoWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfoWriter.cs index 89d42674ab4457..935b6c397c6256 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfoWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfInfoWriter.cs @@ -137,7 +137,7 @@ public void WriteInfoReference(uint typeIndex) } } - public void WriteCodeReference(string sectionSymbolName, long offset = 0) + public void WriteCodeReference(Utf8String sectionSymbolName, long offset = 0) { Debug.Assert(offset >= 0); _infoSectionWriter.EmitSymbolReference(_codeRelocType, sectionSymbolName, offset); @@ -169,7 +169,7 @@ public void WriteStartLocationList() _infoSectionWriter.EmitSymbolReference(RelocType.IMAGE_REL_BASED_HIGHLOW, ".debug_loc", (int)offset); } - public void WriteLocationListExpression(string methodName, long startOffset, long endOffset, DwarfExpressionBuilder expressionBuilder) + public void WriteLocationListExpression(Utf8String methodName, long startOffset, long endOffset, DwarfExpressionBuilder expressionBuilder) { _ = expressionBuilder; _locSectionWriter.EmitSymbolReference(_codeRelocType, methodName, startOffset); @@ -190,7 +190,7 @@ public void WriteStartRangeList() _infoSectionWriter.EmitSymbolReference(RelocType.IMAGE_REL_BASED_HIGHLOW, ".debug_ranges", offset); } - public void WriteRangeListEntry(string symbolName, long startOffset, long endOffset) + public void WriteRangeListEntry(Utf8String symbolName, long startOffset, long endOffset) { _rangeSectionWriter.EmitSymbolReference(_codeRelocType, symbolName, startOffset); _rangeSectionWriter.EmitSymbolReference(_codeRelocType, symbolName, endOffset); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfLineSequenceWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfLineSequenceWriter.cs index 2fa8650b0afa89..c7eca4d7e0bfd8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfLineSequenceWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/Dwarf/DwarfLineSequenceWriter.cs @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; using ILCompiler.DependencyAnalysis; +using Internal.Text; using static ILCompiler.ObjectWriter.DwarfNative; namespace ILCompiler.ObjectWriter @@ -11,7 +12,7 @@ namespace ILCompiler.ObjectWriter internal sealed class DwarfLineSequenceWriter { private readonly ArrayBufferWriter _writer; - private readonly string _sectionName; + private readonly Utf8String _sectionName; private readonly byte _minimumInstructionLength; private readonly uint _maxDeltaAddressPerSpecialCode; @@ -21,7 +22,7 @@ internal sealed class DwarfLineSequenceWriter private int _line = 1; private int _column; - public DwarfLineSequenceWriter(string sectionName, byte minimumInstructionLength) + public DwarfLineSequenceWriter(Utf8String sectionName, byte minimumInstructionLength) { _writer = new ArrayBufferWriter(); _sectionName = sectionName; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.Aot.cs index 9652211fa0ddc2..8a40fc8e8fdb9f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ElfObjectWriter.Aot.cs @@ -2,14 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Buffers.Binary; using System.Collections.Generic; -using System.IO; using System.Diagnostics; -using System.Buffers.Binary; +using System.IO; using System.Numerics; using System.Reflection; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; +using Internal.Text; using Internal.TypeSystem; using static ILCompiler.DependencyAnalysis.RelocType; using static ILCompiler.ObjectWriter.EabiNative; @@ -50,7 +51,7 @@ private protected override void CreateEhSections() private protected override void EmitUnwindInfo( SectionWriter sectionWriter, INodeWithCodeInfo nodeWithCodeInfo, - string currentSymbolName) + Utf8String currentSymbolName) { if (_machine is not EM_ARM) { @@ -66,8 +67,8 @@ private protected override void EmitUnwindInfo( if (ShouldShareSymbol((ObjectNode)nodeWithCodeInfo)) { - exidxSectionWriter = GetOrCreateSection(ArmUnwindIndexSection, currentSymbolName, $"_unwind0{currentSymbolName}"); - extabSectionWriter = GetOrCreateSection(ArmUnwindTableSection, currentSymbolName, $"_extab0{currentSymbolName}"); + exidxSectionWriter = GetOrCreateSection(ArmUnwindIndexSection, currentSymbolName, Utf8String.Concat("_unwind0"u8, currentSymbolName.AsSpan())); + extabSectionWriter = GetOrCreateSection(ArmUnwindTableSection, currentSymbolName, Utf8String.Concat("_extab0"u8, currentSymbolName.AsSpan())); _sections[exidxSectionWriter.SectionIndex].LinkSection = _sections[sectionWriter.SectionIndex]; } else @@ -90,6 +91,7 @@ private protected override void EmitUnwindInfo( long mainLsdaOffset = 0; Span unwindWord = stackalloc byte[4]; + Span i_str = stackalloc byte[16]; for (int i = 0; i < frameInfos.Length; i++) { FrameInfo frameInfo = frameInfos[i]; @@ -97,8 +99,8 @@ private protected override void EmitUnwindInfo( int end = frameInfo.EndOffset; byte[] blob = frameInfo.BlobData; - string framSymbolName = $"_fram{i}{currentSymbolName}"; - string extabSymbolName = $"_extab{i}{currentSymbolName}"; + Utf8String framSymbolName = _utf8StringBuilder.Clear().Append("_fram"u8).Append(FormatUtf8Int(i_str, i)).Append(currentSymbolName).ToUtf8String(); + Utf8String extabSymbolName = _utf8StringBuilder.Clear().Append("_extab"u8).Append(FormatUtf8Int(i_str, i)).Append(currentSymbolName).ToUtf8String(); sectionWriter.EmitSymbolDefinition(framSymbolName, start); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.Aot.cs index 76cdb395b8228f..6cb3f71f117d88 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.Aot.cs @@ -12,6 +12,7 @@ using System.Text; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; +using Internal.Text; using Internal.TypeSystem; using static ILCompiler.DependencyAnalysis.RelocType; using static ILCompiler.ObjectWriter.MachNative; @@ -56,7 +57,7 @@ namespace ILCompiler.ObjectWriter /// internal sealed partial class MachObjectWriter : UnixObjectWriter { - private sealed record CompactUnwindCode(string PcStartSymbolName, uint PcLength, uint Code, string LsdaSymbolName = null, string PersonalitySymbolName = null); + private sealed record CompactUnwindCode(Utf8String PcStartSymbolName, uint PcLength, uint Code, Utf8String LsdaSymbolName, Utf8String PersonalitySymbolName); // Exception handling sections private MachSection _compactUnwindSection; @@ -66,7 +67,7 @@ private sealed record CompactUnwindCode(string PcStartSymbolName, uint PcLength, private bool IsEhFrameSection(int sectionIndex) => sectionIndex == EhFrameSectionIndex; - partial void EmitCompactUnwindTable(IDictionary definedSymbols) + partial void EmitCompactUnwindTable(IDictionary definedSymbols) { _compactUnwindStream = new MemoryStream(32 * _compactUnwindCodes.Count); // Preset the size of the compact unwind section which is not generated yet @@ -90,10 +91,10 @@ partial void EmitCompactUnwindTable(IDictionary define EmitCompactUnwindSymbol(cu.LsdaSymbolName); } - void EmitCompactUnwindSymbol(string symbolName) + void EmitCompactUnwindSymbol(Utf8String symbolName) { Span tempBuffer = stackalloc byte[8]; - if (symbolName is not null) + if (!symbolName.IsNull) { SymbolDefinition symbol = definedSymbols[symbolName]; MachSection section = _sections[symbol.SectionIndex]; @@ -273,7 +274,7 @@ private static uint GetArm64CompactUnwindCode(byte[] blobData) return unwindCode; } - private protected override bool EmitCompactUnwinding(string startSymbolName, ulong length, string lsdaSymbolName, byte[] blob) + private protected override bool EmitCompactUnwinding(Utf8String startSymbolName, ulong length, Utf8String lsdaSymbolName, byte[] blob) { uint encoding = _compactUnwindDwarfCode; @@ -285,8 +286,9 @@ private protected override bool EmitCompactUnwinding(string startSymbolName, ulo _compactUnwindCodes.Add(new CompactUnwindCode( PcStartSymbolName: startSymbolName, PcLength: (uint)length, - Code: encoding | (encoding != _compactUnwindDwarfCode && lsdaSymbolName is not null ? 0x40000000u : 0), // UNWIND_HAS_LSDA - LsdaSymbolName: encoding != _compactUnwindDwarfCode ? lsdaSymbolName : null + Code: encoding | (encoding != _compactUnwindDwarfCode && !lsdaSymbolName.IsNull ? 0x40000000u : 0), // UNWIND_HAS_LSDA + LsdaSymbolName: encoding != _compactUnwindDwarfCode ? lsdaSymbolName : default, + PersonalitySymbolName: default )); return encoding != _compactUnwindDwarfCode; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs index 03717aa881eef5..fd9c43327f3811 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs @@ -9,6 +9,7 @@ using System.Linq; using ILCompiler.DependencyAnalysis; using ILCompiler.DependencyAnalysisFramework; +using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.TypesDebugInfo; using ObjectData = ILCompiler.DependencyAnalysis.ObjectNode.ObjectData; @@ -24,7 +25,7 @@ public abstract partial class ObjectWriter private protected abstract void EmitUnwindInfo( SectionWriter sectionWriter, INodeWithCodeInfo nodeWithCodeInfo, - string currentSymbolName); + Utf8String currentSymbolName); private protected uint GetVarTypeIndex(bool isStateMachineMoveNextMethod, DebugVarInfoMetadata debugVar) { @@ -55,19 +56,19 @@ private protected uint GetVarTypeIndex(bool isStateMachineMoveNextMethod, DebugV private protected abstract void EmitDebugFunctionInfo( uint methodTypeIndex, - string methodName, + Utf8String methodName, SymbolDefinition methodSymbol, INodeWithDebugInfo debugNode, bool hasSequencePoints); private protected virtual void EmitDebugThunkInfo( - string methodName, + Utf8String methodName, SymbolDefinition methodSymbol, INodeWithDebugInfo debugNode) { } - private protected abstract void EmitDebugSections(IDictionary definedSymbols); + private protected abstract void EmitDebugSections(IDictionary definedSymbols); partial void EmitDebugInfo(IReadOnlyCollection nodes, Logger logger) { @@ -99,7 +100,7 @@ partial void EmitDebugInfo(IReadOnlyCollection nodes, Logger log if (node is INodeWithDebugInfo debugNode and ISymbolDefinitionNode symbolDefinitionNode) { - string methodName = GetMangledName(symbolDefinitionNode); + Utf8String methodName = GetMangledName(symbolDefinitionNode); if (_definedSymbols.TryGetValue(methodName, out var methodSymbol)) { if (node is IMethodNode methodNode) @@ -129,7 +130,7 @@ partial void EmitDebugInfo(IReadOnlyCollection nodes, Logger log partial void PrepareForUnwindInfo() => CreateEhSections(); - partial void EmitUnwindInfoForNode(ObjectNode node, string currentSymbolName, SectionWriter sectionWriter) + partial void EmitUnwindInfoForNode(ObjectNode node, Utf8String currentSymbolName, SectionWriter sectionWriter) { if (node is INodeWithCodeInfo nodeWithCodeInfo) { @@ -137,7 +138,7 @@ partial void EmitUnwindInfoForNode(ObjectNode node, string currentSymbolName, Se } } - partial void HandleControlFlowForRelocation(ISymbolNode relocTarget, string relocSymbolName) + partial void HandleControlFlowForRelocation(ISymbolNode relocTarget, Utf8String relocSymbolName) { if (relocTarget is IMethodNode or AssemblyStubNode or AddressTakenExternFunctionSymbolNode) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/UnixObjectWriter.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/UnixObjectWriter.Aot.cs index 70923f97089317..85ecb3d0bb70e5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/UnixObjectWriter.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/UnixObjectWriter.Aot.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Buffers.Binary; using ILCompiler.DependencyAnalysis; +using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.TypesDebugInfo; @@ -41,7 +42,7 @@ internal abstract partial class UnixObjectWriter : ObjectWriter private protected virtual bool UseFrameNames => false; - private protected virtual bool EmitCompactUnwinding(string startSymbolName, ulong length, string lsdaSymbolName, byte[] blob) => false; + private protected virtual bool EmitCompactUnwinding(Utf8String startSymbolName, ulong length, Utf8String lsdaSymbolName, byte[] blob) => false; private protected override void CreateEhSections() { @@ -96,13 +97,13 @@ private protected void EmitLsda( if (associatedDataNode is not null) { - string symbolName = GetMangledName(associatedDataNode); + Utf8String symbolName = GetMangledName(associatedDataNode); lsdaSectionWriter.EmitSymbolReference(RelocType.IMAGE_REL_BASED_RELPTR32, symbolName, 0); } if (ehInfo is not null) { - string symbolName = GetMangledName(ehInfo); + Utf8String symbolName = GetMangledName(ehInfo); lsdaSectionWriter.EmitSymbolReference(RelocType.IMAGE_REL_BASED_RELPTR32, symbolName, 0); } @@ -144,18 +145,18 @@ public int GetHashCode(INodeWithCodeInfo obj) } } - private Dictionary _lsdas = new Dictionary(LsdaComparer.Instance); + private Dictionary _lsdas = new Dictionary(LsdaComparer.Instance); public static bool IsCacheable(INodeWithCodeInfo nodeWithCodeInfo) => nodeWithCodeInfo.EHInfo == null && !MethodAssociatedDataNode.MethodHasAssociatedData((IMethodNode)nodeWithCodeInfo); - public string[] FindCachedLsda(INodeWithCodeInfo nodeWithCodeInfo) + public Utf8String[] FindCachedLsda(INodeWithCodeInfo nodeWithCodeInfo) { Debug.Assert(IsCacheable(nodeWithCodeInfo)); return _lsdas.GetValueOrDefault(nodeWithCodeInfo); } - public void AddLsdaToCache(INodeWithCodeInfo nodeWithCodeInfo, string[] symbols) + public void AddLsdaToCache(INodeWithCodeInfo nodeWithCodeInfo, Utf8String[] symbols) { Debug.Assert(IsCacheable(nodeWithCodeInfo)); _lsdas.Add(nodeWithCodeInfo, symbols); @@ -167,7 +168,7 @@ public void AddLsdaToCache(INodeWithCodeInfo nodeWithCodeInfo, string[] symbols) private protected override void EmitUnwindInfo( SectionWriter sectionWriter, INodeWithCodeInfo nodeWithCodeInfo, - string currentSymbolName) + Utf8String currentSymbolName) { if (nodeWithCodeInfo.FrameInfos is FrameInfo[] frameInfos && nodeWithCodeInfo is ISymbolDefinitionNode) @@ -175,11 +176,11 @@ private protected override void EmitUnwindInfo( bool useFrameNames = UseFrameNames; SectionWriter lsdaSectionWriter; - string[] newLsdaSymbols = null; - string[] emittedLsdaSymbols = null; + Utf8String[] newLsdaSymbols = null; + Utf8String[] emittedLsdaSymbols = null; if (ShouldShareSymbol((ObjectNode)nodeWithCodeInfo)) { - lsdaSectionWriter = GetOrCreateSection(LsdaSection, currentSymbolName, $"_lsda0{currentSymbolName}"); + lsdaSectionWriter = GetOrCreateSection(LsdaSection, currentSymbolName, Utf8String.Concat("_lsda0"u8, currentSymbolName.AsSpan())); } else { @@ -188,11 +189,12 @@ private protected override void EmitUnwindInfo( { emittedLsdaSymbols = _lsdaCache.FindCachedLsda(nodeWithCodeInfo); if (emittedLsdaSymbols == null) - newLsdaSymbols = new string[frameInfos.Length]; + newLsdaSymbols = new Utf8String[frameInfos.Length]; } } long mainLsdaOffset = 0; + Span i_str = stackalloc byte[16]; for (int i = 0; i < frameInfos.Length; i++) { FrameInfo frameInfo = frameInfos[i]; @@ -201,27 +203,27 @@ private protected override void EmitUnwindInfo( int end = frameInfo.EndOffset; byte[] blob = frameInfo.BlobData; - string lsdaSymbolName; + Utf8String lsdaSymbolName; if (emittedLsdaSymbols != null) { lsdaSymbolName = emittedLsdaSymbols[i]; } else { - lsdaSymbolName = $"_lsda{i}{currentSymbolName}"; + lsdaSymbolName = _utf8StringBuilder.Clear().Append("_lsda"u8).Append(FormatUtf8Int(i_str, i)).Append(currentSymbolName).ToUtf8String(); if (newLsdaSymbols != null) newLsdaSymbols[i] = lsdaSymbolName; lsdaSectionWriter.EmitSymbolDefinition(lsdaSymbolName); EmitLsda(nodeWithCodeInfo, frameInfos, i, _lsdaSectionWriter, ref mainLsdaOffset); } - string framSymbolName = $"_fram{i}{currentSymbolName}"; + Utf8String framSymbolName = _utf8StringBuilder.Clear().Append("_fram"u8).Append(FormatUtf8Int(i_str, i)).Append(currentSymbolName).ToUtf8String(); if (useFrameNames && start != 0) { sectionWriter.EmitSymbolDefinition(framSymbolName, start); } - string startSymbolName = useFrameNames && start != 0 ? framSymbolName : currentSymbolName; + Utf8String startSymbolName = useFrameNames && start != 0 ? framSymbolName : currentSymbolName; ulong length = (ulong)(end - start); if (!EmitCompactUnwinding(startSymbolName, length, lsdaSymbolName, blob)) { @@ -232,7 +234,7 @@ private protected override void EmitUnwindInfo( pcStartSymbolOffset: useFrameNames ? 0 : start, pcLength: (ulong)(end - start), lsdaSymbolName, - personalitySymbolName: null); + personalitySymbolName: default); _dwarfEhFrame.AddFde(fde); } } @@ -244,7 +246,7 @@ private protected override void EmitUnwindInfo( private protected override void EmitDebugFunctionInfo( uint methodTypeIndex, - string methodName, + Utf8String methodName, SymbolDefinition methodSymbol, INodeWithDebugInfo debugNode, bool hasSequencePoints) @@ -278,7 +280,7 @@ private protected override void EmitDebugFunctionInfo( } } - private protected override void EmitDebugSections(IDictionary definedSymbols) + private protected override void EmitDebugSections(IDictionary definedSymbols) { foreach (UnixSectionDefinition section in _sections) { @@ -311,7 +313,7 @@ private protected override void EmitDebugSections(IDictionary typeNameLengthStr = stackalloc byte[16]; + mangledJustTypeName.Length.TryFormat(typeNameLengthStr, out int written); - return "_ZTV" + mangledJustTypeName.Length.ToString(CultureInfo.InvariantCulture) + mangledJustTypeName; + return Utf8String.Concat("_ZTV"u8, typeNameLengthStr.Slice(0, written), mangledJustTypeName.AsSpan()); } - public sealed override string GCStatics(TypeDesc type) + public sealed override Utf8String GCStatics(TypeDesc type) { - return "__GCSTATICS" + NameMangler.GetMangledTypeName(type); + return Utf8String.Concat("__GCSTATICS"u8, NameMangler.GetMangledTypeName(type).AsSpan()); } - public sealed override string NonGCStatics(TypeDesc type) + public sealed override Utf8String NonGCStatics(TypeDesc type) { - return "__NONGCSTATICS" + NameMangler.GetMangledTypeName(type); + return Utf8String.Concat("__NONGCSTATICS"u8, NameMangler.GetMangledTypeName(type).AsSpan()); } - public sealed override string ThreadStatics(TypeDesc type) + public sealed override Utf8String ThreadStatics(TypeDesc type) { - return NameMangler.CompilationUnitPrefix + "__THREADSTATICS" + NameMangler.GetMangledTypeName(type); + return Utf8String.Concat(NameMangler.CompilationUnitPrefix.AsSpan(), "__THREADSTATICS"u8, NameMangler.GetMangledTypeName(type).AsSpan()); } - public sealed override string ThreadStaticsIndex(TypeDesc type) + public sealed override Utf8String ThreadStaticsIndex(TypeDesc type) { - return "__TypeThreadStaticIndex" + NameMangler.GetMangledTypeName(type); + return Utf8String.Concat("__TypeThreadStaticIndex"u8, NameMangler.GetMangledTypeName(type).AsSpan()); } - public sealed override string TypeGenericDictionary(TypeDesc type) + public sealed override Utf8String TypeGenericDictionary(TypeDesc type) { - return GenericDictionaryNamePrefix + NameMangler.GetMangledTypeName(type); + return Utf8String.Concat(GenericDictionaryNamePrefix, NameMangler.GetMangledTypeName(type)); } - public sealed override string MethodGenericDictionary(MethodDesc method) + public sealed override Utf8String MethodGenericDictionary(MethodDesc method) { - return GenericDictionaryNamePrefix + NameMangler.GetMangledMethodName(method); + return Utf8String.Concat(GenericDictionaryNamePrefix, NameMangler.GetMangledMethodName(method)); } - public sealed override string ExternMethod(string unmangledName, MethodDesc method) + public sealed override Utf8String ExternMethod(Utf8String unmangledName, MethodDesc method) { return unmangledName; } - public sealed override string ExternVariable(string unmangledName) + public sealed override Utf8String ExternVariable(Utf8String unmangledName) { return unmangledName; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UserDefinedTypeDescriptor.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UserDefinedTypeDescriptor.cs index 9464667df35b67..7ab79c353fc7e8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UserDefinedTypeDescriptor.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UserDefinedTypeDescriptor.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Reflection.Metadata; +using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; using Internal.TypeSystem.TypesDebugInfo; @@ -233,7 +234,7 @@ public uint GetMethodFunctionIdTypeIndex(MethodDesc method) descriptor.MemberFunction = GetMethodTypeIndex(method); descriptor.ParentClass = GetTypeIndex(method.OwningType, true); - descriptor.Name = method.GetName(); + descriptor.Name = new Utf8String(method.Name.ToArray()); typeIndex = _objectWriter.GetMemberFunctionId(descriptor); _methodIdIndices.Add(method, typeIndex); @@ -420,7 +421,7 @@ private uint GetEnumTypeIndex(TypeDesc type) FieldDesc field = fieldsDescriptors[i]; EnumRecordTypeDescriptor recordTypeDescriptor; recordTypeDescriptor.Value = GetEnumRecordValue(field); - recordTypeDescriptor.Name = field.GetName(); + recordTypeDescriptor.Name = new Utf8String(field.Name.ToArray()); typeRecords[i] = recordTypeDescriptor; } uint typeIndex = _objectWriter.GetEnumTypeIndex(enumTypeDescriptor, typeRecords); @@ -585,9 +586,9 @@ private uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType) List threadStaticFields = new List(); List staticsDescs = new List(); - string nonGcStaticDataName = NodeFactory.NameMangler.NodeMangler.NonGCStatics(type); - string gcStaticDataName = NodeFactory.NameMangler.NodeMangler.GCStatics(type); - string threadStaticDataName = NodeFactory.NameMangler.NodeMangler.ThreadStatics(type); + Utf8String nonGcStaticDataName = NodeFactory.NameMangler.NodeMangler.NonGCStatics(type); + Utf8String gcStaticDataName = NodeFactory.NameMangler.NodeMangler.GCStatics(type); + Utf8String threadStaticDataName = NodeFactory.NameMangler.NodeMangler.ThreadStatics(type); bool isNativeAOT = Abi == TargetAbi.NativeAot; bool hasNonGcStatics = NodeFactory.MetadataManager.HasNonGcStaticBase(defType); @@ -665,7 +666,7 @@ private uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType) { FieldTypeIndex = fieldTypeIndex, Offset = (ulong)fieldOffsetEmit, - Name = fieldDesc.GetName() + Name = new Utf8String(fieldDesc.Name.ToArray()) }; if (fieldDesc.IsStatic) @@ -749,7 +750,7 @@ private uint GetClassTypeIndex(TypeDesc type, bool needsCompleteType) return typeIndex; } - private void InsertStaticFieldRegionMember(List fieldDescs, DefType defType, List staticFields, string staticFieldForm, + private void InsertStaticFieldRegionMember(List fieldDescs, DefType defType, List staticFields, Utf8String staticFieldForm, bool staticDataInObject, bool isThreadStatic) { if (staticFields != null && (staticFields.Count > 0)) @@ -764,7 +765,7 @@ private void InsertStaticFieldRegionMember(List fieldDescs, ClassTypeDescriptor classTypeDescriptor = new ClassTypeDescriptor { IsStruct = !staticDataInObject ? 1 : 0, - Name = $"__type{staticFieldForm}{_objectWriter.GetMangledName(defType)}", + Name = Utf8String.Concat("__type"u8, staticFieldForm.AsSpan(), _objectWriter.GetMangledName(defType).AsSpan()), BaseClassId = 0 }; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs index be2930565d322e..336badab4639f4 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/WindowsNodeMangler.cs @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Internal.Text; using Internal.TypeSystem; +using System; using System.Diagnostics; namespace ILCompiler @@ -13,10 +15,10 @@ public class WindowsNodeMangler : NodeMangler { private TargetDetails _target; - public const string NonGCStaticMemberName = "__NONGCSTATICS"; - public const string GCStaticMemberName = "__GCSTATICS"; - public const string ThreadStaticMemberName = "__THREADSTATICS"; - public const string ThreadStaticIndexName = "__THREADSTATICINDEX"; + public static Utf8String NonGCStaticMemberName = "__NONGCSTATICS"; + public static Utf8String GCStaticMemberName = "__GCSTATICS"; + public static Utf8String ThreadStaticMemberName = "__THREADSTATICS"; + public static Utf8String ThreadStaticIndexName = "__THREADSTATICINDEX"; public WindowsNodeMangler(TargetDetails target) { @@ -24,60 +26,64 @@ public WindowsNodeMangler(TargetDetails target) } // Mangled name of boxed version of a type - public sealed override string MangledBoxedTypeName(TypeDesc type) + public sealed override Utf8String MangledBoxedTypeName(TypeDesc type) { Debug.Assert(type.IsValueType); - return "Boxed_" + NameMangler.GetMangledTypeName(type); + return Utf8String.Concat("Boxed_"u8, NameMangler.GetMangledTypeName(type).AsSpan()); } - public sealed override string MethodTable(TypeDesc type) + public sealed override Utf8String MethodTable(TypeDesc type) { - string mangledJustTypeName = type.IsValueType + Utf8String mangledJustTypeName = type.IsValueType ? MangledBoxedTypeName(type) - : NameMangler.GetMangledTypeName(type).ToString(); + : NameMangler.GetMangledTypeName(type); // "??_7TypeName@@6B@" is the C++ mangling for "const TypeName::`vftable'" // This, along with LF_VTSHAPE debug records added by the object writer // is the debugger magic that allows debuggers to vcast types to their bases. - return "??_7" + mangledJustTypeName + "@@6B@"; + return Utf8String.Concat("??_7"u8, mangledJustTypeName.AsSpan(), "@@6B@"u8); } - private string CreateStaticFieldName(TypeDesc type, string fieldName) + private Utf8String CreateStaticFieldName(TypeDesc type, ReadOnlySpan fieldName) { - return @$"?{fieldName}@{NameMangler.GetMangledTypeName(type)}@@"; + return Utf8String.Concat("?"u8, fieldName, "@"u8, NameMangler.GetMangledTypeName(type).AsSpan(), "@@"u8); } - public sealed override string GCStatics(TypeDesc type) + public sealed override Utf8String GCStatics(TypeDesc type) { - return CreateStaticFieldName(type, GCStaticMemberName); + return CreateStaticFieldName(type, GCStaticMemberName.AsSpan()); } - public sealed override string NonGCStatics(TypeDesc type) + public sealed override Utf8String NonGCStatics(TypeDesc type) { - return CreateStaticFieldName(type, NonGCStaticMemberName); + return CreateStaticFieldName(type, NonGCStaticMemberName.AsSpan()); } - public sealed override string ThreadStatics(TypeDesc type) + public sealed override Utf8String ThreadStatics(TypeDesc type) { - return CreateStaticFieldName(type, NameMangler.CompilationUnitPrefix + ThreadStaticMemberName); + Utf8String name = NameMangler.CompilationUnitPrefix.Length > 0 + ? Utf8String.Concat(NameMangler.CompilationUnitPrefix, ThreadStaticMemberName) + : ThreadStaticMemberName; + + return CreateStaticFieldName(type, name.AsSpan()); } - public sealed override string ThreadStaticsIndex(TypeDesc type) + public sealed override Utf8String ThreadStaticsIndex(TypeDesc type) { - return CreateStaticFieldName(type, ThreadStaticIndexName); + return CreateStaticFieldName(type, ThreadStaticIndexName.AsSpan()); } - public sealed override string TypeGenericDictionary(TypeDesc type) + public sealed override Utf8String TypeGenericDictionary(TypeDesc type) { - return GenericDictionaryNamePrefix + NameMangler.GetMangledTypeName(type); + return Utf8String.Concat(GenericDictionaryNamePrefix, NameMangler.GetMangledTypeName(type)); } - public sealed override string MethodGenericDictionary(MethodDesc method) + public sealed override Utf8String MethodGenericDictionary(MethodDesc method) { - return GenericDictionaryNamePrefix + NameMangler.GetMangledMethodName(method); + return Utf8String.Concat(GenericDictionaryNamePrefix, NameMangler.GetMangledMethodName(method)); } - public sealed override string ExternMethod(string unmangledName, MethodDesc method) + public sealed override Utf8String ExternMethod(Utf8String unmangledName, MethodDesc method) { if (_target.Architecture != TargetArchitecture.X86) { @@ -117,7 +123,7 @@ public sealed override string ExternMethod(string unmangledName, MethodDesc meth }; } - public sealed override string ExternVariable(string unmangledName) + public sealed override Utf8String ExternVariable(Utf8String unmangledName) { if (_target.Architecture != TargetArchitecture.X86) { diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs index 238de065635ef8..a3160b962d82cc 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs @@ -1062,14 +1062,14 @@ public void DetectGenericCycles(TypeSystemEntity caller, TypeSystemEntity callee _genericCycleDetector?.DetectCycle(caller, callee); } - public string GetSymbolAlternateName(ISymbolNode node, out bool isHidden) + public Utf8String GetSymbolAlternateName(ISymbolNode node, out bool isHidden) { isHidden = false; if (node == Header) { - return "RTR_HEADER"; + return new Utf8String("RTR_HEADER"u8.ToArray()); } - return null; + return default; } } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/MapFileBuilder.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/MapFileBuilder.cs index 9d49bb86680145..a1fc983de716c5 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/MapFileBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/MapFileBuilder.cs @@ -19,6 +19,7 @@ using ILCompiler.DependencyAnalysis.ReadyToRun; using ILCompiler.Diagnostics; using ILCompiler.ObjectWriter; +using Internal.Text; namespace ILCompiler.PEWriter { @@ -37,19 +38,19 @@ public class MapFileBuilder /// private class NodeTypeStatistics { - public readonly string Name; + public readonly Utf8String Name; public int Count; public int Length; - public NodeTypeStatistics(string name) + public NodeTypeStatistics(Utf8String name) { Name = name; } public void AddNode(OutputNode node) { - Debug.Assert(Name == node.Name); + Debug.Assert(Name.AsSpan().SequenceEqual(node.Name.AsSpan())); Count++; Length += node.Length; } @@ -116,7 +117,7 @@ private void WriteHeader(StreamWriter writer) private IEnumerable GetNodeTypeStatistics() { List nodeTypeStats = new List(); - Dictionary statsNameIndex = new Dictionary(); + Dictionary statsNameIndex = new Dictionary(); foreach (OutputNode node in _outputInfoBuilder.Nodes) { if (!statsNameIndex.TryGetValue(node.Name, out int statsIndex)) diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index d1508e4f738828..4f705b6453141a 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -8,12 +8,13 @@ using System.Runtime.InteropServices; using Internal.IL; -using Internal.TypeSystem; using Internal.ReadyToRunConstants; +using Internal.Text; +using Internal.TypeSystem; +using Internal.TypeSystem.Ecma; using ILCompiler; using ILCompiler.DependencyAnalysis; -using Internal.TypeSystem.Ecma; #if SUPPORT_JIT using MethodCodeNode = Internal.Runtime.JitSupport.JitMethodCodeNode; @@ -1922,7 +1923,7 @@ private void getAddressOfPInvokeTarget(CORINFO_METHOD_STRUCT_* method, ref CORIN { MethodDesc md = HandleToObject(method); - string externName = _compilation.PInvokeILProvider.GetDirectCallExternName(md); + Utf8String externName = _compilation.PInvokeILProvider.GetDirectCallExternName(md); externName = _compilation.NodeFactory.NameMangler.NodeMangler.ExternMethod(externName, md); pLookup = CreateConstLookupToSymbol(_compilation.NodeFactory.ExternFunctionSymbol(externName));