Skip to content

Commit

Permalink
[NativeAOT] Remove obsolete C++ name mangling (dotnet#96983)
Browse files Browse the repository at this point in the history
  • Loading branch information
filipnavara authored and tmds committed Jan 23, 2024
1 parent b110ff8 commit 89f46a5
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 128 deletions.
179 changes: 52 additions & 127 deletions src/coreclr/tools/Common/Compiler/NativeAotNameMangler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@ namespace ILCompiler
public class NativeAotNameMangler : NameMangler
{
#if !READYTORUN
private readonly bool _mangleForCplusPlus;

public NativeAotNameMangler(NodeMangler nodeMangler, bool mangleForCplusPlus) : base(nodeMangler)
public NativeAotNameMangler(NodeMangler nodeMangler) : base(nodeMangler)
{
_mangleForCplusPlus = mangleForCplusPlus;
}
#else
private readonly bool _mangleForCplusPlus = false;
#endif

private string _compilationUnitPrefix;
Expand Down Expand Up @@ -68,13 +63,6 @@ public override string SanitizeName(string s, bool typeName = false)

sb ??= new StringBuilder(s, 0, i, s.Length);

// For CppCodeGen, replace "." (C# namespace separator) with "::" (C++ namespace separator)
if (typeName && c == '.' && _mangleForCplusPlus)
{
sb.Append("::");
continue;
}

// Everything else is replaced by underscore.
// TODO: We assume that there won't be collisions with our own or C++ built-in identifiers.
sb.Append('_');
Expand All @@ -85,9 +73,7 @@ public override string SanitizeName(string s, bool typeName = false)
// The character sequences denoting generic instantiations, arrays, byrefs, or pointers must be
// restricted to that use only. Replace them if they happened to be used in any identifiers in
// the compilation input.
return _mangleForCplusPlus
? sanitizedName.Replace(EnterNameScopeSequence, "_AA_").Replace(ExitNameScopeSequence, "_VV_")
: sanitizedName;
return sanitizedName;
}

private static byte[] GetBytesFromString(string literal)
Expand Down Expand Up @@ -163,9 +149,9 @@ public override string GetMangledTypeName(TypeDesc type)
}
}

private string EnterNameScopeSequence => _mangleForCplusPlus ? "_A_" : "<";
private string ExitNameScopeSequence => _mangleForCplusPlus ? "_V_" : ">";
private string DelimitNameScopeSequence => _mangleForCplusPlus? "_C_" : ",";
private const string EnterNameScopeSequence = "<";
private const string ExitNameScopeSequence = ">";
private const string DelimitNameScopeSequence = ",";

protected string NestMangledName(string name)
{
Expand All @@ -190,7 +176,7 @@ private string ComputeMangledTypeName(TypeDesc type)
// Abbreviate System.Private to S.P. This might conflict with user defined assembly names,
// but we already have a problem due to running SanitizeName without disambiguating the result
// This problem needs a better fix.
if (isSystemPrivate && !_mangleForCplusPlus)
if (isSystemPrivate)
assemblyName = string.Concat("S.P.", assemblyName.AsSpan(15));
string prependAssemblyName = SanitizeName(assemblyName);

Expand All @@ -216,46 +202,38 @@ private string ComputeMangledTypeName(TypeDesc type)
containingType = containingType.ContainingType;
}

name = SanitizeName(name, true);

