summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorNoah Falk <noahfalk@users.noreply.github.com>2018-04-10 20:35:33 -0700
committerGitHub <noreply@github.com>2018-04-10 20:35:33 -0700
commit6854a3ea1f0946a115de208dbb2371896c3ca23a (patch)
tree00b5265d1edd7efb60fddfd7656a329318ff8322 /src/vm
parent2ffcdd00249fd37e3c0d823df79ff19579028d66 (diff)
downloadcoreclr-6854a3ea1f0946a115de208dbb2371896c3ca23a.tar.gz
coreclr-6854a3ea1f0946a115de208dbb2371896c3ca23a.tar.bz2
coreclr-6854a3ea1f0946a115de208dbb2371896c3ca23a.zip
Fix x86 steady state tiered compilation performance (#17476)
* Fix x86 steady state tiered compilation performance Also included - a few tiered compilation only test hooks + small logging fix for JitBench Tiered compilation wasn't correctly implementing the MayHavePrecode and RequiresStableEntryPoint policy functions. On x64 this was a non-issue, but due to compact entrypoints on x86 it lead to methods allocating both FuncPtrStubs and Precodes. The FuncPtrStubs would never get backpatched which caused never ending invocations of the Prestub for some methods. Although such code still runs correctly, it is much slower than it needs to be. On MusicStore x86 I am seeing a 20% improvement in steady state RPS after this fix, bringing us inline with what I've seen on x64.
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/eeconfig.cpp5
-rw-r--r--src/vm/eeconfig.h4
-rw-r--r--src/vm/method.cpp6
-rw-r--r--src/vm/method.hpp2
-rw-r--r--src/vm/prestub.cpp13
-rw-r--r--src/vm/tieredcompilation.cpp3
6 files changed, 26 insertions, 7 deletions
diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp
index 1b44367e84..7782e69565 100644
--- a/src/vm/eeconfig.cpp
+++ b/src/vm/eeconfig.cpp
@@ -375,6 +375,8 @@ HRESULT EEConfig::Init()
#if defined(FEATURE_TIERED_COMPILATION)
fTieredCompilation = false;
+ fTieredCompilation_CallCounting = false;
+ fTieredCompilation_OptimizeTier0 = false;
tieredCompilation_tier1CallCountThreshold = 1;
tieredCompilation_tier1CallCountingDelayMs = 0;
#endif
@@ -1242,6 +1244,9 @@ HRESULT EEConfig::sync()
//this older name is deprecated, but still accepted for a time. Preserving it is a very small overhead not to needlessly break things.
CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_LEGACY_TieredCompilation) != 0;
+ fTieredCompilation_CallCounting = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Test_CallCounting) != 0;
+ fTieredCompilation_OptimizeTier0 = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Test_OptimizeTier0) != 0;
+
tieredCompilation_tier1CallCountThreshold =
CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation_Tier1CallCountThreshold);
if (tieredCompilation_tier1CallCountThreshold < 1)
diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h
index 5c88f42ac7..e30c0e238f 100644
--- a/src/vm/eeconfig.h
+++ b/src/vm/eeconfig.h
@@ -285,6 +285,8 @@ public:
// Tiered Compilation config
#if defined(FEATURE_TIERED_COMPILATION)
bool TieredCompilation(void) const {LIMITED_METHOD_CONTRACT; return fTieredCompilation; }
+ bool TieredCompilation_CallCounting() const {LIMITED_METHOD_CONTRACT; return fTieredCompilation_CallCounting; }
+ bool TieredCompilation_OptimizeTier0() const {LIMITED_METHOD_CONTRACT; return fTieredCompilation_OptimizeTier0; }
DWORD TieredCompilation_Tier1CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_tier1CallCountThreshold; }
DWORD TieredCompilation_Tier1CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_tier1CallCountingDelayMs; }
#endif
@@ -1109,6 +1111,8 @@ private: //----------------------------------------------------------------
#if defined(FEATURE_TIERED_COMPILATION)
bool fTieredCompilation;
+ bool fTieredCompilation_CallCounting;
+ bool fTieredCompilation_OptimizeTier0;
DWORD tieredCompilation_tier1CallCountThreshold;
DWORD tieredCompilation_tier1CallCountingDelayMs;
#endif
diff --git a/src/vm/method.cpp b/src/vm/method.cpp
index d323ef0f40..e1bd021bc7 100644
--- a/src/vm/method.cpp
+++ b/src/vm/method.cpp
@@ -2414,7 +2414,11 @@ BOOL MethodDesc::RequiresMethodDescCallingConvention(BOOL fEstimateForChunk /*=F
BOOL MethodDesc::RequiresStableEntryPoint(BOOL fEstimateForChunk /*=FALSE*/)
{
LIMITED_METHOD_CONTRACT;
-
+
+ // Create precodes for versionable methods
+ if (IsVersionableWithPrecode())
+ return TRUE;
+
// Create precodes for edit and continue to make methods updateable
if (IsEnCMethod() || IsEnCAddedMethod())
return TRUE;
diff --git a/src/vm/method.hpp b/src/vm/method.hpp
index f4f2a70257..c1316d06c3 100644
--- a/src/vm/method.hpp
+++ b/src/vm/method.hpp
@@ -284,7 +284,7 @@ public:
}
CONTRACTL_END
- return !MayHaveNativeCode() || IsRemotingInterceptedViaPrestub();
+ return !MayHaveNativeCode() || IsRemotingInterceptedViaPrestub() || IsVersionableWithPrecode();
}
void InterlockedUpdateFlags2(BYTE bMask, BOOL fSet);
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 5f37ff9f44..507f8d3d00 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -1736,15 +1736,20 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
// When the TieredCompilationManager has received enough call notifications
// for this method only then do we back-patch it.
BOOL fCanBackpatchPrestub = TRUE;
+ BOOL fEligibleForCallCounting = FALSE;
#ifdef FEATURE_TIERED_COMPILATION
TieredCompilationManager* pTieredCompilationManager = nullptr;
BOOL fEligibleForTieredCompilation = IsEligibleForTieredCompilation();
BOOL fWasPromotedToTier1 = FALSE;
if (fEligibleForTieredCompilation)
{
- pTieredCompilationManager = GetAppDomain()->GetTieredCompilationManager();
- CallCounter * pCallCounter = GetCallCounter();
- pCallCounter->OnMethodCalled(this, pTieredCompilationManager, &fCanBackpatchPrestub, &fWasPromotedToTier1);
+ fEligibleForCallCounting = g_pConfig->TieredCompilation_CallCounting();
+ if (fEligibleForCallCounting)
+ {
+ pTieredCompilationManager = GetAppDomain()->GetTieredCompilationManager();
+ CallCounter * pCallCounter = GetCallCounter();
+ pCallCounter->OnMethodCalled(this, pTieredCompilationManager, &fCanBackpatchPrestub, &fWasPromotedToTier1);
+ }
}
#endif
@@ -1757,7 +1762,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
{
pCode = GetCodeVersionManager()->PublishVersionableCodeIfNecessary(this, fCanBackpatchPrestub);
- if (pTieredCompilationManager != nullptr && fCanBackpatchPrestub && pCode != NULL && !fWasPromotedToTier1)
+ if (pTieredCompilationManager != nullptr && fEligibleForCallCounting && fCanBackpatchPrestub && pCode != NULL && !fWasPromotedToTier1)
{
pTieredCompilationManager->OnMethodCallCountingStoppedWithoutTier1Promotion(this);
}
diff --git a/src/vm/tieredcompilation.cpp b/src/vm/tieredcompilation.cpp
index f139ddea5c..b87d01af8d 100644
--- a/src/vm/tieredcompilation.cpp
+++ b/src/vm/tieredcompilation.cpp
@@ -611,7 +611,8 @@ CORJIT_FLAGS TieredCompilationManager::GetJitFlags(NativeCodeVersion nativeCodeV
return flags;
}
- if (nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTier0)
+ if (nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTier0 &&
+ !g_pConfig->TieredCompilation_OptimizeTier0())
{
flags.Set(CORJIT_FLAGS::CORJIT_FLAG_TIER0);
}