Skip to content

Commit 2db51aa

Browse files
authored
Apply some obvious rich debug info optimizations (#73373)
* Stop sending many duplicate MethodDetails events for rich debug info When rich debug info is enabled we send MethodDetails events for all inlinees as otherwise no information for those may have been sent (in case they have not been jitted). During rundown this was sending a lot of duplicate events. * Compress rich debug info and optimize ETW events * Compress rich debug info when stored in the runtime. For Avalonia.ILSpy which has ~33k methods, the memory overhead of rich debug info goes from 7 MB -> 2.1 MB * ETW events do not use the delta compression, but still optimize them a little by avoiding sending out the padding and unnecessarily large types. The average size of a rich debug info ETW event goes from 259 bytes to 219 bytes for ILSpy * Add DoEncodedDeltaU32NonMonotonic and use it The inline ordinals may not be monotonically increasing and the existing DoEncodedDeltaU32 is unnecessarily inefficient for the cases where it isn't (plus, will assert). * Use non-monotonic delta compression for IL offsets Gets us an extra ~10% size reduction in my tests
1 parent e8a85b7 commit 2db51aa

File tree

5 files changed

+291
-62
lines changed

5 files changed

+291
-62
lines changed

src/coreclr/inc/eventtracebase.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,11 @@ class CrstBase;
690690
class BulkTypeEventLogger;
691691
class TypeHandle;
692692
class Thread;
693-
693+
template<typename ELEMENT, typename TRAITS>
694+
class SetSHash;
695+
template<typename ELEMENT>
696+
class PtrSetSHashTraits;
697+
typedef SetSHash<MethodDesc*, PtrSetSHashTraits<MethodDesc*>> MethodDescSet;
694698

695699
// All ETW helpers must be a part of this namespace
696700
// We have auto-generated macros to directly fire the events
@@ -903,8 +907,8 @@ namespace ETW
903907
static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions);
904908
static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
905909
static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId);
906-
static VOID SendMethodRichDebugInfo(MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId);
907-
static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, PrepareCodeConfig *pConfig = NULL);
910+
static VOID SendMethodRichDebugInfo(MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId, MethodDescSet* sentMethodDetailsSet);
911+
static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, PrepareCodeConfig *pConfig = NULL, MethodDescSet* sentMethodDetailsSet = NULL);
908912
static VOID SendHelperEvent(ULONGLONG ullHelperStartAddress, ULONG ulHelperSize, LPCWSTR pHelperName);
909913
public:
910914
typedef union _MethodStructs
@@ -937,6 +941,7 @@ namespace ETW
937941
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
938942
static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
939943
static VOID SendMethodDetailsEvent(MethodDesc *pMethodDesc);
944+
static VOID SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, MethodDescSet* set);
940945
static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName);
941946
static VOID StubsInitialized(PVOID *pHelperStartAddress, PVOID *pHelperNames, LONG ulNoOfHelpers);
942947
static VOID MethodRestored(MethodDesc * pMethodDesc);

src/coreclr/inc/nibblestream.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,22 @@ class NibbleWriter
159159
WriteEncodedU32(dw);
160160
};
161161

162+
void WriteUnencodedU32(uint32_t x)
163+
{
164+
CONTRACTL
165+
{
166+
THROWS;
167+
GC_NOTRIGGER;
168+
}
169+
CONTRACTL_END;
170+
171+
for (int i = 0; i < 8; i++)
172+
{
173+
WriteNibble(static_cast<NIBBLE>(x & 0b1111));
174+
x >>= 4;
175+
}
176+
}
177+
162178
protected:
163179
NIBBLE m_PendingNibble; // Pending value, not yet written out.
164180
bool m_fPending;
@@ -288,6 +304,26 @@ class NibbleReader
288304
return (dw & 1) ? (-x) : (x);
289305
}
290306

307+
DWORD ReadUnencodedU32()
308+
{
309+
CONTRACTL
310+
{
311+
THROWS;
312+
GC_NOTRIGGER;
313+
SUPPORTS_DAC;
314+
}
315+
CONTRACTL_END;
316+
317+
DWORD result = 0;
318+
319+
for (int i = 0; i < 8; i++)
320+
{
321+
result |= static_cast<DWORD>(ReadNibble()) << (i * 4);
322+
}
323+
324+
return result;
325+
}
326+
291327
protected:
292328
PTR_BYTE m_pBuffer;
293329
size_t m_cBytes; // size of buffer.

0 commit comments

Comments
 (0)