if (_mangleForCplusPlus)
// If this is one of the well known types, use a shorter name
// We know this won't conflict because all the other types are
// prefixed by the assembly name.
if (isSystemModule)
{
// Always generate a fully qualified name
name = "::" + prependAssemblyName + "::" + name;
switch (t.Category)
{
case TypeFlags.Boolean: name = "Bool"; break;
case TypeFlags.Byte: name = "UInt8"; break;
case TypeFlags.SByte: name = "Int8"; break;
case TypeFlags.UInt16: name = "UInt16"; break;
case TypeFlags.Int16: name = "Int16"; break;
case TypeFlags.UInt32: name = "UInt32"; break;
case TypeFlags.Int32: name = "Int32"; break;
case TypeFlags.UInt64: name = "UInt64"; break;
case TypeFlags.Int64: name = "Int64"; break;
case TypeFlags.Char: name = "Char"; break;
case TypeFlags.Double: name = "Double"; break;
case TypeFlags.Single: name = "Single"; break;
case TypeFlags.IntPtr: name = "IntPtr"; break;
case TypeFlags.UIntPtr: name = "UIntPtr"; break;
default:
if (t.IsObject)
name = "Object";
else if (t.IsString)
name = "String";
break;
}
}
else
{
name = prependAssemblyName + "_" + name;

// If this is one of the well known types, use a shorter name
// We know this won't conflict because all the other types are
// prefixed by the assembly name.
if (isSystemModule)
{
switch (t.Category)
{
case TypeFlags.Boolean: name = "Bool"; break;
case TypeFlags.Byte: name = "UInt8"; break;
case TypeFlags.SByte: name = "Int8"; break;
case TypeFlags.UInt16: name = "UInt16"; break;
case TypeFlags.Int16: name = "Int16"; break;
case TypeFlags.UInt32: name = "UInt32"; break;
case TypeFlags.Int32: name = "Int32"; break;
case TypeFlags.UInt64: name = "UInt64"; break;
case TypeFlags.Int64: name = "Int64"; break;
case TypeFlags.Char: name = "Char"; break;
case TypeFlags.Double: name = "Double"; break;
case TypeFlags.Single: name = "Single"; break;
case TypeFlags.IntPtr: name = "IntPtr"; break;
case TypeFlags.UIntPtr: name = "UIntPtr"; break;
default:
if (t.IsObject)
name = "Object";
else if (t.IsString)
name = "String";
break;
}
}
name = prependAssemblyName + "_" + SanitizeName(name, true);
}

// Ensure that name is unique and update our tables accordingly.
Expand Down Expand Up @@ -308,8 +286,7 @@ private string ComputeMangledTypeName(TypeDesc type)
default:
// Case of a generic type. If `type' is a type definition we use the type name
// for mangling, otherwise we use the mangling of the type and its generic type
// parameters, e.g. A <B> becomes A_<___B_>_ in RyuJIT compilation, or A_A___B_V_
// in C++ compilation.
// parameters, e.g. A <B> becomes A_<___B_>_.
var typeDefinition = type.GetTypeDefinition();
if (typeDefinition != type)
{
Expand All @@ -320,8 +297,6 @@ private string ComputeMangledTypeName(TypeDesc type)
for (int i = 0; i < inst.Length; i++)
{
string instArgName = GetMangledTypeName(inst[i]);
if (_mangleForCplusPlus)
instArgName = instArgName.Replace("::", "_");
if (i > 0)
mangledInstantiation += "__";

Expand All @@ -342,10 +317,6 @@ private string ComputeMangledTypeName(TypeDesc type)
// This is a type definition. Since we didn't fall in the `is EcmaType` case above,
// it's likely a compiler-generated type.
mangledName = SanitizeName(((DefType)type).GetFullName(), true);

// Always generate a fully qualified name
if (_mangleForCplusPlus)
mangledName = "::" + mangledName;
}
break;
}
Expand All @@ -364,32 +335,25 @@ private string ComputeMangledTypeName(TypeDesc type)

