diff options
author | Koundinya Veluri <kouvel@users.noreply.github.com> | 2019-05-02 13:48:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-02 13:48:13 -0700 |
commit | 607c8db3931cc4f4afe086f2cd4dd957d35ef0ac (patch) | |
tree | 511c45c80e528ca2b2b249213fd7a15a64191652 /src | |
parent | ee8c00f18b0230fa92bed627ebd0dbe26d30b721 (diff) | |
download | coreclr-607c8db3931cc4f4afe086f2cd4dd957d35ef0ac.tar.gz coreclr-607c8db3931cc4f4afe086f2cd4dd957d35ef0ac.tar.bz2 coreclr-607c8db3931cc4f4afe086f2cd4dd957d35ef0ac.zip |
When QuickJit is enabled, disable it for methods that contain loops by default (#24252)
When QuickJit is enabled, disable it for methods that contain loops by default
Fixes https://github.com/dotnet/coreclr/issues/19751 by default when QuickJit is enabled
- Added config variable TC_QuickJitForLoops. When disabled (the default), the JIT identifies loops and explicit tail calls and switches to tier 1 JIT.
- This would prevent the possibility of spending too long in QuickJit code, but may decrease startup time a bit when QuickJit is enabled
- Removed TC_StartupTier_OptimizeCode, as now that there is TC_QuickJit, I didn't see a good use for it
- Removed references to "StartupTier" in config variables because we had previously decided not to call it that.
- When QuickJit is disabled, avoid creating native code slots for methods in non-R2R'ed modules, as tiering would be disabled for those anyway
- Marked TC_QuickJit config var as external
Diffstat (limited to 'src')
-rw-r--r-- | src/inc/clrconfigvalues.h | 13 | ||||
-rw-r--r-- | src/inc/corinfo.h | 3 | ||||
-rw-r--r-- | src/jit/compiler.cpp | 8 | ||||
-rw-r--r-- | src/jit/compiler.h | 7 | ||||
-rw-r--r-- | src/jit/flowgraph.cpp | 97 | ||||
-rw-r--r-- | src/vm/callcounter.cpp | 4 | ||||
-rw-r--r-- | src/vm/eeconfig.cpp | 42 | ||||
-rw-r--r-- | src/vm/eeconfig.h | 16 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 15 | ||||
-rw-r--r-- | src/vm/methodtablebuilder.cpp | 5 | ||||
-rw-r--r-- | src/vm/prestub.cpp | 15 | ||||
-rw-r--r-- | src/vm/tieredcompilation.cpp | 17 |
12 files changed, 193 insertions, 49 deletions
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h index 3d8c26929d..ab4b8e4a05 100644 --- a/src/inc/clrconfigvalues.h +++ b/src/inc/clrconfigvalues.h @@ -647,13 +647,12 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_GainExponent, /// #ifdef FEATURE_TIERED_COMPILATION RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TieredCompilation, W("TieredCompilation"), 1, "Enables tiered compilation") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_QuickJit, W("TC_QuickJit"), 0, "For methods that would be jitted, enable using quick JIT when appropriate.") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_StartupTier_CallCountThreshold, W("TC_StartupTier_CallCountThreshold"), 30, "Number of times a method must be called in the startup tier after which it is promoted to the next tier.") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_StartupTier_CallCountingDelayMs, W("TC_StartupTier_CallCountingDelayMs"), 100, "A perpetual delay in milliseconds that is applied call counting in the startup tier and jitting at higher tiers, while there is startup-like activity.") -RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_StartupTier_DelaySingleProcMultiplier, W("TC_StartupTier_DelaySingleProcMultiplier"), 10, "Multiplier for TC_StartupTier_CallCountingDelayMs that is applied on a single-processor machine or when the process is affinitized to a single processor.") - -RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_StartupTier_CallCounting, W("TC_StartupTier_CallCounting"), 1, "Enabled by default (only activates when TieredCompilation is also enabled). If disabled immediately backpatches prestub, and likely prevents any promotion to higher tiers") -RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_StartupTier_OptimizeCode, W("TC_StartupTier_OptimizeCode"), 0, "Use optimized codegen (normally used by the optimized tier) in the startup tier") +RETAIL_CONFIG_DWORD_INFO(EXTERNAL_TC_QuickJit, W("TC_QuickJit"), 0, "For methods that would be jitted, enable using quick JIT when appropriate.") +RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TC_QuickJitForLoops, W("TC_QuickJitForLoops"), 0, "When quick JIT is enabled, quick JIT may also be used for methods that contain loops.") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountThreshold, W("TC_CallCountThreshold"), 30, "Number of times a method must be called in tier 0 after which it is promoted to the next tier.") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCountingDelayMs, W("TC_CallCountingDelayMs"), 100, "A perpetual delay in milliseconds that is applied call counting in tier 0 and jitting at higher tiers, while there is startup-like activity.") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DelaySingleProcMultiplier, W("TC_DelaySingleProcMultiplier"), 10, "Multiplier for TC_CallCountingDelayMs that is applied on a single-processor machine or when the process is affinitized to a single processor.") +RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_CallCounting, W("TC_CallCounting"), 1, "Enabled by default (only activates when TieredCompilation is also enabled). If disabled immediately backpatches prestub, and likely prevents any promotion to higher tiers") #endif /// diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index df6adfe154..1a223a1f8b 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -832,7 +832,7 @@ enum CorInfoFlag CORINFO_FLG_INTRINSIC = 0x00400000, // This method MAY have an intrinsic ID CORINFO_FLG_CONSTRUCTOR = 0x00800000, // This method is an instance or type initializer CORINFO_FLG_AGGRESSIVE_OPT = 0x01000000, // The method may contain hot code and should be aggressively optimized if possible -// CORINFO_FLG_UNUSED = 0x02000000, + CORINFO_FLG_DISABLE_TIER0_FOR_LOOPS = 0x02000000, // Indicates that tier 0 JIT should not be used for a method that contains a loop CORINFO_FLG_NOSECURITYWRAP = 0x04000000, // The method requires no security checks CORINFO_FLG_DONT_INLINE = 0x10000000, // The method should not be inlined CORINFO_FLG_DONT_INLINE_CALLER = 0x20000000, // The method should not be inlined, nor should its callers. It cannot be tail called. @@ -864,6 +864,7 @@ enum CorInfoMethodRuntimeFlags CORINFO_FLG_BAD_INLINEE = 0x00000001, // The method is not suitable for inlining CORINFO_FLG_VERIFIABLE = 0x00000002, // The method has verifiable code CORINFO_FLG_UNVERIFIABLE = 0x00000004, // The method has unverifiable code + CORINFO_FLG_SWITCHED_TO_TIER1 = 0x00000008, // The JIT decided to switch to tier 1 for this method, when a different tier was requested }; diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index 378d83bd1f..6b6a64c25e 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -5814,6 +5814,8 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, info.compTotalHotCodeSize = 0; info.compTotalColdCodeSize = 0; + fgHasBackwardJump = false; + #ifdef DEBUG compCurBB = nullptr; lvaTable = nullptr; @@ -5946,6 +5948,12 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, goto _Next; } + if (fgHasBackwardJump && (info.compFlags & CORINFO_FLG_DISABLE_TIER0_FOR_LOOPS) != 0 && fgCanSwitchToTier1()) + { + // Method likely has a loop, switch to the OptimizedTier to avoid spending too much time running slower code + fgSwitchToTier1(); + } + compSetOptimizationLevel(); #if COUNT_BASIC_BLOCKS diff --git a/src/jit/compiler.h b/src/jit/compiler.h index fed7003faa..d10f34de0c 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -5296,6 +5296,13 @@ protected: void fgInitBBLookup(); BasicBlock* fgLookupBB(unsigned addr); + bool fgHasBackwardJump; + + bool fgCanSwitchToTier1(); + void fgSwitchToTier1(); + + bool fgMayExplicitTailCall(); + void fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget); void fgMarkBackwardJump(BasicBlock* startBlock, BasicBlock* endBlock); diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index 236302cca5..c9348d88af 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -4253,6 +4253,94 @@ private: }; //------------------------------------------------------------------------ +// fgCanSwitchToTier1: Determines if conditions are met to allow switching the opt level to tier 1 +// +// Return Value: +// True if the opt level may be switched to tier 1, false otherwise +// +// Assumptions: +// - compInitOptions() has been called +// - compSetOptimizationLevel() has not been called +// +// Notes: +// This method is to be called at some point before compSetOptimizationLevel() to determine if the opt level may be +// changed based on information gathered in early phases. + +bool Compiler::fgCanSwitchToTier1() +{ + bool result = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0) && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT) && + !opts.compDbgCode && !compIsForInlining(); + if (result) + { + // Ensure that it would be safe to change the opt level + assert(opts.compFlags == CLFLG_MINOPT); + assert(!opts.IsMinOptsSet()); + } + + return result; +} + +//------------------------------------------------------------------------ +// fgSwitchToTier1: Switch the opt level to tier 1 +// +// Assumptions: +// - fgCanSwitchToTier1() is true +// - compSetOptimizationLevel() has not been called +// +// Notes: +// This method is to be called at some point before compSetOptimizationLevel() to switch the opt level to tier 1 +// based on information gathered in early phases. + +void Compiler::fgSwitchToTier1() +{ + assert(fgCanSwitchToTier1()); + + // Switch to tier 1 and re-init options + assert(opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0)); + opts.jitFlags->Clear(JitFlags::JIT_FLAG_TIER0); + opts.jitFlags->Set(JitFlags::JIT_FLAG_TIER1); + compInitOptions(opts.jitFlags); + + // Notify the VM of the change + info.compCompHnd->setMethodAttribs(info.compMethodHnd, CORINFO_FLG_SWITCHED_TO_TIER1); +} + +//------------------------------------------------------------------------ +// fgMayExplicitTailCall: Estimates conservatively for an explicit tail call, if the importer may actually use a tail +// call. +// +// Return Value: +// - False if a tail call will not be generated +// - True if a tail call *may* be generated +// +// Assumptions: +// - compInitOptions() has been called +// - info.compIsVarArgs has been initialized +// - An explicit tail call has been seen +// - compSetOptimizationLevel() has not been called + +bool Compiler::fgMayExplicitTailCall() +{ + assert(!compIsForInlining()); + + if (info.compFlags & CORINFO_FLG_SYNCH) + { + // Caller is synchronized + return false; + } + +#if !FEATURE_FIXED_OUT_ARGS + if (info.compIsVarArgs) + { + // Caller is varargs + return false; + } +#endif // FEATURE_FIXED_OUT_ARGS + + return true; +} + +//------------------------------------------------------------------------ // fgFindJumpTargets: walk the IL stream, determining jump target offsets // // Arguments: @@ -5137,6 +5225,7 @@ void Compiler::fgMarkBackwardJump(BasicBlock* startBlock, BasicBlock* endBlock) if ((block->bbFlags & BBF_BACKWARD_JUMP) == 0) { block->bbFlags |= BBF_BACKWARD_JUMP; + fgHasBackwardJump = true; } } } @@ -5516,6 +5605,14 @@ unsigned Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, F #endif // !FEATURE_CORECLR && _TARGET_AMD64_ } + if (fgCanSwitchToTier1() && fgMayExplicitTailCall()) + { + // Method has an explicit tail call that may run like a loop or may not be generated as a tail + // call in tier 0, switch to tier 1 to avoid spending too much time running slower code and to + // avoid stack overflow from recursion + fgSwitchToTier1(); + } + #if !defined(FEATURE_CORECLR) && defined(_TARGET_AMD64_) if (isCallPopAndRet) { diff --git a/src/vm/callcounter.cpp b/src/vm/callcounter.cpp index 4130345da0..d360f1227c 100644 --- a/src/vm/callcounter.cpp +++ b/src/vm/callcounter.cpp @@ -39,7 +39,7 @@ bool CallCounter::IsEligibleForTier0CallCounting(MethodDesc* pMethodDesc) _ASSERTE(pMethodDesc != NULL); _ASSERTE(pMethodDesc->IsEligibleForTieredCompilation()); - return g_pConfig->TieredCompilation_StartupTier_CallCounting() && !pMethodDesc->RequestedAggressiveOptimization(); + return g_pConfig->TieredCompilation_CallCounting() && !pMethodDesc->RequestedAggressiveOptimization(); } bool CallCounter::IsTier0CallCountingEnabled(MethodDesc* pMethodDesc) @@ -131,7 +131,7 @@ void CallCounter::OnMethodCalled( if (pEntry == NULL) { isFirstTier0Call = true; - tier0CallCountLimit = (int)g_pConfig->TieredCompilation_StartupTier_CallCountThreshold() - 1; + tier0CallCountLimit = (int)g_pConfig->TieredCompilation_CallCountThreshold() - 1; _ASSERTE(tier0CallCountLimit >= 0); m_methodToCallCount.Add(CallCounterEntry(pMethodDesc, tier0CallCountLimit)); } diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp index 0d4021fc88..a4b8e1d196 100644 --- a/src/vm/eeconfig.cpp +++ b/src/vm/eeconfig.cpp @@ -351,10 +351,10 @@ HRESULT EEConfig::Init() #if defined(FEATURE_TIERED_COMPILATION) fTieredCompilation = false; fTieredCompilation_QuickJit = false; - fTieredCompilation_StartupTier_CallCounting = false; - fTieredCompilation_StartupTier_OptimizeCode = false; - tieredCompilation_StartupTier_CallCountThreshold = 1; - tieredCompilation_StartupTier_CallCountingDelayMs = 0; + fTieredCompilation_QuickJitForLoops = false; + fTieredCompilation_CallCounting = false; + tieredCompilation_CallCountThreshold = 1; + tieredCompilation_CallCountingDelayMs = 0; #endif #ifndef CROSSGEN_COMPILE @@ -1207,29 +1207,30 @@ HRESULT EEConfig::sync() dwSleepOnExit = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_SleepOnExit); #if defined(FEATURE_TIERED_COMPILATION) - fTieredCompilation = Configuration::GetKnobBooleanValue(W("System.Runtime.TieredCompilation"), CLRConfig::EXTERNAL_TieredCompilation) != 0; + fTieredCompilation = Configuration::GetKnobBooleanValue(W("System.Runtime.TieredCompilation"), CLRConfig::EXTERNAL_TieredCompilation); fTieredCompilation_QuickJit = Configuration::GetKnobBooleanValue( W("System.Runtime.TieredCompilation.QuickJit"), - CLRConfig::UNSUPPORTED_TC_QuickJit) != 0; + CLRConfig::EXTERNAL_TC_QuickJit); + fTieredCompilation_QuickJitForLoops = + Configuration::GetKnobBooleanValue( + W("System.Runtime.TieredCompilation.QuickJitForLoops"), + CLRConfig::UNSUPPORTED_TC_QuickJitForLoops); - fTieredCompilation_StartupTier_CallCounting = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_StartupTier_CallCounting) != 0; - fTieredCompilation_StartupTier_OptimizeCode = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_StartupTier_OptimizeCode) != 0; + fTieredCompilation_CallCounting = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_CallCounting) != 0; - tieredCompilation_StartupTier_CallCountThreshold = - CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TC_StartupTier_CallCountThreshold); - if (tieredCompilation_StartupTier_CallCountThreshold < 1) + tieredCompilation_CallCountThreshold = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_CallCountThreshold); + if (tieredCompilation_CallCountThreshold < 1) { - tieredCompilation_StartupTier_CallCountThreshold = 1; + tieredCompilation_CallCountThreshold = 1; } - else if (tieredCompilation_StartupTier_CallCountThreshold > INT_MAX) // CallCounter uses 'int' + else if (tieredCompilation_CallCountThreshold > INT_MAX) // CallCounter uses 'int' { - tieredCompilation_StartupTier_CallCountThreshold = INT_MAX; + tieredCompilation_CallCountThreshold = INT_MAX; } - tieredCompilation_StartupTier_CallCountingDelayMs = - CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TC_StartupTier_CallCountingDelayMs); + tieredCompilation_CallCountingDelayMs = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_CallCountingDelayMs); #ifndef FEATURE_PAL bool hadSingleProcessorAtStartup = CPUGroupInfo::HadSingleProcessorAtStartup(); @@ -1239,14 +1240,13 @@ HRESULT EEConfig::sync() if (hadSingleProcessorAtStartup) { - DWORD delayMultiplier = - CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TC_StartupTier_DelaySingleProcMultiplier); + DWORD delayMultiplier = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TC_DelaySingleProcMultiplier); if (delayMultiplier > 1) { - DWORD newDelay = tieredCompilation_StartupTier_CallCountingDelayMs * delayMultiplier; - if (newDelay / delayMultiplier == tieredCompilation_StartupTier_CallCountingDelayMs) + DWORD newDelay = tieredCompilation_CallCountingDelayMs * delayMultiplier; + if (newDelay / delayMultiplier == tieredCompilation_CallCountingDelayMs) { - tieredCompilation_StartupTier_CallCountingDelayMs = newDelay; + tieredCompilation_CallCountingDelayMs = newDelay; } } } diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h index aef34b3236..f96a5a214c 100644 --- a/src/vm/eeconfig.h +++ b/src/vm/eeconfig.h @@ -285,10 +285,10 @@ public: #if defined(FEATURE_TIERED_COMPILATION) bool TieredCompilation(void) const { LIMITED_METHOD_CONTRACT; return fTieredCompilation; } bool TieredCompilation_QuickJit() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJit; } - bool TieredCompilation_StartupTier_CallCounting() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_StartupTier_CallCounting; } - bool TieredCompilation_StartupTier_OptimizeCode() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_StartupTier_OptimizeCode; } - DWORD TieredCompilation_StartupTier_CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_StartupTier_CallCountThreshold; } - DWORD TieredCompilation_StartupTier_CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_StartupTier_CallCountingDelayMs; } + bool TieredCompilation_QuickJitForLoops() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJitForLoops; } + bool TieredCompilation_CallCounting() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_CallCounting; } + DWORD TieredCompilation_CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_CallCountThreshold; } + DWORD TieredCompilation_CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_CallCountingDelayMs; } #endif #ifndef CROSSGEN_COMPILE @@ -1018,10 +1018,10 @@ private: //---------------------------------------------------------------- #if defined(FEATURE_TIERED_COMPILATION) bool fTieredCompilation; bool fTieredCompilation_QuickJit; - bool fTieredCompilation_StartupTier_CallCounting; - bool fTieredCompilation_StartupTier_OptimizeCode; - DWORD tieredCompilation_StartupTier_CallCountThreshold; - DWORD tieredCompilation_StartupTier_CallCountingDelayMs; + bool fTieredCompilation_QuickJitForLoops; + bool fTieredCompilation_CallCounting; + DWORD tieredCompilation_CallCountThreshold; + DWORD tieredCompilation_CallCountingDelayMs; #endif #ifndef CROSSGEN_COMPILE diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 11d5039210..1b260b3c58 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -6849,6 +6849,13 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) result |= CORINFO_FLG_DELEGATE_INVOKE; } +#ifndef CROSSGEN_COMPILE + if (!g_pConfig->TieredCompilation_QuickJitForLoops()) + { + result |= CORINFO_FLG_DISABLE_TIER0_FOR_LOOPS; + } +#endif + return result; } @@ -6901,6 +6908,14 @@ void CEEInfo::setMethodAttribs ( } } +#ifdef FEATURE_TIERED_COMPILATION + if (attribs & CORINFO_FLG_SWITCHED_TO_TIER1) + { + _ASSERTE(ftn->IsEligibleForTieredCompilation()); + ftn->GetCallCounter()->DisableTier0CallCounting(ftn); + } +#endif + EE_TO_JIT_TRANSITION(); } diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 5b094f6555..b2e7a07859 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -6959,6 +6959,11 @@ MethodTableBuilder::NeedsNativeCodeSlot(bmtMDMethod * pMDMethod) #ifdef FEATURE_TIERED_COMPILATION // Keep in-sync with MethodDesc::DetermineAndSetIsEligibleForTieredCompilation() if (g_pConfig->TieredCompilation() && + + // Policy - If QuickJit is disabled and the module is not ReadyToRun, the method would be ineligible for tiering + // currently to avoid some unnecessary overhead + (g_pConfig->TieredCompilation_QuickJit() || GetModule()->IsReadyToRun()) && + (pMDMethod->GetMethodType() == METHOD_TYPE_NORMAL || pMDMethod->GetMethodType() == METHOD_TYPE_INSTANTIATED)) { return TRUE; diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp index 4adf32ede1..17174ad79f 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -998,6 +998,21 @@ PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEn return pOtherCode; } +#ifdef FEATURE_TIERED_COMPILATION + if (pFlags->IsSet(CORJIT_FLAGS::CORJIT_FLAG_TIER0)) + { + MethodDesc *methodDesc = pConfig->GetMethodDesc(); + _ASSERTE(methodDesc->IsEligibleForTieredCompilation()); + + // 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)) + { + pConfig->GetCodeVersion().SetOptimizationTier(NativeCodeVersion::OptimizationTier1); + } + } +#endif + #if defined(FEATURE_JIT_PITCHING) SavePitchingCandidate(this, *pSizeOfCode); #endif diff --git a/src/vm/tieredcompilation.cpp b/src/vm/tieredcompilation.cpp index 467125f065..91cfff4c00 100644 --- a/src/vm/tieredcompilation.cpp +++ b/src/vm/tieredcompilation.cpp @@ -84,8 +84,6 @@ void TieredCompilationManager::Init() MODE_PREEMPTIVE; } CONTRACTL_END; - - CrstHolder holder(&m_lock); } #endif // FEATURE_TIERED_COMPILATION && !DACCESS_COMPILE @@ -109,7 +107,7 @@ NativeCodeVersion::OptimizationTier TieredCompilationManager::GetInitialOptimiza return NativeCodeVersion::OptimizationTier1; } - if (!g_pConfig->TieredCompilation_StartupTier_CallCounting()) + if (!g_pConfig->TieredCompilation_CallCounting()) { // Call counting is disabled altogether through config, the intention is to remain at the initial tier return NativeCodeVersion::OptimizationTier0; @@ -150,7 +148,7 @@ void TieredCompilationManager::OnTier0MethodCalled( // Stop call counting when the delay is in effect IsTieringDelayActive() || // Initiate the delay on tier 0 activity (when a new eligible method is called the first time) - (isFirstCall && g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs() != 0) || + (isFirstCall && g_pConfig->TieredCompilation_CallCountingDelayMs() != 0) || // Stop call counting when ready for tier 1 promotion currentCallCountLimit <= 0; @@ -168,7 +166,7 @@ void TieredCompilationManager::OnMethodCallCountingStoppedWithoutTierPromotion(M _ASSERTE(pMethodDesc != nullptr); _ASSERTE(pMethodDesc->IsEligibleForTieredCompilation()); - if (g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs() == 0 || + if (g_pConfig->TieredCompilation_CallCountingDelayMs() == 0 || !pMethodDesc->GetCallCounter()->IsCallCountingEnabled(pMethodDesc)) { return; @@ -314,7 +312,7 @@ bool TieredCompilationManager::TryInitiateTieringDelay() { WRAPPER_NO_CONTRACT; _ASSERTE(g_pConfig->TieredCompilation()); - _ASSERTE(g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs() != 0); + _ASSERTE(g_pConfig->TieredCompilation_CallCountingDelayMs() != 0); NewHolder<SArray<MethodDesc*>> methodsPendingCountingHolder = new(nothrow) SArray<MethodDesc*>(); if (methodsPendingCountingHolder == nullptr) @@ -364,7 +362,7 @@ bool TieredCompilationManager::TryInitiateTieringDelay() &m_tieringDelayTimerHandle, TieringDelayTimerCallback, timerContextHolder, - g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs(), + g_pConfig->TieredCompilation_CallCountingDelayMs(), (DWORD)-1 /* Period, non-repeating */, 0 /* flags */)) { @@ -448,7 +446,7 @@ void TieredCompilationManager::TieringDelayTimerCallbackWorker() { if (ThreadpoolMgr::ChangeTimerQueueTimer( tieringDelayTimerHandle, - g_pConfig->TieredCompilation_StartupTier_CallCountingDelayMs(), + g_pConfig->TieredCompilation_CallCountingDelayMs(), (DWORD)-1 /* Period, non-repeating */)) { success = true; @@ -818,8 +816,7 @@ CORJIT_FLAGS TieredCompilationManager::GetJitFlags(NativeCodeVersion nativeCodeV return flags; } - if (nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTier0 && - !g_pConfig->TieredCompilation_StartupTier_OptimizeCode()) + if (nativeCodeVersion.GetOptimizationTier() == NativeCodeVersion::OptimizationTier0) { flags.Set(CORJIT_FLAGS::CORJIT_FLAG_TIER0); } |