summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoundinya Veluri <kouvel@users.noreply.github.com>2019-05-08 19:16:16 -0700
committerGitHub <noreply@github.com>2019-05-08 19:16:16 -0700
commit93ec324ee831cd4db087ae985c5b3a814ba8abb3 (patch)
tree350a6362ac2548c390d1294c3388150f7626fa28
parent54affc4d950184a11f7815eaa418cba5fe0a9a36 (diff)
downloadcoreclr-93ec324ee831cd4db087ae985c5b3a814ba8abb3.tar.gz
coreclr-93ec324ee831cd4db087ae985c5b3a814ba8abb3.tar.bz2
coreclr-93ec324ee831cd4db087ae985c5b3a814ba8abb3.zip
Fix ETL event rejit IDs and sending of the IL to native map event when code versioning is in use (#24422)
Fix ETL event rejit IDs and sending of the IL to native map event when code versioning is in use Fixes https://github.com/dotnet/coreclr/issues/22904 Fixes https://github.com/dotnet/coreclr/issues/22908 - Method events now always send the native code ID for the rejit ID, and the IL to native map event continues to send the IL code ID - Took code versioning into account when sending rundown events for a method including the IL to native map
-rw-r--r--src/debug/ee/debugger.cpp16
-rw-r--r--src/debug/ee/debugger.h2
-rw-r--r--src/debug/ee/functioninfo.cpp1
-rw-r--r--src/inc/eventtracebase.h14
-rw-r--r--src/vm/dbginterface.h2
-rw-r--r--src/vm/eventtrace.cpp200
-rw-r--r--src/vm/prestub.cpp1
7 files changed, 126 insertions, 110 deletions
diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
index 235a937cd6..c6ce925ec5 100644
--- a/src/debug/ee/debugger.cpp
+++ b/src/debug/ee/debugger.cpp
@@ -3079,7 +3079,7 @@ HRESULT Debugger::GetILToNativeMapping(PCODE pNativeCodeStartAddress, ULONG32 cM
HRESULT Debugger::GetILToNativeMappingIntoArrays(
MethodDesc * pMethodDesc,
- PCODE pCode,
+ PCODE pNativeCodeStartAddress,
USHORT cMapMax,
USHORT * pcMap,
UINT ** prguiILOffset,
@@ -3092,6 +3092,7 @@ HRESULT Debugger::GetILToNativeMappingIntoArrays(
}
CONTRACTL_END;
+ _ASSERTE(pMethodDesc != NULL);
_ASSERTE(pcMap != NULL);
_ASSERTE(prguiILOffset != NULL);
_ASSERTE(prguiNativeOffset != NULL);
@@ -3102,7 +3103,18 @@ HRESULT Debugger::GetILToNativeMappingIntoArrays(
// Get the JIT info by functionId.
- DebuggerJitInfo * pDJI = GetJitInfo(pMethodDesc, (const BYTE *)pCode);
+ if (pMethodDesc->IsWrapperStub() || pMethodDesc->IsDynamicMethod())
+ {
+ return E_FAIL;
+ }
+
+ DebuggerMethodInfo *pDMI = GetOrCreateMethodInfo(pMethodDesc->GetModule(), pMethodDesc->GetMemberDef());
+ if (pDMI == NULL)
+ {
+ return E_FAIL;
+ }
+
+ DebuggerJitInfo *pDJI = pDMI->FindOrCreateInitAndAddJitInfo(pMethodDesc, pNativeCodeStartAddress);
// Dunno what went wrong
if (pDJI == NULL)
diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h
index 8386a227eb..67180c0a27 100644
--- a/src/debug/ee/debugger.h
+++ b/src/debug/ee/debugger.h
@@ -2031,7 +2031,7 @@ public:
HRESULT GetILToNativeMappingIntoArrays(
MethodDesc * pMethodDesc,
- PCODE pCode,
+ PCODE pNativeCodeStartAddress,
USHORT cMapMax,
USHORT * pcMap,
UINT ** prguiILOffset,
diff --git a/src/debug/ee/functioninfo.cpp b/src/debug/ee/functioninfo.cpp
index 1bbcde2c54..7638180530 100644
--- a/src/debug/ee/functioninfo.cpp
+++ b/src/debug/ee/functioninfo.cpp
@@ -1584,6 +1584,7 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f
else
{
_ASSERTE(g_pEEInterface->GetNativeCodeMethodDesc(startAddr) == fd);
+ _ASSERTE(g_pEEInterface->GetNativeCodeStartAddress(startAddr) == startAddr);
}
// Check the lsit to see if we've already populated an entry for this JitInfo.
diff --git a/src/inc/eventtracebase.h b/src/inc/eventtracebase.h
index 12a4201a32..5a92d98fd9 100644
--- a/src/inc/eventtracebase.h
+++ b/src/inc/eventtracebase.h
@@ -31,6 +31,8 @@
struct EventStructTypeData;
void InitializeEventTracing();
+typedef DWORD NativeCodeVersionId; // keep in sync with codeversion.h
+
// !!!!!!! NOTE !!!!!!!!
// The flags must match those in the ETW manifest exactly
// !!!!!!! NOTE !!!!!!!!
@@ -569,18 +571,18 @@ namespace ETW
friend class ETW::EnumerationLog;
#ifdef FEATURE_EVENT_TRACE
static VOID SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAllocator *pLoaderAllocatorFilter, DWORD dwEventOptions);
- static VOID SendEventsForJitMethodsHelper(BaseDomain *pDomainFilter,
+ static VOID SendEventsForJitMethodsHelper(
LoaderAllocator *pLoaderAllocatorFilter,
DWORD dwEventOptions,
BOOL fLoadOrDCStart,
BOOL fUnloadOrDCEnd,
BOOL fSendMethodEvent,
BOOL fSendILToNativeMapEvent,
- BOOL fGetReJitIDs);
+ BOOL fGetCodeIds);
static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions);
static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
- static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, SIZE_T pCode, ReJITID rejitID);
- static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE);
+ static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, ReJITID ilCodeId);
+ static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, NativeCodeVersionId nativeCodeId = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE);
static VOID SendHelperEvent(ULONGLONG ullHelperStartAddress, ULONG ulHelperSize, LPCWSTR pHelperName);
public:
typedef union _MethodStructs
@@ -606,7 +608,7 @@ namespace ETW
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint);
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
- static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE);
+ static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, ReJITID ilCodeId = 0, NativeCodeVersionId nativeCodeId = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE);
static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName);
static VOID StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG ulNoOfHelpers);
static VOID MethodRestored(MethodDesc * pMethodDesc);
@@ -616,7 +618,7 @@ namespace ETW
public:
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {};
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL) {};
- static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, SIZE_T pCode = 0, ReJITID rejitID = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE) {};
+ static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, ReJITID ilCodeId = 0, NativeCodeVersionId nativeCodeId = 0, BOOL bProfilerRejectedPrecompiledCode = FALSE, BOOL bReadyToRunRejectedPrecompiledCode = FALSE) {};
static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {};
static VOID StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG ulNoOfHelpers) {};
static VOID MethodRestored(MethodDesc * pMethodDesc) {};
diff --git a/src/vm/dbginterface.h b/src/vm/dbginterface.h
index 13231c0f5f..ebf85e397a 100644
--- a/src/vm/dbginterface.h
+++ b/src/vm/dbginterface.h
@@ -286,7 +286,7 @@ public:
virtual HRESULT GetILToNativeMappingIntoArrays(
MethodDesc * pMethodDesc,
- PCODE pCode,
+ PCODE pNativeCodeStartAddress,
USHORT cMapMax,
USHORT * pcMap,
UINT ** prguiILOffset,
diff --git a/src/vm/eventtrace.cpp b/src/vm/eventtrace.cpp
index c145584551..a4e7d6ffe4 100644
--- a/src/vm/eventtrace.cpp
+++ b/src/vm/eventtrace.cpp
@@ -61,83 +61,83 @@ Volatile<LONGLONG> ETW::GCLog::s_l64LastClientSequenceNumber = 0;
//---------------------------------------------------------------------------------------
// Helper macros to determine which version of the Method events to use
//
-// The V2 versions of these events include the ReJITID, the V1 versions do not.
+// The V2 versions of these events include the NativeCodeId, the V1 versions do not.
// Historically, when we version events, we'd just stop sending the old version and only
// send the new one. However, now that we have xperf in heavy use internally and soon to be
// used externally, we need to be a bit careful. In particular, we'd like to allow
-// current xperf to continue working without knowledge of ReJITIDs, and allow future
+// current xperf to continue working without knowledge of NativeCodeIds, and allow future
// xperf to decode symbols in ReJITted functions. Thus,
// * During a first-JIT, only issue the existing V1 MethodLoad, etc. events (NOT v0,
-// NOT v2). This event does not include a ReJITID, and can thus continue to be
+// NOT v2). This event does not include a NativeCodeId, and can thus continue to be
// parsed by older decoders.
// * During a rejit, only issue the new V2 events (NOT v0 or v1), which will include a
-// nonzero ReJITID. Thus, your unique key for a method extent would be MethodID +
-// ReJITID + extent (hot/cold). These events will be ignored by older decoders
+// nonzero NativeCodeId. Thus, your unique key for a method extent would be MethodID +
+// NativeCodeId + extent (hot/cold). These events will be ignored by older decoders
// (including current xperf) because of the version number, but xperf will be
// updated to decode these in the future.
-#define FireEtwMethodLoadVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID) \
+#define FireEtwMethodLoadVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodLoadVerbose_V1(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID); } \
else \
- { FireEtwMethodLoadVerbose_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID); } \
+ { FireEtwMethodLoadVerbose_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId); } \
}
-#define FireEtwMethodLoad_V1_or_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, clrInstanceID, rejitID) \
+#define FireEtwMethodLoad_V1_or_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodLoad_V1(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, clrInstanceID); } \
else \
- { FireEtwMethodLoad_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, clrInstanceID, rejitID); } \
+ { FireEtwMethodLoad_V2(ullMethodIdentifier, ullModuleID, ullMethodStartAddress, ulMethodSize, ulMethodToken, ulMethodFlags, clrInstanceID, nativeCodeId); } \
}
-#define FireEtwMethodUnloadVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID) \
+#define FireEtwMethodUnloadVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodUnloadVerbose_V1(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID); } \
else \
- { FireEtwMethodUnloadVerbose_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID); } \
+ { FireEtwMethodUnloadVerbose_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId); } \
}
-#define FireEtwMethodUnload_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, rejitID) \
+#define FireEtwMethodUnload_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodUnload_V1(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID); } \
else \
- { FireEtwMethodUnload_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, rejitID); } \
+ { FireEtwMethodUnload_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, nativeCodeId); } \
}
-#define FireEtwMethodDCStartVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID) \
+#define FireEtwMethodDCStartVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodDCStartVerbose_V1(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID); } \
else \
- { FireEtwMethodDCStartVerbose_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID); } \
+ { FireEtwMethodDCStartVerbose_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId); } \
}
-#define FireEtwMethodDCStart_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, rejitID) \
+#define FireEtwMethodDCStart_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodDCStart_V1(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID); } \
else \
- { FireEtwMethodDCStart_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, rejitID); } \
+ { FireEtwMethodDCStart_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, nativeCodeId); } \
}
-#define FireEtwMethodDCEndVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID) \
+#define FireEtwMethodDCEndVerbose_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodDCEndVerbose_V1(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID); } \
else \
- { FireEtwMethodDCEndVerbose_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, rejitID); } \
+ { FireEtwMethodDCEndVerbose_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, szDtraceOutput1, szDtraceOutput2, szDtraceOutput3, clrInstanceID, nativeCodeId); } \
}
-#define FireEtwMethodDCEnd_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, rejitID) \
+#define FireEtwMethodDCEnd_V1_or_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, nativeCodeId) \
{ \
- if (rejitID == 0) \
+ if (nativeCodeId == 0) \
{ FireEtwMethodDCEnd_V1(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID); } \
else \
- { FireEtwMethodDCEnd_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, rejitID); } \
+ { FireEtwMethodDCEnd_V2(ullMethodIdentifier, ullModuleID, ullColdMethodStartAddress, ulColdMethodSize, ulMethodToken, ulColdMethodFlags, clrInstanceID, nativeCodeId); } \
}
// Module load / unload events:
@@ -5227,7 +5227,7 @@ VOID ETW::MethodLog::GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPo
/*******************************************************/
/* This is called by the runtime when a method is jitted completely */
/*******************************************************/
-VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, SIZE_T pCode, ReJITID rejitID, BOOL bProfilerRejectedPrecompiledCode, BOOL bReadyToRunRejectedPrecompiledCode)
+VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, ReJITID ilCodeId, NativeCodeVersionId nativeCodeId, BOOL bProfilerRejectedPrecompiledCode, BOOL bReadyToRunRejectedPrecompiledCode)
{
CONTRACTL {
NOTHROW;
@@ -5240,7 +5240,7 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC
TRACE_LEVEL_INFORMATION,
CLR_JIT_KEYWORD))
{
- ETW::MethodLog::SendMethodEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodLoad, TRUE, namespaceOrClassName, methodName, methodSignature, pCode, rejitID, bProfilerRejectedPrecompiledCode, bReadyToRunRejectedPrecompiledCode);
+ ETW::MethodLog::SendMethodEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodLoad, TRUE, namespaceOrClassName, methodName, methodSignature, pNativeCodeStartAddress, nativeCodeId, bProfilerRejectedPrecompiledCode, bReadyToRunRejectedPrecompiledCode);
}
if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
@@ -5255,7 +5255,7 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC
_ASSERTE(g_pDebugInterface != NULL);
g_pDebugInterface->InitializeLazyDataIfNecessary();
- ETW::MethodLog::SendMethodILToNativeMapEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodILToNativeMap, pCode, rejitID);
+ ETW::MethodLog::SendMethodILToNativeMapEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodILToNativeMap, pNativeCodeStartAddress, ilCodeId);
}
} EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
@@ -6263,7 +6263,7 @@ VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *n
/****************************************************************************/
/* This routine is used to send a method load/unload or rundown event */
/****************************************************************************/
-VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, SIZE_T pCode, ReJITID rejitID, BOOL bProfilerRejectedPrecompiledCode, BOOL bReadyToRunRejectedPrecompiledCode)
+VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, NativeCodeVersionId nativeCodeId, BOOL bProfilerRejectedPrecompiledCode, BOOL bReadyToRunRejectedPrecompiledCode)
{
CONTRACTL {
THROWS;
@@ -6346,7 +6346,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodFlags = ulMethodFlags | ETW::MethodLog::MethodStructs::HotSection; // Method Extent (bits 28, 29, 30, 31)
// MethodDesc ==> Code Address ==>JitMananger
- TADDR start = pCode ? pCode : PCODEToPINSTR(pMethodDesc->GetNativeCode());
+ TADDR start = PCODEToPINSTR(pNativeCodeStartAddress ? pNativeCodeStartAddress : pMethodDesc->GetNativeCode());
if(start == 0) {
// this method hasn't been jitted
return;
@@ -6424,7 +6424,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6435,7 +6435,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
if(bFireEventForColdSection)
{
@@ -6451,7 +6451,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6462,7 +6462,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulColdMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
}
}
@@ -6481,7 +6481,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6492,7 +6492,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
if(bFireEventForColdSection)
{
@@ -6508,7 +6508,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6519,7 +6519,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulColdMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
}
}
@@ -6538,7 +6538,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6549,7 +6549,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
if(bFireEventForColdSection)
{
@@ -6565,7 +6565,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6576,7 +6576,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulColdMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
}
}
@@ -6595,7 +6595,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6606,7 +6606,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
if(bFireEventForColdSection)
{
@@ -6622,7 +6622,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
szDtraceOutput2,
szDtraceOutput3,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
else
{
@@ -6633,7 +6633,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
ulMethodToken,
ulColdMethodFlags,
GetClrInstanceId(),
- rejitID);
+ nativeCodeId);
}
}
}
@@ -6662,7 +6662,7 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
//
// static
-VOID ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, SIZE_T pCode, ReJITID rejitID)
+VOID ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, ReJITID ilCodeId)
{
CONTRACTL
{
@@ -6695,7 +6695,7 @@ VOID ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWOR
HRESULT hr = g_pDebugInterface->GetILToNativeMappingIntoArrays(
pMethodDesc,
- pCode,
+ pNativeCodeStartAddress,
kMapEntriesMax,
&cMap,
&rguiILOffset,
@@ -6711,7 +6711,7 @@ VOID ETW::MethodLog::SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWOR
{
FireEtwMethodILToNativeMap(
ullMethodIdentifier,
- rejitID,
+ ilCodeId,
0, // Extent: This event is only sent for JITted (not NGENd) methods, and
// currently there is only one extent (hot) for JITted methods.
cMap,
@@ -6803,20 +6803,22 @@ VOID ETW::MethodLog::SendEventsForNgenMethods(Module *pModule, DWORD dwEventOpti
// Called be ETW::MethodLog::SendEventsForJitMethods
// Sends the ETW events once our caller determines whether or not rejit locks can be acquired
-VOID ETW::MethodLog::SendEventsForJitMethodsHelper(BaseDomain *pDomainFilter,
- LoaderAllocator *pLoaderAllocatorFilter,
+VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAllocatorFilter,
DWORD dwEventOptions,
BOOL fLoadOrDCStart,
BOOL fUnloadOrDCEnd,
BOOL fSendMethodEvent,
BOOL fSendILToNativeMapEvent,
- BOOL fGetReJitIDs)
+ BOOL fGetCodeIds)
{
CONTRACTL{
THROWS;
GC_NOTRIGGER;
} CONTRACTL_END;
+ _ASSERTE(pLoaderAllocatorFilter == nullptr || pLoaderAllocatorFilter->IsCollectible());
+ _ASSERTE(pLoaderAllocatorFilter == nullptr || !fGetCodeIds);
+
EEJitManager::CodeHeapIterator heapIterator(pLoaderAllocatorFilter);
while (heapIterator.Next())
{
@@ -6824,16 +6826,40 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(BaseDomain *pDomainFilter,
if (pMD == NULL)
continue;
- TADDR codeStart = heapIterator.GetMethodCode();
+ PCODE codeStart = PINSTRToPCODE(heapIterator.GetMethodCode());
- // Grab rejitID from the rejit manager. In some cases, such as collectible loader
- // allocators, we don't support rejit so we need to short circuit the call.
- // This also allows our caller to avoid having to pre-enter the rejit
- // manager locks.
+ // Get the IL and native code IDs. In some cases, such as collectible loader
+ // allocators, we don't support code versioning so we need to short circuit the call.
+ // This also allows our caller to avoid having to pre-enter the relevant locks.
// see code:#TableLockHolder
- ReJITID rejitID =
- fGetReJitIDs ? ReJitManager::GetReJitIdNoLock(pMD, codeStart) : 0;
-
+ ReJITID ilCodeId = 0;
+ NativeCodeVersionId nativeCodeId = 0;
+#ifdef FEATURE_CODE_VERSIONING
+ if (fGetCodeIds)
+ {
+ CodeVersionManager *pCodeVersionManager = pMD->GetCodeVersionManager();
+ _ASSERTE(pCodeVersionManager->LockOwnedByCurrentThread());
+ NativeCodeVersion nativeCodeVersion = pCodeVersionManager->GetNativeCodeVersion(pMD, codeStart);
+ if (nativeCodeVersion.IsNull())
+ {
+ // The code version manager hasn't been updated with the jitted code
+ if (codeStart != pMD->GetNativeCode())
+ {
+ continue;
+ }
+ }
+ else
+ {
+ nativeCodeId = nativeCodeVersion.GetVersionId();
+ ilCodeId = nativeCodeVersion.GetILCodeVersionId();
+ }
+ }
+ else
+#endif
+ if (codeStart != pMD->GetNativeCode())
+ {
+ continue;
+ }
// When we're called to announce loads, then the methodload event itself must
// precede any supplemental events, so that the method load or method jitting
@@ -6851,41 +6877,13 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(BaseDomain *pDomainFilter,
NULL, // methodName
NULL, // methodSignature
codeStart,
- rejitID);
+ nativeCodeId);
}
}
- // The filtering line below excludes all methods that don't go directly to the
- // native body (And that includes all Tiered JIT methods). In V3.0 Tiered JIT
- // is only by default which means important methods are filtered out.
- //
- // This filter used to exclude all events for a particular method, but has been
- // moved here so it only applies to the IL->Native map.
- // This filter needs to be removed in its entirety, because right now all Tiered
- // methods don't have a IL->Native map (and thus can't support source line profiling)
- // moving it here at least minimizes the damage.
- //
- // We did not remove the filter right now because currently
- // SendMethodILToNativeMapEvent relies on a fragile invariant where all lazy data is
- // known to be populated (see g_pDebugInterface->InitializeLazyDataIfNecessary(); above)
- // and this may not be true for tiered methods.
- //
- // There was also concern that there are races where the heap-iterator might see
- // data between the time that the code was created and the debug information was set
- // (there is a lock that protects the code manager data, however the JIT does not
- // let all the data in one go (in particular the debug data is set latter).
- //
- // Note that currently the rejitID variable is likely always 0 because it seems that
- // fGetReJitIDs=false except in the case that an appdomain is being unloaded (which I
- // think never happens in .NET core)
- //
- // Issue #22904 tracks the work to fix the IL->Native mapping.
- if ((rejitID != 0) || (codeStart == PCODEToPINSTR(pMD->GetNativeCode())))
- {
- // Send any supplemental events requested for this MethodID
- if (fSendILToNativeMapEvent)
- ETW::MethodLog::SendMethodILToNativeMapEvent(pMD, dwEventOptions, codeStart, rejitID);
- }
+ // Send any supplemental events requested for this MethodID
+ if (fSendILToNativeMapEvent)
+ ETW::MethodLog::SendMethodILToNativeMapEvent(pMD, dwEventOptions, codeStart, ilCodeId);
// When we're called to announce unloads, then the methodunload event itself must
// come after any supplemental events, so that the method unload event is the
@@ -6902,7 +6900,7 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(BaseDomain *pDomainFilter,
NULL, // methodName
NULL, // methodSignature
codeStart,
- rejitID);
+ nativeCodeId);
}
}
}
@@ -6958,7 +6956,7 @@ VOID ETW::MethodLog::SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAl
// #TableLockHolder:
//
// A word about ReJitManager::TableLockHolder... As we enumerate through the functions,
- // we may need to grab their ReJITIDs. The ReJitManager grabs its table Crst in order to
+ // we may need to grab their code IDs. The ReJitManager grabs its table Crst in order to
// fetch these. However, several other kinds of locks are being taken during this
// enumeration, such as the SystemDomain lock and the EEJitManager::CodeHeapIterator's
// lock. In order to avoid lock-leveling issues, we grab the appropriate ReJitManager
@@ -6974,10 +6972,11 @@ VOID ETW::MethodLog::SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAl
//
// We only support getting rejit IDs when filtering by domain.
+#ifdef FEATURE_CODE_VERSIONING
if (pDomainFilter)
{
CodeVersionManager::TableLockHolder lkRejitMgrModule(pDomainFilter->GetCodeVersionManager());
- SendEventsForJitMethodsHelper(pDomainFilter,
+ SendEventsForJitMethodsHelper(
pLoaderAllocatorFilter,
dwEventOptions,
fLoadOrDCStart,
@@ -6987,8 +6986,9 @@ VOID ETW::MethodLog::SendEventsForJitMethods(BaseDomain *pDomainFilter, LoaderAl
TRUE);
}
else
+#endif
{
- SendEventsForJitMethodsHelper(pDomainFilter,
+ SendEventsForJitMethodsHelper(
pLoaderAllocatorFilter,
dwEventOptions,
fLoadOrDCStart,
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 1d99f43b30..0e45b96cad 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -811,6 +811,7 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
&methodName,
&methodSignature,
pCode,
+ pConfig->GetCodeVersion().GetILCodeVersionId(),
pConfig->GetCodeVersion().GetVersionId(),
pConfig->ProfilerRejectedPrecompiledCode(),
pConfig->ReadyToRunRejectedPrecompiledCode());