1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
8 // Fetched configuration data from the registry (should we Jit, run GC checks ...)
28 TypeName *next; // Next name
30 friend class TypeNamesList;
33 TypeName *pNames; // List of names
39 HRESULT Init(__in_z LPCWSTR str);
40 bool IsInList(LPCUTF8 typeName);
44 typedef struct _ConfigStringKeyValuePair
49 _ConfigStringKeyValuePair()
59 } ConfigStringKeyValuePair;
61 typedef WStringSHash<ConfigStringKeyValuePair> ConfigStringHashtable;
66 // Holds a pointer to a hashtable that is populated with data from config files.
67 // Also acts as a node for a circular doubly-linked list.
71 friend class ConfigList;
76 ConfigStringHashtable* Table();
79 // Connect this node into the list that prev is in.
81 void Add(ConfigSource* prev);
85 LIMITED_METHOD_CONTRACT;
89 ConfigSource* Previous()
91 LIMITED_METHOD_CONTRACT;
97 ConfigStringHashtable m_Table;
98 ConfigSource *m_pNext;
99 ConfigSource *m_pPrev;
103 // Wrapper around the ConfigSource circular doubly-linked list.
109 // Iterator for traversing through a ConfigList.
114 ConfigIter(ConfigList* pList)
123 pEnd = &(pList->m_pElement);
128 // TODO: Check if iterating through the list once skips an element.
129 // Returns the next node. If the next node is the head, returns null.
130 // Note that iteration can be resumed by calling next again.
132 ConfigStringHashtable* Next()
134 CONTRACT (ConfigStringHashtable*) {
139 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
142 pCurrent = pCurrent->Next();;
146 RETURN pCurrent->Table();
149 ConfigStringHashtable* Previous()
151 CONTRACT (ConfigStringHashtable*) {
156 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
159 pCurrent = pCurrent->Previous();
163 RETURN pCurrent->Table();
168 ConfigSource* pCurrent;
171 ConfigStringHashtable* Add()
173 CONTRACT (ConfigStringHashtable*) {
177 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
180 ConfigSource* pEntry = new (nothrow) ConfigSource();
185 pEntry->Add(&m_pElement);
186 RETURN pEntry->Table();
189 ConfigStringHashtable* Append()
191 CONTRACT (ConfigStringHashtable*) {
195 POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
198 ConfigSource* pEntry = new (nothrow) ConfigSource();
202 pEntry->Add(m_pElement.Previous());
203 RETURN pEntry->Table();
206 void Append(ConfigSource * pEntry)
208 LIMITED_METHOD_CONTRACT;
209 PRECONDITION(CheckPointer(pEntry));
211 pEntry->Add(m_pElement.Previous());
223 ConfigSource* pNext = m_pElement.Next();
224 while(pNext != &m_pElement) {
225 ConfigSource *last = pNext;
226 pNext = pNext->m_pNext;
231 friend class ConfigIter;
234 ConfigSource m_pElement;
241 OPT_DEFAULT = OPT_BLENDED };
244 parseAll, // parse entire config file
245 stopAfterRuntimeSection // stop after <runtime>...</runtime> section
257 static HRESULT Setup();
262 // Spinning heuristics
264 DWORD SpinInitialDuration(void) const {LIMITED_METHOD_CONTRACT; return dwSpinInitialDuration; }
265 DWORD SpinBackoffFactor(void) const {LIMITED_METHOD_CONTRACT; return dwSpinBackoffFactor; }
266 DWORD SpinLimitProcCap(void) const {LIMITED_METHOD_CONTRACT; return dwSpinLimitProcCap; }
267 DWORD SpinLimitProcFactor(void) const {LIMITED_METHOD_CONTRACT; return dwSpinLimitProcFactor; }
268 DWORD SpinLimitConstant(void) const {LIMITED_METHOD_CONTRACT; return dwSpinLimitConstant; }
269 DWORD SpinRetryCount(void) const {LIMITED_METHOD_CONTRACT; return dwSpinRetryCount; }
270 DWORD MonitorSpinCount(void) const {LIMITED_METHOD_CONTRACT; return dwMonitorSpinCount; }
274 DWORD JitHostMaxSlabCache(void) const {LIMITED_METHOD_CONTRACT; return dwJitHostMaxSlabCache; }
275 bool GetTrackDynamicMethodDebugInfo(void) const {LIMITED_METHOD_CONTRACT; return fTrackDynamicMethodDebugInfo; }
276 unsigned int GenOptimizeType(void) const {LIMITED_METHOD_CONTRACT; return iJitOptimizeType; }
277 bool JitFramed(void) const {LIMITED_METHOD_CONTRACT; return fJitFramed; }
278 bool JitAlignLoops(void) const {LIMITED_METHOD_CONTRACT; return fJitAlignLoops; }
279 bool AddRejitNops(void) const {LIMITED_METHOD_DAC_CONTRACT; return fAddRejitNops; }
280 bool JitMinOpts(void) const {LIMITED_METHOD_CONTRACT; return fJitMinOpts; }
282 // Tiered Compilation config
283 #if defined(FEATURE_TIERED_COMPILATION)
284 bool TieredCompilation(void) const { LIMITED_METHOD_CONTRACT; return fTieredCompilation; }
285 bool TieredCompilation_QuickJit() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJit; }
286 bool TieredCompilation_QuickJitForLoops() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_QuickJitForLoops; }
287 bool TieredCompilation_CallCounting() const { LIMITED_METHOD_CONTRACT; return fTieredCompilation_CallCounting; }
288 DWORD TieredCompilation_CallCountThreshold() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_CallCountThreshold; }
289 DWORD TieredCompilation_CallCountingDelayMs() const { LIMITED_METHOD_CONTRACT; return tieredCompilation_CallCountingDelayMs; }
292 #ifndef CROSSGEN_COMPILE
293 bool BackpatchEntryPointSlots() const { LIMITED_METHOD_CONTRACT; return backpatchEntryPointSlots; }
296 #if defined(FEATURE_GDBJIT) && defined(_DEBUG)
297 inline bool ShouldDumpElfOnMethod(LPCUTF8 methodName) const
302 PRECONDITION(CheckPointer(methodName, NULL_OK));
304 return RegexOrExactMatch(pszGDBJitElfDump, methodName);
306 #endif // FEATURE_GDBJIT && _DEBUG
308 #if defined(FEATURE_GDBJIT_FRAME)
309 inline bool ShouldEmitDebugFrame(void) const {LIMITED_METHOD_CONTRACT; return fGDBJitEmitDebugFrame;}
310 #endif // FEATURE_GDBJIT_FRAME
311 BOOL PInvokeRestoreEsp(BOOL fDefault) const
313 LIMITED_METHOD_CONTRACT;
315 switch (fPInvokeRestoreEsp)
317 case (unsigned)-1: return fDefault;
318 case 0: return FALSE;
319 default : return TRUE;
323 bool LegacyNullReferenceExceptionPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyNullReferenceExceptionPolicy; }
324 bool LegacyUnhandledExceptionPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyUnhandledExceptionPolicy; }
326 #ifdef FEATURE_CORRUPTING_EXCEPTIONS
327 // Returns a bool to indicate if the legacy CSE (pre-v4) behaviour is enabled or not
328 bool LegacyCorruptedStateExceptionsPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyCorruptedStateExceptionsPolicy; }
329 #endif // FEATURE_CORRUPTING_EXCEPTIONS
331 bool InteropValidatePinnedObjects() const { LIMITED_METHOD_CONTRACT; return m_fInteropValidatePinnedObjects; }
332 bool InteropLogArguments() const { LIMITED_METHOD_CONTRACT; return m_fInteropLogArguments; }
335 bool GenDebuggableCode(void) const {LIMITED_METHOD_CONTRACT; return fDebuggable; }
336 bool IsStressOn(void) const {LIMITED_METHOD_CONTRACT; return fStressOn; }
337 int GetAPIThreadStressCount(void) const {LIMITED_METHOD_CONTRACT; return apiThreadStressCount; }
339 bool ShouldExposeExceptionsInCOMToConsole() const {LIMITED_METHOD_CONTRACT; return (iExposeExceptionsInCOM & 1) != 0; }
340 bool ShouldExposeExceptionsInCOMToMsgBox() const {LIMITED_METHOD_CONTRACT; return (iExposeExceptionsInCOM & 2) != 0; }
342 static bool RegexOrExactMatch(LPCUTF8 regex, LPCUTF8 input);
344 inline bool ShouldPrestubHalt(MethodDesc* pMethodInfo) const
347 return IsInMethList(pPrestubHalt, pMethodInfo);
350 inline bool ShouldInvokeHalt(MethodDesc* pMethodInfo) const
353 return IsInMethList(pInvokeHalt, pMethodInfo);
357 inline bool ShouldPrestubGC(MethodDesc* pMethodInfo) const
360 return IsInMethList(pPrestubGC, pMethodInfo);
362 inline bool ShouldBreakOnClassLoad(LPCUTF8 className) const
368 PRECONDITION(CheckPointer(className, NULL_OK));
370 return RegexOrExactMatch(pszBreakOnClassLoad, className);
372 inline bool ShouldBreakOnClassBuild(LPCUTF8 className) const
378 PRECONDITION(CheckPointer(className, NULL_OK));
380 return RegexOrExactMatch(pszBreakOnClassBuild, className);
382 inline bool BreakOnInstantiationEnabled() const
384 LIMITED_METHOD_CONTRACT;
385 return pszBreakOnInstantiation != NULL;
387 inline bool ShouldBreakOnInstantiation(LPCUTF8 className) const
393 PRECONDITION(CheckPointer(className, NULL_OK));
395 return RegexOrExactMatch(pszBreakOnInstantiation, className);
397 inline bool ShouldBreakOnMethod(LPCUTF8 methodName) const
403 PRECONDITION(CheckPointer(methodName, NULL_OK));
405 return RegexOrExactMatch(pszBreakOnMethodName, methodName);
407 inline bool ShouldDumpOnClassLoad(LPCUTF8 className) const
413 PRECONDITION(CheckPointer(className, NULL_OK));
415 return RegexOrExactMatch(pszDumpOnClassLoad, className);
417 inline bool ShouldBreakOnInteropStubSetup(LPCUTF8 methodName) const
423 PRECONDITION(CheckPointer(methodName, NULL_OK));
425 return RegexOrExactMatch(pszBreakOnInteropStubSetup, methodName);
427 inline bool ShouldBreakOnComToClrNativeInfoInit(LPCUTF8 methodName) const
433 PRECONDITION(CheckPointer(methodName, NULL_OK));
435 return RegexOrExactMatch(pszBreakOnComToClrNativeInfoInit, methodName);
437 inline bool ShouldBreakOnStructMarshalSetup(LPCUTF8 className) const
443 PRECONDITION(CheckPointer(className, NULL_OK));
445 return RegexOrExactMatch(pszBreakOnStructMarshalSetup, className);
447 static HRESULT ParseTypeList(__in_z LPWSTR str, TypeNamesList** out);
448 static void DestroyTypeList(TypeNamesList* list);
450 inline bool ShouldGcCoverageOnMethod(LPCUTF8 methodName) const
456 PRECONDITION(CheckPointer(methodName, NULL_OK));
458 return (pszGcCoverageOnMethod == 0 || methodName == 0 || RegexOrExactMatch(pszGcCoverageOnMethod, methodName));
461 bool IsJitVerificationDisabled(void) const {LIMITED_METHOD_CONTRACT; return fJitVerificationDisable; }
463 #ifdef WIN64EXCEPTIONS
464 bool SuppressLockViolationsOnReentryFromOS() const {LIMITED_METHOD_CONTRACT; return fSuppressLockViolationsOnReentryFromOS; }
467 #ifdef STUBLINKER_GENERATES_UNWIND_INFO
468 bool IsStubLinkerUnwindInfoVerificationOn() const { LIMITED_METHOD_CONTRACT; return fStubLinkerUnwindInfoVerificationOn; }
473 #ifdef FEATURE_COMINTEROP
474 inline bool LogCCWRefCountChangeEnabled()
476 LIMITED_METHOD_CONTRACT;
477 return bLogCCWRefCountChange;
480 void SetLogCCWRefCountChangeEnabled(bool newVal);
481 bool ShouldLogCCWRefCountChange(LPCUTF8 pszClassName, LPCUTF8 pszNamespace) const;
483 inline bool EnableRCWCleanupOnSTAShutdown()
485 LIMITED_METHOD_CONTRACT;
486 return fEnableRCWCleanupOnSTAShutdown;
488 #endif // FEATURE_COMINTEROP
491 bool ExpandModulesOnLoad(void) const { LIMITED_METHOD_CONTRACT; return fExpandAllOnLoad; }
494 #ifdef FEATURE_DOUBLE_ALIGNMENT_HINT
495 // Because the large object heap is 8 byte aligned, we want to put
496 // arrays of doubles there more agressively than normal objects.
497 // This is the threshold for this. It is the number of doubles,
498 // not the number of bytes in the array.
499 unsigned int GetDoubleArrayToLargeObjectHeapThreshold() const { LIMITED_METHOD_CONTRACT; return DoubleArrayToLargeObjectHeapThreshold; }
502 inline bool ProbeForStackOverflow() const
504 LIMITED_METHOD_CONTRACT;
505 return fProbeForStackOverflow;
509 inline bool AppDomainLeaks() const
511 // Workaround for CoreCLR bug #12075, until this configuration option is removed
512 // (CoreCLR Bug #12094)
513 LIMITED_METHOD_DAC_CONTRACT;
518 #ifdef TEST_DATA_CONSISTENCY
519 // get the value of fTestDataConsistency, which controls whether we test that we can correctly detect
520 // held locks in DAC builds. This is determined by an environment variable.
521 inline bool TestDataConsistency() const { LIMITED_METHOD_DAC_CONTRACT; return fTestDataConsistency; }
526 unsigned SuspendThreadDeadlockTimeoutMs() const
527 {LIMITED_METHOD_CONTRACT; return m_SuspendThreadDeadlockTimeoutMs; }
529 unsigned SuspendDeadlockTimeout() const
530 {LIMITED_METHOD_CONTRACT; return m_SuspendDeadlockTimeout; }
533 bool IsVerifierOff() const {LIMITED_METHOD_CONTRACT; return fVerifierOff; }
535 inline bool fAssertOnBadImageFormat() const
536 {LIMITED_METHOD_CONTRACT; return m_fAssertOnBadImageFormat; }
538 inline bool fAssertOnFailFast() const
539 {LIMITED_METHOD_CONTRACT; return m_fAssertOnFailFast; }
541 inline bool SuppressChecks() const
542 {LIMITED_METHOD_CONTRACT; return fSuppressChecks; }
544 inline bool EnableFullDebug() const
545 {LIMITED_METHOD_CONTRACT; return fEnableFullDebug; }
548 #ifdef ENABLE_STARTUP_DELAY
549 inline int StartupDelayMS()
550 { LIMITED_METHOD_CONTRACT; return iStartupDelayMS; }
555 enum HeapVerifyFlags {
557 HEAPVERIFY_GC = 1, // Verify the heap at beginning and end of GC
558 HEAPVERIFY_BARRIERCHECK = 2, // Verify the brick table
559 HEAPVERIFY_SYNCBLK = 4, // Verify sync block scanning
561 // the following options can be used to mitigate some of the overhead introduced
562 // by heap verification. some options might cause heap verifiction to be less
563 // effective depending on the scenario.
565 HEAPVERIFY_NO_RANGE_CHECKS = 0x10, // Excludes checking if an OBJECTREF is within the bounds of the managed heap
566 HEAPVERIFY_NO_MEM_FILL = 0x20, // Excludes filling unused segment portions with fill pattern
567 HEAPVERIFY_POST_GC_ONLY = 0x40, // Performs heap verification post-GCs only (instead of before and after each GC)
568 HEAPVERIFY_DEEP_ON_COMPACT = 0x80 // Performs deep object verfication only on compacting GCs.
571 int GetHeapVerifyLevel() {LIMITED_METHOD_CONTRACT; return iGCHeapVerify; }
573 bool IsHeapVerifyEnabled() const {LIMITED_METHOD_CONTRACT; return iGCHeapVerify != 0; }
576 #if defined(STRESS_HEAP) || defined(_DEBUG)
577 void SetGCStressLevel(int val) {LIMITED_METHOD_CONTRACT; iGCStress = val; }
581 GCSTRESS_ALLOC = 1, // GC on all allocs and 'easy' places
582 GCSTRESS_TRANSITION = 2, // GC on transitions to preemtive GC
583 GCSTRESS_INSTR_JIT = 4, // GC on every allowable JITed instr
584 GCSTRESS_INSTR_NGEN = 8, // GC on every allowable NGEN instr
585 GCSTRESS_UNIQUE = 16, // GC only on a unique stack trace
588 GCStressFlags GetGCStressLevel() const { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; return GCStressFlags(iGCStress); }
593 bool IsGCStressMix () const {LIMITED_METHOD_CONTRACT; return iGCStressMix != 0;}
594 int GetGCStressStep() const {LIMITED_METHOD_CONTRACT; return iGCStressStep; }
597 bool IsGCBreakOnOOMEnabled() const {LIMITED_METHOD_CONTRACT; return fGCBreakOnOOM; }
599 size_t GetGCgen0size () const {LIMITED_METHOD_CONTRACT; return iGCgen0size; }
600 void SetGCgen0size (size_t iSize) {LIMITED_METHOD_CONTRACT; iGCgen0size = iSize; }
601 size_t GetSegmentSize () const {LIMITED_METHOD_CONTRACT; return iGCSegmentSize; }
602 void SetSegmentSize (size_t iSize) {LIMITED_METHOD_CONTRACT; iGCSegmentSize = iSize; }
604 int GetGCconcurrent() const {LIMITED_METHOD_CONTRACT; return iGCconcurrent; }
605 void SetGCconcurrent(int val) {LIMITED_METHOD_CONTRACT; iGCconcurrent = val; }
607 int GetGCLatencyMode() const {LIMITED_METHOD_CONTRACT; return iGCLatencyMode; }
609 int GetGCForceCompact() const {LIMITED_METHOD_CONTRACT; return iGCForceCompact; }
610 int GetGCRetainVM () const {LIMITED_METHOD_CONTRACT; return iGCHoardVM;}
611 DWORD GetGCLOHThreshold() const {LIMITED_METHOD_CONTRACT; return iGCLOHThreshold;}
612 int GetGCLOHCompactionMode() const {LIMITED_METHOD_CONTRACT; return iGCLOHCompactionMode;}
613 int GetGCHeapCount() const {LIMITED_METHOD_CONTRACT; return iGCHeapCount;}
614 int GetGCNoAffinitize () const {LIMITED_METHOD_CONTRACT; return iGCNoAffinitize;}
615 size_t GetGCAffinityMask() const {LIMITED_METHOD_CONTRACT; return iGCAffinityMask;}
616 size_t GetGCHeapHardLimit() const {LIMITED_METHOD_CONTRACT; return iGCHeapHardLimit;}
617 int GetGCHeapHardLimitPercent() const {LIMITED_METHOD_CONTRACT; return iGCHeapHardLimitPercent;}
621 int GetGCTrimCommit() const {LIMITED_METHOD_CONTRACT; return iGCTrimCommit;}
625 #ifdef FEATURE_CONSERVATIVE_GC
626 bool GetGCConservative() const {LIMITED_METHOD_CONTRACT; return iGCConservative;}
629 bool GetGCAllowVeryLargeObjects() const {LIMITED_METHOD_CONTRACT; return iGCAllowVeryLargeObjects;}
632 bool SkipGCCoverage(LPCUTF8 assemblyName) const {WRAPPER_NO_CONTRACT; return (pSkipGCCoverageList != NULL
633 && pSkipGCCoverageList->IsInList(assemblyName));}
637 inline DWORD FastGCStressLevel() const
638 {LIMITED_METHOD_CONTRACT; return iFastGCStress;}
640 inline DWORD InjectFatalError() const
642 LIMITED_METHOD_CONTRACT;
643 return iInjectFatalError;
646 inline BOOL SaveThreadInfo() const
648 return fSaveThreadInfo;
651 inline DWORD SaveThreadInfoMask() const
653 return dwSaveThreadInfoMask;
660 IUnknown* GetTraceIUnknown() const {LIMITED_METHOD_CONTRACT; return m_pTraceIUnknown; }
661 int GetTraceWrapper() const {LIMITED_METHOD_CONTRACT; return m_TraceWrapper; }
668 REQUIRE_ZAPS_NONE, // Dont care if native image is used or not
669 REQUIRE_ZAPS_ALL, // All assemblies must have native images
670 REQUIRE_ZAPS_ALL_JIT_OK,// All assemblies must have native images, but its OK if the JIT-compiler also gets used (if some function was not ngenned)
671 REQUIRE_ZAPS_SUPPORTED, // All assemblies must have native images, unless the loader does not support the scenario. Its OK if the JIT-compiler also gets used
675 RequireZapsType RequireZaps() const {LIMITED_METHOD_CONTRACT; return iRequireZaps; }
676 bool RequireZap(LPCUTF8 assemblyName) const;
678 bool ForbidZap(LPCUTF8 assemblyName) const;
680 bool ExcludeReadyToRun(LPCUTF8 assemblyName) const;
682 LPCWSTR ZapSet() const { LIMITED_METHOD_CONTRACT; return pZapSet; }
684 bool NgenBindOptimizeNonGac() const { LIMITED_METHOD_CONTRACT; return fNgenBindOptimizeNonGac; }
686 LPUTF8 GetZapBBInstr() const { LIMITED_METHOD_CONTRACT; return szZapBBInstr; }
687 LPWSTR GetZapBBInstrDir() const { LIMITED_METHOD_CONTRACT; return szZapBBInstrDir; }
688 DWORD DisableStackwalkCache() const {LIMITED_METHOD_CONTRACT; return dwDisableStackwalkCache; }
690 bool StressLog() const { LIMITED_METHOD_CONTRACT; return fStressLog; }
691 bool ForceEnc() const { LIMITED_METHOD_CONTRACT; return fForceEnc; }
693 // Optimizations to improve working set
695 HRESULT sync(); // check the registry again and update local state
697 // Helpers to read configuration
699 // This function exposes the config file data to CLRConfig. A pointer to this function is passed into CLRConfig on EEConfig::init.
700 // We are using BOOLs instead of ConfigSearch for direction since CLRConfig isn't always linked to EEConfig.
701 static HRESULT GetConfigValueCallback(__in_z LPCWSTR pKey, __deref_out_opt LPCWSTR* value, BOOL systemOnly, BOOL applicationFirst);
704 // NOTE: The following function is deprecated; use the CLRConfig class instead.
705 // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
707 static HRESULT GetConfigString_DontUse_(__in_z LPCWSTR name, __deref_out_z LPWSTR*out, BOOL fPrependCOMPLUS = TRUE,
708 ConfigSearch direction = CONFIG_SYSTEM); // Note that you own the returned string!
711 // NOTE: The following function is deprecated; use the CLRConfig class instead.
712 // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
714 static DWORD GetConfigDWORD_DontUse_(__in_z LPCWSTR name, DWORD defValue,
715 DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL,
716 BOOL fPrependCOMPLUS = TRUE,
717 ConfigSearch direction = CONFIG_SYSTEM);
720 // NOTE: The following function is deprecated; use the CLRConfig class instead.
721 // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
723 static ULONGLONG GetConfigULONGLONG_DontUse_(__in_z LPCWSTR name, ULONGLONG defValue,
724 DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL,
725 BOOL fPrependCOMPLUS = TRUE,
726 ConfigSearch direction = CONFIG_SYSTEM);
728 // NOTE: The following function is deprecated; use the CLRConfig class instead.
729 // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
731 static DWORD GetConfigDWORDFavoringConfigFile_DontUse_(__in_z LPCWSTR name, DWORD defValue,
732 DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL,
733 BOOL fPrependCOMPLUS = TRUE,
734 ConfigSearch direction = CONFIG_SYSTEM);
737 // NOTE: The following function is deprecated; use the CLRConfig class instead.
738 // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h.
740 static DWORD GetConfigFlag_DontUse_(__in_z LPCWSTR name, DWORD bitToSet, bool defValue = FALSE);
744 bool ShouldLogAlloc(const char *pClass) const { LIMITED_METHOD_CONTRACT; return pPerfTypesToLog && pPerfTypesToLog->IsInList(pClass);}
745 int AllocSizeThreshold() const {LIMITED_METHOD_CONTRACT; return iPerfAllocsSizeThreshold; }
746 int AllocNumThreshold() const { LIMITED_METHOD_CONTRACT; return iPerfNumAllocsThreshold; }
751 DWORD NgenForceFailureMask() { LIMITED_METHOD_CONTRACT; return dwNgenForceFailureMask; }
752 DWORD NgenForceFailureCount() { LIMITED_METHOD_CONTRACT; return dwNgenForceFailureCount; }
753 DWORD NgenForceFailureKind() { LIMITED_METHOD_CONTRACT; return dwNgenForceFailureKind; }
757 GCPOLL_TYPE_DEFAULT, // Use the default gc poll for the platform
758 GCPOLL_TYPE_HIJACK, // Depend on thread hijacking for gc suspension
759 GCPOLL_TYPE_POLL, // Emit function calls to a helper for GC Poll
760 GCPOLL_TYPE_INLINE, // Emit inlined tests to the helper for GC Poll
763 GCPollType GetGCPollType() { LIMITED_METHOD_CONTRACT; return iGCPollType; }
767 DWORD GetHostTestThreadAbort() const {LIMITED_METHOD_CONTRACT; return testThreadAbort;}
769 #define INJECTFAULT_LOADERHEAP 0x1
770 #define INJECTFAULT_GCHEAP 0x2
771 #define INJECTFAULT_SO 0x4
772 #define INJECTFAULT_GMHEAP 0x8
773 #define INJECTFAULT_DYNAMICCODEHEAP 0x10
774 #define INJECTFAULT_MAPVIEWOFFILE 0x20
775 #define INJECTFAULT_JITHEAP 0x40
777 DWORD ShouldInjectFault(DWORD faultType) const {LIMITED_METHOD_CONTRACT; return fShouldInjectFault & faultType;}
781 private: //----------------------------------------------------------------
783 bool fInited; // have we synced to the registry at least once?
787 DWORD dwJitHostMaxSlabCache; // max size for jit host slab cache
788 bool fTrackDynamicMethodDebugInfo; // Enable/Disable tracking dynamic method debug info
789 bool fJitFramed; // Enable/Disable EBP based frames
790 bool fJitAlignLoops; // Enable/Disable loop alignment
791 bool fAddRejitNops; // Enable/Disable nop padding for rejit. default is true
792 bool fJitMinOpts; // Enable MinOpts for all jitted methods
794 unsigned iJitOptimizeType; // 0=Blended,1=SmallCode,2=FastCode, default is 0=Blended
796 unsigned fPInvokeRestoreEsp; // -1=Default, 0=Never, Else=Always
798 bool fLegacyNullReferenceExceptionPolicy; // Old AV's as NullRef behavior
799 bool fLegacyUnhandledExceptionPolicy; // Old unhandled exception policy (many are swallowed)
801 #ifdef FEATURE_CORRUPTING_EXCEPTIONS
802 bool fLegacyCorruptedStateExceptionsPolicy;
803 #endif // FEATURE_CORRUPTING_EXCEPTIONS
805 LPUTF8 pszBreakOnClassLoad; // Halt just before loading this class
807 #ifdef TEST_DATA_CONSISTENCY
808 bool fTestDataConsistency; // true if we are testing locks for data consistency in the debugger--
809 // If a lock is held during inspection, we assume the data under the lock
810 // is inconsistent. We have a special code path for testing this
811 // which we will follow if this is set. The value is determined by
812 // the environment variable TestDataConsistency
815 bool m_fInteropValidatePinnedObjects; // After returning from a M->U interop call, validate GC heap around objects pinned by IL stubs.
816 bool m_fInteropLogArguments; // Log all pinned arguments passed to an interop call
819 static HRESULT ParseMethList(__in_z LPWSTR str, MethodNamesList* * out);
820 static void DestroyMethList(MethodNamesList* list);
821 static bool IsInMethList(MethodNamesList* list, MethodDesc* pMD);
825 int apiThreadStressCount;
827 MethodNamesList* pPrestubHalt; // list of methods on which to break when hit prestub
828 MethodNamesList* pPrestubGC; // list of methods on which to cause a GC when hit prestub
829 MethodNamesList* pInvokeHalt; // list of methods on which to break when hit prestub
832 LPUTF8 pszBreakOnClassBuild; // Halt just before loading this class
833 LPUTF8 pszBreakOnInstantiation; // Halt just before instantiating a non-canonical generic type
834 LPUTF8 pszBreakOnMethodName; // Halt when doing something with this method in the class defined in ClassBuild
835 LPUTF8 pszDumpOnClassLoad; // Dump the class to the log
837 LPUTF8 pszBreakOnInteropStubSetup; // Halt before we set up the interop stub for a method
838 LPUTF8 pszBreakOnComToClrNativeInfoInit; // Halt before we init the native info for a COM to CLR call
839 LPUTF8 pszBreakOnStructMarshalSetup; // Halt before the field marshallers are set up for a struct
841 bool m_fAssertOnBadImageFormat; // If false, don't assert on invalid IL (for testing)
842 bool m_fAssertOnFailFast; // If false, don't assert if we detect a stack corruption
844 bool fConditionalContracts; // Conditional contracts (off inside asserts)
845 bool fSuppressChecks; // Disable checks (including contracts)
847 DWORD iExposeExceptionsInCOM; // Should we exposed exceptions that will be transformed into HRs?
849 unsigned m_SuspendThreadDeadlockTimeoutMs; // Used in Thread::SuspendThread()
850 unsigned m_SuspendDeadlockTimeout; // Used in Thread::SuspendRuntime.
852 bool fEnableFullDebug;
855 #ifdef FEATURE_COMINTEROP
856 bool bLogCCWRefCountChange; // Is CCW logging on
857 LPCUTF8 pszLogCCWRefCountChange; // OutputDebugString when AddRef/Release is called on a CCW
858 // for the specified type(s)
859 bool fEnableRCWCleanupOnSTAShutdown; // Register our IInitializeSpy even in classic processes
860 #endif // FEATURE_COMINTEROP
862 #ifdef FEATURE_DOUBLE_ALIGNMENT_HINT
863 unsigned int DoubleArrayToLargeObjectHeapThreshold; // double arrays of more than this number of elems go in large object heap
867 bool fExpandAllOnLoad; // True if we want to load all types/jit all methods in an assembly
869 bool fJitVerificationDisable; // Turn off jit verification (for testing purposes only)
875 #ifdef WIN64EXCEPTIONS
876 bool fSuppressLockViolationsOnReentryFromOS;
879 #ifdef STUBLINKER_GENERATES_UNWIND_INFO
880 bool fStubLinkerUnwindInfoVerificationOn;
883 #ifdef ENABLE_STARTUP_DELAY
884 int iStartupDelayMS; //Adds sleep to startup.
887 // Spinning heuristics
888 DWORD dwSpinInitialDuration;
889 DWORD dwSpinBackoffFactor;
890 DWORD dwSpinLimitProcCap;
891 DWORD dwSpinLimitProcFactor;
892 DWORD dwSpinLimitConstant;
893 DWORD dwSpinRetryCount;
894 DWORD dwMonitorSpinCount;
900 #if defined(STRESS_HEAP) || defined(_DEBUG)
909 #define DEFAULT_GC_PRN_LVL 3
911 size_t iGCSegmentSize;
918 int iGCLOHCompactionMode;
919 DWORD iGCLOHThreshold;
922 size_t iGCAffinityMask;
923 size_t iGCHeapHardLimit;
924 int iGCHeapHardLimitPercent;
932 #ifdef FEATURE_CONSERVATIVE_GC
933 bool iGCConservative;
934 #endif // FEATURE_CONSERVATIVE_GC
936 bool iGCAllowVeryLargeObjects;
943 LPUTF8 pszGcCoverageOnMethod;
945 DWORD iInjectFatalError;
947 BOOL fSaveThreadInfo;
948 DWORD dwSaveThreadInfoMask;
950 AssemblyNamesList *pSkipGCCoverageList;
953 RequireZapsType iRequireZaps;
954 // Assemblies which need to have native images.
955 // This is only used if iRequireZaps!=REQUIRE_ZAPS_NONE
956 // This can be used to enforce that ngen images are used only selectively for some assemblies
957 AssemblyNamesList * pRequireZapsList;
958 // assemblies which need NOT have native images.
959 // This is only used if iRequireZaps!=REQUIRE_ZAPS_NONE
960 // This overrides pRequireZapsList.
961 AssemblyNamesList * pRequireZapsExcludeList;
963 // Assemblies which cannot use Ready to Run images.
964 AssemblyNamesList * pReadyToRunExcludeList;
967 // Exact opposite of require zaps
969 AssemblyNamesList * pForbidZapsList;
970 AssemblyNamesList * pForbidZapsExcludeList;
975 bool fNgenBindOptimizeNonGac;
979 bool fProbeForStackOverflow;
981 // Stackwalk optimization flag
982 DWORD dwDisableStackwalkCache;
985 LPWSTR szZapBBInstrDir;
989 IUnknown* m_pTraceIUnknown;
993 // Flag to keep track of memory
997 // GC Alloc perf flags
998 int iPerfNumAllocsThreshold; // Start logging after this many allocations are made
999 int iPerfAllocsSizeThreshold; // Log allocations of this size or above
1000 TypeNamesList* pPerfTypesToLog; // List of types whose allocations are to be logged
1004 // New configuration
1005 ConfigList m_Configuration;
1008 DWORD dwNgenForceFailureMask;
1009 DWORD dwNgenForceFailureCount;
1010 DWORD dwNgenForceFailureKind;
1013 GCPollType iGCPollType;
1016 DWORD fShouldInjectFault;
1017 DWORD testThreadAbort;
1020 #if defined(FEATURE_TIERED_COMPILATION)
1021 bool fTieredCompilation;
1022 bool fTieredCompilation_QuickJit;
1023 bool fTieredCompilation_QuickJitForLoops;
1024 bool fTieredCompilation_CallCounting;
1025 DWORD tieredCompilation_CallCountThreshold;
1026 DWORD tieredCompilation_CallCountingDelayMs;
1029 #ifndef CROSSGEN_COMPILE
1030 bool backpatchEntryPointSlots;
1033 #if defined(FEATURE_GDBJIT) && defined(_DEBUG)
1034 LPCUTF8 pszGDBJitElfDump;
1035 #endif // FEATURE_GDBJIT && _DEBUG
1037 #if defined(FEATURE_GDBJIT_FRAME)
1038 bool fGDBJitEmitDebugFrame;
1042 HRESULT GetConfiguration_DontUse_(__in_z LPCWSTR pKey, ConfigSearch direction, __deref_out_opt LPCWSTR* value);
1044 DWORD GetConfigDWORDInternal_DontUse_ (__in_z LPCWSTR name, DWORD defValue, //for getting data in the constructor of EEConfig
1045 DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL,
1046 BOOL fPrependCOMPLUS = TRUE,
1047 ConfigSearch direction = CONFIG_SYSTEM);
1050 CallSite_1 = 0x0001,
1051 CallSite_2 = 0x0002,
1052 CallSite_3 = 0x0004,
1053 CallSite_4 = 0x0008,
1054 CallSite_5 = 0x0010,
1055 CallSite_6 = 0x0020,
1056 CallSite_7 = 0x0040,
1057 CallSite_8 = 0x0080,
1060 #if defined(_DEBUG) && !defined(DACCESS_COMPILE)
1061 void DebugCheckAndForceIBCFailure(BitForMask bitForMask);
1065 #if defined(_TARGET_AMD64_)
1068 // Defaults to 0, which means we will not generate long jump dispatch stubs.
1069 // But if this is set to a positive integer, then this
1070 // will be 1/x ration of stubs we generate as long jump. So if x is 4, then
1071 // every 1 in 4 dispatch stubs will be long jump stubs.
1072 size_t m_cGenerateLongJumpDispatchStubRatio;
1074 // Total count of stubs generated, used with above variable to determine if
1075 // the next stub should be a long jump.
1076 size_t m_cDispatchStubsGenerated;
1079 BOOL ShouldGenerateLongJumpDispatchStub()
1081 return (m_cDispatchStubsGenerated++ % m_cGenerateLongJumpDispatchStubRatio) == 0;
1085 // Just return false when we're in DEBUG but not on AMD64
1086 BOOL ShouldGenerateLongJumpDispatchStub()
1090 #endif // _TARGET_AMD64_
1095 bool bDiagnosticSuspend;
1098 bool GetDiagnosticSuspend()
1099 { return bDiagnosticSuspend; }
1103 DWORD dwSleepOnExit;
1106 DWORD GetSleepOnExit()
1107 { return dwSleepOnExit; }
1114 // We actually want our asserts for illegal IL, but testers need to test that
1115 // we fail gracefully under those conditions. Thus we have to hide them for those runs.
1116 #define BAD_FORMAT_NOTHROW_ASSERT(str) \
1118 if (g_pConfig->fAssertOnBadImageFormat()) { \
1121 else if (!(str)) { \
1122 if (IsDebuggerPresent()) DebugBreak(); \
1126 // STRESS_ASSERT is meant to be temperary additions to the code base that stop the
1127 // runtime quickly when running stress
1128 #define STRESS_ASSERT(cond) do { if (!(cond) && g_pConfig->IsStressOn()) DebugBreak(); } while(0)
1130 #define FILE_FORMAT_CHECK_MSG(_condition, _message) \
1132 if (g_pConfig != NULL && g_pConfig->fAssertOnBadImageFormat()) \
1133 ASSERT_CHECK(_condition, _message, "Bad file format"); \
1134 else if (!(_condition)) \
1138 #define FILE_FORMAT_CHECK(_condition) FILE_FORMAT_CHECK_MSG(_condition, "")
1142 #define STRESS_ASSERT(cond)
1143 #define BAD_FORMAT_NOTHROW_ASSERT(str)
1145 #define FILE_FORMAT_CHECK_MSG(_condition, _message)
1146 #define FILE_FORMAT_CHECK(_condition)
1150 // NGENImagesAllowed is the safe way to determine if NGEN Images are allowed to be loaded. (Defined as
1151 // a macro instead of an inlined function to avoid compilation errors due to dependent
1152 // definitions not being available to this header.)
1153 #ifdef PROFILING_SUPPORTED
1154 #define NGENImagesAllowed() \
1155 (g_fAllowNativeImages && /* No one disabled use of native images */ \
1156 !(CORProfilerDisableAllNGenImages())) /* Profiler didn't explicitly refuse NGEN images */
1158 #define NGENImagesAllowed() \
1159 (g_fAllowNativeImages)
1162 #endif // EECONFIG_H