Add ETL flags for ReadyToRun (#15801)
authorAndy Ayers <andya@microsoft.com>
Thu, 1 Feb 2018 02:01:22 +0000 (18:01 -0800)
committerGitHub <noreply@github.com>
Thu, 1 Feb 2018 02:01:22 +0000 (18:01 -0800)
Add flags to track the presence of ReadyToRun codegen in an assembly
and module.

Add jitting flags to indicate when a method is jitted because the
precompiled code was rejected, either by a profiler or by ReadyToRun
dependence tracking.

Together these can be used to distingish between
* methods jitted because their assemblies were not precompiled
* methods jitted because they were not precompiled in an otherwise
precompiled assembly

src/inc/eventtracebase.h
src/vm/eventtrace.cpp
src/vm/method.hpp
src/vm/prestub.cpp
src/vm/readytoruninfo.cpp
src/vm/readytoruninfo.h

index c29308d..c46cb8a 100644 (file)
@@ -518,6 +518,7 @@ namespace ETW
                 DynamicAssembly=0x2,
                 NativeAssembly=0x4,
                 CollectibleAssembly=0x8,
+                ReadyToRunAssembly=0x10,
             }AssemblyFlags;
 
             typedef enum _ModuleFlags
@@ -526,7 +527,8 @@ namespace ETW
                 NativeModule=0x2,
                 DynamicModule=0x4,
                 ManifestModule=0x8,
-                IbcOptimized=0x10
+                IbcOptimized=0x10,
+                ReadyToRunModule=0x20,
             }ModuleFlags;
 
             typedef enum _RangeFlags
@@ -575,7 +577,7 @@ namespace ETW
         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);
+        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 SendHelperEvent(ULONGLONG ullHelperStartAddress, ULONG ulHelperSize, LPCWSTR pHelperName);
     public:
         typedef union _MethodStructs
@@ -586,7 +588,9 @@ namespace ETW
                 GenericMethod=0x2,
                 SharedGenericCode=0x4,
                 JittedMethod=0x8,
-                JitHelperMethod=0x10
+                JitHelperMethod=0x10,
+                ProfilerRejectedPrecompiledCode=0x20,
+                ReadyToRunRejectedPrecompiledCode=0x40,
             }MethodFlags;
 
             typedef enum _MethodExtent
@@ -598,7 +602,7 @@ namespace ETW
         }MethodStructs;
 
         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);
+        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 StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName);
         static VOID StubsInitialized(PVOID *pHelperStartAddresss, PVOID *pHelperNames, LONG ulNoOfHelpers);
         static VOID MethodRestored(MethodDesc * pMethodDesc);
