The calling method for interface dispatches is used to provide imports specific to each call site (actually currently a shared one per calling method). Replace the use of mangled calling method name with its `MethodDesc` object as the key for the interface dispatch cell.
This saves ~4% working set measured on a large application.
Also, removed mangled name as the key for method-specific readonly data blobs the JIT allocates. This was much more modest since most methods don't need a readonly blob.
namespace ILCompiler.DependencyAnalysis
{
- public class SettableReadOnlyDataBlob : ObjectNode, ISymbolDefinitionNode
+ public class MethodReadOnlyDataNode : ObjectNode, ISymbolDefinitionNode
{
- private Utf8String _name;
- private ObjectNodeSection _section;
+ private MethodDesc _owningMethod;
private ObjectData _data;
- public SettableReadOnlyDataBlob(Utf8String name, ObjectNodeSection section)
+ public MethodReadOnlyDataNode(MethodDesc owningMethod)
{
- _name = name;
- _section = section;
+ _owningMethod = owningMethod;
}
- public override ObjectNodeSection Section => _section;
+ public override ObjectNodeSection Section => ObjectNodeSection.ReadOnlyDataSection;
public override bool StaticDependenciesAreComputed => _data != null;
public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb)
{
- sb.Append(_name);
+ sb.Append("__readonlydata_" + nameMangler.GetMangledMethodName(_owningMethod));
}
public int Offset => 0;
public override bool IsShareable => true;
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
{
- return _name.CompareTo(((SettableReadOnlyDataBlob)other)._name);
+ return comparer.Compare(_owningMethod, ((MethodReadOnlyDataNode)other)._owningMethod);
}
#endif
}
private byte[] _roData;
- private SettableReadOnlyDataBlob _roDataBlob;
+ private MethodReadOnlyDataNode _roDataBlob;
private int _roDataAlignment;
private int _numFrameInfos;
_roData = new byte[roDataSize];
- _roDataBlob = _compilation.NodeFactory.SettableReadOnlyDataBlob(
- "__readonlydata_" + _compilation.NameMangler.GetMangledMethodName(MethodBeingCompiled));
+ _roDataBlob = new MethodReadOnlyDataNode(MethodBeingCompiled);
roDataBlock = (void*)GetPin(_roData);
}
ReadyToRunHelper helper,
Signature instanceSignature,
bool useVirtualCall = false,
- string callSite = null)
- : base(importSectionNode, instanceSignature, callSite)
+ MethodDesc callingMethod = null)
+ : base(importSectionNode, instanceSignature, callingMethod)
{
_helper = helper;
_useVirtualCall = useVirtualCall;
sb.Append(_helper.ToString());
sb.Append(") -> ");
ImportSignature.AppendMangledName(nameMangler, sb);
- if (CallSite != null)
+ if (CallingMethod != null)
{
sb.Append(" @ ");
- sb.Append(CallSite);
+ sb.Append(nameMangler.GetMangledMethodName(CallingMethod));
}
}
bool useVirtualCall,
bool useInstantiatingStub,
Signature instanceSignature,
- string callSite = null)
- : base(factory, importSectionNode, helper, instanceSignature, useVirtualCall, callSite)
+ MethodDesc callingMethod = null)
+ : base(factory, importSectionNode, helper, instanceSignature, useVirtualCall, callingMethod)
{
_method = method;
_useInstantiatingStub = useInstantiatingStub;
using System;
using System.Collections.Generic;
using Internal.Text;
+using Internal.TypeSystem;
namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
internal readonly SignatureEmbeddedPointerIndirectionNode ImportSignature;
- internal readonly string CallSite;
+ internal readonly MethodDesc CallingMethod;
- public Import(ImportSectionNode tableNode, Signature importSignature, string callSite = null)
+ public Import(ImportSectionNode tableNode, Signature importSignature, MethodDesc callingMethod = null)
{
Table = tableNode;
- CallSite = callSite;
+ CallingMethod = callingMethod;
ImportSignature = new SignatureEmbeddedPointerIndirectionNode(this, importSignature);
}
public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
{
Import otherNode = (Import)other;
- int result = string.Compare(CallSite, otherNode.CallSite);
+ int result = comparer.Compare(CallingMethod, otherNode.CallingMethod);
if (result != 0)
return result;
{
sb.Append("SignaturePointer_");
Target.AppendMangledName(nameMangler, sb);
- if (_import.CallSite != null)
+ if (_import.CallingMethod != null)
{
sb.Append(" @ ");
- sb.Append(_import.CallSite);
+ sb.Append(nameMangler.GetMangledMethodName(_import.CallingMethod));
}
}
return _genericReadyToRunHelpersFromType.GetOrAdd(new ReadyToRunGenericHelperKey(id, target, dictionaryOwner));
}
- private NodeCache<Utf8String, SettableReadOnlyDataBlob> _readOnlyDataBlobs;
-
- public SettableReadOnlyDataBlob SettableReadOnlyDataBlob(Utf8String name)
- {
- return _readOnlyDataBlobs.GetOrAdd(name);
- }
-
private struct ReadyToRunGenericHelperKey : IEquatable<ReadyToRunGenericHelperKey>
{
public readonly object Target;
(TypeDesc)helperKey.Target));
});
- _readOnlyDataBlobs = new NodeCache<Utf8String, SettableReadOnlyDataBlob>(key =>
- {
- return new SettableReadOnlyDataBlob(key, ObjectNodeSection.ReadOnlyDataSection);
- });
-
_constructedHelpers = new NodeCache<ReadyToRunHelper, Import>(helperId =>
{
return new Import(EagerImports, new ReadyToRunHelperSignature(helperId));
_codegenNodeFactory.MethodSignature(ReadyToRunFixupKind.VirtualEntry,
cellKey.Method,
cellKey.IsUnboxingStub, isInstantiatingStub: false),
- cellKey.CallSite);
+ cellKey.CallingMethod);
});
_delegateCtors = new NodeCache<TypeAndMethod, ISymbolNode>(ctorKey =>
private NodeCache<MethodAndCallSite, ISymbolNode> _interfaceDispatchCells = new NodeCache<MethodAndCallSite, ISymbolNode>();
- public ISymbolNode InterfaceDispatchCell(MethodWithToken method, bool isUnboxingStub, string callSite)
+ public ISymbolNode InterfaceDispatchCell(MethodWithToken method, bool isUnboxingStub, MethodDesc callingMethod)
{
- MethodAndCallSite cellKey = new MethodAndCallSite(method, isUnboxingStub, callSite);
+ MethodAndCallSite cellKey = new MethodAndCallSite(method, isUnboxingStub, callingMethod);
return _interfaceDispatchCells.GetOrAdd(cellKey);
}
{
public readonly MethodWithToken Method;
public readonly bool IsUnboxingStub;
- public readonly string CallSite;
+ public readonly MethodDesc CallingMethod;
- public MethodAndCallSite(MethodWithToken method, bool isUnboxingStub, string callSite)
+ public MethodAndCallSite(MethodWithToken method, bool isUnboxingStub, MethodDesc callingMethod)
{
- CallSite = callSite;
IsUnboxingStub = isUnboxingStub;
Method = method;
+ CallingMethod = callingMethod;
}
public bool Equals(MethodAndCallSite other)
{
- return CallSite == other.CallSite && Method.Equals(other.Method) && IsUnboxingStub == other.IsUnboxingStub;
+ return Method.Equals(other.Method) && IsUnboxingStub == other.IsUnboxingStub && CallingMethod == other.CallingMethod;
}
public override bool Equals(object obj)
public override int GetHashCode()
{
- return (CallSite != null ? CallSite.GetHashCode() : 0)
+ return (CallingMethod != null ? unchecked(199 * CallingMethod.GetHashCode()) : 0)
^ unchecked(31 * Method.GetHashCode())
^ (IsUnboxingStub ? -0x80000000 : 0);
}
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ObjectNode.cs" Link="Compiler\DependencyAnalysis\ObjectNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ObjectNodeSection.cs" Link="Compiler\DependencyAnalysis\ObjectNodeSection.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\Relocation.cs" Link="Compiler\DependencyAnalysis\Relocation.cs" />
- <Compile Include="..\..\Common\Compiler\DependencyAnalysis\SettableReadOnlyDataBlob.cs" Link="Compiler\DependencyAnalysis\SettableReadOnlyDataBlob.cs" />
+ <Compile Include="..\..\Common\Compiler\DependencyAnalysis\MethodReadOnlyDataNode.cs" Link="Compiler\DependencyAnalysis\MethodReadOnlyDataNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\ShadowConcreteMethodNode.cs" Link="Compiler\DependencyAnalysis\ShadowConcreteMethodNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\SortableDependencyNode.cs" Link="Compiler\DependencyAnalysis\SortableDependencyNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\Target_ARM64\AddrMode.cs" Link="Compiler\DependencyAnalysis\Target_ARM64\AddrMode.cs" />
_compilation.SymbolNodeFactory.InterfaceDispatchCell(
new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType: null),
isUnboxingStub: false,
- _compilation.NameMangler.GetMangledMethodName(MethodBeingCompiled).ToString()));
+ MethodBeingCompiled));
}
break;