public override Utf8String GetMangledMethodName(MethodDesc method)
{
if (_mangleForCplusPlus)
Utf8String utf8MangledName;
lock (this)
{
return GetUnqualifiedMangledMethodName(method);
if (_mangledMethodNames.TryGetValue(method, out utf8MangledName))
return utf8MangledName;
}
else
{
Utf8String utf8MangledName;
lock (this)
{
if (_mangledMethodNames.TryGetValue(method, out utf8MangledName))
return utf8MangledName;
}

Utf8StringBuilder sb = new Utf8StringBuilder();
sb.Append(GetMangledTypeName(method.OwningType));
sb.Append("__");
sb.Append(GetUnqualifiedMangledMethodName(method));
utf8MangledName = sb.ToUtf8String();

lock (this)
{
_mangledMethodNames.TryAdd(method, utf8MangledName);
}
Utf8StringBuilder sb = new Utf8StringBuilder();
sb.Append(GetMangledTypeName(method.OwningType));
sb.Append("__");
sb.Append(GetUnqualifiedMangledMethodName(method));
utf8MangledName = sb.ToUtf8String();

return utf8MangledName;
lock (this)
{
_mangledMethodNames.TryAdd(method, utf8MangledName);
}

return utf8MangledName;
}

private Utf8String GetUnqualifiedMangledMethodName(MethodDesc method)
Expand All @@ -408,17 +372,7 @@ private Utf8String GetPrefixMangledTypeName(IPrefixMangledType prefixMangledType
{
Utf8StringBuilder sb = new Utf8StringBuilder();
sb.Append(EnterNameScopeSequence).Append(prefixMangledType.Prefix).Append(ExitNameScopeSequence);

if (_mangleForCplusPlus)
{
string name = GetMangledTypeName(prefixMangledType.BaseType).ToString().Replace("::", "_");
sb.Append(name);
}
else
{
sb.Append(GetMangledTypeName(prefixMangledType.BaseType));
}

sb.Append(GetMangledTypeName(prefixMangledType.BaseType));
return sb.ToUtf8String();
}

Expand All @@ -433,16 +387,12 @@ private Utf8String GetPrefixMangledSignatureName(IPrefixMangledSignature prefixM
sb.Append(EnterNameScopeSequence);

string sigRetTypeName = GetMangledTypeName(signature.ReturnType);
if (_mangleForCplusPlus)
sigRetTypeName = sigRetTypeName.Replace("::", "_");
sb.Append(sigRetTypeName);

for (int i = 0; i < signature.Length; i++)
{
sb.Append("__");
string sigArgName = GetMangledTypeName(signature[i]);
if (_mangleForCplusPlus)
sigArgName = sigArgName.Replace("::", "_");
sb.Append(sigArgName);
}

Expand All @@ -455,17 +405,7 @@ private Utf8String GetPrefixMangledMethodName(IPrefixMangledMethod prefixMangled
{
Utf8StringBuilder sb = new Utf8StringBuilder();
sb.Append(EnterNameScopeSequence).Append(prefixMangledMethod.Prefix).Append(ExitNameScopeSequence);

if (_mangleForCplusPlus)
{
string name = GetMangledMethodName(prefixMangledMethod.BaseMethod).ToString().Replace("::", "_");
sb.Append(name);
}
else
{
sb.Append(GetMangledMethodName(prefixMangledMethod.BaseMethod));
}

sb.Append(GetMangledMethodName(prefixMangledMethod.BaseMethod));
return sb.ToUtf8String();
}

Expand Down Expand Up @@ -510,8 +450,6 @@ private Utf8String ComputeUnqualifiedMangledMethodName(MethodDesc method)
for (int i = 0; i < inst.Length; i++)
{
string instArgName = GetMangledTypeName(inst[i]);
if (_mangleForCplusPlus)
instArgName = instArgName.Replace("::", "_");
if (i > 0)
sb.Append("__");
sb.Append(instArgName);
Expand Down Expand Up @@ -548,17 +486,6 @@ private Utf8String ComputeUnqualifiedMangledMethodName(MethodDesc method)
}
}

// Unless we're doing CPP mangling, there's no point in caching the unqualified
// method name. We only needed it to construct the fully qualified name. Nobody
// is going to ask for the unqualified name again.
if (_mangleForCplusPlus)
{
lock (this)
{
_unqualifiedMangledMethodNames.TryAdd(method, utf8MangledName);
}
}

return utf8MangledName;
}

Expand All @@ -578,9 +505,7 @@ public override Utf8String GetMangledFieldName(FieldDesc field)

private Utf8String ComputeMangledFieldName(FieldDesc field)
{
string prependTypeName = null;
if (!_mangleForCplusPlus)
prependTypeName = GetMangledTypeName(field.OwningType);
string prependTypeName = GetMangledTypeName(field.OwningType);

if (field is EcmaField)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public sealed class RyuJitCompilationBuilder : CompilationBuilder

public RyuJitCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group)
: base(context, group,
new NativeAotNameMangler(context.Target.IsWindows ? (NodeMangler)new WindowsNodeMangler() : (NodeMangler)new UnixNodeMangler(), false))
new NativeAotNameMangler(context.Target.IsWindows ? (NodeMangler)new WindowsNodeMangler() : (NodeMangler)new UnixNodeMangler()))
{
}

Expand Down

0 comments on commit 89f46a5

Please sign in to comment.