index 5fb63c9..7da8060 100644 (file)
@@ -5277,7 +5277,7 @@ HRESULT ETW::CodeSymbolLog::ReadInMemorySymbols(
 /*******************************************************/
 /* 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)
+VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, SIZE_T pCode, ReJITID rejitID, BOOL bProfilerRejectedPrecompiledCode, BOOL bReadyToRunRejectedPrecompiledCode)
 {
     CONTRACTL {
         NOTHROW;
@@ -5290,7 +5290,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);
+            ETW::MethodLog::SendMethodEvent(pMethodDesc, ETW::EnumerationLog::EnumerationStructs::JitMethodLoad, TRUE, namespaceOrClassName, methodName, methodSignature, pCode, rejitID, bProfilerRejectedPrecompiledCode, bReadyToRunRejectedPrecompiledCode); 
         }
 
         if(ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, 
@@ -5803,6 +5803,7 @@ VOID ETW::LoaderLog::SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions
     BOOL bIsCollectibleAssembly = pAssembly->IsCollectible();
     BOOL bIsDomainNeutral = pAssembly->IsDomainNeutral() ;
     BOOL bHasNativeImage = pAssembly->GetManifestFile()->HasNativeImage();
+    BOOL bIsReadyToRun = pAssembly->GetManifestFile()->IsILImageReadyToRun();
 
     ULONGLONG ullAssemblyId = (ULONGLONG)pAssembly;
     ULONGLONG ullDomainId = (ULONGLONG)pAssembly->GetDomain();
@@ -5810,7 +5811,8 @@ VOID ETW::LoaderLog::SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions
     ULONG ulAssemblyFlags = ((bIsDomainNeutral ? ETW::LoaderLog::LoaderStructs::DomainNeutralAssembly : 0) |
                              (bIsDynamicAssembly ? ETW::LoaderLog::LoaderStructs::DynamicAssembly : 0) |
                              (bHasNativeImage ? ETW::LoaderLog::LoaderStructs::NativeAssembly : 0) |
-                             (bIsCollectibleAssembly ? ETW::LoaderLog::LoaderStructs::CollectibleAssembly : 0));
+                             (bIsCollectibleAssembly ? ETW::LoaderLog::LoaderStructs::CollectibleAssembly : 0) |
+                             (bIsReadyToRun ? ETW::LoaderLog::LoaderStructs::ReadyToRunAssembly : 0));
 
     SString sAssemblyPath;
     pAssembly->GetDisplayName(sAssemblyPath);
@@ -6127,12 +6129,14 @@ VOID ETW::LoaderLog::SendModuleEvent(Module *pModule, DWORD dwEventOptions, BOOL
     {
         bIsIbcOptimized = pModule->IsIbcOptimized();
     }
+    BOOL bIsReadyToRun = pModule->IsReadyToRun();
     ULONG ulReservedFlags = 0;
     ULONG ulFlags = ((bIsDomainNeutral ? ETW::LoaderLog::LoaderStructs::DomainNeutralModule : 0) |
                      (bHasNativeImage ? ETW::LoaderLog::LoaderStructs::NativeModule : 0) |
                      (bIsDynamicAssembly ? ETW::LoaderLog::LoaderStructs::DynamicModule : 0) |
                      (bIsManifestModule ? ETW::LoaderLog::LoaderStructs::ManifestModule : 0) |
-                     (bIsIbcOptimized ? ETW::LoaderLog::LoaderStructs::IbcOptimized : 0));
+                     (bIsIbcOptimized ? ETW::LoaderLog::LoaderStructs::IbcOptimized : 0) |
+                     (bIsReadyToRun ? ETW::LoaderLog::LoaderStructs::ReadyToRunModule : 0));
 
     // Grab PDB path, guid, and age for managed PDB and native (NGEN) PDB when
     // available.  Any failures are not fatal.  The corresponding PDB info will remain
@@ -6318,7 +6322,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)
+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)
 {
     CONTRACTL {
         THROWS;
@@ -6392,7 +6396,9 @@ VOID ETW::MethodLog::SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptio
         (bHasSharedGenericCode ? ETW::MethodLog::MethodStructs::SharedGenericCode : 0) |
         (bIsGenericMethod ? ETW::MethodLog::MethodStructs::GenericMethod : 0) |
         (bIsDynamicMethod ? ETW::MethodLog::MethodStructs::DynamicMethod : 0) |
-        (bIsJit ? ETW::MethodLog::MethodStructs::JittedMethod : 0)));
+        (bIsJit ? ETW::MethodLog::MethodStructs::JittedMethod : 0) |
+        (bProfilerRejectedPrecompiledCode ? ETW::MethodLog::MethodStructs::ProfilerRejectedPrecompiledCode : 0) |
+        (bReadyToRunRejectedPrecompiledCode ? ETW::MethodLog::MethodStructs::ReadyToRunRejectedPrecompiledCode : 0)));
 
     // Intentionally set the extent flags (cold vs. hot) only after all the other common
     // flags (above) have been set.
index 9791ddd..664716b 100644 (file)
@@ -1865,8 +1865,8 @@ public:
 private:
     PCODE PrepareILBasedCode(PrepareCodeConfig* pConfig);
     PCODE GetPrecompiledCode(PrepareCodeConfig* pConfig);
-    PCODE GetPrecompiledNgenCode();
-    PCODE GetPrecompiledR2RCode();
+    PCODE GetPrecompiledNgenCode(PrepareCodeConfig* pConfig);
+    PCODE GetPrecompiledR2RCode(PrepareCodeConfig* pConfig);
     PCODE GetMulticoreJitCode();
     COR_ILMETHOD_DECODER* GetAndVerifyILHeader(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory);
     COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory);
@@ -1891,12 +1891,18 @@ public:
     virtual BOOL SetNativeCode(PCODE pCode, PCODE * ppAlternateCodeToUse);
     virtual COR_ILMETHOD* GetILHeader();
     virtual CORJIT_FLAGS GetJitCompilationFlags();
+    BOOL ProfilerRejectedPrecompiledCode();
+    BOOL ReadyToRunRejectedPrecompiledCode();
+    void SetProfilerRejectedPrecompiledCode();
+    void SetReadyToRunRejectedPrecompiledCode();
     
 protected:
     MethodDesc* m_pMethodDesc;
     NativeCodeVersion m_nativeCodeVersion;
     BOOL m_needsMulticoreJitNotification;
     BOOL m_mayUsePrecompiledCode;
+    BOOL m_ProfilerRejectedPrecompiledCode;
+    BOOL m_ReadyToRunRejectedPrecompiledCode;
 };
 
 #ifdef FEATURE_CODE_VERSIONING
index cd85713..99f6ebb 100644 (file)
@@ -319,13 +319,13 @@ PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig)
     PCODE pCode = NULL;
 
 #ifdef FEATURE_PREJIT 
-    pCode = GetPrecompiledNgenCode();
+    pCode = GetPrecompiledNgenCode(pConfig);
 #endif
 
 #ifdef FEATURE_READYTORUN
     if (pCode == NULL)
     {
-        pCode = GetPrecompiledR2RCode();
+        pCode = GetPrecompiledR2RCode(pConfig);
         if (pCode != NULL)
         {
             pConfig->SetNativeCode(pCode, &pCode);
@@ -336,7 +336,7 @@ PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig)
     return pCode;
 }
 
-PCODE MethodDesc::GetPrecompiledNgenCode()
+PCODE MethodDesc::GetPrecompiledNgenCode(PrepareCodeConfig* pConfig)
 {
     STANDARD_VM_CONTRACT;
     PCODE pCode = NULL;
@@ -371,6 +371,7 @@ PCODE MethodDesc::GetPrecompiledNgenCode()
         {
             SetNativeCodeInterlocked(NULL, pCode);
             _ASSERTE(!IsPreImplemented());
+            pConfig->SetProfilerRejectedPrecompiledCode();
             pCode = NULL;
         }
     }
@@ -423,7 +424,7 @@ PCODE MethodDesc::GetPrecompiledNgenCode()
 }
 
 
-PCODE MethodDesc::GetPrecompiledR2RCode()
+PCODE MethodDesc::GetPrecompiledR2RCode(PrepareCodeConfig* pConfig)
 {
     STANDARD_VM_CONTRACT;
 
@@ -432,7 +433,7 @@ PCODE MethodDesc::GetPrecompiledR2RCode()
     Module * pModule = GetModule();
     if (pModule->IsReadyToRun())
     {
-        pCode = pModule->GetReadyToRunInfo()->GetEntryPoint(this);
+        pCode = pModule->GetReadyToRunInfo()->GetEntryPoint(this, pConfig);
     }
 #endif
     return pCode;
@@ -725,7 +726,9 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
                 &methodName,
                 &methodSignature,
                 pCode,
-                pConfig->GetCodeVersion().GetVersionId());
+                pConfig->GetCodeVersion().GetVersionId(),
+                pConfig->ProfilerRejectedPrecompiledCode(),
+                pConfig->ReadyToRunRejectedPrecompiledCode());
         }
 
     }
@@ -910,7 +913,9 @@ PrepareCodeConfig::PrepareCodeConfig(NativeCodeVersion codeVersion, BOOL needsMu
     m_pMethodDesc(codeVersion.GetMethodDesc()),
     m_nativeCodeVersion(codeVersion),
     m_needsMulticoreJitNotification(needsMulticoreJitNotification),
-    m_mayUsePrecompiledCode(mayUsePrecompiledCode)
+    m_mayUsePrecompiledCode(mayUsePrecompiledCode),
+    m_ProfilerRejectedPrecompiledCode(FALSE),
+    m_ReadyToRunRejectedPrecompiledCode(FALSE)
 {}
 
 MethodDesc* PrepareCodeConfig::GetMethodDesc()
@@ -931,6 +936,30 @@ BOOL PrepareCodeConfig::NeedsMulticoreJitNotification()
     return m_needsMulticoreJitNotification;
 }
 
+BOOL PrepareCodeConfig::ProfilerRejectedPrecompiledCode()
+{
+    LIMITED_METHOD_CONTRACT;
+    return m_ProfilerRejectedPrecompiledCode;
+}
+
+void PrepareCodeConfig::SetProfilerRejectedPrecompiledCode()
+{
+    LIMITED_METHOD_CONTRACT;
+    m_ProfilerRejectedPrecompiledCode = TRUE;
+}
+
+BOOL PrepareCodeConfig::ReadyToRunRejectedPrecompiledCode()
+{
+    LIMITED_METHOD_CONTRACT;
+    return m_ReadyToRunRejectedPrecompiledCode;
+}
+
+void PrepareCodeConfig::SetReadyToRunRejectedPrecompiledCode()
+{
+    LIMITED_METHOD_CONTRACT;
+    m_ReadyToRunRejectedPrecompiledCode = TRUE;
+}
+
 NativeCodeVersion PrepareCodeConfig::GetCodeVersion()
 {
     LIMITED_METHOD_CONTRACT;
index bcb8e83..5e29aed 100644 (file)
@@ -15,6 +15,7 @@
 #include "compile.h"
 #include "versionresilienthashcode.h"
 #include "typehashingalgorithms.h"
+#include "method.hpp"
 
 using namespace NativeFormat;
 
@@ -673,7 +674,7 @@ static bool SigMatchesMethodDesc(MethodDesc* pMD, SigPointer &sig, Module * pMod
     return true;
 }
 
-PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, BOOL fFixups /*=TRUE*/)
+PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, PrepareCodeConfig* pConfig, BOOL fFixups /*=TRUE*/)
 {
     STANDARD_VM_CONTRACT;
 
@@ -727,6 +728,7 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, BOOL fFixups /*=TRUE*/)
         }
         if (!fShouldSearchCache)
         {
+            pConfig->SetProfilerRejectedPrecompiledCode();
             return NULL;
         }
 #endif // PROFILING_SUPPORTED
