Use type system entities instead of strings for node identity (#35918)
authorSimon Nattress <nattress@gmail.com>
Thu, 7 May 2020 20:26:49 +0000 (13:26 -0700)
committerGitHub <noreply@github.com>
Thu, 7 May 2020 20:26:49 +0000 (13:26 -0700)
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.

src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/MethodReadOnlyDataNode.cs [moved from src/coreclr/src/tools/Common/Compiler/DependencyAnalysis/SettableReadOnlyDataBlob.cs with 71% similarity]
src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperImport.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DelayLoadHelperMethodImport.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Import.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureEmbeddedPointerIndirectionNode.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunSymbolNodeFactory.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs

@@ -10,24 +10,22 @@ using Internal.TypeSystem;
 
 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;
@@ -50,7 +48,7 @@ namespace ILCompiler.DependencyAnalysis
 
         public override int CompareToImpl(ISortableNode other, CompilerComparer comparer)
         {
-            return _name.CompareTo(((SettableReadOnlyDataBlob)other)._name);
+            return comparer.Compare(_owningMethod, ((MethodReadOnlyDataNode)other)._owningMethod);
         }
 #endif
     }
index 753fc0a..dd6e4c8 100644 (file)
@@ -2565,7 +2565,7 @@ namespace Internal.JitInterface
 
         private byte[] _roData;
 
-        private SettableReadOnlyDataBlob _roDataBlob;
+        private MethodReadOnlyDataNode _roDataBlob;
         private int _roDataAlignment;
 
         private int _numFrameInfos;
@@ -2611,8 +2611,7 @@ namespace Internal.JitInterface
 
                 _roData = new byte[roDataSize];
 
-                _roDataBlob = _compilation.NodeFactory.SettableReadOnlyDataBlob(
-                    "__readonlydata_" + _compilation.NameMangler.GetMangledMethodName(MethodBeingCompiled));
+                _roDataBlob = new MethodReadOnlyDataNode(MethodBeingCompiled);
 
                 roDataBlock = (void*)GetPin(_roData);
             }
index df83464..d8f6c8f 100644 (file)
@@ -27,8 +27,8 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             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;
@@ -45,10 +45,10 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             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));
             }
         }
 
index 4002bfd..656a68f 100644 (file)
@@ -30,8 +30,8 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             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;
index e276c75..ebd73a8 100644 (file)
@@ -5,6 +5,7 @@
 using System;
 using System.Collections.Generic;
 using Internal.Text;
+using Internal.TypeSystem;
 
 namespace ILCompiler.DependencyAnalysis.ReadyToRun
 {
@@ -17,12 +18,12 @@ 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);
         }
 
@@ -66,7 +67,7 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
         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;
 
index eec9374..c07b78b 100644 (file)
@@ -38,10 +38,10 @@ namespace ILCompiler.DependencyAnalysis
         {
             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));
             }
         }
 
index e4b76f7..f6bff77 100644 (file)
@@ -96,13 +96,6 @@ namespace ILCompiler.DependencyAnalysis
             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;
@@ -211,11 +204,6 @@ namespace ILCompiler.DependencyAnalysis
                         (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));
index da85b63..aeca8c8 100644 (file)
@@ -107,7 +107,7 @@ namespace ILCompiler.DependencyAnalysis
                     _codegenNodeFactory.MethodSignature(ReadyToRunFixupKind.VirtualEntry,
                         cellKey.Method,
                         cellKey.IsUnboxingStub, isInstantiatingStub: false),
-                    cellKey.CallSite);
+                    cellKey.CallingMethod);
             });
 
             _delegateCtors = new NodeCache<TypeAndMethod, ISymbolNode>(ctorKey =>
@@ -423,9 +423,9 @@ namespace ILCompiler.DependencyAnalysis
 
         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);
         }
 
@@ -453,18 +453,18 @@ namespace ILCompiler.DependencyAnalysis
         {
             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)
@@ -474,7 +474,7 @@ namespace ILCompiler.DependencyAnalysis
 
             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);
             }
index 6c0babe..798f707 100644 (file)
@@ -62,7 +62,7 @@
     <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" />
index a0691e4..5324970 100644 (file)
@@ -1549,7 +1549,7 @@ namespace Internal.JitInterface
                             _compilation.SymbolNodeFactory.InterfaceDispatchCell(
                                 new MethodWithToken(targetMethod, HandleToModuleToken(ref pResolvedToken, targetMethod), constrainedType: null),
                                 isUnboxingStub: false,
-                                _compilation.NameMangler.GetMangledMethodName(MethodBeingCompiled).ToString()));
+                                MethodBeingCompiled));
                         }
                     break;