diff options
author | Koundinya Veluri <kouvel@users.noreply.github.com> | 2019-05-03 22:35:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-03 22:35:03 -0700 |
commit | 90b54dca8429076e90ff80ba53491961c42069c2 (patch) | |
tree | cf5e18e37a6a3952155e9c8a28603f5c4c0f5671 | |
parent | 4ad11ccba4ebb458046891bd07c0c7d4440d7df4 (diff) | |
download | coreclr-90b54dca8429076e90ff80ba53491961c42069c2.tar.gz coreclr-90b54dca8429076e90ff80ba53491961c42069c2.tar.bz2 coreclr-90b54dca8429076e90ff80ba53491961c42069c2.zip |
Fix incorrect tier reported by SOS (#24374)
Fix incorrect tier reported by SOS
- The tier of the initial code version was being assumed to be 0
- Whether call counting is enabled for a method needed to be available to the DAC
- Some small renames / cleanup to simplify code
-rw-r--r-- | src/vm/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/vm/callcounter.cpp | 58 | ||||
-rw-r--r-- | src/vm/callcounter.h | 59 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 2 | ||||
-rw-r--r-- | src/vm/prestub.cpp | 6 | ||||
-rw-r--r-- | src/vm/tieredcompilation.cpp | 6 | ||||
-rw-r--r-- | src/vm/tieredcompilation.h | 2 |
7 files changed, 67 insertions, 68 deletions
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index f5cbaac86e..8fb311ed2d 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -41,6 +41,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON assembly.cpp baseassemblyspec.cpp binder.cpp + callcounter.cpp ceeload.cpp class.cpp classhash.cpp @@ -287,7 +288,6 @@ set(VM_SOURCES_WKS assemblynative.cpp assemblyspec.cpp cachelinealloc.cpp - callcounter.cpp callhelpers.cpp callsiteinspect.cpp ceemain.cpp diff --git a/src/vm/callcounter.cpp b/src/vm/callcounter.cpp index d360f1227c..6b94f7303e 100644 --- a/src/vm/callcounter.cpp +++ b/src/vm/callcounter.cpp @@ -15,14 +15,15 @@ #include "callcounter.h" #ifdef FEATURE_TIERED_COMPILATION +#ifndef DACCESS_COMPILE -CallCounterEntry CallCounterEntry::CreateWithTier0CallCountingDisabled(const MethodDesc *m) +CallCounterEntry CallCounterEntry::CreateWithCallCountingDisabled(MethodDesc *m) { WRAPPER_NO_CONTRACT; _ASSERTE(m != nullptr); CallCounterEntry entry(m, INT_MAX); - _ASSERTE(!entry.IsTier0CallCountingEnabled()); + _ASSERTE(!entry.IsCallCountingEnabled()); return entry; } @@ -33,7 +34,9 @@ CallCounter::CallCounter() m_lock.Init(LOCK_TYPE_DEFAULT); } -bool CallCounter::IsEligibleForTier0CallCounting(MethodDesc* pMethodDesc) +#endif // !DACCESS_COMPILE + +bool CallCounter::IsEligibleForCallCounting(PTR_MethodDesc pMethodDesc) { WRAPPER_NO_CONTRACT; _ASSERTE(pMethodDesc != NULL); @@ -42,25 +45,30 @@ bool CallCounter::IsEligibleForTier0CallCounting(MethodDesc* pMethodDesc) return g_pConfig->TieredCompilation_CallCounting() && !pMethodDesc->RequestedAggressiveOptimization(); } -bool CallCounter::IsTier0CallCountingEnabled(MethodDesc* pMethodDesc) +bool CallCounter::IsCallCountingEnabled(PTR_MethodDesc pMethodDesc) { WRAPPER_NO_CONTRACT; - _ASSERTE(pMethodDesc != NULL); + _ASSERTE(pMethodDesc != PTR_NULL); _ASSERTE(pMethodDesc->IsEligibleForTieredCompilation()); - _ASSERTE(IsEligibleForTier0CallCounting(pMethodDesc)); + _ASSERTE(IsEligibleForCallCounting(pMethodDesc)); +#ifndef DACCESS_COMPILE SpinLockHolder holder(&m_lock); +#endif - const CallCounterEntry *entry = m_methodToCallCount.LookupPtr(pMethodDesc); - return entry == nullptr || entry->IsTier0CallCountingEnabled(); + PTR_CallCounterEntry entry = + (PTR_CallCounterEntry)const_cast<CallCounterEntry *>(m_methodToCallCount.LookupPtr(pMethodDesc)); + return entry == PTR_NULL || entry->IsCallCountingEnabled(); } -void CallCounter::DisableTier0CallCounting(MethodDesc* pMethodDesc) +#ifndef DACCESS_COMPILE + +void CallCounter::DisableCallCounting(MethodDesc* pMethodDesc) { WRAPPER_NO_CONTRACT; _ASSERTE(pMethodDesc != NULL); _ASSERTE(pMethodDesc->IsEligibleForTieredCompilation()); - _ASSERTE(IsEligibleForTier0CallCounting(pMethodDesc)); + _ASSERTE(IsEligibleForCallCounting(pMethodDesc)); // Disabling call counting will affect the tier of the MethodDesc's first native code version. Callers must ensure that this // change is made deterministically and prior to or while jitting the first native code version such that the tier would not @@ -74,13 +82,13 @@ void CallCounter::DisableTier0CallCounting(MethodDesc* pMethodDesc) CallCounterEntry *existingEntry = const_cast<CallCounterEntry *>(m_methodToCallCount.LookupPtr(pMethodDesc)); if (existingEntry != nullptr) { - existingEntry->DisableTier0CallCounting(); + existingEntry->DisableCallCounting(); return; } // Typically, the entry would already exist because OnMethodCalled() would have been called before this function on the same // thread. With multi-core JIT, a function may be jitted before it is called, in which case the entry would not exist. - m_methodToCallCount.Add(CallCounterEntry::CreateWithTier0CallCountingDisabled(pMethodDesc)); + m_methodToCallCount.Add(CallCounterEntry::CreateWithCallCountingDisabled(pMethodDesc)); } // This is called by the prestub each time the method is invoked in a particular @@ -102,7 +110,7 @@ void CallCounter::OnMethodCalled( _ASSERTE(wasPromotedToNextTierRef != nullptr); // At the moment, call counting is only done for tier 0 code - _ASSERTE(IsEligibleForTier0CallCounting(pMethodDesc)); + _ASSERTE(IsEligibleForCallCounting(pMethodDesc)); // PERF: This as a simple to implement, but not so performant, call counter // Currently this is only called until we reach a fixed call count and then @@ -117,8 +125,8 @@ void CallCounter::OnMethodCalled( // leaving the prestub unpatched, but may not be good overall as it increases // the size of the jitted code. - bool isFirstTier0Call = false; - int tier0CallCountLimit; + bool isFirstCall = false; + int callCountLimit; { //Be careful if you convert to something fully lock/interlocked-free that //you correctly handle what happens when some N simultaneous calls don't @@ -130,15 +138,14 @@ void CallCounter::OnMethodCalled( CallCounterEntry* pEntry = const_cast<CallCounterEntry*>(m_methodToCallCount.LookupPtr(pMethodDesc)); if (pEntry == NULL) { - isFirstTier0Call = true; - tier0CallCountLimit = (int)g_pConfig->TieredCompilation_CallCountThreshold() - 1; - _ASSERTE(tier0CallCountLimit >= 0); - m_methodToCallCount.Add(CallCounterEntry(pMethodDesc, tier0CallCountLimit)); + isFirstCall = true; + callCountLimit = (int)g_pConfig->TieredCompilation_CallCountThreshold() - 1; + _ASSERTE(callCountLimit >= 0); + m_methodToCallCount.Add(CallCounterEntry(pMethodDesc, callCountLimit)); } - else if (pEntry->IsTier0CallCountingEnabled()) + else if (pEntry->IsCallCountingEnabled()) { - pEntry->tier0CallCountLimit--; - tier0CallCountLimit = pEntry->tier0CallCountLimit; + callCountLimit = --pEntry->callCountLimit; } else { @@ -148,12 +155,13 @@ void CallCounter::OnMethodCalled( } } - pTieredCompilationManager->OnTier0MethodCalled( + pTieredCompilationManager->OnMethodCalled( pMethodDesc, - isFirstTier0Call, - tier0CallCountLimit, + isFirstCall, + callCountLimit, shouldStopCountingCallsRef, wasPromotedToNextTierRef); } +#endif // !DACCESS_COMPILE #endif // FEATURE_TIERED_COMPILATION diff --git a/src/vm/callcounter.h b/src/vm/callcounter.h index e47502134c..6bcefd3845 100644 --- a/src/vm/callcounter.h +++ b/src/vm/callcounter.h @@ -17,36 +17,40 @@ struct CallCounterEntry { CallCounterEntry() {} - CallCounterEntry(const MethodDesc* m, const int tier0CallCountLimit) - : pMethod(m), tier0CallCountLimit(tier0CallCountLimit) {} + CallCounterEntry(PTR_MethodDesc m, const int callCountLimit) + : pMethod(m), callCountLimit(callCountLimit) {} - const MethodDesc* pMethod; - int tier0CallCountLimit; + PTR_MethodDesc pMethod; + int callCountLimit; -#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) - static CallCounterEntry CreateWithTier0CallCountingDisabled(const MethodDesc *m); +#ifndef DACCESS_COMPILE + static CallCounterEntry CreateWithCallCountingDisabled(MethodDesc *m); +#endif - bool IsTier0CallCountingEnabled() const + bool IsCallCountingEnabled() const { LIMITED_METHOD_CONTRACT; - return tier0CallCountLimit != INT_MAX; + return callCountLimit != INT_MAX; } - void DisableTier0CallCounting() +#ifndef DACCESS_COMPILE + void DisableCallCounting() { LIMITED_METHOD_CONTRACT; - tier0CallCountLimit = INT_MAX; + callCountLimit = INT_MAX; } #endif }; +typedef DPTR(struct CallCounterEntry) PTR_CallCounterEntry; + class CallCounterHashTraits : public DefaultSHashTraits<CallCounterEntry> { public: typedef typename DefaultSHashTraits<CallCounterEntry>::element_t element_t; typedef typename DefaultSHashTraits<CallCounterEntry>::count_t count_t; - typedef const MethodDesc* key_t; + typedef PTR_MethodDesc key_t; static key_t GetKey(element_t e) { @@ -61,13 +65,13 @@ public: static count_t Hash(key_t k) { LIMITED_METHOD_CONTRACT; - return (count_t)(size_t)k; + return (count_t)dac_cast<TADDR>(k); } - static const element_t Null() { LIMITED_METHOD_CONTRACT; return element_t(NULL, 0); } - static const element_t Deleted() { LIMITED_METHOD_CONTRACT; return element_t((const MethodDesc*)-1, 0); } - static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pMethod == NULL; } - static bool IsDeleted(const element_t &e) { return e.pMethod == (const MethodDesc*)-1; } + static const element_t Null() { LIMITED_METHOD_CONTRACT; return element_t(PTR_NULL, 0); } + static const element_t Deleted() { LIMITED_METHOD_CONTRACT; return element_t((PTR_MethodDesc)-1, 0); } + static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pMethod == PTR_NULL; } + static bool IsDeleted(const element_t &e) { return e.pMethod == (PTR_MethodDesc)-1; } }; typedef SHash<NoRemoveSHashTraits<CallCounterHashTraits>> CallCounterHash; @@ -80,29 +84,16 @@ typedef SHash<NoRemoveSHashTraits<CallCounterHashTraits>> CallCounterHash; class CallCounter { public: -#if defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE) +#ifdef DACCESS_COMPILE CallCounter() {} #else CallCounter(); #endif -#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) - static bool IsEligibleForCallCounting(MethodDesc* pMethodDesc) - { - WRAPPER_NO_CONTRACT; - return IsEligibleForTier0CallCounting(pMethodDesc); - } - - static bool IsEligibleForTier0CallCounting(MethodDesc* pMethodDesc); - - bool IsCallCountingEnabled(MethodDesc* pMethodDesc) - { - WRAPPER_NO_CONTRACT; - return IsTier0CallCountingEnabled(pMethodDesc); - } - - bool IsTier0CallCountingEnabled(MethodDesc* pMethodDesc); - void DisableTier0CallCounting(MethodDesc* pMethodDesc); + static bool IsEligibleForCallCounting(PTR_MethodDesc pMethodDesc); + bool IsCallCountingEnabled(PTR_MethodDesc pMethodDesc); +#ifndef DACCESS_COMPILE + void DisableCallCounting(MethodDesc* pMethodDesc); #endif void OnMethodCalled(MethodDesc* pMethodDesc, TieredCompilationManager *pTieredCompilationManager, BOOL* shouldStopCountingCallsRef, BOOL* wasPromotedToNextTierRef); diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 1b260b3c58..49e343fc3d 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -6912,7 +6912,7 @@ void CEEInfo::setMethodAttribs ( if (attribs & CORINFO_FLG_SWITCHED_TO_TIER1) { _ASSERTE(ftn->IsEligibleForTieredCompilation()); - ftn->GetCallCounter()->DisableTier0CallCounting(ftn); + ftn->GetCallCounter()->DisableCallCounting(ftn); } #endif diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp index 17174ad79f..aaab4c65e5 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -376,9 +376,9 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) if (!g_pConfig->TieredCompilation_QuickJit() && IsEligibleForTieredCompilation() && pConfig->GetCodeVersion().GetOptimizationTier() == NativeCodeVersion::OptimizationTier0 && - CallCounter::IsEligibleForTier0CallCounting(this)) + CallCounter::IsEligibleForCallCounting(this)) { - GetCallCounter()->DisableTier0CallCounting(this); + GetCallCounter()->DisableCallCounting(this); pConfig->GetCodeVersion().SetOptimizationTier(NativeCodeVersion::OptimizationTier1); } #endif @@ -1006,7 +1006,7 @@ PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEn // Update the tier in the code version. The JIT may have decided to switch from tier 0 to tier 1, in which case call // counting would have been disabled for the method. - if (!methodDesc->GetCallCounter()->IsTier0CallCountingEnabled(methodDesc)) + if (!methodDesc->GetCallCounter()->IsCallCountingEnabled(methodDesc)) { pConfig->GetCodeVersion().SetOptimizationTier(NativeCodeVersion::OptimizationTier1); } diff --git a/src/vm/tieredcompilation.cpp b/src/vm/tieredcompilation.cpp index 91cfff4c00..d2df5a270d 100644 --- a/src/vm/tieredcompilation.cpp +++ b/src/vm/tieredcompilation.cpp @@ -93,7 +93,7 @@ NativeCodeVersion::OptimizationTier TieredCompilationManager::GetInitialOptimiza WRAPPER_NO_CONTRACT; _ASSERTE(pMethodDesc != NULL); -#if defined(FEATURE_TIERED_COMPILATION) && !defined(DACCESS_COMPILE) +#ifdef FEATURE_TIERED_COMPILATION if (!pMethodDesc->IsEligibleForTieredCompilation()) { // The optimization tier is not used @@ -113,7 +113,7 @@ NativeCodeVersion::OptimizationTier TieredCompilationManager::GetInitialOptimiza return NativeCodeVersion::OptimizationTier0; } - if (!pMethodDesc->GetCallCounter()->IsTier0CallCountingEnabled(pMethodDesc)) + if (!pMethodDesc->GetCallCounter()->IsCallCountingEnabled(pMethodDesc)) { // Tier 0 call counting may have been disabled based on information about precompiled code or for other reasons, the // intention is to begin at tier 1 @@ -132,7 +132,7 @@ NativeCodeVersion::OptimizationTier TieredCompilationManager::GetInitialOptimiza // // currentCallCountLimit is pre-decremented, that is to say the value is <= 0 when the // threshold for promoting to tier 1 is reached. -void TieredCompilationManager::OnTier0MethodCalled( +void TieredCompilationManager::OnMethodCalled( MethodDesc* pMethodDesc, bool isFirstCall, int currentCallCountLimit, diff --git a/src/vm/tieredcompilation.h b/src/vm/tieredcompilation.h index 0a2507672b..6cc21a9580 100644 --- a/src/vm/tieredcompilation.h +++ b/src/vm/tieredcompilation.h @@ -34,7 +34,7 @@ public: #ifdef FEATURE_TIERED_COMPILATION public: - void OnTier0MethodCalled(MethodDesc* pMethodDesc, bool isFirstCall, int currentCallCountLimit, BOOL* shouldStopCountingCallsRef, BOOL* wasPromotedToNextTierRef); + void OnMethodCalled(MethodDesc* pMethodDesc, bool isFirstCall, int currentCallCountLimit, BOOL* shouldStopCountingCallsRef, BOOL* wasPromotedToNextTierRef); void OnMethodCallCountingStoppedWithoutTierPromotion(MethodDesc* pMethodDesc); void AsyncPromoteMethodToTier1(MethodDesc* pMethodDesc); void Shutdown(); |