@@ -747,7 +749,12 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, BOOL fFixups /*=TRUE*/)
         if (fFixups)
         {
             if (!m_pModule->FixupDelayList(dac_cast<TADDR>(m_pLayout->GetBase()) + offset))
+            {
+#ifndef CROSSGEN_COMPILE
+                pConfig->SetReadyToRunRejectedPrecompiledCode();
+#endif // CROSSGEN_COMPILE
                 return NULL;
+            }
         }
 
         id >>= 2;
index 2266e9c..c7eab9e 100644 (file)
@@ -17,6 +17,8 @@
 
 typedef DPTR(struct READYTORUN_SECTION) PTR_READYTORUN_SECTION;
 
+class PrepareCodeConfig;
+
 typedef DPTR(class ReadyToRunInfo) PTR_ReadyToRunInfo;
 class ReadyToRunInfo
 {
@@ -50,7 +52,7 @@ public:
 
     static PTR_ReadyToRunInfo Initialize(Module * pModule, AllocMemTracker *pamTracker);
 
-    PCODE GetEntryPoint(MethodDesc * pMD, BOOL fFixups = TRUE);
+    PCODE GetEntryPoint(MethodDesc * pMD, PrepareCodeConfig* pConfig, BOOL fFixups = TRUE);
 
     MethodDesc * GetMethodDescForEntryPoint(PCODE entryPoint);