Convert BulkTypeLogger Allocations From Stack to Heap (#15907)
authorBrian Robbins <brianrob@microsoft.com>
Thu, 18 Jan 2018 22:49:54 +0000 (14:49 -0800)
committerGitHub <noreply@github.com>
Thu, 18 Jan 2018 22:49:54 +0000 (14:49 -0800)
src/vm/eventtrace.cpp
src/vm/eventtracepriv.h

index 72503d6..f66c92e 100644 (file)
@@ -1714,7 +1714,6 @@ void BulkTypeEventLogger::FireBulkTypeEvent()
         // No types were batched up, so nothing to send
         return;
     }
-    
     UINT16 nClrInstanceID = GetClrInstanceId();
 
 #if !defined(FEATURE_PAL)
@@ -1792,6 +1791,12 @@ void BulkTypeEventLogger::FireBulkTypeEvent()
     
 #else // FEATURE_PAL
 
+    if(m_pBulkTypeEventBuffer == NULL)
+    {
+        // The buffer could not be allocated when this object was created, so bail.
+        return;
+    }
+
     UINT iSize = 0;
     
     for (int iTypeData = 0; iTypeData < m_nBulkTypeValueCount; iTypeData++)
@@ -1800,7 +1805,7 @@ void BulkTypeEventLogger::FireBulkTypeEvent()
         
         // Do fixed-size data as one bulk copy
         memcpy(
-                m_BulkTypeEventBuffer + iSize,
+                m_pBulkTypeEventBuffer + iSize,
                 &(target.fixedSizedData),
                 sizeof(target.fixedSizedData));
         iSize += sizeof(target.fixedSizedData);
@@ -1810,20 +1815,20 @@ void BulkTypeEventLogger::FireBulkTypeEvent()
         LPCWSTR wszName = target.sName.GetUnicode();
         if (wszName == NULL)
         {
-            m_BulkTypeEventBuffer[iSize++] = 0;
-            m_BulkTypeEventBuffer[iSize++] = 0;
+            m_pBulkTypeEventBuffer[iSize++] = 0;
+            m_pBulkTypeEventBuffer[iSize++] = 0;
         }
         else
         {
             UINT nameSize = (target.sName.GetCount() + 1) * sizeof(WCHAR);
-            memcpy(m_BulkTypeEventBuffer + iSize, wszName, nameSize);
+            memcpy(m_pBulkTypeEventBuffer + iSize, wszName, nameSize);
             iSize += nameSize;
         }
 
         // Type parameter count
         ULONG params = target.rgTypeParameters.GetCount();
         
-        ULONG *ptrInt = (ULONG*)(m_BulkTypeEventBuffer + iSize);
+        ULONG *ptrInt = (ULONG*)(m_pBulkTypeEventBuffer + iSize);
         *ptrInt = params;
         iSize += 4;
         
@@ -1832,12 +1837,12 @@ void BulkTypeEventLogger::FireBulkTypeEvent()
         // Type parameter array
         if (target.cTypeParameters > 0)
         {
-            memcpy(m_BulkTypeEventBuffer + iSize, target.rgTypeParameters.GetElements(), sizeof(ULONGLONG) * target.cTypeParameters);
+            memcpy(m_pBulkTypeEventBuffer + iSize, target.rgTypeParameters.GetElements(), sizeof(ULONGLONG) * target.cTypeParameters);
             iSize += sizeof(ULONGLONG) * target.cTypeParameters;
         }
     }
 
-    FireEtwBulkType(m_nBulkTypeValueCount, GetClrInstanceId(), iSize, m_BulkTypeEventBuffer);
+    FireEtwBulkType(m_nBulkTypeValueCount, GetClrInstanceId(), iSize, m_pBulkTypeEventBuffer);
 
 #endif // FEATURE_PAL
     // Reset state
index 7aca509..ae4f1c5 100644 (file)
@@ -254,6 +254,11 @@ class BulkTypeEventLogger
 {
 private:
 
+#ifdef FEATURE_PAL
+    // The maximum event size, and the size of the buffer that we allocate to hold the event contents.
+    static const size_t kSizeOfEventBuffer = 65536;
+#endif
+
     // Estimate of how many bytes we can squeeze in the event data for the value struct
     // array.  (Intentionally overestimate the size of the non-array parts to keep it safe.)
     static const int kMaxBytesTypeValues = (cbMaxEtwEvent - 0x30);
@@ -295,7 +300,7 @@ private:
     BulkTypeValue m_rgBulkTypeValues[kMaxCountTypeValues];
 
 #ifdef FEATURE_PAL
-    BYTE m_BulkTypeEventBuffer[65536];
+    BYTE *m_pBulkTypeEventBuffer;
 #endif
 
 #ifdef FEATURE_REDHAWK
@@ -308,9 +313,38 @@ public:
     BulkTypeEventLogger() :
         m_nBulkTypeValueCount(0),
         m_nBulkTypeValueByteCount(0)
+#ifdef FEATURE_PAL
+        , m_pBulkTypeEventBuffer(NULL)
+#endif
+    {
+        CONTRACTL
+        {
+            NOTHROW;
+            GC_NOTRIGGER;
+            MODE_ANY;
+        }
+        CONTRACTL_END;
+
+#ifdef FEATURE_PAL
+        m_pBulkTypeEventBuffer = new (nothrow) BYTE[kSizeOfEventBuffer];
+#endif
+    }
+
+#ifdef FEATURE_PAL
+    ~BulkTypeEventLogger()
     {
-        LIMITED_METHOD_CONTRACT;
+        CONTRACTL
+        {
+            NOTHROW;
+            GC_NOTRIGGER;
+            MODE_ANY;
+        }
+        CONTRACTL_END;
+
+        delete[] m_pBulkTypeEventBuffer;
+        m_pBulkTypeEventBuffer = NULL;
     }
+#endif
 
     void LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSystemLog::TypeLogBehavior typeLogBehavior);
     void FireBulkTypeEvent();