Reduce allocated object cost of debug info (#35873)
authorDavid Wrighton <davidwr@microsoft.com>
Wed, 6 May 2020 20:26:53 +0000 (13:26 -0700)
committerGitHub <noreply@github.com>
Wed, 6 May 2020 20:26:53 +0000 (13:26 -0700)
Reduce allocated object cost of debug info, by converting it into its final form as its extracted from the JIT and not as its emitted into the file. Also has a small benefit of increased parallelization as its now created in a parallel portion of the build instead of a sequential portion of the build. Overall size win of 0.5% observed.

src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/DebugInfoTableNode.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodWithGCInfo.cs

index 68f0443..31fd6ba 100644 (file)
@@ -85,8 +85,8 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             {
                 MemoryStream methodDebugBlob = new MemoryStream();
                 
-                byte[] bounds = CreateBoundsBlobForMethod(method);
-                byte[] vars = CreateVarBlobForMethod(method);
+                byte[] bounds = method.DebugLocInfos;
+                byte[] vars = method.DebugVarInfos;
 
                 NibbleWriter nibbleWriter = new NibbleWriter();
                 nibbleWriter.WriteUInt((uint)(bounds?.Length ?? 0));
@@ -122,16 +122,16 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
                 definedSymbols: new ISymbolDefinitionNode[] { this });
         }
 
-        private byte[] CreateBoundsBlobForMethod(MethodWithGCInfo method)
+        public static byte[] CreateBoundsBlobForMethod(OffsetMapping[] offsetMapping)
         {
-            if (method.DebugLocInfos == null || method.DebugLocInfos.Length == 0)
+            if (offsetMapping == null || offsetMapping.Length == 0)
                 return null;
 
             NibbleWriter writer = new NibbleWriter();
-            writer.WriteUInt((uint)method.DebugLocInfos.Length);
+            writer.WriteUInt((uint)offsetMapping.Length);
 
             uint previousNativeOffset = 0;
-            foreach (var locInfo in method.DebugLocInfos)
+            foreach (var locInfo in offsetMapping)
             {
                 writer.WriteUInt(locInfo.nativeOffset - previousNativeOffset);
                 writer.WriteUInt(locInfo.ilOffset + 3); // Count of items in Internal.JitInterface.MappingTypes to adjust the IL offset by
@@ -143,15 +143,15 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             return writer.ToArray();
         }
 
-        private byte[] CreateVarBlobForMethod(MethodWithGCInfo method)
+        public static byte[] CreateVarBlobForMethod(NativeVarInfo[] varInfos)
         {
-            if (method.DebugVarInfos == null || method.DebugVarInfos.Length == 0)
+            if (varInfos == null || varInfos.Length == 0)
                 return null;
 
             NibbleWriter writer = new NibbleWriter();
-            writer.WriteUInt((uint)method.DebugVarInfos.Length);
+            writer.WriteUInt((uint)varInfos.Length);
 
-            foreach (var nativeVarInfo in method.DebugVarInfos)
+            foreach (var nativeVarInfo in varInfos)
             {
                 writer.WriteUInt(nativeVarInfo.startOffset);
                 writer.WriteUInt(nativeVarInfo.endOffset - nativeVarInfo.startOffset);
index ccf912f..7c7911a 100644 (file)
@@ -22,8 +22,8 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
         private FrameInfo[] _frameInfos;
         private byte[] _gcInfo;
         private ObjectData _ehInfo;
-        private OffsetMapping[] _debugLocInfos;
-        private NativeVarInfo[] _debugVarInfos;
+        private byte[] _debugLocInfos;
+        private byte[] _debugVarInfos;
         private DebugEHClauseInfo[] _debugEHClauseInfos;
         private List<ISymbolNode> _fixups;
         private MethodDesc[] _inlinedMethods;
@@ -268,20 +268,24 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun
             _ehInfo = ehInfo;
         }
 
-        public OffsetMapping[] DebugLocInfos => _debugLocInfos;
-        public NativeVarInfo[] DebugVarInfos => _debugVarInfos;
+        public byte[] DebugLocInfos => _debugLocInfos;
+        public byte[] DebugVarInfos => _debugVarInfos;
         public DebugEHClauseInfo[] DebugEHClauseInfos => _debugEHClauseInfos;
 
         public void InitializeDebugLocInfos(OffsetMapping[] debugLocInfos)
         {
             Debug.Assert(_debugLocInfos == null);
-            _debugLocInfos = debugLocInfos;
+            // Process the debug info from JIT format to R2R format immediately as it is large
+            // and not used in the rest of the process except to emit.
+            _debugLocInfos = DebugInfoTableNode.CreateBoundsBlobForMethod(debugLocInfos);
         }
 
         public void InitializeDebugVarInfos(NativeVarInfo[] debugVarInfos)
         {
             Debug.Assert(_debugVarInfos == null);
-            _debugVarInfos = debugVarInfos;
+            // Process the debug info from JIT format to R2R format immediately as it is large
+            // and not used in the rest of the process except to emit.
+            _debugVarInfos = DebugInfoTableNode.CreateVarBlobForMethod(debugVarInfos);
         }
 
         public void InitializeDebugEHClauseInfos(DebugEHClauseInfo[] debugEHClauseInfos)