RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ProfAPI_DetachMaxSleepMs, W("ProfAPI_DetachMaxSleepMs"), 0, "The maximum time, in milliseconds, the CLR will wait before checking whether a profiler that is in the process of detaching is ready to be unloaded.")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ProfAPI_RejitOnAttach, W("ProfApi_RejitOnAttach"), 1, "Enables the ability for profilers to rejit methods on attach.")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ProfAPI_InliningTracking, W("ProfApi_InliningTracking"), 1, "Enables the runtime's tracking of inlining for profiler ReJIT.")
+RETAIL_CONFIG_DWORD_INFO(EXTERNAL_DebuggerLaunchDisablesCodeVersioning, W("EXTERNAL_DebuggerLaunchDisablesCodeVersioning"), 1, "Attaching a debugger at startup will disable TieredCompilation and RejitOnAttach.")
CONFIG_DWORD_INFO(INTERNAL_ProfAPI_EnableRejitDiagnostics, W("ProfAPI_EnableRejitDiagnostics"), 0, "Enable extra dumping to stdout of rejit structures")
CONFIG_DWORD_INFO(INTERNAL_ProfAPIFault, W("ProfAPIFault"), 0, "Test-only bitmask to inject various types of faults in the profapi code")
CONFIG_DWORD_INFO(INTERNAL_TestOnlyAllowedEventMask, W("TestOnlyAllowedEventMask"), 0, "Test-only bitmask to allow profiler tests to override CLR enforcement of COR_PRF_ALLOWABLE_AFTER_ATTACH and COR_PRF_MONITOR_IMMUTABLE")
}
}
+ static ConfigDWORD debuggerDisablesCodeVersioning;
+ if( (debuggerDisablesCodeVersioning.val(CLRConfig::EXTERNAL_DebuggerLaunchDisablesCodeVersioning) != 0) && CORDebuggerAttached())
+ {
+ LOG((LF_CORDB, LL_INFO10, "Debugger is active at startup, disabling code versioning to prevent a potential deadlock.\n"));
+ g_pConfig->DisableDefaultCodeVersioning();
+ }
LOG((LF_CORDB, LL_INFO10, "Left-side debugging services setup.\n"));
bDiagnosticSuspend = false;
#endif
+ fDisableDefaultCodeVersioning = false;
+
#if defined(FEATURE_TIERED_COMPILATION)
fTieredCompilation = false;
fTieredCompilation_QuickJit = false;
bool JitFramed(void) const {LIMITED_METHOD_CONTRACT; return fJitFramed; }
bool JitMinOpts(void) const {LIMITED_METHOD_CONTRACT; return fJitMinOpts; }
+ void DisableDefaultCodeVersioning() { fDisableDefaultCodeVersioning = TRUE; }
+ bool DefaultCodeVersioningDisabled() const {LIMITED_METHOD_CONTRACT; return fDisableDefaultCodeVersioning; }
+
// Tiered Compilation config
#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_QuickJitForLoops() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJitForLoops; }
- DWORD TieredCompilation_BackgroundWorkerTimeoutMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_BackgroundWorkerTimeoutMs; }
- bool TieredCompilation_CallCounting() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_CallCounting; }
- UINT16 TieredCompilation_CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_CallCountThreshold; }
- DWORD TieredCompilation_CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_CallCountingDelayMs; }
- bool TieredCompilation_UseCallCountingStubs() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_UseCallCountingStubs; }
- DWORD TieredCompilation_DeleteCallCountingStubsAfter() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_DeleteCallCountingStubsAfter; }
+ bool TieredCompilation(void) const { LIMITED_METHOD_CONTRACT; return fTieredCompilation && !fDisableDefaultCodeVersioning; }
+ bool TieredCompilation_QuickJit() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJit && !fDisableDefaultCodeVersioning; }
+ bool TieredCompilation_QuickJitForLoops() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJitForLoops && !fDisableDefaultCodeVersioning; }
+ DWORD TieredCompilation_BackgroundWorkerTimeoutMs() const { LIMITED_METHOD_CONTRACT; return fDisableDefaultCodeVersioning ? 0 : tieredCompilation_BackgroundWorkerTimeoutMs; }
+ bool TieredCompilation_CallCounting() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_CallCounting && !fDisableDefaultCodeVersioning; }
+ UINT16 TieredCompilation_CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return fDisableDefaultCodeVersioning ? 1 : tieredCompilation_CallCountThreshold; }
+ DWORD TieredCompilation_CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return fDisableDefaultCodeVersioning ? 0 : tieredCompilation_CallCountingDelayMs; }
+ bool TieredCompilation_UseCallCountingStubs() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_UseCallCountingStubs && !fDisableDefaultCodeVersioning; }
+ DWORD TieredCompilation_DeleteCallCountingStubsAfter() const { LIMITED_METHOD_CONTRACT; return fDisableDefaultCodeVersioning ? 0 : tieredCompilation_DeleteCallCountingStubsAfter; }
#endif
#if defined(FEATURE_ON_STACK_REPLACEMENT)
DWORD testThreadAbort;
#endif
+ bool fDisableDefaultCodeVersioning;
+
#if defined(FEATURE_TIERED_COMPILATION)
bool fTieredCompilation;
bool fTieredCompilation_QuickJit;
static bool profilerStartupRejit = CORProfilerEnableRejit() != FALSE;
static ConfigDWORD rejitOnAttachEnabled;
- return profilerStartupRejit || (rejitOnAttachEnabled.val(CLRConfig::EXTERNAL_ProfAPI_RejitOnAttach) != 0);
+ return profilerStartupRejit || ((rejitOnAttachEnabled.val(CLRConfig::EXTERNAL_ProfAPI_RejitOnAttach) != 0) && !g_pConfig->DefaultCodeVersioningDisabled());
}
inline BOOL ReJitManager::IsReJITInlineTrackingEnabled()
LIMITED_METHOD_CONTRACT;
static ConfigDWORD rejitInliningEnabled;
- return rejitInliningEnabled.val(CLRConfig::EXTERNAL_ProfAPI_RejitOnAttach) != 0;
+ return rejitInliningEnabled.val(CLRConfig::EXTERNAL_ProfAPI_RejitOnAttach) != 0 && !g_pConfig->DefaultCodeVersioningDisabled();
}
#ifndef DACCESS_COMPILE