diff options
Diffstat (limited to 'src/vm')
-rw-r--r-- | src/vm/assembly.cpp | 43 | ||||
-rw-r--r-- | src/vm/assembly.hpp | 12 | ||||
-rw-r--r-- | src/vm/ceeload.cpp | 79 | ||||
-rw-r--r-- | src/vm/ceeload.h | 7 | ||||
-rw-r--r-- | src/vm/pefile.h | 1 | ||||
-rw-r--r-- | src/vm/pefile.inl | 17 | ||||
-rw-r--r-- | src/vm/readytoruninfo.cpp | 34 |
7 files changed, 154 insertions, 39 deletions
diff --git a/src/vm/assembly.cpp b/src/vm/assembly.cpp index 5f0e75dd4d..d95eec0720 100644 --- a/src/vm/assembly.cpp +++ b/src/vm/assembly.cpp @@ -141,6 +141,9 @@ Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pFile, DebuggerAssemblyContr #ifdef FEATURE_COMINTEROP , m_InteropAttributeStatus(INTEROP_ATTRIBUTE_UNSET) #endif +#ifdef FEATURE_PREJIT + , m_isInstrumentedStatus(IS_INSTRUMENTED_UNSET) +#endif { STANDARD_VM_CONTRACT; } @@ -2329,21 +2332,37 @@ BOOL Assembly::IsInstrumented() STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_FAULT; - BOOL isInstrumented = false; - - EX_TRY + // This will set the value of m_isInstrumentedStatus by calling IsInstrumentedHelper() + // that method performs string pattern matching using the Config value of ZapBBInstr + // We cache the value returned from that method in m_isInstrumentedStatus + // + if (m_isInstrumentedStatus == IS_INSTRUMENTED_UNSET) { - FAULT_NOT_FATAL(); + EX_TRY + { + FAULT_NOT_FATAL(); - isInstrumented = IsInstrumentedHelper(); - } - EX_CATCH - { - isInstrumented = false; + if (IsInstrumentedHelper()) + { + m_isInstrumentedStatus = IS_INSTRUMENTED_TRUE; + } + else + { + m_isInstrumentedStatus = IS_INSTRUMENTED_FALSE; + } + } + + EX_CATCH + { + m_isInstrumentedStatus = IS_INSTRUMENTED_FALSE; + } + EX_END_CATCH(RethrowTerminalExceptions); } - EX_END_CATCH(RethrowTerminalExceptions); - return isInstrumented; + // At this point m_isInstrumentedStatus can't have the value of IS_INSTRUMENTED_UNSET + _ASSERTE(m_isInstrumentedStatus != IS_INSTRUMENTED_UNSET); + + return (m_isInstrumentedStatus == IS_INSTRUMENTED_TRUE); } BOOL Assembly::IsInstrumentedHelper() @@ -2357,7 +2376,7 @@ BOOL Assembly::IsInstrumentedHelper() return false; // We must have a native image in order to perform IBC instrumentation - if (!GetManifestFile()->HasNativeImage()) + if (!GetManifestFile()->HasNativeOrReadyToRunImage()) return false; // @Consider using the full name instead of the short form diff --git a/src/vm/assembly.hpp b/src/vm/assembly.hpp index 22b031bcad..0fdb9a248a 100644 --- a/src/vm/assembly.hpp +++ b/src/vm/assembly.hpp @@ -551,7 +551,7 @@ public: BOOL IsSIMDVectorAssembly() { LIMITED_METHOD_DAC_CONTRACT; return m_fIsSIMDVectorAssembly; } -#ifdef FEATURE_PREJIT +#ifdef FEATURE_PREJIT BOOL IsInstrumented(); BOOL IsInstrumentedHelper(); #endif // FEATURE_PREJIT @@ -704,7 +704,6 @@ protected: // Keep track of the vars that need to be freed. short int m_FreeFlag; - private: //**************************************************************************************** @@ -775,6 +774,15 @@ private: DWORD m_dwReliabilityContract; +#ifdef FEATURE_PREJIT + enum IsInstrumentedStatus { + IS_INSTRUMENTED_UNSET = 0, + IS_INSTRUMENTED_FALSE = 1, + IS_INSTRUMENTED_TRUE = 2, + }; + IsInstrumentedStatus m_isInstrumentedStatus; +#endif // FEATURE_PREJIT + }; typedef Assembly::ModuleIterator ModuleIterator; diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 61d8ae207f..1979d694cb 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -437,6 +437,55 @@ Module::Module(Assembly *pAssembly, mdFile moduleRef, PEFile *file) file->AddRef(); } +void Module::InitializeForProfiling() +{ + CONTRACTL + { + INSTANCE_CHECK; + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + PRECONDITION(HasNativeOrReadyToRunImage()); + } + CONTRACTL_END; + + COUNT_T cbProfileList = 0; + + m_nativeImageProfiling = FALSE; + + if (HasNativeImage()) + { + PEImageLayout * pNativeImage = GetNativeImage(); + CORCOMPILE_VERSION_INFO * pNativeVersionInfo = pNativeImage->GetNativeVersionInfoMaybeNull(); + if ((pNativeVersionInfo != NULL) && (pNativeVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_INSTRUMENTATION)) + { + m_nativeImageProfiling = GetAssembly()->IsInstrumented(); + } + + // Link the module to the profile data list if available. + m_methodProfileList = pNativeImage->GetNativeProfileDataList(&cbProfileList); + } + else // ReadyToRun image + { + // We already setup the m_methodProfileList in the ReadyToRunInfo constructor + if (m_methodProfileList != nullptr) + { + ReadyToRunInfo * pInfo = GetReadyToRunInfo(); + PEImageLayout * pImage = pInfo->GetImage(); + + // Enable profiling if the ZapBBInstr value says to + m_nativeImageProfiling = GetAssembly()->IsInstrumented(); + } + } + +#ifdef FEATURE_LAZY_COW_PAGES + // When running a IBC tuning image to gather profile data + // we increment the block counts contained in this area. + // + if (cbProfileList) + EnsureWritablePages(m_methodProfileList, cbProfileList); +#endif +} #ifdef FEATURE_PREJIT @@ -461,20 +510,6 @@ void Module::InitializeNativeImage(AllocMemTracker* pamTracker) ExecutionManager::AddNativeImageRange(dac_cast<TADDR>(pNativeImage->GetBase()), pNativeImage->GetVirtualSize(), this); - CORCOMPILE_VERSION_INFO * pNativeVersionInfo = pNativeImage->GetNativeVersionInfoMaybeNull(); - if ((pNativeVersionInfo != NULL) && (pNativeVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_INSTRUMENTATION)) - { - m_nativeImageProfiling = GetAssembly()->IsInstrumented(); - } - - // Link the module to the profile data list if available. - COUNT_T cbProfileList; - m_methodProfileList = pNativeImage->GetNativeProfileDataList(&cbProfileList); -#ifdef FEATURE_LAZY_COW_PAGES - if (cbProfileList) - EnsureWritablePages(m_methodProfileList, cbProfileList); -#endif - #ifndef CROSSGEN_COMPILE LoadTokenTables(); LoadHelperTable(); @@ -652,9 +687,15 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName) #ifdef FEATURE_PREJIT // Set up native image if (HasNativeImage()) + { InitializeNativeImage(pamTracker); + } #endif // FEATURE_PREJIT + if (HasNativeOrReadyToRunImage()) + { + InitializeForProfiling(); + } #ifdef FEATURE_NATIVE_IMAGE_GENERATION if (g_CorCompileVerboseLevel) @@ -4279,6 +4320,16 @@ BOOL Module::IsVisibleToDebugger() return TRUE; } +BOOL Module::HasNativeOrReadyToRunImage() +{ +#ifdef FEATURE_READYTORUN + if (IsReadyToRun()) + return TRUE; +#endif + + return HasNativeImage(); +} + PEImageLayout * Module::GetNativeOrReadyToRunImage() { LIMITED_METHOD_CONTRACT; diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h index ba95b2da62..2f3fe90a08 100644 --- a/src/vm/ceeload.h +++ b/src/vm/ceeload.h @@ -1790,6 +1790,7 @@ protected: protected: #ifndef DACCESS_COMPILE virtual void Initialize(AllocMemTracker *pamTracker, LPCWSTR szName = NULL); + void InitializeForProfiling(); #ifdef FEATURE_PREJIT void InitializeNativeImage(AllocMemTracker* pamTracker); #endif @@ -2734,6 +2735,8 @@ public: } #endif // FEATURE_PREJIT + + BOOL HasNativeOrReadyToRunImage(); PEImageLayout * GetNativeOrReadyToRunImage(); PTR_CORCOMPILE_IMPORT_SECTION GetImportSections(COUNT_T *pCount); PTR_CORCOMPILE_IMPORT_SECTION GetImportSectionFromIndex(COUNT_T index); @@ -3066,6 +3069,10 @@ public: static void ProfileDataAllocateTokenLists(ProfileEmitter * pEmitter, TokenProfileData* pTokenProfileData); HRESULT WriteMethodProfileDataLogFile(bool cleanup); static void WriteAllModuleProfileData(bool cleanup); + void SetMethodProfileList(CORCOMPILE_METHOD_PROFILE_LIST * value) + { + m_methodProfileList = value; + } void CreateProfilingData(); void DeleteProfilingData(); diff --git a/src/vm/pefile.h b/src/vm/pefile.h index d4f375565d..b7c7bd3e7c 100644 --- a/src/vm/pefile.h +++ b/src/vm/pefile.h @@ -378,6 +378,7 @@ public: PEImage *GetNativeImageWithRef(); PEImage *GetPersistentNativeImage(); #endif + BOOL HasNativeOrReadyToRunImage(); BOOL HasNativeImage(); PTR_PEImageLayout GetLoaded(); PTR_PEImageLayout GetLoadedNative(); diff --git a/src/vm/pefile.inl b/src/vm/pefile.inl index 9bd478e137..44192ae3e7 100644 --- a/src/vm/pefile.inl +++ b/src/vm/pefile.inl @@ -1338,6 +1338,23 @@ inline BOOL PEFile::HasNativeImage() #endif } +inline BOOL PEFile::HasNativeOrReadyToRunImage() +{ + CONTRACTL + { + INSTANCE_CHECK; + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + SO_TOLERANT; + CANNOT_TAKE_LOCK; + SUPPORTS_DAC; + } + CONTRACTL_END; + + return (HasNativeImage() || IsILImageReadyToRun()); +} + inline PTR_PEImageLayout PEFile::GetLoadedIL() { LIMITED_METHOD_CONTRACT; diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp index 6a47aa8f4c..623556d793 100644 --- a/src/vm/readytoruninfo.cpp +++ b/src/vm/readytoruninfo.cpp @@ -590,17 +590,29 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT m_entryPointToMethodDescMap.Init(TRUE, &lock); } - //In format version >= 2.1 there is an optional inlining table - if (IsImageVersionAtLeast(2, 1)) - { - IMAGE_DATA_DIRECTORY * pInlineTrackingInfoDir = FindSection(READYTORUN_SECTION_INLINING_INFO); - if (pInlineTrackingInfoDir != NULL) - { - const BYTE* pInlineTrackingMapData = (const BYTE*)GetImage()->GetDirectoryData(pInlineTrackingInfoDir); - PersistentInlineTrackingMapR2R::TryLoad(pModule, pInlineTrackingMapData, pInlineTrackingInfoDir->Size, - pamTracker, &m_pPersistentInlineTrackingMap); - } - } + // For format version 2.1 and later, there is an optional inlining table + if (IsImageVersionAtLeast(2, 1)) + { + IMAGE_DATA_DIRECTORY * pInlineTrackingInfoDir = FindSection(READYTORUN_SECTION_INLINING_INFO); + if (pInlineTrackingInfoDir != NULL) + { + const BYTE* pInlineTrackingMapData = (const BYTE*)GetImage()->GetDirectoryData(pInlineTrackingInfoDir); + PersistentInlineTrackingMapR2R::TryLoad(pModule, pInlineTrackingMapData, pInlineTrackingInfoDir->Size, + pamTracker, &m_pPersistentInlineTrackingMap); + } + } + // Fpr format version 2.2 and later, there is an optional profile-data section + if (IsImageVersionAtLeast(2, 2)) + { + IMAGE_DATA_DIRECTORY * pProfileDataInfoDir = FindSection(READYTORUN_SECTION_PROFILEDATA_INFO); + if (pProfileDataInfoDir != NULL) + { + CORCOMPILE_METHOD_PROFILE_LIST * pMethodProfileList; + pMethodProfileList = (CORCOMPILE_METHOD_PROFILE_LIST *)GetImage()->GetDirectoryData(pProfileDataInfoDir); + + pModule->SetMethodProfileList(pMethodProfileList); + } + } } static bool SigMatchesMethodDesc(MethodDesc* pMD, SigPointer &sig, Module * pModule) |