summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/assembly.cpp43
-rw-r--r--src/vm/assembly.hpp12
-rw-r--r--src/vm/ceeload.cpp79
-rw-r--r--src/vm/ceeload.h7
-rw-r--r--src/vm/pefile.h1
-rw-r--r--src/vm/pefile.inl17
-rw-r--r--src/vm/readytoruninfo.cpp34
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)