Remove some Diagnostics.Eventing allocations (#8869)
authorBen Adams <thundercat@illyriad.co.uk>
Mon, 23 Jan 2017 16:24:21 +0000 (16:24 +0000)
committerVance Morrison <vancem@microsoft.com>
Mon, 23 Jan 2017 16:24:21 +0000 (08:24 -0800)
Remove some closure allocations

escapes string[] to static rather than function alloc

src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs

index ce0fcb6..175f0f1 100644 (file)
@@ -341,9 +341,10 @@ namespace System.Diagnostics.Tracing
         {
             List<SessionInfo> liveSessionList = null;
 
-            GetSessionInfo((Action<int, long>)
-                ((etwSessionId, matchAllKeywords) =>
-                    GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref liveSessionList)));
+            GetSessionInfo(
+                (int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList) =>
+                    GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref sessionList),
+                ref liveSessionList);
 
             List<Tuple<SessionInfo, bool>> changedSessionList = new List<Tuple<SessionInfo, bool>>();
 
@@ -407,12 +408,14 @@ namespace System.Diagnostics.Tracing
             }
         }
 
+        private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList);
+        
         /// <summary>
         /// This method enumerates over all active ETW sessions that have enabled 'this.m_Guid' 
         /// for the current process ID, calling 'action' for each session, and passing it the
         /// ETW session and the 'AllKeywords' the session enabled for the current provider.
         /// </summary>
-        private unsafe void GetSessionInfo(Action<int, long> action)
+        private unsafe void GetSessionInfo(SessionInfoCallback action, ref List<SessionInfo> sessionList)
         {
             // We wish the EventSource package to be legal for Windows Store applications.   
             // Currently EnumerateTraceGuidsEx is not an allowed API, so we avoid its use here
@@ -453,7 +456,7 @@ namespace System.Diagnostics.Tracing
                     var enabledInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_ENABLE_INFO*)&providerInstance[1];
                     // iterate over the list of active ETW sessions "listening" to the current provider
                     for (int j = 0; j < providerInstance->EnableCount; j++)
-                        action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword);
+                        action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword, ref sessionList);
                 }
                 if (providerInstance->NextOffset == 0)
                     break;
@@ -503,7 +506,7 @@ namespace System.Diagnostics.Tracing
                                     string keywordBitString = dataAsString.Substring(startIdx, endIdx-startIdx);
                                     int keywordBit;
                                     if (0 < endIdx && int.TryParse(keywordBitString, out keywordBit))
-                                        action(etwSessionId, 1L << keywordBit);
+                                        action(etwSessionId, 1L << keywordBit, ref sessionList);
                                 }
                             }
                         }
index 81ea1e1..405fbb2 100644 (file)
@@ -4210,7 +4210,7 @@ namespace System.Diagnostics.Tracing
         public EventListener()
         {
             // This will cause the OnEventSourceCreated callback to fire. 
-            CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener(this));
+            CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener((EventListener)obj));
         }
 
         /// <summary>
@@ -6730,6 +6730,7 @@ namespace System.Diagnostics.Tracing
             stringBuilder.Append(eventMessage, startIndex, count);
         }
 
+        private static readonly string[] s_escapes = { "&amp;", "&lt;", "&gt;", "&apos;", "&quot;", "%r", "%n", "%t" };
         // Manifest messages use %N conventions for their message substitutions.   Translate from
         // .NET conventions.   We can't use RegEx for this (we are in mscorlib), so we do it 'by hand' 
         private string TranslateToManifestConvention(string eventMessage, string evtName)
@@ -6797,16 +6798,10 @@ namespace System.Diagnostics.Tracing
                 }
                 else if ((chIdx = "&<>'\"\r\n\t".IndexOf(eventMessage[i])) >= 0)
                 {
-                    string[] escapes = { "&amp;", "&lt;", "&gt;", "&apos;", "&quot;", "%r", "%n", "%t" };
-                    var update = new Action<char, string>(
-                        (ch, escape) =>
-                        {
-                            UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
-                            i++;
-                            stringBuilder.Append(escape);
-                            writtenSoFar = i;
-                        });
-                    update(eventMessage[i], escapes[chIdx]);
+                    UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
+                    i++;
+                    stringBuilder.Append(s_escapes[chIdx]);
+                    writtenSoFar = i;
                 }
                 else
                     i++;