diff options
Diffstat (limited to 'src/vm/eeconfig.h')
-rw-r--r-- | src/vm/eeconfig.h | 1367 |
1 files changed, 1367 insertions, 0 deletions
diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h new file mode 100644 index 0000000000..02342d7e93 --- /dev/null +++ b/src/vm/eeconfig.h @@ -0,0 +1,1367 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// EEConfig.H +// + +// +// Fetched configuration data from the registry (should we Jit, run GC checks ...) +// +// + + + +#ifndef EECONFIG_H +#define EECONFIG_H + +class MethodDesc; + +#include "shash.h" +#include "corhost.h" + +#ifdef _DEBUG +class TypeNamesList +{ + class TypeName + { + LPUTF8 typeName; + TypeName *next; // Next name + + friend class TypeNamesList; + }; + + TypeName *pNames; // List of names + +public: + TypeNamesList(); + ~TypeNamesList(); + + HRESULT Init(__in_z LPCWSTR str); + bool IsInList(LPCUTF8 typeName); +}; +#endif + +typedef struct _ConfigStringKeyValuePair +{ + WCHAR * key; + WCHAR * value; + + _ConfigStringKeyValuePair() + { + key = NULL; + value = NULL; + } + + WCHAR * GetKey() + { + return key; + } +} ConfigStringKeyValuePair; + +typedef WStringSHash<ConfigStringKeyValuePair> ConfigStringHashtable; + +class ConfigList; + +// +// Holds a pointer to a hashtable that is populated with data from config files. +// Also acts as a node for a circular doubly-linked list. +// +class ConfigSource +{ + friend class ConfigList; +public: + ConfigSource(); + ~ConfigSource(); + + ConfigStringHashtable* Table(); + + // + // Connect this node into the list that prev is in. + // + void Add(ConfigSource* prev); + + ConfigSource* Next() + { + LIMITED_METHOD_CONTRACT; + return m_pNext; + } + + ConfigSource* Previous() + { + LIMITED_METHOD_CONTRACT; + return m_pPrev; + } + + +private: + ConfigStringHashtable m_Table; + ConfigSource *m_pNext; + ConfigSource *m_pPrev; +}; + +// +// Wrapper around the ConfigSource circular doubly-linked list. +// +class ConfigList +{ +public: + // + // Iterator for traversing through a ConfigList. + // + class ConfigIter + { + public: + ConfigIter(ConfigList* pList) + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + FORBID_FAULT; + SO_TOLERANT; + } CONTRACTL_END; + + pEnd = &(pList->m_pElement); + pCurrent = pEnd; + } + + // + // TODO: Check if iterating through the list once skips an element. + // Returns the next node. If the next node is the head, returns null. + // Note that iteration can be resumed by calling next again. + // + ConfigStringHashtable* Next() + { + CONTRACT (ConfigStringHashtable*) { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + FORBID_FAULT; + SO_TOLERANT; + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } CONTRACT_END; + + pCurrent = pCurrent->Next();; + if(pCurrent == pEnd) + RETURN NULL; + else + RETURN pCurrent->Table(); + } + + ConfigStringHashtable* Previous() + { + CONTRACT (ConfigStringHashtable*) { + NOTHROW; + GC_NOTRIGGER; + FORBID_FAULT; + // MODE_ANY; + SO_TOLERANT; + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } CONTRACT_END; + + pCurrent = pCurrent->Previous(); + if(pCurrent == pEnd) + RETURN NULL; + else + RETURN pCurrent->Table(); + } + + private: + ConfigSource* pEnd; + ConfigSource* pCurrent; + }; + + ConfigStringHashtable* Add() + { + CONTRACT (ConfigStringHashtable*) { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } CONTRACT_END; + + ConfigSource* pEntry = new (nothrow) ConfigSource(); + + if (pEntry == NULL) + RETURN NULL; + + pEntry->Add(&m_pElement); + RETURN pEntry->Table(); + } + + ConfigStringHashtable* Append() + { + CONTRACT (ConfigStringHashtable*) { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + POSTCONDITION(CheckPointer(RETVAL, NULL_OK)); + } CONTRACT_END; + + ConfigSource* pEntry = new (nothrow) ConfigSource(); + if (pEntry == NULL) + RETURN NULL; + + pEntry->Add(m_pElement.Previous()); + RETURN pEntry->Table(); + } + + void Append(ConfigSource * pEntry) + { + LIMITED_METHOD_CONTRACT; + PRECONDITION(CheckPointer(pEntry)); + + pEntry->Add(m_pElement.Previous()); + } + + ~ConfigList() + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + FORBID_FAULT; + } CONTRACTL_END; + + ConfigSource* pNext = m_pElement.Next(); + while(pNext != &m_pElement) { + ConfigSource *last = pNext; + pNext = pNext->m_pNext; + delete last; + } + } + +friend class ConfigIter; + +private: + ConfigSource m_pElement; +}; + +enum { OPT_BLENDED, + OPT_SIZE, + OPT_SPEED, + OPT_RANDOM, + OPT_DEFAULT = OPT_BLENDED }; + +/* Control of impersonation flow: + FASTFLOW means that impersonation is flowed only if it has been achieved through managed means. This is the default and avoids a kernel call. + NOFLOW is the Everett default where we don't flow the impersonation at all + ALWAYSFLOW is the (potentially) slow mode where we will always flow the impersonation, regardless of how it was achieved (managed or p/invoke). Includes + a kernel call. + Keep in sync with values in SecurityContext.cs + */ +enum { + IMP_FASTFLOW = 0, + IMP_NOFLOW = 1, + IMP_ALWAYSFLOW = 2, + IMP_DEFAULT = IMP_FASTFLOW }; + +enum ParseCtl { + parseAll, // parse entire config file + stopAfterRuntimeSection // stop after <runtime>...</runtime> section +}; + +extern CorHostProtectionManager s_CorHostProtectionManager; + +class EEConfig +{ +public: + typedef enum { + CONFIG_SYSTEM, + CONFIG_APPLICATION, + CONFIG_SYSTEMONLY + } ConfigSearch; + + static HRESULT Setup(); + + void *operator new(size_t size); + + HRESULT Init(); + HRESULT Cleanup(); + + // Spinning heuristics + + DWORD SpinInitialDuration(void) const {LIMITED_METHOD_CONTRACT; return dwSpinInitialDuration; } + DWORD SpinBackoffFactor(void) const {LIMITED_METHOD_CONTRACT; return dwSpinBackoffFactor; } + DWORD SpinLimitProcCap(void) const {LIMITED_METHOD_CONTRACT; return dwSpinLimitProcCap; } + DWORD SpinLimitProcFactor(void) const {LIMITED_METHOD_CONTRACT; return dwSpinLimitProcFactor; } + DWORD SpinLimitConstant(void) const {LIMITED_METHOD_CONTRACT; return dwSpinLimitConstant; } + DWORD SpinRetryCount(void) const {LIMITED_METHOD_CONTRACT; return dwSpinRetryCount; } + + // Jit-config + + unsigned int GenOptimizeType(void) const {LIMITED_METHOD_CONTRACT; return iJitOptimizeType; } + bool JitFramed(void) const {LIMITED_METHOD_CONTRACT; return fJitFramed; } + bool JitAlignLoops(void) const {LIMITED_METHOD_CONTRACT; return fJitAlignLoops; } + bool AddRejitNops(void) const {LIMITED_METHOD_DAC_CONTRACT; return fAddRejitNops; } + bool JitMinOpts(void) const {LIMITED_METHOD_CONTRACT; return fJitMinOpts; } + + BOOL PInvokeRestoreEsp(BOOL fDefault) const + { + LIMITED_METHOD_CONTRACT; + + switch (fPInvokeRestoreEsp) + { + case (unsigned)-1: return fDefault; + case 0: return FALSE; + default : return TRUE; + } + } + + bool LegacyNullReferenceExceptionPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyNullReferenceExceptionPolicy; } + bool LegacyUnhandledExceptionPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyUnhandledExceptionPolicy; } + bool LegacyVirtualMethodCallVerification(void) const {LIMITED_METHOD_CONTRACT; return fLegacyVirtualMethodCallVerification; } + + bool LegacyApartmentInitPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyApartmentInitPolicy; } + bool LegacyComHierarchyVisibility(void) const {LIMITED_METHOD_CONTRACT; return fLegacyComHierarchyVisibility; } + bool LegacyComVTableLayout(void) const {LIMITED_METHOD_CONTRACT; return fLegacyComVTableLayout; } + bool NewComVTableLayout(void) const {LIMITED_METHOD_CONTRACT; return fNewComVTableLayout; } + +#ifdef FEATURE_CORRUPTING_EXCEPTIONS + // Returns a bool to indicate if the legacy CSE (pre-v4) behaviour is enabled or not + bool LegacyCorruptedStateExceptionsPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyCorruptedStateExceptionsPolicy; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS + + // SECURITY + unsigned ImpersonationMode(void) const + { + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + SO_TOLERANT; + } CONTRACTL_END; + return iImpersonationPolicy ; + } + void SetLegacyImpersonationPolicy() { LIMITED_METHOD_CONTRACT; iImpersonationPolicy = IMP_NOFLOW; } + void SetAlwaysFlowImpersonationPolicy() { LIMITED_METHOD_CONTRACT; iImpersonationPolicy = IMP_ALWAYSFLOW; } + +#ifdef _DEBUG + bool LogTransparencyErrors() const { LIMITED_METHOD_CONTRACT; return fLogTransparencyErrors; } + bool DisableTransparencyEnforcement() const { LIMITED_METHOD_CONTRACT; return fLogTransparencyErrors; } +#endif // _DEBUG + + void SetLegacyLoadMscorsnOnStartup(bool val) { LIMITED_METHOD_CONTRACT; fLegacyLoadMscorsnOnStartup = val; } + bool LegacyLoadMscorsnOnStartup(void) const { LIMITED_METHOD_CONTRACT; return fLegacyLoadMscorsnOnStartup; } + bool BypassTrustedAppStrongNames() const { LIMITED_METHOD_CONTRACT; return fBypassStrongNameVerification; } // See code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass + bool GeneratePublisherEvidence(void) const { LIMITED_METHOD_CONTRACT; return fGeneratePublisherEvidence; } + bool EnforceFIPSPolicy() const { LIMITED_METHOD_CONTRACT; return fEnforceFIPSPolicy; } + bool LegacyHMACMode() const { LIMITED_METHOD_CONTRACT; return fLegacyHMACMode; } + +#ifdef FEATURE_COMINTEROP + bool ComInsteadOfManagedRemoting() const {LIMITED_METHOD_CONTRACT; return m_fComInsteadOfManagedRemoting; } +#endif //FEATURE_COMINTEROP + bool InteropValidatePinnedObjects() const { LIMITED_METHOD_CONTRACT; return m_fInteropValidatePinnedObjects; } + bool InteropLogArguments() const { LIMITED_METHOD_CONTRACT; return m_fInteropLogArguments; } + +#ifdef _DEBUG + bool GenDebuggableCode(void) const {LIMITED_METHOD_CONTRACT; return fDebuggable; } + bool IsStressOn(void) const {LIMITED_METHOD_CONTRACT; return fStressOn; } + int GetAPIThreadStressCount(void) const {LIMITED_METHOD_CONTRACT; return apiThreadStressCount; } + bool TlbImpSkipLoading() const {LIMITED_METHOD_CONTRACT; return fTlbImpSkipLoading; } + + bool ShouldExposeExceptionsInCOMToConsole() const {LIMITED_METHOD_CONTRACT; return (iExposeExceptionsInCOM & 1) != 0; } + bool ShouldExposeExceptionsInCOMToMsgBox() const {LIMITED_METHOD_CONTRACT; return (iExposeExceptionsInCOM & 2) != 0; } + + static bool RegexOrExactMatch(LPCUTF8 regex, LPCUTF8 input); + + inline bool ShouldPrestubHalt(MethodDesc* pMethodInfo) const + { + WRAPPER_NO_CONTRACT; + return IsInMethList(pPrestubHalt, pMethodInfo); + } + + inline bool ShouldInvokeHalt(MethodDesc* pMethodInfo) const + { + WRAPPER_NO_CONTRACT; + return IsInMethList(pInvokeHalt, pMethodInfo); + } + + + inline bool ShouldPrestubGC(MethodDesc* pMethodInfo) const + { + WRAPPER_NO_CONTRACT; + return IsInMethList(pPrestubGC, pMethodInfo); + } + inline bool ShouldBreakOnClassLoad(LPCUTF8 className) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(className, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszBreakOnClassLoad, className); + } + inline bool ShouldBreakOnClassBuild(LPCUTF8 className) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(className, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszBreakOnClassBuild, className); + } + inline bool BreakOnInstantiationEnabled() const + { + LIMITED_METHOD_CONTRACT; + return pszBreakOnInstantiation != NULL; + } + inline bool ShouldBreakOnInstantiation(LPCUTF8 className) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(className, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszBreakOnInstantiation, className); + } + inline bool ShouldBreakOnMethod(LPCUTF8 methodName) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(methodName, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszBreakOnMethodName, methodName); + } + inline bool ShouldDumpOnClassLoad(LPCUTF8 className) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(className, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszDumpOnClassLoad, className); + } + inline bool ShouldBreakOnInteropStubSetup(LPCUTF8 methodName) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(methodName, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszBreakOnInteropStubSetup, methodName); + } + inline bool ShouldBreakOnComToClrNativeInfoInit(LPCUTF8 methodName) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(methodName, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszBreakOnComToClrNativeInfoInit, methodName); + } + inline bool ShouldBreakOnStructMarshalSetup(LPCUTF8 className) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(className, NULL_OK)); + } CONTRACTL_END + return RegexOrExactMatch(pszBreakOnStructMarshalSetup, className); + } + static HRESULT ParseTypeList(__in_z LPWSTR str, TypeNamesList** out); + static void DestroyTypeList(TypeNamesList* list); + + inline bool ShouldGcCoverageOnMethod(LPCUTF8 methodName) const + { + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + // MODE_ANY; + PRECONDITION(CheckPointer(methodName, NULL_OK)); + } CONTRACTL_END + return (pszGcCoverageOnMethod == 0 || methodName == 0 || RegexOrExactMatch(pszGcCoverageOnMethod, methodName)); + } + + bool IsJitVerificationDisabled(void) const {LIMITED_METHOD_CONTRACT; return fJitVerificationDisable; } + +#ifdef WIN64EXCEPTIONS + bool SuppressLockViolationsOnReentryFromOS() const {LIMITED_METHOD_CONTRACT; return fSuppressLockViolationsOnReentryFromOS; } +#endif + +#ifdef STUBLINKER_GENERATES_UNWIND_INFO + bool IsStubLinkerUnwindInfoVerificationOn() const { LIMITED_METHOD_CONTRACT; return fStubLinkerUnwindInfoVerificationOn; } +#endif + +#endif // _DEBUG + +#ifdef FEATURE_COMINTEROP + inline bool LogCCWRefCountChangeEnabled() + { + LIMITED_METHOD_CONTRACT; + return bLogCCWRefCountChange; + } + + void SetLogCCWRefCountChangeEnabled(bool newVal); + bool ShouldLogCCWRefCountChange(LPCUTF8 pszClassName, LPCUTF8 pszNamespace) const; + + inline bool EnableRCWCleanupOnSTAShutdown() + { + LIMITED_METHOD_CONTRACT; + return fEnableRCWCleanupOnSTAShutdown; + } +#endif // FEATURE_COMINTEROP + +#ifdef FEATURE_CORECLR + bool VerifyModulesOnLoad(void) const { LIMITED_METHOD_CONTRACT; return fVerifyAllOnLoad; } +#endif +#ifdef _DEBUG + bool ExpandModulesOnLoad(void) const { LIMITED_METHOD_CONTRACT; return fExpandAllOnLoad; } +#endif //_DEBUG + +#ifdef FEATURE_DOUBLE_ALIGNMENT_HINT + // Because the large object heap is 8 byte aligned, we want to put + // arrays of doubles there more agressively than normal objects. + // This is the threshold for this. It is the number of doubles, + // not the number of bytes in the array. + unsigned int GetDoubleArrayToLargeObjectHeapThreshold() const { LIMITED_METHOD_CONTRACT; return DoubleArrayToLargeObjectHeapThreshold; } +#endif + +#ifdef FEATURE_LOADER_OPTIMIZATION + inline DWORD DefaultSharePolicy() const + { + LIMITED_METHOD_CONTRACT; + return dwSharePolicy; + } +#endif + + inline bool CacheBindingFailures() const + { + LIMITED_METHOD_CONTRACT; + return fCacheBindingFailures; + } + + inline bool UseLegacyIdentityFormat() const + { + LIMITED_METHOD_CONTRACT; + return fUseLegacyIdentityFormat; + } + + inline bool DisableFusionUpdatesFromADManager() const + { + LIMITED_METHOD_CONTRACT; + return fDisableFusionUpdatesFromADManager; + } + + inline void SetDisableCommitThreadStack(bool val) + { + LIMITED_METHOD_CONTRACT; + fDisableCommitThreadStack = val; + } + + inline bool GetDisableCommitThreadStack() const + { + LIMITED_METHOD_CONTRACT; + return fDisableCommitThreadStack; + } + + inline bool ProbeForStackOverflow() const + { + LIMITED_METHOD_CONTRACT; + return fProbeForStackOverflow; + } + + inline bool AppDomainUnload() const + {LIMITED_METHOD_CONTRACT; return fAppDomainUnload; } + + inline DWORD AppDomainUnloadRetryCount() const + {LIMITED_METHOD_CONTRACT; return dwADURetryCount; } + + +#ifdef _DEBUG + inline bool AppDomainLeaks() const + {LIMITED_METHOD_DAC_CONTRACT; return fAppDomainLeaks; } +#endif + + inline bool DeveloperInstallation() const + {LIMITED_METHOD_CONTRACT; return m_fDeveloperInstallation; } + +#ifdef TEST_DATA_CONSISTENCY + // get the value of fTestDataConsistency, which controls whether we test that we can correctly detect + // held locks in DAC builds. This is determined by an environment variable. + inline bool TestDataConsistency() const { LIMITED_METHOD_DAC_CONTRACT; return fTestDataConsistency; } +#endif + +#ifdef _DEBUG + + unsigned SuspendThreadDeadlockTimeoutMs() const + {LIMITED_METHOD_CONTRACT; return m_SuspendThreadDeadlockTimeoutMs; } + + unsigned SuspendDeadlockTimeout() const + {LIMITED_METHOD_CONTRACT; return m_SuspendDeadlockTimeout; } + + // Verifier + bool IsVerifierOff() const {LIMITED_METHOD_CONTRACT; return fVerifierOff; } + + inline bool fAssertOnBadImageFormat() const + {LIMITED_METHOD_CONTRACT; return m_fAssertOnBadImageFormat; } + + inline bool fAssertOnFailFast() const + {LIMITED_METHOD_CONTRACT; return m_fAssertOnFailFast; } + + inline bool SuppressChecks() const + {LIMITED_METHOD_CONTRACT; return fSuppressChecks; } + + inline bool Do_AllowUntrustedCaller_Checks() + {LIMITED_METHOD_CONTRACT; return fDoAllowUntrustedCallerChecks; } + + inline bool EnableFullDebug() const + {LIMITED_METHOD_CONTRACT; return fEnableFullDebug; } + +#endif +#ifdef ENABLE_STARTUP_DELAY + inline int StartupDelayMS() + { LIMITED_METHOD_CONTRACT; return iStartupDelayMS; } +#endif + +#ifdef VERIFY_HEAP + // GC config + enum HeapVerifyFlags { + HEAPVERIFY_NONE = 0, + HEAPVERIFY_GC = 1, // Verify the heap at beginning and end of GC + HEAPVERIFY_BARRIERCHECK = 2, // Verify the brick table + HEAPVERIFY_SYNCBLK = 4, // Verify sync block scanning + + // the following options can be used to mitigate some of the overhead introduced + // by heap verification. some options might cause heap verifiction to be less + // effective depending on the scenario. + + HEAPVERIFY_NO_RANGE_CHECKS = 0x10, // Excludes checking if an OBJECTREF is within the bounds of the managed heap + HEAPVERIFY_NO_MEM_FILL = 0x20, // Excludes filling unused segment portions with fill pattern + HEAPVERIFY_POST_GC_ONLY = 0x40, // Performs heap verification post-GCs only (instead of before and after each GC) + HEAPVERIFY_DEEP_ON_COMPACT = 0x80 // Performs deep object verfication only on compacting GCs. + }; + + int GetHeapVerifyLevel() {LIMITED_METHOD_CONTRACT; return iGCHeapVerify; } + + bool IsHeapVerifyEnabled() const {LIMITED_METHOD_CONTRACT; return iGCHeapVerify != 0; } +#endif + +#if defined(STRESS_HEAP) || defined(_DEBUG) + void SetGCStressLevel(int val) {LIMITED_METHOD_CONTRACT; iGCStress = val; } + + enum GCStressFlags { + GCSTRESS_NONE = 0, + GCSTRESS_ALLOC = 1, // GC on all allocs and 'easy' places + GCSTRESS_TRANSITION = 2, // GC on transitions to preemtive GC + GCSTRESS_INSTR_JIT = 4, // GC on every allowable JITed instr + GCSTRESS_INSTR_NGEN = 8, // GC on every allowable NGEN instr + GCSTRESS_UNIQUE = 16, // GC only on a unique stack trace + }; + + GCStressFlags GetGCStressLevel() const { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; return GCStressFlags(iGCStress); } +#endif + +#ifdef _DEBUG // TRACE_GC + + int GetGCtraceStart() const {LIMITED_METHOD_CONTRACT; return iGCtraceStart; } + int GetGCtraceEnd () const {LIMITED_METHOD_CONTRACT; return iGCtraceEnd; } + int GetGCtraceFac () const {LIMITED_METHOD_CONTRACT; return iGCtraceFac; } + int GetGCprnLvl () const {LIMITED_METHOD_CONTRACT; return iGCprnLvl; } + +#endif + +#ifdef STRESS_HEAP + + bool IsGCStressMix () const {LIMITED_METHOD_CONTRACT; return iGCStressMix != 0;} + int GetGCStressStep() const {LIMITED_METHOD_CONTRACT; return iGCStressStep; } +#endif + + bool IsGCBreakOnOOMEnabled() const {LIMITED_METHOD_CONTRACT; return fGCBreakOnOOM; } + + size_t GetGCgen0size () const {LIMITED_METHOD_CONTRACT; return iGCgen0size; } + void SetGCgen0size (size_t iSize) {LIMITED_METHOD_CONTRACT; iGCgen0size = iSize; } + size_t GetSegmentSize () const {LIMITED_METHOD_CONTRACT; return iGCSegmentSize; } + void SetSegmentSize (size_t iSize) {LIMITED_METHOD_CONTRACT; iGCSegmentSize = iSize; } + + int GetGCconcurrent() const {LIMITED_METHOD_CONTRACT; return iGCconcurrent; } + void SetGCconcurrent(int val) {LIMITED_METHOD_CONTRACT; iGCconcurrent = val; } +#ifdef _DEBUG + int GetGCLatencyMode() const {LIMITED_METHOD_CONTRACT; return iGCLatencyMode; } +#endif //_DEBUG + int GetGCForceCompact() const {LIMITED_METHOD_CONTRACT; return iGCForceCompact; } + int GetGCRetainVM () const {LIMITED_METHOD_CONTRACT; return iGCHoardVM;} + int GetGCLOHCompactionMode() const {LIMITED_METHOD_CONTRACT; return iGCLOHCompactionMode;} + int GetGCHeapCount() const {LIMITED_METHOD_CONTRACT; return iGCHeapCount;} + int GetGCNoAffinitize () const {LIMITED_METHOD_CONTRACT; return iGCNoAffinitize;} + +#ifdef GCTRIMCOMMIT + + int GetGCTrimCommit() const {LIMITED_METHOD_CONTRACT; return iGCTrimCommit;} + +#endif + +#ifdef FEATURE_CONSERVATIVE_GC + bool GetGCConservative() const {LIMITED_METHOD_CONTRACT; return iGCConservative;} +#endif +#ifdef _WIN64 + bool GetGCAllowVeryLargeObjects() const {LIMITED_METHOD_CONTRACT; return iGCAllowVeryLargeObjects;} +#endif +#ifdef _DEBUG + bool SkipGCCoverage(LPCUTF8 assemblyName) const {WRAPPER_NO_CONTRACT; return (pSkipGCCoverageList != NULL + && pSkipGCCoverageList->IsInList(assemblyName));} +#endif + + + // thread stress: number of threads to run +#ifdef STRESS_THREAD + DWORD GetStressThreadCount () const {LIMITED_METHOD_CONTRACT; return dwStressThreadCount;} +#endif + +#ifdef _DEBUG + inline DWORD FastGCStressLevel() const + {LIMITED_METHOD_CONTRACT; return iFastGCStress;} + + inline DWORD InjectFatalError() const + { + LIMITED_METHOD_CONTRACT; + return iInjectFatalError; + } + + inline BOOL SaveThreadInfo() const + { + return fSaveThreadInfo; + } + + inline DWORD SaveThreadInfoMask() const + { + return dwSaveThreadInfoMask; + } +#endif + + +#ifdef _DEBUG + // Interop config + IUnknown* GetTraceIUnknown() const {LIMITED_METHOD_CONTRACT; return m_pTraceIUnknown; } + int GetTraceWrapper() const {LIMITED_METHOD_CONTRACT; return m_TraceWrapper; } +#endif + + // Loader + + enum RequireZapsType + { + REQUIRE_ZAPS_NONE, // Dont care if native image is used or not + REQUIRE_ZAPS_ALL, // All assemblies must have native images + 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) + 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 + + REQUIRE_ZAPS_COUNT + }; + RequireZapsType RequireZaps() const {LIMITED_METHOD_CONTRACT; return iRequireZaps; } + bool RequireZap(LPCUTF8 assemblyName) const; +#ifdef _DEBUG + bool ForbidZap(LPCUTF8 assemblyName) const; +#endif + bool ExcludeReadyToRun(LPCUTF8 assemblyName) const; + +#ifdef _TARGET_AMD64_ + bool DisableNativeImageLoad(LPCUTF8 assemblyName) const; + bool IsDisableNativeImageLoadListNonEmpty() const { LIMITED_METHOD_CONTRACT; return (pDisableNativeImageLoadList != NULL); } +#endif + + LPCWSTR ZapSet() const { LIMITED_METHOD_CONTRACT; return pZapSet; } + + bool NgenBindOptimizeNonGac() const { LIMITED_METHOD_CONTRACT; return fNgenBindOptimizeNonGac; } + + LPUTF8 GetZapBBInstr() const { LIMITED_METHOD_CONTRACT; return szZapBBInstr; } + LPWSTR GetZapBBInstrDir() const { LIMITED_METHOD_CONTRACT; return szZapBBInstrDir; } + DWORD DisableStackwalkCache() const {LIMITED_METHOD_CONTRACT; return dwDisableStackwalkCache; } + DWORD UseNewCrossDomainRemoting() const { LIMITED_METHOD_CONTRACT; return fUseNewCrossDomainRemoting; } + + bool StressLog() const { LIMITED_METHOD_CONTRACT; return fStressLog; } + bool ForceEnc() const { LIMITED_METHOD_CONTRACT; return fForceEnc; } + + // Optimizations to improve working set + + HRESULT sync(); // check the registry again and update local state + + // Helpers to read configuration + + // This function exposes the config file data to CLRConfig. A pointer to this function is passed into CLRConfig on EEConfig::init. + // We are using BOOLs instead of ConfigSearch for direction since CLRConfig isn't always linked to EEConfig. + static HRESULT GetConfigValueCallback(__in_z LPCWSTR pKey, __deref_out_opt LPCWSTR* value, BOOL systemOnly, BOOL applicationFirst); + + // + // NOTE: The following function is deprecated; use the CLRConfig class instead. + // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h. + // + static HRESULT GetConfigString_DontUse_(__in_z LPCWSTR name, __deref_out_z LPWSTR*out, BOOL fPrependCOMPLUS = TRUE, + ConfigSearch direction = CONFIG_SYSTEM); // Note that you own the returned string! + + // + // NOTE: The following function is deprecated; use the CLRConfig class instead. + // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h. + // + static DWORD GetConfigDWORD_DontUse_(__in_z LPCWSTR name, DWORD defValue, + DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL, + BOOL fPrependCOMPLUS = TRUE, + ConfigSearch direction = CONFIG_SYSTEM); + + // + // NOTE: The following function is deprecated; use the CLRConfig class instead. + // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h. + // + static ULONGLONG GetConfigULONGLONG_DontUse_(__in_z LPCWSTR name, ULONGLONG defValue, + DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL, + BOOL fPrependCOMPLUS = TRUE, + ConfigSearch direction = CONFIG_SYSTEM); + // + // NOTE: The following function is deprecated; use the CLRConfig class instead. + // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h. + // + static DWORD GetConfigDWORDFavoringConfigFile_DontUse_(__in_z LPCWSTR name, DWORD defValue, + DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL, + BOOL fPrependCOMPLUS = TRUE, + ConfigSearch direction = CONFIG_SYSTEM); + + // + // NOTE: The following function is deprecated; use the CLRConfig class instead. + // To access a configuration value through CLRConfig, add an entry in file:../inc/CLRConfigValues.h. + // + static DWORD GetConfigFlag_DontUse_(__in_z LPCWSTR name, DWORD bitToSet, bool defValue = FALSE); + +#ifdef _DEBUG + // GC alloc logging + bool ShouldLogAlloc(const char *pClass) const { LIMITED_METHOD_CONTRACT; return pPerfTypesToLog && pPerfTypesToLog->IsInList(pClass);} + int AllocSizeThreshold() const {LIMITED_METHOD_CONTRACT; return iPerfAllocsSizeThreshold; } + int AllocNumThreshold() const { LIMITED_METHOD_CONTRACT; return iPerfNumAllocsThreshold; } + +#endif // _DEBUG + + enum NgenHardBindType + { + NGEN_HARD_BIND_NONE, // Do not hardbind at all + NGEN_HARD_BIND_LIST, // Only hardbind to what is specified by CustomAttributes (and any default assemblies specified by the CLR) + NGEN_HARD_BIND_ALL, // Hardbind to any existing ngen images if possible + NGEN_HARD_BIND_COUNT, + + NGEN_HARD_BIND_DEFAULT = NGEN_HARD_BIND_LIST, + }; + + NgenHardBindType NgenHardBind() { LIMITED_METHOD_CONTRACT; return iNgenHardBind; } + +#ifdef _DEBUG + DWORD NgenForceFailureMask() { LIMITED_METHOD_CONTRACT; return dwNgenForceFailureMask; } + DWORD NgenForceFailureCount() { LIMITED_METHOD_CONTRACT; return dwNgenForceFailureCount; } + DWORD NgenForceFailureKind() { LIMITED_METHOD_CONTRACT; return dwNgenForceFailureKind; } +#endif + enum GCPollType + { + GCPOLL_TYPE_DEFAULT, // Use the default gc poll for the platform + GCPOLL_TYPE_HIJACK, // Depend on thread hijacking for gc suspension + GCPOLL_TYPE_POLL, // Emit function calls to a helper for GC Poll + GCPOLL_TYPE_INLINE, // Emit inlined tests to the helper for GC Poll + GCPOLL_TYPE_COUNT + }; + GCPollType GetGCPollType() { LIMITED_METHOD_CONTRACT; return iGCPollType; } + +#ifdef _DEBUG + BOOL ShouldGenerateStubForHost() const {LIMITED_METHOD_CONTRACT; return fGenerateStubForHost;} + void DisableGenerateStubForHost() {LIMITED_METHOD_CONTRACT; fGenerateStubForHost = FALSE;} + + DWORD GetHostTestADUnload() const {LIMITED_METHOD_CONTRACT; return testADUnload;} + + DWORD GetHostTestThreadAbort() const {LIMITED_METHOD_CONTRACT; return testThreadAbort;} + +#define INJECTFAULT_LOADERHEAP 0x1 +#define INJECTFAULT_HANDLETABLE 0x1 +#define INJECTFAULT_GCHEAP 0x2 +#define INJECTFAULT_SO 0x4 +#define INJECTFAULT_GMHEAP 0x8 +#define INJECTFAULT_DYNAMICCODEHEAP 0x10 +#define INJECTFAULT_MAPVIEWOFFILE 0x20 +#define INJECTFAULT_JITHEAP 0x40 + + DWORD ShouldInjectFault(DWORD faultType) const {LIMITED_METHOD_CONTRACT; return fShouldInjectFault & faultType;} + +#endif + +private: //---------------------------------------------------------------- + + // @TODO - Fusion needs to be able to read this value, but they are unable to + // pull in all of the appropriate headers for all of the #defines found below. + // As long as this is defined at the top of the object, the "incorrect offsets" that + // will come as a result won't matter. + bool fCacheBindingFailures; + bool fUseLegacyIdentityFormat; + bool fDisableFusionUpdatesFromADManager; + bool fInited; // have we synced to the registry at least once? + + // Jit-config + + bool fJitFramed; // Enable/Disable EBP based frames + bool fJitAlignLoops; // Enable/Disable loop alignment + bool fAddRejitNops; // Enable/Disable nop padding for rejit. default is true + bool fJitMinOpts; // Enable MinOpts for all jitted methods + + unsigned iJitOptimizeType; // 0=Blended,1=SmallCode,2=FastCode, default is 0=Blended + + unsigned fPInvokeRestoreEsp; // -1=Default, 0=Never, Else=Always + + bool fLegacyNullReferenceExceptionPolicy; // Old AV's as NullRef behavior + bool fLegacyUnhandledExceptionPolicy; // Old unhandled exception policy (many are swallowed) + bool fLegacyVirtualMethodCallVerification; // Old (pre-whidbey) policy for call (nonvirt) of virtual function + +#ifdef FEATURE_CORRUPTING_EXCEPTIONS + bool fLegacyCorruptedStateExceptionsPolicy; +#endif // FEATURE_CORRUPTING_EXCEPTIONS + + bool fLegacyApartmentInitPolicy; // Old nondeterministic COM apartment initialization switch + bool fLegacyComHierarchyVisibility; // Old behavior allowing QIs for classes with invisible parents + bool fLegacyComVTableLayout; // Old behavior passing out IClassX interface for IUnknown and IDispatch. + bool fNewComVTableLayout; // New behavior passing out Basic interface for IUnknown and IDispatch. + + // SECURITY + unsigned iImpersonationPolicy; //control flow of impersonation in the SecurityContext. 0=FASTFLOW 1= +#ifdef _DEBUG + bool fLogTransparencyErrors; // don't throw on transparency errors, instead log to the CLR log file +#endif // _DEBUG + bool fLegacyLoadMscorsnOnStartup; // load mscorsn.dll when starting up the runtime. + bool fBypassStrongNameVerification; // bypass strong name verification of trusted app assemblies + bool fGeneratePublisherEvidence; // verify Authenticode signatures of assemblies during load, generating publisher evidence for them + bool fEnforceFIPSPolicy; // enforce that only FIPS certified crypto algorithms are created if the FIPS machine settting is enabled + bool fLegacyHMACMode; // HMACSHA384 and HMACSHA512 should default to the Whidbey block size + + LPUTF8 pszBreakOnClassLoad; // Halt just before loading this class + +#ifdef TEST_DATA_CONSISTENCY + bool fTestDataConsistency; // true if we are testing locks for data consistency in the debugger-- + // If a lock is held during inspection, we assume the data under the lock + // is inconsistent. We have a special code path for testing this + // which we will follow if this is set. The value is determined by + // the environment variable TestDataConsistency +#endif + +#ifdef FEATURE_COMINTEROP + bool m_fComInsteadOfManagedRemoting; // When communicating with a cross app domain CCW, use COM instead of managed remoting. +#endif + bool m_fInteropValidatePinnedObjects; // After returning from a M->U interop call, validate GC heap around objects pinned by IL stubs. + bool m_fInteropLogArguments; // Log all pinned arguments passed to an interop call + +#ifdef _DEBUG + static HRESULT ParseMethList(__in_z LPWSTR str, MethodNamesList* * out); + static void DestroyMethList(MethodNamesList* list); + static bool IsInMethList(MethodNamesList* list, MethodDesc* pMD); + + bool fDebuggable; + bool fStressOn; + int apiThreadStressCount; + + MethodNamesList* pPrestubHalt; // list of methods on which to break when hit prestub + MethodNamesList* pPrestubGC; // list of methods on which to cause a GC when hit prestub + MethodNamesList* pInvokeHalt; // list of methods on which to break when hit prestub + + + LPUTF8 pszBreakOnClassBuild; // Halt just before loading this class + LPUTF8 pszBreakOnInstantiation; // Halt just before instantiating a non-canonical generic type + LPUTF8 pszBreakOnMethodName; // Halt when doing something with this method in the class defined in ClassBuild + LPUTF8 pszDumpOnClassLoad; // Dump the class to the log + + LPUTF8 pszBreakOnInteropStubSetup; // Halt before we set up the interop stub for a method + LPUTF8 pszBreakOnComToClrNativeInfoInit; // Halt before we init the native info for a COM to CLR call + LPUTF8 pszBreakOnStructMarshalSetup; // Halt before the field marshallers are set up for a struct + + bool fAppDomainLeaks; // Enable appdomain leak detection for object refs + + bool m_fAssertOnBadImageFormat; // If false, don't assert on invalid IL (for testing) + bool m_fAssertOnFailFast; // If false, don't assert if we detect a stack corruption + + bool fConditionalContracts; // Conditional contracts (off inside asserts) + bool fSuppressChecks; // Disable checks (including contracts) + + DWORD iExposeExceptionsInCOM; // Should we exposed exceptions that will be transformed into HRs? + + // Tlb Tools + bool fTlbImpSkipLoading; + + unsigned m_SuspendThreadDeadlockTimeoutMs; // Used in Thread::SuspendThread() + unsigned m_SuspendDeadlockTimeout; // Used in Thread::SuspendRuntime. + + bool fEnableFullDebug; +#endif // _DEBUG + +#ifdef FEATURE_COMINTEROP + bool bLogCCWRefCountChange; // Is CCW logging on + LPCUTF8 pszLogCCWRefCountChange; // OutputDebugString when AddRef/Release is called on a CCW + // for the specified type(s) + bool fEnableRCWCleanupOnSTAShutdown; // Register our IInitializeSpy even in classic processes +#endif // FEATURE_COMINTEROP + +#ifdef FEATURE_DOUBLE_ALIGNMENT_HINT + unsigned int DoubleArrayToLargeObjectHeapThreshold; // double arrays of more than this number of elems go in large object heap +#endif + +#ifdef FEATURE_LOADER_OPTIMIZATION + DWORD dwSharePolicy; // Default policy for loading assemblies into the domain neutral area +#endif + + // Only developer machines are allowed to use DEVPATH. This value is set when there is an appropriate entry + // in the machine configuration file. This should not be sent out in the redist. + bool m_fDeveloperInstallation; // We are on a developers machine + bool fAppDomainUnload; // Enable appdomain unloading + +#ifdef FEATURE_CORECLR + bool fVerifyAllOnLoad; // True if we want to verify all methods in an assembly at load time. +#endif //FEATURE_CORECLR + + DWORD dwADURetryCount; + +#ifdef _DEBUG + bool fExpandAllOnLoad; // True if we want to load all types/jit all methods in an assembly + // at load time. + bool fJitVerificationDisable; // Turn off jit verification (for testing purposes only) + + + // Verifier + bool fVerifierOff; + + bool fDoAllowUntrustedCallerChecks; // do AllowUntrustedCallerChecks + +#ifdef WIN64EXCEPTIONS + bool fSuppressLockViolationsOnReentryFromOS; +#endif + +#ifdef STUBLINKER_GENERATES_UNWIND_INFO + bool fStubLinkerUnwindInfoVerificationOn; +#endif +#endif // _DEBUG +#ifdef ENABLE_STARTUP_DELAY + int iStartupDelayMS; //Adds sleep to startup. +#endif + + // Spinning heuristics + DWORD dwSpinInitialDuration; + DWORD dwSpinBackoffFactor; + DWORD dwSpinLimitProcCap; + DWORD dwSpinLimitProcFactor; + DWORD dwSpinLimitConstant; + DWORD dwSpinRetryCount; + +#ifdef VERIFY_HEAP + int iGCHeapVerify; +#endif + +#ifdef _DEBUG // TRACE_GC + + int iGCtraceStart; + int iGCtraceEnd; + int iGCtraceFac; + int iGCprnLvl; + +#endif + +#if defined(STRESS_HEAP) || defined(_DEBUG) + int iGCStress; +#endif + +#ifdef STRESS_HEAP + int iGCStressMix; + int iGCStressStep; +#endif + +#define DEFAULT_GC_PRN_LVL 3 + size_t iGCgen0size; + size_t iGCSegmentSize; + int iGCconcurrent; +#ifdef _DEBUG + int iGCLatencyMode; +#endif //_DEBUG + int iGCForceCompact; + int iGCHoardVM; + int iGCLOHCompactionMode; + int iGCHeapCount; + int iGCNoAffinitize; + +#ifdef GCTRIMCOMMIT + + int iGCTrimCommit; + +#endif + +#ifdef FEATURE_CONSERVATIVE_GC + bool iGCConservative; +#endif // FEATURE_CONSERVATIVE_GC +#ifdef _WIN64 + bool iGCAllowVeryLargeObjects; +#endif // _WIN64 + + bool fGCBreakOnOOM; + +#ifdef STRESS_THREAD + DWORD dwStressThreadCount; +#endif + +#ifdef _DEBUG + DWORD iFastGCStress; + LPUTF8 pszGcCoverageOnMethod; + + DWORD iInjectFatalError; + + BOOL fSaveThreadInfo; + DWORD dwSaveThreadInfoMask; + + AssemblyNamesList *pSkipGCCoverageList; +#endif + + RequireZapsType iRequireZaps; + // Assemblies which need to have native images. + // This is only used if iRequireZaps!=REQUIRE_ZAPS_NONE + // This can be used to enforce that ngen images are used only selectively for some assemblies + AssemblyNamesList * pRequireZapsList; + // assemblies which need NOT have native images. + // This is only used if iRequireZaps!=REQUIRE_ZAPS_NONE + // This overrides pRequireZapsList. + AssemblyNamesList * pRequireZapsExcludeList; + + // Assemblies which cannot use Ready to Run images. + AssemblyNamesList * pReadyToRunExcludeList; + +#ifdef _DEBUG + // Exact opposite of require zaps + BOOL iForbidZaps; + AssemblyNamesList * pForbidZapsList; + AssemblyNamesList * pForbidZapsExcludeList; +#endif + +#ifdef _TARGET_AMD64_ + // Assemblies for which we will not load a native image. This is from the COMPlus_DisableNativeImageLoadList + // variable / reg key. It performs the same function as the config file key "<disableNativeImageLoad>" (except + // that is it just a list of assembly names, which the config file key can specify full assembly identities). + // This was added to support COMPlus_UseLegacyJit, to support the rollout of RyuJIT to replace JIT64, where + // the user can cause the CLR to fall back to JIT64 for JITting but not for NGEN. This allows the user to + // force JITting for a specified list of NGEN assemblies. + AssemblyNamesList * pDisableNativeImageLoadList; +#endif + + LPCWSTR pZapSet; + + bool fNgenBindOptimizeNonGac; + + bool fStressLog; + bool fForceEnc; + bool fDisableCommitThreadStack; + bool fProbeForStackOverflow; + + // Stackwalk optimization flag + DWORD dwDisableStackwalkCache; + + // New cross domain remoting + DWORD fUseNewCrossDomainRemoting; + + LPUTF8 szZapBBInstr; + LPWSTR szZapBBInstrDir; + +#ifdef _DEBUG + // interop logging + IUnknown* m_pTraceIUnknown; + int m_TraceWrapper; +#endif + + // Flag to keep track of memory + int m_fFreepZapSet; + +#ifdef _DEBUG + // GC Alloc perf flags + int iPerfNumAllocsThreshold; // Start logging after this many allocations are made + int iPerfAllocsSizeThreshold; // Log allocations of this size or above + TypeNamesList* pPerfTypesToLog; // List of types whose allocations are to be logged + +#endif // _DEBUG + + // New configuration + ConfigList m_Configuration; + + BOOL fEnableHardbinding; + NgenHardBindType iNgenHardBind; +#ifdef _DEBUG + DWORD dwNgenForceFailureMask; + DWORD dwNgenForceFailureCount; + DWORD dwNgenForceFailureKind; +#endif + + GCPollType iGCPollType; + +#ifdef _DEBUG + BOOL fGenerateStubForHost; + DWORD fShouldInjectFault; + DWORD testADUnload; + DWORD testThreadAbort; +#endif + +public: +#ifndef FEATURE_CORECLR // unimpactful install --> no config files + HRESULT ImportConfigurationFile( + ConfigStringHashtable* pTable, + LPCWSTR pszFileName, + LPCWSTR version, + ParseCtl parseCtl = parseAll); + + HRESULT AppendConfigurationFile( + LPCWSTR pszFileName, + LPCWSTR version, + ParseCtl parseCtl = parseAll); + + HRESULT SetupConfiguration(); +#endif // FEATURE_CORECLR + + HRESULT GetConfiguration_DontUse_(__in_z LPCWSTR pKey, ConfigSearch direction, __deref_out_opt LPCWSTR* value); + LPCWSTR GetProcessBindingFile(); // All flavors must support this method + SIZE_T GetSizeOfProcessBindingFile(); // All flavors must support this method + + DWORD GetConfigDWORDInternal_DontUse_ (__in_z LPCWSTR name, DWORD defValue, //for getting data in the constructor of EEConfig + DWORD level=(DWORD) REGUTIL::COR_CONFIG_ALL, + BOOL fPrependCOMPLUS = TRUE, + ConfigSearch direction = CONFIG_SYSTEM); + + enum BitForMask { + CallSite_1 = 0x0001, + CallSite_2 = 0x0002, + CallSite_3 = 0x0004, + CallSite_4 = 0x0008, + CallSite_5 = 0x0010, + CallSite_6 = 0x0020, + CallSite_7 = 0x0040, + CallSite_8 = 0x0080, + }; + +#if defined(_DEBUG) && !defined(DACCESS_COMPILE) + void DebugCheckAndForceIBCFailure(BitForMask bitForMask); +#endif + +#if defined(_DEBUG) +#if defined(_TARGET_AMD64_) +private: + + // Defaults to 0, which means we will not generate long jump dispatch stubs. + // But if this is set to a positive integer, then this + // will be 1/x ration of stubs we generate as long jump. So if x is 4, then + // every 1 in 4 dispatch stubs will be long jump stubs. + size_t m_cGenerateLongJumpDispatchStubRatio; + + // Total count of stubs generated, used with above variable to determine if + // the next stub should be a long jump. + size_t m_cDispatchStubsGenerated; + +public: + BOOL ShouldGenerateLongJumpDispatchStub() + { + return (m_cDispatchStubsGenerated++ % m_cGenerateLongJumpDispatchStubRatio) == 0; + } +#else +public: + // Just return false when we're in DEBUG but not on AMD64 + BOOL ShouldGenerateLongJumpDispatchStub() + { + return FALSE; + } +#endif // _TARGET_AMD64_ +#endif // _DEBUG + +#if defined(_DEBUG) +private: + bool bDiagnosticSuspend; + +public: + bool GetDiagnosticSuspend() + { return bDiagnosticSuspend; } +#endif + +private: + DWORD dwSleepOnExit; + +public: + DWORD GetSleepOnExit() + { return dwSleepOnExit; } + +#if FEATURE_APPX +private: + DWORD dwWindows8ProfileAPICheckFlag; + +public: + DWORD GetWindows8ProfileAPICheckFlag() { return dwWindows8ProfileAPICheckFlag; } +#endif +}; + + + +#ifdef _DEBUG_IMPL + + // We actually want our asserts for illegal IL, but testers need to test that + // we fail gracefully under those conditions. Thus we have to hide them for those runs. +#define BAD_FORMAT_NOTHROW_ASSERT(str) \ + do { \ + if (g_pConfig->fAssertOnBadImageFormat()) { \ + _ASSERTE(str); \ + } \ + else if (!(str)) { \ + if (IsDebuggerPresent()) DebugBreak(); \ + } \ + } while(0) + + // STRESS_ASSERT is meant to be temperary additions to the code base that stop the + // runtime quickly when running stress +#define STRESS_ASSERT(cond) do { if (!(cond) && g_pConfig->IsStressOn()) DebugBreak(); } while(0) + +#define FILE_FORMAT_CHECK_MSG(_condition, _message) \ + do { \ + if (g_pConfig != NULL && g_pConfig->fAssertOnBadImageFormat()) \ + ASSERT_CHECK(_condition, _message, "Bad file format"); \ + else if (!(_condition)) \ + DebugBreak(); \ + } while (0) + +#define FILE_FORMAT_CHECK(_condition) FILE_FORMAT_CHECK_MSG(_condition, "") + +#else + +#define STRESS_ASSERT(cond) +#define BAD_FORMAT_NOTHROW_ASSERT(str) + +#define FILE_FORMAT_CHECK_MSG(_condition, _message) +#define FILE_FORMAT_CHECK(_condition) + +#endif + +void InitHostProtectionManager(); + +extern BYTE g_CorHostProtectionManagerInstance[]; + +inline CorHostProtectionManager* GetHostProtectionManager() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; +// MODE_ANY; + SO_TOLERANT; + } + CONTRACTL_END; + + return (CorHostProtectionManager*)g_CorHostProtectionManagerInstance; +} + +extern BOOL g_CLRPolicyRequested; + +// NGENImagesAllowed is the safe way to determine if NGEN Images are allowed to be loaded. (Defined as +// a macro instead of an inlined function to avoid compilation errors due to dependent +// definitions not being available to this header.) +#ifdef PROFILING_SUPPORTED +#define NGENImagesAllowed() \ + (g_fAllowNativeImages && /* No one disabled use of native images */ \ + !(CORProfilerDisableAllNGenImages())) /* Profiler didn't explicitly refuse NGEN images */ +#else +#define NGENImagesAllowed() \ + (g_fAllowNativeImages) +#endif + +#endif // EECONFIG_H |