diff options
author | Pat Gavlin <pagavlin@microsoft.com> | 2016-02-25 07:19:33 -0800 |
---|---|---|
committer | Pat Gavlin <pagavlin@microsoft.com> | 2016-02-25 07:19:33 -0800 |
commit | d2b9a6e8bae487ae092fca2d3bccd109c7ef85f9 (patch) | |
tree | 68584f2abe48ea3ada91c9c6c93cf3ba2102f0c6 | |
parent | c3b883ca33c1080ec65815684aabce462624b1b4 (diff) | |
download | coreclr-d2b9a6e8bae487ae092fca2d3bccd109c7ef85f9.tar.gz coreclr-d2b9a6e8bae487ae092fca2d3bccd109c7ef85f9.tar.bz2 coreclr-d2b9a6e8bae487ae092fca2d3bccd109c7ef85f9.zip |
Add a new set of APIs for JIT configuration.
These APIs accommodate the retrieval of config values using the JIT
interface rather than the utilcode library. All configuration options
are now initialized upon the first call to compileMethod. The values
of configuration options are available off of an ambient JitConfig
object.
This also changed `JitHost::get*ConfigValue` to use the
`EEConfig_default` policy instead of `REGUTIL_default` in order to
avoid breaking a small set of JIT config options available in release
builds that were using the former. This change is exceedingly
unlikely to adversely affect the behavior of other JIT config options
that were originally fetched using `REGUTIL_default`, since values
for these options should not be present any locations searched
by `EEConfig_default` that are not searched by
`REGUTIL_default` (namely config files).
[tfs-changeset: 1578859]
41 files changed, 785 insertions, 394 deletions
diff --git a/src/inc/utilcode.h b/src/inc/utilcode.h index a9cb0077fc..c781dcedb3 100644 --- a/src/inc/utilcode.h +++ b/src/inc/utilcode.h @@ -1181,6 +1181,8 @@ void SplitPath(__in SString const &path, __inout_opt SString *fname, __inout_opt SString *ext); +#if !defined(NO_CLRCONFIG) + //***************************************************************************** // // **** REGUTIL - Static helper functions for reading/writing to Windows registry. @@ -1515,6 +1517,8 @@ private: LPWSTR m_wszString; }; +#endif // defined(NO_CLRCONFIG) + #include "ostype.h" #define CLRGetTickCount64() GetTickCount64() @@ -4167,6 +4171,8 @@ public: } }; +#if !defined(NO_CLRCONFIG) + /**************************************************************************/ /* simple wrappers around the REGUTIL and MethodNameList routines that make the lookup lazy */ @@ -4273,6 +4279,8 @@ private: BYTE m_inited; }; +#endif // !defined(NO_CLRCONFIG) + //***************************************************************************** // Convert a pointer to a string into a GUID. //***************************************************************************** diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt index e8c7204715..305c54a1c6 100644 --- a/src/jit/CMakeLists.txt +++ b/src/jit/CMakeLists.txt @@ -31,6 +31,7 @@ set( JIT_SOURCES hashbv.cpp importer.cpp instr.cpp + jitconfig.cpp jittelemetry.cpp lclvars.cpp liveness.cpp diff --git a/src/jit/alloc.cpp b/src/jit/alloc.cpp index 4ca13cdbd4..cc27c83fd0 100644 --- a/src/jit/alloc.cpp +++ b/src/jit/alloc.cpp @@ -65,8 +65,7 @@ bool norls_allocator::nraInit(IEEMemoryManager* pMemoryManager, size_t pageSiz nraPageSize = pageSize ? pageSize : THE_ALLOCATOR_BASE_SIZE; #ifdef DEBUG - static ConfigDWORD fShouldInjectFault; - nraShouldInjectFault = fShouldInjectFault.val(CLRConfig::INTERNAL_InjectFault) != 0; + nraShouldInjectFault = JitConfig.ShouldInjectFault() != 0; #endif if (preAlloc) diff --git a/src/jit/alloc.h b/src/jit/alloc.h index 601b98455f..11bb1f8d72 100644 --- a/src/jit/alloc.h +++ b/src/jit/alloc.h @@ -208,8 +208,7 @@ inline bool norls_allocator::nraDirectAlloc() // directly to the OS. This allows taking advantage of pageheap and other gflag // knobs for ensuring that we do not have buffer overruns in the JIT. - static ConfigDWORD fJitDirectAlloc; - return (fJitDirectAlloc.val(CLRConfig::INTERNAL_JitDirectAlloc) != 0); + return JitConfig.JitDirectAlloc() != 0; } #else // RELEASE diff --git a/src/jit/block.cpp b/src/jit/block.cpp index 30211d6a9f..0103988318 100644 --- a/src/jit/block.cpp +++ b/src/jit/block.cpp @@ -37,8 +37,7 @@ flowList* ShuffleHelper(unsigned hash, flowList* res) unsigned SsaStressHashHelper() { // hash = 0: turned off, hash = 1: use method hash, hash = *: use custom hash. - static ConfigDWORD fJitSsaStress; - unsigned hash = fJitSsaStress.val(CLRConfig::INTERNAL_JitSsaStress); + unsigned hash = JitConfig.JitSsaStress(); if (hash == 0) { diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp index b8eee4dbba..06df590c75 100644 --- a/src/jit/codegencommon.cpp +++ b/src/jit/codegencommon.cpp @@ -3035,11 +3035,9 @@ void CodeGen::genGenerateCode(void * * codePtr, { // Use COMPLUS_JitNoForceFallback=1 to prevent NOWAY assert testing from happening, // especially that caused by enabling JIT stress. - static ConfigDWORD fJitNoForceFallback; - if (!fJitNoForceFallback.val(CLRConfig::INTERNAL_JitNoForceFallback)) + if (!JitConfig.JitNoForceFallback()) { - static ConfigDWORD fJitForceFallback; - if (fJitForceFallback.val(CLRConfig::INTERNAL_JitForceFallback) || + if (JitConfig.JitForceFallback() || compiler->compStressCompile(Compiler::STRESS_GENERIC_VARN, 5) ) { NO_WAY_NOASSERT("Stress failure"); diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp index 57807fb846..846f51df05 100644 --- a/src/jit/codegenlegacy.cpp +++ b/src/jit/codegenlegacy.cpp @@ -6209,8 +6209,7 @@ bool CodeGen::genCodeForQmarkWithCMOV(GenTreePtr tree, noway_assert(colon->gtOper == GT_COLON); #ifdef DEBUG - static ConfigDWORD fJitNoCMOV; - if (fJitNoCMOV.val(CLRConfig::INTERNAL_JitNoCMOV)) + if (JitConfig.JitNoCMOV()) { return false; } @@ -12254,8 +12253,7 @@ void CodeGen::genCodeForTreeSpecialOp(GenTreePtr tree, #ifdef FEATURE_ENABLE_NO_RANGE_CHECKS // MUST NEVER CHECK-IN WITH THIS ENABLED. // This is just for convenience in doing performance investigations and requires x86ret builds - static ConfigDWORD fJitNoRngChk; - if (!fJitNoRngChk.val(CLRConfig::PRIVATE_JitNoRangeChks)) + if (!JitConfig.JitNoRngChk()) #endif genRangeCheck(tree); } diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index 71312bc61f..074540b00b 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -58,6 +58,7 @@ LONG Compiler::jitNestingLevel = 0; #ifdef ALT_JIT // static +bool Compiler::s_pAltJitExcludeAssembliesListInitialized = false; AssemblyNamesList2* Compiler::s_pAltJitExcludeAssembliesList = nullptr; #endif // ALT_JIT @@ -758,8 +759,7 @@ void Compiler::compShutdown() #if defined(DEBUG) || MEASURE_INLINING #ifdef DEBUG - static ConfigDWORD fJitInlinePrintStats; - if ((unsigned)fJitInlinePrintStats.val(CLRConfig::INTERNAL_JitInlinePrintStats) == 1) + if ((unsigned)JitConfig.JitInlinePrintStats() == 1) #endif // DEBUG { fprintf(fout, "\n"); @@ -1023,8 +1023,7 @@ void Compiler::compShutdown() #if LOOP_HOIST_STATS #ifdef DEBUG // Always display loop stats in retail - static ConfigDWORD fDisplayLoopHoistStats; - if (fDisplayLoopHoistStats.val(CLRConfig::INTERNAL_JitLoopHoistStats) != 0) + if (JitConfig.DisplayLoopHoistStats() != 0) #endif // DEBUG { PrintAggregateLoopHoistStats(stdout); @@ -1526,8 +1525,7 @@ static bool DidComponentUnitTests = false; void Compiler::compDoComponentUnitTestsOnce() { - static ConfigDWORD fRunComponentUnitTests; - if (!fRunComponentUnitTests.val(CLRConfig::INTERNAL_JitComponentUnitTests)) + if (!JitConfig.RunComponentUnitTests()) return; if (!DidComponentUnitTests) @@ -1853,8 +1851,7 @@ void Compiler::compSetProcessor() if (((compileFlags & CORJIT_FLG_PREJIT) == 0) && ((compileFlags & CORJIT_FLG_USE_AVX2) != 0)) { - static ConfigDWORD fEnableAVX; - if (fEnableAVX.val(CLRConfig::EXTERNAL_EnableAVX) != 0) + if (JitConfig.EnableAVX() != 0) { opts.compCanUseAVX = true; if (!compIsForInlining()) @@ -1885,11 +1882,9 @@ void Compiler::compSetProcessor() SSE2_FORCE_INVALID = -1 }; - static ConfigDWORD fJitCanUseSSE2; - - if (fJitCanUseSSE2.val_DontUse_(CLRConfig::INTERNAL_JitCanUseSSE2, (unsigned) SSE2_FORCE_INVALID) == SSE2_FORCE_DISABLE) + if (JitConfig.JitCanUseSSE2() == SSE2_FORCE_DISABLE) opts.compCanUseSSE2 = false; - else if (fJitCanUseSSE2.val_DontUse_(CLRConfig::INTERNAL_JitCanUseSSE2, (unsigned) SSE2_FORCE_INVALID) == SSE2_FORCE_USE) + else if (JitConfig.JitCanUseSSE2() == SSE2_FORCE_USE) opts.compCanUseSSE2 = true; else if (opts.compCanUseSSE2) opts.compCanUseSSE2 = !compStressCompile(STRESS_GENERIC_VARN, 50); @@ -1938,8 +1933,8 @@ bool Compiler::compShouldThrowOnNoway( return !opts.MinOpts() || !compIsFullTrust(); } -// ConfigDWORD does not offer an option for decimal flags. Any numbers are interpreted as hex. -// I could add the decimal option to ConfigDWORD or I could write a function to reinterpret this +// ConfigInteger does not offer an option for decimal flags. Any numbers are interpreted as hex. +// I could add the decimal option to ConfigInteger or I could write a function to reinterpret this // value as the user intended. unsigned ReinterpretHexAsDecimal(unsigned in) { @@ -2059,20 +2054,14 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #ifdef DEBUG - ConfigMethodSet* pfAltJit; + const JitConfigValues::MethodSet* pfAltJit; if (opts.eeFlags & CORJIT_FLG_PREJIT) { - static ConfigMethodSet fAltJitNgen; - fAltJitNgen.ensureInit(CLRConfig::INTERNAL_AltJitNgen); - - pfAltJit = &fAltJitNgen; + pfAltJit = &JitConfig.AltJitNgen(); } else { - static ConfigMethodSet fAltJit; - fAltJit.ensureInit(CLRConfig::EXTERNAL_AltJit); - - pfAltJit = &fAltJit; + pfAltJit = &JitConfig.AltJit(); } #ifdef ALT_JIT @@ -2081,8 +2070,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) opts.altJit = true; } - static ConfigDWORD fAltJitLimit; - unsigned altJitLimit = ReinterpretHexAsDecimal(fAltJitLimit.val(CLRConfig::INTERNAL_AltJitLimit)); + unsigned altJitLimit = ReinterpretHexAsDecimal(JitConfig.AltJitLimit()); if (altJitLimit > 0 && Compiler::jitTotalMethodCompiled >= altJitLimit) { opts.altJit = false; @@ -2091,16 +2079,14 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #else // !DEBUG - LPWSTR altJitVal; + const char* altJitVal; if (opts.eeFlags & CORJIT_FLG_PREJIT) { - static ConfigString fAltJitNgen; - altJitVal = fAltJitNgen.val(CLRConfig::INTERNAL_AltJitNgen); + altJitVal = JitConfig.AltJitNgen().list(); } else { - static ConfigString fAltJit; - altJitVal = fAltJit.val(CLRConfig::EXTERNAL_AltJit); + altJitVal = JitConfig.AltJit().list(); } #ifdef ALT_JIT @@ -2108,7 +2094,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // You don't get to give a regular expression of methods to match. // (Partially, this is because we haven't computed and stored the method and class name except in debug, and it // might be expensive to do so.) - if ((altJitVal != NULL) && (wcscmp(altJitVal, W("*")) == 0)) + if ((altJitVal != nullptr) && (strcmp(altJitVal, "*") == 0)) { opts.altJit = true; } @@ -2121,16 +2107,16 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) if (opts.altJit) { // First, initialize the AltJitExcludeAssemblies list, but only do it once. - static ConfigString fAltJitExcludeAssemblies; - if (!fAltJitExcludeAssemblies.isInitialized()) + if (!s_pAltJitExcludeAssembliesListInitialized) { - LPWSTR wszAltJitExcludeAssemblyList = fAltJitExcludeAssemblies.val(CLRConfig::EXTERNAL_AltJitExcludeAssemblies); + const wchar_t* wszAltJitExcludeAssemblyList = JitConfig.AltJitExcludeAssemblies(); if (wszAltJitExcludeAssemblyList != nullptr) { // NOTE: The Assembly name list is allocated in the process heap, not in the no-release heap, which is reclaimed // for every compilation. This is ok because we only allocate once, due to the static. s_pAltJitExcludeAssembliesList = new (ProcessHeapAllocator::Singleton()) AssemblyNamesList2(wszAltJitExcludeAssemblyList, ProcessHeapAllocator::Singleton()); } + s_pAltJitExcludeAssembliesListInitialized = true; } if (s_pAltJitExcludeAssembliesList != nullptr) @@ -2158,9 +2144,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // if (compIsForImportOnly() && (!altJitConfig || opts.altJit)) { - static ConfigMethodSet fJitImportBreak; - fJitImportBreak.ensureInit(CLRConfig::INTERNAL_JitImportBreak); - if (fJitImportBreak.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitImportBreak().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) assert(!"JitImportBreak reached"); } @@ -2192,63 +2176,41 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) if (opts.eeFlags & CORJIT_FLG_PREJIT) { - static ConfigMethodSet fNgenDump; - fNgenDump.ensureInit(CLRConfig::INTERNAL_NgenDump); - - if (fNgenDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.NgenDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) verboseDump = true; - static ConfigDWORD fNgenHashDump; - unsigned ngenHashDumpVal = (unsigned) fNgenHashDump.val(CLRConfig::INTERNAL_NgenHashDump); + unsigned ngenHashDumpVal = (unsigned) JitConfig.NgenHashDump(); if ((ngenHashDumpVal != (DWORD)-1) && (ngenHashDumpVal == info.compMethodHash())) verboseDump = true; - static ConfigMethodSet fNgenDumpIR; - fNgenDumpIR.ensureInit(CLRConfig::INTERNAL_NgenDumpIR); - - if (fNgenDumpIR.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.NgenDumpIR().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) dumpIR = true; - static ConfigDWORD fNgenHashDumpIR; - unsigned ngenHashDumpIRVal = (unsigned) fNgenHashDumpIR.val(CLRConfig::INTERNAL_NgenHashDumpIR); + unsigned ngenHashDumpIRVal = (unsigned) JitConfig.NgenHashDumpIR(); if ((ngenHashDumpIRVal != (DWORD)-1) && (ngenHashDumpIRVal == info.compMethodHash())) dumpIR = true; - static ConfigString ngenDumpIRFormat; - dumpIRFormat = ngenDumpIRFormat.val(CLRConfig::INTERNAL_NgenDumpIRFormat); - - static ConfigString ngenDumpIRPhase; - dumpIRPhase = ngenDumpIRPhase.val(CLRConfig::INTERNAL_NgenDumpIRPhase); + dumpIRFormat = JitConfig.NgenDumpIRFormat(); + dumpIRPhase = JitConfig.NgenDumpIRPhase(); } else { - static ConfigMethodSet fJitDump; - fJitDump.ensureInit(CLRConfig::INTERNAL_JitDump); - - if (fJitDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) verboseDump = true; - static ConfigDWORD fJitHashDump; - unsigned jitHashDumpVal = (unsigned) fJitHashDump.val(CLRConfig::INTERNAL_JitHashDump); + unsigned jitHashDumpVal = (unsigned) JitConfig.JitHashDump(); if ((jitHashDumpVal != (DWORD)-1) && (jitHashDumpVal == info.compMethodHash())) verboseDump = true; - static ConfigMethodSet fJitDumpIR; - fJitDumpIR.ensureInit(CLRConfig::INTERNAL_JitDumpIR); - - if (fJitDumpIR.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitDumpIR().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) dumpIR = true; - static ConfigDWORD fJitHashDumpIR; - unsigned jitHashDumpIRVal = (unsigned) fJitHashDumpIR.val(CLRConfig::INTERNAL_JitHashDumpIR); + unsigned jitHashDumpIRVal = (unsigned) JitConfig.JitHashDumpIR(); if ((jitHashDumpIRVal != (DWORD)-1) && (jitHashDumpIRVal == info.compMethodHash())) dumpIR = true; - static ConfigString jitDumpIRFormat; - dumpIRFormat = jitDumpIRFormat.val(CLRConfig::INTERNAL_JitDumpIRFormat); - - static ConfigString jitDumpIRPhase; - dumpIRPhase = jitDumpIRPhase.val(CLRConfig::INTERNAL_JitDumpIRPhase); + dumpIRFormat = JitConfig.JitDumpIRFormat(); + dumpIRPhase = JitConfig.JitDumpIRPhase(); } if (dumpIRPhase == nullptr) @@ -2614,83 +2576,60 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) { if (opts.eeFlags & CORJIT_FLG_PREJIT) { - static ConfigDWORD fNgenOrder; - if ((fNgenOrder.val(CLRConfig::INTERNAL_NgenOrder) & 1) == 1) + if ((JitConfig.NgenOrder() & 1) == 1) opts.dspOrder = true; - static ConfigMethodSet fNgenGCDump; - fNgenGCDump.ensureInit(CLRConfig::INTERNAL_NgenGCDump); - if (fNgenGCDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.NgenGCDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.dspGCtbls = true; - static ConfigMethodSet fNgenDisasm; - fNgenDisasm.ensureInit(CLRConfig::INTERNAL_NgenDisasm); - if (fNgenDisasm.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.NgenDisasm().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.disAsm = true; - if (fNgenDisasm.contains("SPILLED", NULL)) + if (JitConfig.NgenDisasm().contains("SPILLED", NULL, NULL)) opts.disAsmSpilled = true; - static ConfigMethodSet fNgenUnwindDump; - fNgenUnwindDump.ensureInit(CLRConfig::INTERNAL_NgenUnwindDump); - if (fNgenUnwindDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.NgenUnwindDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.dspUnwind = true; - static ConfigMethodSet fNgenEHDump; - fNgenEHDump.ensureInit(CLRConfig::INTERNAL_NgenEHDump); - if (fNgenEHDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.NgenEHDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.dspEHTable = true; } else { - static ConfigDWORD fJitOrder; - if ((fJitOrder.val(CLRConfig::INTERNAL_JitOrder) & 1) == 1) + if ((JitConfig.JitOrder() & 1) == 1) opts.dspOrder = true; - static ConfigMethodSet fJitGCDump; - fJitGCDump.ensureInit(CLRConfig::INTERNAL_JitGCDump); - if (fJitGCDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitGCDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.dspGCtbls = true; - static ConfigMethodSet fJitDisasm; - fJitDisasm.ensureInit(CLRConfig::INTERNAL_JitDisasm); - if (fJitDisasm.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitDisasm().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.disAsm = true; - if (fJitDisasm.contains("SPILLED", NULL)) + if (JitConfig.JitDisasm().contains("SPILLED", NULL, NULL)) opts.disAsmSpilled = true; - static ConfigMethodSet fJitUnwindDump; - fJitUnwindDump.ensureInit(CLRConfig::INTERNAL_JitUnwindDump); - if (fJitUnwindDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitUnwindDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.dspUnwind = true; - static ConfigMethodSet fJitEHDump; - fJitEHDump.ensureInit(CLRConfig::INTERNAL_JitEHDump); - if (fJitEHDump.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitEHDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.dspEHTable = true; } #ifdef LATE_DISASM - static ConfigMethodSet fJitLateDisasm; - fJitLateDisasm.ensureInit(CLRConfig::INTERNAL_JitLateDisasm); - if (fJitLateDisasm.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitLateDisasm().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.doLateDisasm = true; #endif // LATE_DISASM // This one applies to both Ngen/Jit Disasm output: COMPLUS_JitDiffableDasm=1 - static ConfigDWORD fDiffableDasm; - if (fDiffableDasm.val(CLRConfig::INTERNAL_JitDiffableDasm) != 0) + if (JitConfig.DiffableDasm() != 0) { opts.disDiffable = true; opts.dspDiffable = true; } - static ConfigDWORD fDisplayMemStats; - if (fDisplayMemStats.val(CLRConfig::INTERNAL_JitMemStats) != 0) + if (JitConfig.DisplayMemStats() != 0) s_dspMemStats = true; - static ConfigDWORD fJitLargeBranches; - if (fJitLargeBranches.val(CLRConfig::INTERNAL_JitLargeBranches) != 0) + if (JitConfig.JitLargeBranches() != 0) opts.compLargeBranches = true; } @@ -2707,12 +2646,10 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) codeGen->setVerbose(true); } - static ConfigDWORD fTreesBeforeAfterMorph; - treesBeforeAfterMorph = (fTreesBeforeAfterMorph.val(CLRConfig::INTERNAL_JitDumpBeforeAfterMorph) == 1); + treesBeforeAfterMorph = (JitConfig.TreesBeforeAfterMorph() == 1); morphNum = 0; // Initialize the morphed-trees counting. - static ConfigDWORD fJitExpensiveDebugCheckLevel; - expensiveDebugCheckLevel = fJitExpensiveDebugCheckLevel.val(CLRConfig::INTERNAL_JitExpensiveDebugCheckLevel); + expensiveDebugCheckLevel = JitConfig.JitExpensiveDebugCheckLevel(); if (expensiveDebugCheckLevel == 0) { // If we're in a stress mode that modifies the flowgraph, make 1 the default. @@ -2729,21 +2666,16 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) printf(""); // in our logic this causes a flush } - static ConfigMethodSet fJitBreak; - fJitBreak.ensureInit(CLRConfig::INTERNAL_JitBreak); - if (fJitBreak.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitBreak().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) assert(!"JitBreak reached"); - static ConfigDWORD fJitHashBreak; - unsigned jitHashBreakVal = (unsigned)fJitHashBreak.val(CLRConfig::INTERNAL_JitHashBreak); + unsigned jitHashBreakVal = (unsigned)JitConfig.JitHashBreak(); if ((jitHashBreakVal != (DWORD)-1) && (jitHashBreakVal == info.compMethodHash())) assert(!"JitHashBreak reached"); - static ConfigMethodSet fJitDebugBreak; - fJitDebugBreak.ensureInit(CLRConfig::INTERNAL_JitDebugBreak); if (verbose || - fJitDebugBreak.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args) || - fJitBreak.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + JitConfig.JitDebugBreak().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args) || + JitConfig.JitBreak().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) { compDebugBreak = true; } @@ -2757,8 +2689,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #ifdef DEBUGGING_SUPPORT #ifdef DEBUG assert(!codeGen->isGCTypeFixed()); - static ConfigDWORD fJitGCChecks; - opts.compGcChecks = (fJitGCChecks.val_DontUse_(CLRConfig::INTERNAL_JitGCChecks) != 0) || + opts.compGcChecks = (JitConfig.JitGCChecks() != 0) || compStressCompile(STRESS_GENERIC_VARN, 5); enum @@ -2768,8 +2699,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) STACK_CHECK_ALL = 0x3, }; - static ConfigDWORD fJitStackChecks; - DWORD dwJitStackChecks = fJitStackChecks.val_DontUse_(CLRConfig::INTERNAL_JitStackChecks); + DWORD dwJitStackChecks = JitConfig.JitStackChecks(); if (compStressCompile(STRESS_GENERIC_VARN, 5)) dwJitStackChecks = STACK_CHECK_ALL; opts.compStackCheckOnRet = (dwJitStackChecks & DWORD(STACK_CHECK_ON_RETURN)) != 0; opts.compStackCheckOnCall = (dwJitStackChecks & DWORD(STACK_CHECK_ON_CALL)) != 0; @@ -2800,8 +2730,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // Honour complus_JitELTHookEnabled only if VM has not asked us to generate profiler // hooks in the first place. That is, Override VM only if it hasn't asked for a // profiler callback for this method. - static ConfigDWORD fJitELTHookEnabled; - if (!compProfilerHookNeeded && (fJitELTHookEnabled.val(CLRConfig::INTERNAL_JitELTHookEnabled) != 0)) + if (!compProfilerHookNeeded && (JitConfig.JitELTHookEnabled() != 0)) { opts.compJitELTHookEnabled = true; } @@ -2817,14 +2746,13 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #endif // PROFILING_SUPPORTED #if FEATURE_TAILCALL_OPT - static ConfigString fTailCallOpt; - LPWSTR strTailCallOpt = fTailCallOpt.val(CLRConfig::EXTERNAL_TailCallOpt); + const wchar_t* strTailCallOpt = JitConfig.TailCallOpt(); if (strTailCallOpt != nullptr) { opts.compTailCallOpt = (UINT)_wtoi(strTailCallOpt) != 0; } - static ConfigDWORD fTailCallLoopOpt; - if (fTailCallLoopOpt.val(CLRConfig::EXTERNAL_TailCallLoopOpt) == 0) + + if (JitConfig.TailCallLoopOpt() == 0) { opts.compTailCallLoopOpt = false; } @@ -2848,8 +2776,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) #ifdef DEBUG #if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND) // Whether encoding of absolute addr as PC-rel offset is enabled in RyuJIT - static ConfigDWORD fEnablePCRelAddr; - opts.compEnablePCRelAddr = (fEnablePCRelAddr.val(CLRConfig::INTERNAL_JitEnablePCRelAddr) != 0); + opts.compEnablePCRelAddr = (JitConfig.EnablePCRelAddr() != 0); #endif #endif //DEBUG @@ -2873,21 +2800,15 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // JitForceProcedureSplitting is used to force procedure splitting on checked assemblies. // This is useful for debugging on a checked build. Note that we still only do procedure // splitting in the zapper. - static ConfigMethodSet fJitForceProcedureSplitting; - fJitForceProcedureSplitting.ensureInit(CLRConfig::INTERNAL_JitForceProcedureSplitting); - if (fJitForceProcedureSplitting.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitForceProcedureSplitting().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.compProcedureSplitting = true; // JitNoProcedureSplitting will always disable procedure splitting. - static ConfigMethodSet fJitNoProcedureSplitting; - fJitNoProcedureSplitting.ensureInit(CLRConfig::INTERNAL_JitNoProcedureSplitting); - if (fJitNoProcedureSplitting.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitNoProcedureSplitting().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.compProcedureSplitting = false; // // JitNoProcedureSplittingEH will disable procedure splitting in functions with EH. - static ConfigMethodSet fJitNoProcedureSplittingEH; - fJitNoProcedureSplittingEH.ensureInit(CLRConfig::INTERNAL_JitNoProcedureSplittingEH); - if (fJitNoProcedureSplittingEH.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitNoProcedureSplittingEH().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) opts.compProcedureSplittingEH = false; #endif } @@ -2933,8 +2854,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) opts.compNeedStackProbes = false; #ifdef DEBUG - static ConfigDWORD fStackProbesOverride; - if (fStackProbesOverride.val_DontUse_(CLRConfig::INTERNAL_JitStackProbes) != 0 || + if (JitConfig.StackProbesOverride() != 0 || compStressCompile(STRESS_GENERIC_VARN, 5)) { opts.compNeedStackProbes = true; @@ -2945,9 +2865,8 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // Now, set compMaxUncheckedOffsetForNullObject for STRESS_NULL_OBJECT_CHECK if (compStressCompile(STRESS_NULL_OBJECT_CHECK, 30)) { - static ConfigDWORD fJitMaxUncheckedOffset; compMaxUncheckedOffsetForNullObject = - (unsigned) fJitMaxUncheckedOffset.val(CLRConfig::INTERNAL_JitMaxUncheckedOffset); + (unsigned) JitConfig.JitMaxUncheckedOffset(); if (verbose) { printf("STRESS_NULL_OBJECT_CHECK: compMaxUncheckedOffsetForNullObject=0x%X\n", compMaxUncheckedOffsetForNullObject); } @@ -3011,17 +2930,14 @@ bool Compiler::compJitHaltMethod() /* This method returns true when we use an INS_BREAKPOINT to allow us to step into the generated native code */ /* Note that this these two "Jit" environment variables also work for ngen images */ - static ConfigMethodSet fJitHalt; - fJitHalt.ensureInit(CLRConfig::INTERNAL_JitHalt); - if (fJitHalt.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitHalt().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) { return true; } /* Use this Hash variant when there are a lot of method with the same name and different signatures */ - static ConfigDWORD fJitHashHalt; - unsigned fJitHashHaltVal = (unsigned)fJitHashHalt.val(CLRConfig::INTERNAL_JitHashHalt); + unsigned fJitHashHaltVal = (unsigned)JitConfig.JitHashHalt(); if ((fJitHashHaltVal != (unsigned)-1) && (fJitHashHaltVal == info.compMethodHash())) { return true; @@ -3056,21 +2972,17 @@ bool Compiler::compStressCompile(compStressArea stressArea, return false; } - static ConfigMethodSet fJitStressOnly; - fJitStressOnly.ensureInit(CLRConfig::INTERNAL_JitStressOnly); - if (!fJitStressOnly.isEmpty() && - !fJitStressOnly.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (!JitConfig.JitStressOnly().isEmpty() && + !JitConfig.JitStressOnly().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) { return false; } bool doStress = false; - static ConfigString fJitStressModeNames; - LPWSTR strStressModeNames; + const wchar_t* strStressModeNames; // Does user explicitly prevent using this STRESS_MODE through the command line? - static ConfigString fJitStressModeNamesNot; - LPWSTR strStressModeNamesNot = fJitStressModeNamesNot.val(CLRConfig::INTERNAL_JitStressModeNamesNot); + const wchar_t* strStressModeNamesNot = JitConfig.JitStressModeNamesNot(); if ((strStressModeNamesNot != NULL) && (wcsstr(strStressModeNamesNot, s_compStressModeNames[stressArea]) != NULL)) { @@ -3083,7 +2995,7 @@ bool Compiler::compStressCompile(compStressArea stressArea, } // Does user explicitly set this STRESS_MODE through the command line? - strStressModeNames = fJitStressModeNames.val(CLRConfig::INTERNAL_JitStressModeNames); + strStressModeNames = JitConfig.JitStressModeNames(); if ((strStressModeNames != NULL) && (wcsstr(strStressModeNames, s_compStressModeNames[stressArea]) != NULL)) { @@ -3258,9 +3170,7 @@ void Compiler::compSetOptimizationLevel() } #ifdef DEBUG - static ConfigDWORD fJitMinOpts; - - jitMinOpts = fJitMinOpts.val_DontUse_(CLRConfig::UNSUPPORTED_JITMinOpts, 0); + jitMinOpts = JitConfig.JitMinOpts(); if (!theMinOptsValue && (jitMinOpts > 0)) { @@ -3324,10 +3234,7 @@ void Compiler::compSetOptimizationLevel() if (!theMinOptsValue) { - static ConfigMethodSet jitMinOptsName; - jitMinOptsName.ensureInit(CLRConfig::INTERNAL_JITMinOptsName); - - if (jitMinOptsName.contains(info.compMethodName, info.compClassName, info.compMethodInfo->args.pSig)) + if (JitConfig.JitMinOptsName().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) theMinOptsValue = true; } @@ -3339,34 +3246,27 @@ void Compiler::compSetOptimizationLevel() // unless unless CLFLG_MINOPT is set else if (!(compileFlags & CORJIT_FLG_PREJIT)) { - static ConfigDWORD fJitMinOptsCodeSize; - static ConfigDWORD fJitMinOptsInstrCount; - static ConfigDWORD fJitMinOptsBbCount; - static ConfigDWORD fJitMinOptsLvNumCount; - static ConfigDWORD fJitMinOptsLvRefCount; - static ConfigDWORD fJitBreakOnMinOpts; - - if (fJitMinOptsCodeSize.val_DontUse_(CLRConfig::INTERNAL_JITMinOptsCodeSize, DEFAULT_MIN_OPTS_CODE_SIZE) < info.compILCodeSize) + if ((unsigned)JitConfig.JitMinOptsCodeSize() < info.compILCodeSize) { JITLOG((LL_INFO10, "IL Code Size exceeded, using MinOpts for method %s\n", info.compFullName)); theMinOptsValue = true; } - else if (fJitMinOptsInstrCount.val_DontUse_(CLRConfig::INTERNAL_JITMinOptsInstrCount, DEFAULT_MIN_OPTS_INSTR_COUNT) < opts.instrCount) + else if ((unsigned)JitConfig.JitMinOptsInstrCount() < opts.instrCount) { JITLOG((LL_INFO10, "IL instruction count exceeded, using MinOpts for method %s\n", info.compFullName)); theMinOptsValue = true; } - else if (fJitMinOptsBbCount.val_DontUse_(CLRConfig::INTERNAL_JITMinOptsBbCount, DEFAULT_MIN_OPTS_BB_COUNT) < fgBBcount) + else if ((unsigned)JitConfig.JitMinOptsBbCount() < fgBBcount) { JITLOG((LL_INFO10, "Basic Block count exceeded, using MinOpts for method %s\n", info.compFullName)); theMinOptsValue = true; } - else if (fJitMinOptsLvNumCount.val_DontUse_(CLRConfig::INTERNAL_JITMinOptsLvNumcount, DEFAULT_MIN_OPTS_LV_NUM_COUNT) < lvaCount) + else if ((unsigned)JitConfig.JitMinOptsLvNumCount() < lvaCount) { JITLOG((LL_INFO10, "Local Variable Num count exceeded, using MinOpts for method %s\n", info.compFullName)); theMinOptsValue = true; } - else if (fJitMinOptsLvRefCount.val_DontUse_(CLRConfig::INTERNAL_JITMinOptsLvRefcount, DEFAULT_MIN_OPTS_LV_REF_COUNT) < opts.lvRefCount) + else if ((unsigned)JitConfig.JitMinOptsLvRefCount() < opts.lvRefCount) { JITLOG((LL_INFO10, "Local Variable Ref count exceeded, using MinOpts for method %s\n", info.compFullName)); theMinOptsValue = true; @@ -3375,7 +3275,7 @@ void Compiler::compSetOptimizationLevel() { JITLOG((LL_INFO10000, "IL Code Size,Instr %4d,%4d, Basic Block count %3d, Local Variable Num,Ref count %3d,%3d for method %s\n", info.compILCodeSize, opts.instrCount, fgBBcount, lvaCount, opts.lvRefCount, info.compFullName)); - if (fJitBreakOnMinOpts.val_DontUse_(CLRConfig::INTERNAL_JITBreakOnMinOpts, 0) != 0) + if (JitConfig.JitBreakOnMinOpts() != 0) { assert(!"MinOpts enabled"); } @@ -3624,7 +3524,7 @@ void Compiler::compCompile(void * * methodCodePtr, EndPhase(PHASE_PRE_IMPORT); #ifdef DEBUG - bool funcTrace = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitFunctionTrace) != 0); + bool funcTrace = JitConfig.JitFunctionTrace() != 0; if (!compIsForInlining()) { @@ -3864,14 +3764,13 @@ void Compiler::compCompile(void * * methodCodePtr, bool doRangeAnalysis = true; #ifdef DEBUG - static ConfigDWORD fJitDoOptConfig[7]; - doSsa = (fJitDoOptConfig[0].val(CLRConfig::INTERNAL_JitDoSsa) != 0); - doEarlyProp = doSsa && (fJitDoOptConfig[1].val(CLRConfig::INTERNAL_JitDoEarlyProp) != 0); - doValueNum = doSsa && (fJitDoOptConfig[2].val(CLRConfig::INTERNAL_JitDoValueNumber) != 0); - doLoopHoisting = doValueNum && (fJitDoOptConfig[3].val(CLRConfig::INTERNAL_JitDoLoopHoisting) != 0); - doCopyProp = doValueNum && (fJitDoOptConfig[4].val(CLRConfig::INTERNAL_JitDoCopyProp) != 0); - doAssertionProp = doValueNum && (fJitDoOptConfig[5].val(CLRConfig::INTERNAL_JitDoAssertionProp) != 0); - doRangeAnalysis = doAssertionProp && (fJitDoOptConfig[6].val(CLRConfig::INTERNAL_JitDoRangeAnalysis) != 0); + doSsa = (JitConfig.JitDoSsa() != 0); + doEarlyProp = doSsa && (JitConfig.JitDoEarlyProp() != 0); + doValueNum = doSsa && (JitConfig.JitDoValueNumber() != 0); + doLoopHoisting = doValueNum && (JitConfig.JitDoLoopHoisting() != 0); + doCopyProp = doValueNum && (JitConfig.JitDoCopyProp() != 0); + doAssertionProp = doValueNum && (JitConfig.JitDoAssertionProp() != 0); + doRangeAnalysis = doAssertionProp && (JitConfig.JitDoRangeAnalysis() != 0); #endif if (doSsa) @@ -4199,18 +4098,14 @@ void* forceFrameJIT; // used to force to frame &useful for fastchecked deb bool Compiler::skipMethod() { static ConfigMethodRange fJitRange; - fJitRange.ensureInit(CLRConfig::INTERNAL_JitRange); + fJitRange.ensureInit(JitConfig.JitRange()); if (!fJitRange.contains(info.compCompHnd, info.compMethodHnd)) return true; - static ConfigMethodSet fJitExclude; - fJitExclude.ensureInit(CLRConfig::INTERNAL_JitExclude); - if (fJitExclude.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (JitConfig.JitExclude().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) return true; - static ConfigMethodSet fJitInclude; - fJitInclude.ensureInit(CLRConfig::INTERNAL_JitInclude); - if (!fJitInclude.isEmpty() && !fJitInclude.contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) + if (!JitConfig.JitInclude().isEmpty() && !JitConfig.JitInclude().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args)) return true; return false; @@ -4285,8 +4180,7 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, #endif #if FUNC_INFO_LOGGING - static ConfigString jitFuncInfoFile; - LPCWSTR tmpJitFuncInfoFilename = jitFuncInfoFile.val(CLRConfig::INTERNAL_JitFuncInfoLogFile); + LPCWSTR tmpJitFuncInfoFilename = JitConfig.JitFuncInfoFile(); if (tmpJitFuncInfoFilename != NULL) { @@ -4368,7 +4262,7 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, } static ConfigMethodRange fJitStressRange; - fJitStressRange.ensureInit(CLRConfig::INTERNAL_JitStressRange); + fJitStressRange.ensureInit(JitConfig.JitStressRange()); if (fJitStressRange.contains(info.compCompHnd, info.compMethodHnd)) { bRangeAllowStress = true; @@ -4830,8 +4724,7 @@ int Compiler::compCompileHelper (CORINFO_MODULE_HANDLE clas #endif // Check for COMPLUS_AgressiveInlining - static ConfigDWORD fJitAggressiveInlining; - if (fJitAggressiveInlining.val(CLRConfig::INTERNAL_JitAggressiveInlining)) + if (JitConfig.JitAggressiveInlining()) { compDoAggressiveInlining = true; } @@ -4857,8 +4750,7 @@ int Compiler::compCompileHelper (CORINFO_MODULE_HANDLE clas } // Force verification if asked to do so - static ConfigDWORD fJitForceVer; - if (fJitForceVer.val(CLRConfig::INTERNAL_JitForceVer)) + if (JitConfig.JitForceVer()) tiVerificationNeeded = (instVerInfo == INSTVER_NOT_INSTANTIATION); if (tiVerificationNeeded) @@ -5088,8 +4980,7 @@ int Compiler::compCompileHelper (CORINFO_MODULE_HANDLE clas } #ifdef DEBUG - static ConfigDWORD fDumpJittedMethods; - if (fDumpJittedMethods.val(CLRConfig::INTERNAL_DumpJittedMethods) == 1 && !compIsForInlining()) + if (JitConfig.DumpJittedMethods() == 1 && !compIsForInlining()) { printf("Compiling %4d %s::%s, IL size = %u, hsh=0x%x\n", Compiler::jitTotalMethodCompiled, @@ -5136,8 +5027,7 @@ _Next: #ifdef ALT_JIT #ifdef DEBUG - static ConfigDWORD fRunAltJitCode; - if (fRunAltJitCode.val(CLRConfig::INTERNAL_RunAltJitCode) == 0) + if (JitConfig.RunAltJitCode() == 0) { return CORJIT_SKIPPED; } @@ -6710,8 +6600,7 @@ CritSecObject JitTimer::s_csvLock; LPCWSTR Compiler::JitTimeLogCsv() { - static ConfigString jitConfigTimeLogCsv; - LPCWSTR jitTimeLogCsv = jitConfigTimeLogCsv.val(CLRConfig::INTERNAL_JitTimeLogCsv); + LPCWSTR jitTimeLogCsv = JitConfig.JitTimeLogCsv(); return jitTimeLogCsv; } diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 7925602c0c..bb302ee623 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -4323,8 +4323,7 @@ protected : unsigned fgStressBBProf() { #ifdef DEBUG - static ConfigDWORD fJitStressBBProf; - unsigned result = fJitStressBBProf.val(CLRConfig::INTERNAL_JitStressBBProf); + unsigned result = JitConfig.JitStressBBProf(); if (result == 0) { if (compStressCompile(STRESS_BB_PROFILE, 15)) @@ -7549,6 +7548,7 @@ public : opts; #ifdef ALT_JIT + static bool s_pAltJitExcludeAssembliesListInitialized; static AssemblyNamesList2* s_pAltJitExcludeAssembliesList; #endif // ALT_JIT @@ -7641,8 +7641,7 @@ public : bool compTailCallStress() { #ifdef DEBUG - static ConfigDWORD fTailcallStress; - return (fTailcallStress.val(CLRConfig::INTERNAL_TailcallStress) !=0 + return (JitConfig.TailcallStress() !=0 || compStressCompile(STRESS_TAILCALL, 5) ); #else diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp index 6637891523..882cf51381 100644 --- a/src/jit/compiler.hpp +++ b/src/jit/compiler.hpp @@ -38,10 +38,7 @@ inline bool getInlinePInvokeEnabled() { #ifdef DEBUG - static ConfigDWORD fJITPInvokeEnabled; - static ConfigDWORD fStressCOMCall; - - return fJITPInvokeEnabled.val(CLRConfig::INTERNAL_JITPInvokeEnabled) && !fStressCOMCall.val(CLRConfig::INTERNAL_StressCOMCall); + return JitConfig.JitPInvokeEnabled() && !JitConfig.StressCOMCall(); #else return true; #endif @@ -51,8 +48,7 @@ inline bool getInlinePInvokeCheckEnabled() { #ifdef DEBUG - static ConfigDWORD fJITPInvokeCheckEnabled; - return fJITPInvokeCheckEnabled.val(CLRConfig::INTERNAL_JITPInvokeCheckEnabled) != 0; + return JitConfig.JitPInvokeCheckEnabled() != 0; #else return false; #endif @@ -89,8 +85,7 @@ inline RoundLevel getRoundFloatLevel() { #ifdef DEBUG - static ConfigDWORD fJITRoundFloat; - return (RoundLevel) fJITRoundFloat.val_DontUse_(CLRConfig::INTERNAL_JITRoundFloat, DEFAULT_ROUND_LEVEL); + return (RoundLevel) JitConfig.JitRoundFloat(); #else return DEFAULT_ROUND_LEVEL; #endif @@ -3092,15 +3087,13 @@ void Compiler::tmpDone() inline bool Compiler::shouldUseVerboseTrees() { - static ConfigDWORD fVerboseTrees; - return (fVerboseTrees.val(CLRConfig::INTERNAL_JitDumpVerboseTrees) == 1); + return (JitConfig.JitDumpVerboseTrees() == 1); } inline bool Compiler::shouldUseVerboseSsa() { - static ConfigDWORD fVerboseSsa; - return (fVerboseSsa.val(CLRConfig::INTERNAL_JitDumpVerboseSsa) == 1); + return (JitConfig.JitDumpVerboseSsa() == 1); } //------------------------------------------------------------------------ @@ -3112,8 +3105,7 @@ bool Compiler::shouldUseVerboseSsa() inline bool Compiler::shouldDumpASCIITrees() { - static ConfigDWORD fASCIITrees; - return (fASCIITrees.val(CLRConfig::INTERNAL_JitDumpASCII) == 1); + return (JitConfig.JitDumpASCII() == 1); } /***************************************************************************** @@ -3126,8 +3118,7 @@ bool Compiler::shouldDumpASCIITrees() inline DWORD getJitStressLevel() { - static ConfigDWORD fJitStress; - return fJitStress.val(CLRConfig::INTERNAL_JitStress); + return JitConfig.JitStress(); } /***************************************************************************** @@ -3137,9 +3128,7 @@ DWORD getJitStressLevel() inline DWORD StrictCheckForNonVirtualCallToVirtualMethod() { - static ConfigDWORD fJitStrictCheckForNonVirtualCallToVirtualMethod; - return fJitStrictCheckForNonVirtualCallToVirtualMethod.val( - CLRConfig::INTERNAL_JitStrictCheckForNonVirtualCallToVirtualMethod) == 1; + return JitConfig.JitStrictCheckForNonVirtualCallToVirtualMethod() == 1; } #endif // DEBUG diff --git a/src/jit/disasm.cpp b/src/jit/disasm.cpp index 3a3e0230f1..9b8e0c3c47 100644 --- a/src/jit/disasm.cpp +++ b/src/jit/disasm.cpp @@ -1531,9 +1531,7 @@ void DisAssembler::disAsmCode(BYTE* hotCodePtr, size_t hotCodeSize, BYTE* col #endif // !DEBUG #ifdef DEBUG - static ConfigString fJITLateDisasmTo; - - LPWSTR fileName = fJITLateDisasmTo.val(CLRConfig::INTERNAL_JITLateDisasmTo); + const wchar_t* fileName = JitConfig.JitLateDisasmTo(); if (fileName != nullptr) { errno_t ec = _wfopen_s(&disAsmFile, fileName, W("a+")); diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp index f0da62d153..46cdb6b43e 100644 --- a/src/jit/ee_il_dll.cpp +++ b/src/jit/ee_il_dll.cpp @@ -52,6 +52,14 @@ void __stdcall jitStartup(ICorJitHost* jitHost) { g_jitHost = jitHost; + // `jitStartup` may be called multiple times + // when pre-jitting. We should not reinitialize + // config values each time. + if (!JitConfig.isInitialized()) + { + JitConfig.initialize(jitHost); + } + #ifdef FEATURE_TRACELOGGING JitTelemetry::NotifyDllProcessAttach(); #endif @@ -285,8 +293,7 @@ unsigned CILJit::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags) ((cpuCompileFlags & CORJIT_FLG_FEATURE_SIMD) != 0) && ((cpuCompileFlags & CORJIT_FLG_USE_AVX2) != 0)) { - static ConfigDWORD fEnableAVX; - if (fEnableAVX.val(CLRConfig::EXTERNAL_EnableAVX) != 0) + if (JitConfig.EnableAVX() != 0) { return 32; } diff --git a/src/jit/emit.cpp b/src/jit/emit.cpp index 35b16b679a..5af7adeffc 100644 --- a/src/jit/emit.cpp +++ b/src/jit/emit.cpp @@ -924,8 +924,7 @@ void emitter::emitTmpSizeChanged(unsigned tmpSize) #ifdef DEBUG // Workaround for FP code - static ConfigDWORD fMaxTempAssert; - bool bAssert = fMaxTempAssert.val(CLRConfig::INTERNAL_JITMaxTempAssert)?true:false; + bool bAssert = JitConfig.JitMaxTempAssert()?true:false; if (tmpSize > emitMaxTmpSize && bAssert) { diff --git a/src/jit/emitarm.cpp b/src/jit/emitarm.cpp index a405246d24..99049e4b0e 100644 --- a/src/jit/emitarm.cpp +++ b/src/jit/emitarm.cpp @@ -6620,8 +6620,7 @@ DONE_CALL: { // set JitEmitPrintRefRegs=1 will print out emitThisGCrefRegs and emitThisByrefRegs // at the beginning of this method. - static ConfigDWORD fJitEmitPrintRefRegs; - if (fJitEmitPrintRefRegs.val(CLRConfig::INTERNAL_JitEmitPrintRefRegs) != 0) { + if (JitConfig.JitEmitPrintRefRegs() != 0) { printf("Before emitOutputInstr for id->idDebugOnlyInfo()->idNum=0x%02x\n", id->idDebugOnlyInfo()->idNum); printf(" emitThisGCrefRegs(0x%p)=", dspPtr(&emitThisGCrefRegs)); printRegMaskInt(emitThisGCrefRegs); @@ -6635,8 +6634,7 @@ DONE_CALL: // For example, set JitBreakEmitOutputInstr=a6 will break when this method is called for // emitting instruction a6, (i.e. IN00a6 in jitdump). - static ConfigDWORD fJitBreakEmitOutputInstr; - if ((unsigned)fJitBreakEmitOutputInstr.val(CLRConfig::INTERNAL_JitBreakEmitOutputInstr) == id->idDebugOnlyInfo()->idNum) + if ((unsigned)JitConfig.JitBreakEmitOutputInstr() == id->idDebugOnlyInfo()->idNum) { assert(!"JitBreakEmitOutputInstr reached"); } diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp index 2b203499b4..7421f0dcd7 100644 --- a/src/jit/emitarm64.cpp +++ b/src/jit/emitarm64.cpp @@ -9167,8 +9167,7 @@ size_t emitter::emitOutputInstr(insGroup *ig, { // For example, set JitBreakEmitOutputInstr=a6 will break when this method is called for // emitting instruction a6, (i.e. IN00a6 in jitdump). - static ConfigDWORD fJitBreakEmitOutputInstr; - if ((unsigned)fJitBreakEmitOutputInstr.val(CLRConfig::INTERNAL_JitBreakEmitOutputInstr) == id->idDebugOnlyInfo()->idNum) + if ((unsigned)JitConfig.JitBreakEmitOutputInstr() == id->idDebugOnlyInfo()->idNum) { assert(!"JitBreakEmitOutputInstr reached"); } diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp index 4bf0affe4c..343e00f182 100644 --- a/src/jit/emitxarch.cpp +++ b/src/jit/emitxarch.cpp @@ -11159,8 +11159,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** { // set JitEmitPrintRefRegs=1 will print out emitThisGCrefRegs and emitThisByrefRegs // at the beginning of this method. - static ConfigDWORD fJitEmitPrintRefRegs; - if (fJitEmitPrintRefRegs.val(CLRConfig::INTERNAL_JitEmitPrintRefRegs) != 0) + if (JitConfig.JitEmitPrintRefRegs() != 0) { printf("Before emitOutputInstr for id->idDebugOnlyInfo()->idNum=0x%02x\n", id->idDebugOnlyInfo()->idNum); printf(" emitThisGCrefRegs(0x%p)=", emitComp->dspPtr(&emitThisGCrefRegs)); @@ -11175,8 +11174,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** // For example, set JitBreakEmitOutputInstr=a6 will break when this method is called for // emitting instruction a6, (i.e. IN00a6 in jitdump). - static ConfigDWORD fJitBreakEmitOutputInstr; - if ((unsigned)fJitBreakEmitOutputInstr.val(CLRConfig::INTERNAL_JitBreakEmitOutputInstr) == id->idDebugOnlyInfo()->idNum) + if ((unsigned)JitConfig.JitBreakEmitOutputInstr() == id->idDebugOnlyInfo()->idNum) { assert(!"JitBreakEmitOutputInstr reached"); } diff --git a/src/jit/error.cpp b/src/jit/error.cpp index 2f30227cf3..b853b9f8ef 100644 --- a/src/jit/error.cpp +++ b/src/jit/error.cpp @@ -34,8 +34,7 @@ void DECLSPEC_NORETURN fatal(int errCode) #ifdef DEBUG if (errCode != CORJIT_SKIPPED) // Don't stop on NYI: use COMPLUS_AltJitAssertOnNYI for that. { - static ConfigDWORD fDebugBreakOnVerificationFailure; - if (fDebugBreakOnVerificationFailure.val(CLRConfig::INTERNAL_DebugBreakOnVerificationFailure)) + if (JitConfig.DebugBreakOnVerificationFailure()) { DebugBreak(); } @@ -90,8 +89,7 @@ void DECLSPEC_NORETURN noWayAssertBody() // have the assert code to fall back on here. // The debug path goes through this function also, to do the call to 'fatal'. // This kind of noway is hit for unreached(). - static ConfigDWORD fJitEnableNoWayAssert; - if (fJitEnableNoWayAssert.val(CLRConfig::INTERNAL_JitEnableNoWayAssert)) + if (JitConfig.JitEnableNoWayAssert()) { DebugBreak(); } @@ -172,9 +170,7 @@ void notYetImplemented(const char * msg, const char * filename, unsigned line) #endif // !DEBUG #endif // FUNC_INFO_LOGGING - static ConfigDWORD fAltJitAssertOnNYI; - - DWORD value = fAltJitAssertOnNYI.val(CLRConfig::INTERNAL_AltJitAssertOnNYI); + DWORD value = JitConfig.AltJitAssertOnNYI(); // 0 means just silently skip // If we are in retail builds, assume ignore @@ -237,8 +233,7 @@ LONG __JITfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam) DWORD getBreakOnBadCode() { - static ConfigDWORD fBreakOnBadCode; - return fBreakOnBadCode.val_DontUse_(CLRConfig::INTERNAL_JitBreakOnBadCode, false); + return JitConfig.JitBreakOnBadCode(); } /*****************************************************************************/ @@ -251,10 +246,9 @@ void debugError(const char* msg, const char* file, unsigned line) logf(LL_ERROR, "COMPILATION FAILED: file: %s:%d compiling method %s reason %s\n", file, line, env->compiler->info.compFullName, msg); - static ConfigDWORD fJitRequired; // We now only assert when user explicitly set ComPlus_JitRequired=1 // If ComPlus_JitRequired is 0 or is not set, we will not assert. - if (fJitRequired.val(CLRConfig::INTERNAL_JITRequired) == 1 || getBreakOnBadCode()) + if (JitConfig.JitRequired() == 1 || getBreakOnBadCode()) { // Don't assert if verification is done. if (!env->compiler->tiVerificationNeeded || getBreakOnBadCode()) @@ -323,8 +317,7 @@ void __cdecl assertAbort(const char *why, const char *file, unsigned line) // to the fallback JIT behavior. This is useful when doing ASM diffs, where we only want to see // the first assert for any function, but we don't want to kill the whole ngen process on the // first assert (which would happen if you used COMPLUS_NoGuiOnAssert=1 for example). - static ConfigDWORD fAltJitSkipOnAssert; - if (fAltJitSkipOnAssert.val(CLRConfig::INTERNAL_AltJitSkipOnAssert) != 0) + if (JitConfig.AltJitSkipOnAssert() != 0) { fatal(CORJIT_SKIPPED); } @@ -334,9 +327,7 @@ void __cdecl assertAbort(const char *why, const char *file, unsigned line) // When we are bringing up the new Arm64 JIT we set COMPLUS_ContinueOnAssert=1 // We only want to hit one assert then we will fall back to the interpreter. // - static ConfigDWORD s_InterpreterFallback; - - bool interpreterFallback = (s_InterpreterFallback.val(CLRConfig::INTERNAL_InterpreterFallback) != 0); + bool interpreterFallback = (JitConfig.InterpreterFallback() != 0); if (interpreterFallback) { @@ -360,8 +351,7 @@ int logf_stdout(const char* fmt, va_list args) char buffer[BUFF_SIZE]; int written = _vsnprintf_s(&buffer[0], BUFF_SIZE, _TRUNCATE, fmt, args); - static ConfigDWORD fJitDumpToDebugger; - if (fJitDumpToDebugger.val(CLRConfig::INTERNAL_JitDumpToDebugger)) + if (JitConfig.JitDumpToDebugger()) { OutputDebugStringA(buffer); } @@ -536,8 +526,7 @@ void DECLSPEC_NORETURN badCode3(const char* msg, const char* msg2, int arg, void noWayAssertAbortHelper(const char * cond, const char * file, unsigned line) { // Show the assert UI. - static ConfigDWORD fJitEnableNoWayAssert; - if (fJitEnableNoWayAssert.val(CLRConfig::INTERNAL_JitEnableNoWayAssert)) + if (JitConfig.JitEnableNoWayAssert()) { assertAbort(cond, file, line); } diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp index 3af856f153..0dc9fe67bf 100644 --- a/src/jit/flowgraph.cpp +++ b/src/jit/flowgraph.cpp @@ -31,8 +31,7 @@ void Compiler::fgInit() #ifdef DEBUG fgInlinedCount = 0; - static ConfigDWORD fJitPrintInlinedMethods; - fgPrintInlinedMethods = fJitPrintInlinedMethods.val(CLRConfig::EXTERNAL_JitPrintInlinedMethods) == 1; + fgPrintInlinedMethods = JitConfig.JitPrintInlinedMethods() == 1; #endif // DEBUG /* We haven't yet computed the bbPreds lists */ @@ -163,12 +162,11 @@ void Compiler::fgInit() #ifdef DEBUG if (!compIsForInlining()) { - static ConfigDWORD fJitNoStructPromotion; - if ((fJitNoStructPromotion.val(CLRConfig::INTERNAL_JitNoStructPromotion) & 1) == 1) + if ((JitConfig.JitNoStructPromotion() & 1) == 1) { fgNoStructPromotion = true; } - if ((fJitNoStructPromotion.val(CLRConfig::INTERNAL_JitNoStructPromotion) & 2) == 2) + if ((JitConfig.JitNoStructPromotion() & 2) == 2) { fgNoStructParamPromotion = true; } @@ -10049,8 +10047,7 @@ void Compiler::fgCompactBlocks(BasicBlock* block, BasicBlock* bNe #endif #if DEBUG - static ConfigDWORD fSlowDebugChecksEnabled; - if (fSlowDebugChecksEnabled.val(CLRConfig::INTERNAL_JitSlowDebugChecksEnabled) != 0) + if (JitConfig.JitSlowDebugChecksEnabled() != 0) { // Make sure that the predecessor lists are accurate fgDebugCheckBBlist(); @@ -18914,21 +18911,15 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas #ifdef DEBUG if (opts.eeFlags & CORJIT_FLG_PREJIT) { - static ConfigString sNgenDumpFg; - pattern = sNgenDumpFg.val(CLRConfig::INTERNAL_NgenDumpFg); - static ConfigString sNgenDumpFgFile; - filename = sNgenDumpFgFile.val(CLRConfig::INTERNAL_NgenDumpFgFile); - static ConfigString sNgenDumpFgDir; - pathname = sNgenDumpFgDir.val(CLRConfig::INTERNAL_NgenDumpFgDir); + pattern = JitConfig.NgenDumpFg(); + filename = JitConfig.NgenDumpFgFile(); + pathname = JitConfig.NgenDumpFgDir(); } else { - static ConfigString sJitDumpFg; - pattern = sJitDumpFg.val(CLRConfig::INTERNAL_JitDumpFg); - static ConfigString sJitDumpFgFile; - filename = sJitDumpFgFile.val(CLRConfig::INTERNAL_JitDumpFgFile); - static ConfigString sJitDumpFgDir; - pathname = sJitDumpFgDir.val(CLRConfig::INTERNAL_JitDumpFgDir); + pattern = JitConfig.JitDumpFg(); + filename = JitConfig.JitDumpFgFile(); + pathname = JitConfig.JitDumpFgDir(); } #endif // DEBUG @@ -18941,8 +18932,7 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas if (wcslen(pattern) == 0) return NULL; - static ConfigString sJitDumpFgPhase; - LPCWSTR phasePattern = sJitDumpFgPhase.val(CLRConfig::INTERNAL_JitDumpFgPhase); + LPCWSTR phasePattern = JitConfig.JitDumpFgPhase(); LPCWSTR phaseName = PhaseShortNames[phase]; if (phasePattern == 0) { @@ -19204,9 +19194,8 @@ bool Compiler::fgDumpFlowGraph(Phases phase) { bool result = false; bool dontClose = false; - static ConfigDWORD fJitDumpFgDot; bool createDotFile = false; - if (fJitDumpFgDot.val(CLRConfig::INTERNAL_JitDumpFgDot)) + if (JitConfig.JitDumpFgDot()) { createDotFile = true; } diff --git a/src/jit/gcencode.cpp b/src/jit/gcencode.cpp index cae78c4df5..d5fff4833f 100644 --- a/src/jit/gcencode.cpp +++ b/src/jit/gcencode.cpp @@ -3325,13 +3325,12 @@ class GcInfoEncoderWithLogging { GcInfoEncoder* m_gcInfoEncoder; bool m_doLogging; - static ConfigDWORD s_fJitGCInfoLogging; public: GcInfoEncoderWithLogging(GcInfoEncoder* gcInfoEncoder, bool verbose) : m_gcInfoEncoder(gcInfoEncoder), - m_doLogging(verbose || s_fJitGCInfoLogging.val(CLRConfig::INTERNAL_JitGCInfoLogging) != 0) + m_doLogging(verbose || JitConfig.JitGCInfoLogging() != 0) {} GcSlotId GetStackSlotId( INT32 spOffset, GcSlotFlags flags, GcStackSlotBase spBase = GC_CALLER_SP_REL ) @@ -3484,8 +3483,6 @@ public: }; -ConfigDWORD GcInfoEncoderWithLogging::s_fJitGCInfoLogging; - #define GCENCODER_WITH_LOGGING(withLog, realEncoder) \ GcInfoEncoderWithLogging withLog ## Var(realEncoder, compiler->verbose || compiler->opts.dspGCtbls); \ GcInfoEncoderWithLogging * withLog = &withLog ## Var; diff --git a/src/jit/gentree.h b/src/jit/gentree.h index 08cc26473f..01878a1768 100644 --- a/src/jit/gentree.h +++ b/src/jit/gentree.h @@ -2649,8 +2649,7 @@ struct GenTreeIndex: public GenTreeOp gtStructElemClass(nullptr) // We always initialize this after construction. { #ifdef DEBUG - static ConfigDWORD fJitSkipArrayBoundCheck; - if (fJitSkipArrayBoundCheck.val(CLRConfig::INTERNAL_JitSkipArrayBoundCheck) == 1) + if (JitConfig.JitSkipArrayBoundCheck() == 1) { // Skip bounds check } diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp index 0ad5dc2948..c865fb0f1d 100644 --- a/src/jit/importer.cpp +++ b/src/jit/importer.cpp @@ -71,8 +71,7 @@ void Compiler::impInit() #ifndef DEBUG impInlineSize = DEFAULT_MAX_INLINE_SIZE; #else - static ConfigDWORD fJitInlineSize; - impInlineSize = fJitInlineSize.val_DontUse_(CLRConfig::INTERNAL_JITInlineSize, DEFAULT_MAX_INLINE_SIZE); + impInlineSize = JitConfig.JitInlineSize(); if (compStressCompile(STRESS_INLINE, 50)) impInlineSize *= 10; @@ -191,8 +190,7 @@ inline void Compiler::verRaiseVerifyExceptionIfNeeded(INDEBUG(const char* msg) D const char* tail = strrchr(file, '\\'); if (tail) file = tail+1; - static ConfigDWORD fJitBreakOnUnsafeCode; - if (fJitBreakOnUnsafeCode.val(CLRConfig::INTERNAL_JitBreakOnUnsafeCode)) + if (JitConfig.JitBreakOnUnsafeCode()) assert(!"Unsafe code detected"); #endif @@ -3462,8 +3460,7 @@ void Compiler::verConvertBBToThrowVerificationException(BasicBlock* block printf("\n\nVerification failure: %s near IL %xh \n", info.compFullName, block->bbCodeOffs); } - static ConfigDWORD fDebugBreakOnVerificationFailure; - if (fDebugBreakOnVerificationFailure.val(CLRConfig::INTERNAL_DebugBreakOnVerificationFailure)) + if (JitConfig.DebugBreakOnVerificationFailure()) { DebugBreak(); } @@ -15621,8 +15618,7 @@ void Compiler::impCanInlineNative(int callsiteNativeEstima // effect of different values was within the standard deviation. This may be a place where future tuning // (with additional benchmarks) would be valuable. - static ConfigDWORD fJitInlineSIMDMultiplier; - int simdMultiplier = fJitInlineSIMDMultiplier.val(CLRConfig::INTERNAL_JitInlineSIMDMultiplier); + int simdMultiplier = JitConfig.JitInlineSIMDMultiplier(); multiplier += simdMultiplier; JITDUMP("\nInline candidate has SIMD type args, locals or return value. Multipler increased to %g.", multiplier); @@ -15711,8 +15707,7 @@ void Compiler::impCanInlineNative(int callsiteNativeEstima } #ifdef DEBUG - static ConfigDWORD fJitInlineAdditionalMultiplier; - int additionalMultiplier = fJitInlineAdditionalMultiplier.val(CLRConfig::EXTERNAL_JitInlineAdditionalMultiplier); + int additionalMultiplier = JitConfig.JitInlineAdditionalMultiplier(); if (additionalMultiplier!=0) { @@ -15930,8 +15925,7 @@ void Compiler::impCheckCanInline(GenTreePtr call, const char * className; methodName = pParam->pThis->eeGetMethodName(pParam->fncHandle, &className); - static ConfigDWORD fJitNoInline; - if (fJitNoInline.val(CLRConfig::INTERNAL_JitNoInline)) + if (JitConfig.JitNoInline()) { pParam->result->noteFatal(InlineObservation::CALLEE_IS_JIT_NOINLINE); goto _exit; diff --git a/src/jit/instr.cpp b/src/jit/instr.cpp index c6ca9d35c5..aca8b57ee4 100644 --- a/src/jit/instr.cpp +++ b/src/jit/instr.cpp @@ -3905,8 +3905,7 @@ void CodeGen::instGen_Return(unsigned stkArgSize) void CodeGen::instGen_MemoryBarrier() { #ifdef DEBUG - static ConfigDWORD fJitNoMemoryBarriers; - if (fJitNoMemoryBarriers.val(CLRConfig::INTERNAL_JitNoMemoryBarriers) == 1) + if (JitConfig.JitNoMemoryBarriers() == 1) return; #endif // DEBUG diff --git a/src/jit/jit.h b/src/jit/jit.h index af78504aa0..2b7fdf1357 100644 --- a/src/jit/jit.h +++ b/src/jit/jit.h @@ -199,6 +199,18 @@ #define __PLACEMENT_NEW_INLINE // don't bring in the global placement new, it is easy to make a mistake // with our new(compiler*) pattern. +#if COR_JIT_EE_VER > 460 +#define NO_CLRCONFIG // Don't bring in the usual CLRConfig infrastructure, since the JIT uses the JIT/EE + // interface to retrieve config values. + +// This is needed for contract.inl when FEATURE_STACK_PROBE is enabled. +struct CLRConfig +{ + static struct ConfigKey { } EXTERNAL_NO_SO_NOT_MAINLINE; + static DWORD GetConfigValue(const ConfigKey& key) { return 0; } +}; +#endif + #include "utilcode.h" // this defines assert as _ASSERTE #include "host.h" // this redefines assert for the JIT to use assertAbort #include "utils.h" @@ -520,8 +532,7 @@ extern JitOptions jitOpts; template<typename T> inline T UninitializedWord() { - static ConfigDWORD fDefaultFill; - __int64 word = 0x0101010101010101LL * (fDefaultFill.val(CLRConfig::INTERNAL_JitDefaultFill) & 0xFF); + __int64 word = 0x0101010101010101LL * (JitConfig.JitDefaultFill() & 0xFF); return (T)word; } diff --git a/src/jit/jit.settings.targets b/src/jit/jit.settings.targets index 5f93c539ea..0f3e9e4deb 100644 --- a/src/jit/jit.settings.targets +++ b/src/jit/jit.settings.targets @@ -81,6 +81,7 @@ <CppCompile Include="..\RangeCheck.cpp" /> <CppCompile Include="..\LoopCloning.cpp" /> <CppCompile Include="..\inline.cpp" /> + <CppCompile Include="..\jitconfig.cpp" /> <CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='True'" Include="..\CodeGenLegacy.cpp" /> <CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\Lower.cpp" /> <CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\LSRA.cpp" /> diff --git a/src/jit/jitconfig.cpp b/src/jit/jitconfig.cpp new file mode 100644 index 0000000000..da1875ca0e --- /dev/null +++ b/src/jit/jitconfig.cpp @@ -0,0 +1,298 @@ +// 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. + +#include "jitpch.h" +#ifdef _MSC_VER +#pragma hdrstop +#endif + +#include "jitconfig.h" + +JitConfigValues JitConfig; + +void JitConfigValues::MethodSet::initialize(const wchar_t* list, ICorJitHost* host) +{ + _ASSERTE(m_list == nullptr); + + enum State { NO_NAME, CLS_NAME, FUNC_NAME, ARG_LIST }; // parsing state machine + + const char SEP_CHAR = ' '; // current character use to separate each entry + + wchar_t lastChar = '?'; // dummy + int nameStart = -1; // Index of the start of the current class or method name + MethodName currentName; // Buffer used while parsing the current entry + MethodName** lastName = &m_names; // Last entry inserted into the list + bool isQuoted = false; + + currentName.m_next = nullptr; + currentName.m_methodNameStart = -1; + currentName.m_methodNameLen = -1; + currentName.m_classNameStart = -1; + currentName.m_classNameLen = -1; + currentName.m_numArgs = -1; + + // Convert the input list to UTF-8 + int utf8ListLen = WszWideCharToMultiByte(CP_UTF8, 0, list, -1, NULL, 0, NULL, NULL); + m_list = (char*)host->allocateMemory(utf8ListLen); + if (WszWideCharToMultiByte(CP_UTF8, 0, list, -1, const_cast<LPSTR>(m_list), utf8ListLen, NULL, NULL) == 0) + { + // Failed to convert the list. Free the memory and ignore the list. + host->freeMemory(reinterpret_cast<void*>(const_cast<char*>(m_list))); + m_list = ""; + return; + } + + State state = NO_NAME; + for (int i = 0; lastChar != '\0'; i++) + { + lastChar = m_list[i]; + + switch(state) + { + case NO_NAME: + if (m_list[i] != SEP_CHAR) + { + nameStart = i; + state = CLS_NAME; // we have found the start of the next entry + } + break; + + case CLS_NAME: + if (m_list[nameStart] == '"') + { + for (; m_list[i] != '\0' && m_list[i] != '"'; i++) + ; + + nameStart++; + isQuoted = true; + } + + if (m_list[i] == ':') + { + if (m_list[nameStart] == '*' && !isQuoted) + { + // The class name is a wildcard; mark it invalid. + currentName.m_classNameStart = -1; + currentName.m_classNameLen = -1; + } + else + { + currentName.m_classNameStart = nameStart; + currentName.m_classNameLen = i - nameStart; + + // Remove the trailing quote, if any + if (isQuoted) + { + currentName.m_classNameLen--; + isQuoted = false; + } + } + + // Accept class::name syntax as well + if (m_list[i + 1] == ':') + { + i++; + } + + nameStart = i + 1; + state = FUNC_NAME; + } + else if (m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == '(') + { + // Treat this as a method name without a class name. + currentName.m_classNameStart = -1; + currentName.m_classNameLen = -1; + goto DONE_FUNC_NAME; + } + break; + + case FUNC_NAME: + if (m_list[nameStart] == '"') + { + // The first half of the outer contdition handles the case where the + // class name is valid. + for (; nameStart == i || (m_list[i] != '\0' && m_list[i] != '"'); i++) + ; + + nameStart++; + isQuoted = true; + } + + if (m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == '(') + { + DONE_FUNC_NAME: + _ASSERTE(m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == '('); + + if (m_list[nameStart] == '*' && !isQuoted) + { + // The method name is a wildcard; mark it invalid. + currentName.m_methodNameStart = -1; + currentName.m_methodNameLen = -1; + } + else + { + currentName.m_methodNameStart = nameStart; + currentName.m_methodNameLen = i - nameStart; + + // Remove the trailing quote, if any + if (isQuoted) + { + currentName.m_classNameLen--; + isQuoted = false; + } + } + + if (m_list[i] == '\0' || m_list[i] == SEP_CHAR) + { + currentName.m_numArgs = -1; + goto DONE_ARG_LIST; + } + else + { + _ASSERTE(m_list[i] == '('); + currentName.m_numArgs = -1; + state = ARG_LIST; + } + } + break; + + case ARG_LIST: + if (m_list[i] == '\0' || m_list[i] == ')') + { + if (currentName.m_numArgs == -1) + { + currentName.m_numArgs = 0; + } + + DONE_ARG_LIST: + _ASSERTE(m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == ')'); + + // We have parsed an entire method name; create a new entry in the list for it. + MethodName* name = (MethodName*)host->allocateMemory(sizeof(MethodName)); + *name = currentName; + + _ASSERTE(name->m_next == nullptr); + *lastName = name; + lastName = &name->m_next; + + state = NO_NAME; + + // Skip anything after the argument list until we find the next + // separator character. Otherwise if we see "func(a,b):foo" we + // create entries for "func(a,b)" as well as ":foo". + if (m_list[i] == ')') + { + for (; m_list[i] && m_list[i] != SEP_CHAR; i++) + ; + + lastChar = m_list[i]; + } + } + else + { + if (m_list[i] != SEP_CHAR && currentName.m_numArgs == -1) + { + currentName.m_numArgs = 1; + } + + if (m_list[i] == ',') + { + currentName.m_numArgs++; + } + } + break; + + default: + _ASSERTE(!"Bad state"); + break; + } + } +} + +static bool matchesName(const char* const name, int nameLen, const char* const s2) +{ + return strncmp(name, s2, nameLen) == 0 && s2[nameLen] == '\0'; +} + +bool JitConfigValues::MethodSet::contains(const char* methodName, const char* className, CORINFO_SIG_INFO* sigInfo) const +{ + int numArgs = sigInfo != nullptr ? sigInfo->numArgs : -1; + + // Try to match any the entries in the list. + for (MethodName* name = m_names; name != nullptr; name = name->m_next) + { + // If m_numArgs is valid, check for a mismatch + if (name->m_numArgs != -1 && name->m_numArgs != numArgs) + { + continue; + } + + // If m_methodNameStart is valid, check for a mismatch + if (name->m_methodNameStart != -1) + { + const char* expectedMethodName = &m_list[name->m_methodNameStart]; + if (!matchesName(expectedMethodName, name->m_methodNameLen, methodName)) + { + // C++ embeds the class name into the method name; deal with that here. + const char* colon = strchr(methodName, ':'); + if (colon != nullptr && colon[1] == ':' && matchesName(expectedMethodName, name->m_methodNameLen, methodName)) + { + int classLen = (int)(colon - methodName); + if (name->m_classNameStart == -1 || + (classLen == name->m_classNameLen && + strncmp(&m_list[name->m_classNameStart], methodName, classLen) == 0)) + { + return true; + } + } + continue; + } + } + + // If m_classNameStart is valid, check for a mismatch + if (className == nullptr || name->m_classNameStart == -1 || matchesName(&m_list[name->m_classNameStart], name->m_classNameLen, className)) + { + return true; + } + + // Check for suffix wildcard like System.* + if (name->m_classNameLen > 0 && + m_list[name->m_classNameStart + name->m_classNameLen - 1] == '*' && + strncmp(&m_list[name->m_classNameStart], className, name->m_classNameLen - 1) == 0) + { + return true; + } + +#ifdef _DEBUG + // Maybe className doesn't include the namespace. Try to match that + const char* nsSep = strrchr(className, '.'); + if (nsSep != nullptr && nsSep != className) + { + const char* onlyClass = nsSep[-1] == '.' ? nsSep : &nsSep[1]; + if (matchesName(&m_list[name->m_classNameStart], name->m_classNameLen, onlyClass)) + { + return true; + } + } +#endif + } + + return false; +} + +void JitConfigValues::initialize(ICorJitHost* host) +{ + _ASSERTE(!m_isInitialized); + +#define CONFIG_INTEGER(name, key, defaultValue) m_##name = host->getIntConfigValue(key, defaultValue); +#define CONFIG_STRING(name, key) m_##name = host->getStringConfigValue(key); +#define CONFIG_METHODSET(name, key) \ + const wchar_t* name##value = host->getStringConfigValue(key); \ + m_##name.initialize(name##value, host); \ + host->freeStringConfigValue(name##value); + +#include "jitconfigvalues.h" + + m_isInitialized = true; +} diff --git a/src/jit/jitconfig.h b/src/jit/jitconfig.h new file mode 100644 index 0000000000..9da5808a5a --- /dev/null +++ b/src/jit/jitconfig.h @@ -0,0 +1,70 @@ +// 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. + +#ifndef _JITCONFIG_H_ +#define _JITCONFIG_H_ + +struct CORINFO_SIG_INFO; +class ICorJitHost; + +class JitConfigValues +{ +public: + class MethodSet + { + private: + struct MethodName + { + MethodName* m_next; + int m_methodNameStart; + int m_methodNameLen; + int m_classNameStart; + int m_classNameLen; + int m_numArgs; + }; + + const char* m_list; + MethodName* m_names; + + MethodSet(const MethodSet& other) = delete; + MethodSet& operator=(const MethodSet& other) = delete; + + public: + MethodSet() { } + inline const char* list() const { return m_list; } + + void initialize(const wchar_t* list, ICorJitHost* host); + + inline bool isEmpty() const { return m_names == nullptr; } + bool contains(const char* methodName, const char* className, CORINFO_SIG_INFO* sigInfo) const; + }; + +private: +#define CONFIG_INTEGER(name, key, defaultValue) int m_##name; +#define CONFIG_STRING(name, key) const wchar_t* m_##name; +#define CONFIG_METHODSET(name, key) MethodSet m_##name; +#include "jitconfigvalues.h" + +public: +#define CONFIG_INTEGER(name, key, defaultValue) inline int name() const { return m_##name; } +#define CONFIG_STRING(name, key) inline const wchar_t* name() const { return m_##name; } +#define CONFIG_METHODSET(name, key) inline const MethodSet& name() const { return m_##name; } +#include "jitconfigvalues.h" + +private: + bool m_isInitialized; + + JitConfigValues(const JitConfigValues& other) = delete; + JitConfigValues& operator=(const JitConfigValues& other) = delete; + +public: + JitConfigValues() {} + + inline bool isInitialized() const { return m_isInitialized != 0; } + void initialize(ICorJitHost* host); +}; + +extern JitConfigValues JitConfig; + +#endif diff --git a/src/jit/jitconfigvalues.h b/src/jit/jitconfigvalues.h new file mode 100644 index 0000000000..8136517078 --- /dev/null +++ b/src/jit/jitconfigvalues.h @@ -0,0 +1,193 @@ +// 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. + +#if !defined(CONFIG_INTEGER) || !defined(CONFIG_STRING) || !defined(CONFIG_METHODSET) +#error CONFIG_INTEGER, CONFIG_STRING, and CONFIG_METHODSET must be defined before including this file. +#endif // !defined(CONFIG_INTEGER) || !defined(CONFIG_STRING) || !defined(CONFIG_METHODSET) + +#if defined(DEBUG) +CONFIG_INTEGER(AltJitLimit, W("AltJitLimit"), 0) // Max number of functions to use altjit for (decimal) +CONFIG_INTEGER(AltJitSkipOnAssert, W("AltJitSkipOnAssert"), 0) // If AltJit hits an assert, fall back to the fallback JIT. Useful in conjunction with COMPLUS_ContinueOnAssert=1 +CONFIG_INTEGER(BreakOnDumpToken, W("BreakOnDumpToken"), 0xffffffff) // Breaks when using internal logging on a particular token value. +CONFIG_INTEGER(DebugBreakOnVerificationFailure, W("DebugBreakOnVerificationFailure"), 0) // Halts the jit on verification failure +CONFIG_INTEGER(DiffableDasm, W("JitDiffableDasm"), 0) // Make the disassembly diff-able +CONFIG_INTEGER(DisplayLoopHoistStats, W("JitLoopHoistStats"), 0) // Display JIT loop hoisting statistics +CONFIG_INTEGER(DisplayMemStats, W("JitMemStats"), 0) // Display JIT memory usage statistics +CONFIG_INTEGER(DumpJittedMethods, W("DumpJittedMethods"), 0) // Prints all jitted methods to the console +CONFIG_INTEGER(EnablePCRelAddr, W("JitEnablePCRelAddr"), 1) // Whether absolute addr be encoded as PC-rel offset by RyuJIT where possible +CONFIG_INTEGER(InterpreterFallback, W("InterpreterFallback"), 0) // Fallback to the interpreter when the JIT compiler fails +CONFIG_INTEGER(JitAssertOnMaxRAPasses, W("JitAssertOnMaxRAPasses"), 0) +CONFIG_INTEGER(JitBreakEmitOutputInstr, W("JitBreakEmitOutputInstr"), -1) +CONFIG_INTEGER(JitBreakMorphTree, W("JitBreakMorphTree"), 0xffffffff) +CONFIG_INTEGER(JitBreakOnBadCode, W("JitBreakOnBadCode"), 0) +CONFIG_INTEGER(JitBreakOnMinOpts, W("JITBreakOnMinOpts"), 0) // Halt if jit switches to MinOpts +CONFIG_INTEGER(JitBreakOnUnsafeCode, W("JitBreakOnUnsafeCode"), 0) +CONFIG_INTEGER(JitCanUseSSE2, W("JitCanUseSSE2"), -1) +CONFIG_INTEGER(JitCloneLoops, W("JitCloneLoops"), 1) // If 0, don't clone. Otherwise clone loops for optimizations. +CONFIG_INTEGER(JitDebugLogLoopCloning, W("JitDebugLogLoopCloning"), 0) // In debug builds log places where loop cloning optimizations are performed on the fast path. +CONFIG_INTEGER(JitDefaultFill, W("JitDefaultFill"), 0xff) // In debug builds, initialize the memory allocated by the nra with this byte. +CONFIG_INTEGER(JitDirectAlloc, W("JitDirectAlloc"), 0) +CONFIG_INTEGER(JitDoAssertionProp, W("JitDoAssertionProp"), 1) // Perform assertion propagation optimization +CONFIG_INTEGER(JitDoCopyProp, W("JitDoCopyProp"), 1) // Perform copy propagation on variables that appear redundant +CONFIG_INTEGER(JitDoEarlyProp, W("JitDoEarlyProp"), 1) // Perform Early Value Propagataion +CONFIG_INTEGER(JitDoLoopHoisting, W("JitDoLoopHoisting"), 1) // Perform loop hoisting on loop invariant values +CONFIG_INTEGER(JitDoRangeAnalysis, W("JitDoRangeAnalysis"), 1) // Perform range check analysis +CONFIG_INTEGER(JitDoSsa, W("JitDoSsa"), 1) // Perform Static Single Assignment (SSA) numbering on the variables +CONFIG_INTEGER(JitDoValueNumber, W("JitDoValueNumber"), 1) // Perform value numbering on method expressions +CONFIG_INTEGER(JitDoubleAlign, W("JitDoubleAlign"), 1) +CONFIG_INTEGER(JitDumpASCII, W("JitDumpASCII"), 1) // Uses only ASCII characters in tree dumps +CONFIG_INTEGER(JitDumpFgDot, W("JitDumpFgDot"), 0) // Set to non-zero to emit Dot instead of Xml Flowgraph dump +CONFIG_INTEGER(JitDumpTerseLsra, W("JitDumpTerseLsra"), 1) // Produce terse dump output for LSRA +CONFIG_INTEGER(JitDumpToDebugger, W("JitDumpToDebugger"), 0) // Output JitDump output to the debugger +CONFIG_INTEGER(JitDumpVerboseSsa, W("JitDumpVerboseSsa"), 0) // Produce especially verbose dump output for SSA +CONFIG_INTEGER(JitDumpVerboseTrees, W("JitDumpVerboseTrees"), 0) // Enable more verbose tree dumps +CONFIG_INTEGER(JitEmitPrintRefRegs, W("JitEmitPrintRefRegs"), 0) +CONFIG_INTEGER(JitExpensiveDebugCheckLevel, W("JitExpensiveDebugCheckLevel"), 0) // Level indicates how much checking beyond the default to do in debug builds (currently 1-2) +CONFIG_INTEGER(JitForceFallback, W("JitForceFallback"), 0) // Set to non-zero to test NOWAY assert by forcing a retry +CONFIG_INTEGER(JitForceVer, W("JitForceVer"), 0) +CONFIG_INTEGER(JitFullyInt, W("JitFullyInt"), 0) // Forces Fully interruptable code +CONFIG_INTEGER(JitFunctionTrace, W("JitFunctionTrace"), 0) // If non-zero, print JIT start/end logging +CONFIG_INTEGER(JitGCChecks, W("JitGCChecks"), 0) +CONFIG_INTEGER(JitGCInfoLogging, W("JitGCInfoLogging"), 0) // If true, prints GCInfo-related output to standard output. +CONFIG_INTEGER(JitHashBreak, W("JitHashBreak"), -1) // Same as JitBreak, but for a method hash +CONFIG_INTEGER(JitHashDump, W("JitHashDump"), -1) // Same as JitDump, but for a method hash +CONFIG_INTEGER(JitHashDumpIR, W("JitHashDumpIR"), -1) // Same as JitDumpIR, but for a method hash +CONFIG_INTEGER(JitHashHalt, W("JitHashHalt"), -1) // Same as JitHalt, but for a method hash +CONFIG_INTEGER(JitInlineAdditionalMultiplier, W("JitInlineAdditionalMultiplier"), 0) +CONFIG_INTEGER(JitInlinePrintStats, W("JitInlinePrintStats"), 0) +CONFIG_INTEGER(JitInlineSize, W("JITInlineSize"), DEFAULT_MAX_INLINE_SIZE) +CONFIG_INTEGER(JitLargeBranches, W("JitLargeBranches"), 0) // Force using the largest conditional branch format +CONFIG_INTEGER(JitMaxTempAssert, W("JITMaxTempAssert"), 1) +CONFIG_INTEGER(JitMaxUncheckedOffset, W("JitMaxUncheckedOffset"), 8) +CONFIG_INTEGER(JitMinOpts, W("JITMinOpts"), 0) // Forces MinOpts +CONFIG_INTEGER(JitMinOptsBbCount, W("JITMinOptsBbCount"), DEFAULT_MIN_OPTS_BB_COUNT) // Internal jit control of MinOpts +CONFIG_INTEGER(JitMinOptsCodeSize, W("JITMinOptsCodeSize"), DEFAULT_MIN_OPTS_CODE_SIZE) // Internal jit control of MinOpts +CONFIG_INTEGER(JitMinOptsInstrCount, W("JITMinOptsInstrCount"), DEFAULT_MIN_OPTS_INSTR_COUNT) // Internal jit control of MinOpts +CONFIG_INTEGER(JitMinOptsLvNumCount, W("JITMinOptsLvNumcount"), DEFAULT_MIN_OPTS_LV_NUM_COUNT) // Internal jit control of MinOpts +CONFIG_INTEGER(JitMinOptsLvRefCount, W("JITMinOptsLvRefcount"), DEFAULT_MIN_OPTS_LV_REF_COUNT) // Internal jit control of MinOpts +CONFIG_INTEGER(JitNoCMOV, W("JitNoCMOV"), 0) +CONFIG_INTEGER(JitNoCSE, W("JitNoCSE"), 0) +CONFIG_INTEGER(JitNoCSE2, W("JitNoCSE2"), 0) +CONFIG_INTEGER(JitNoForceFallback, W("JitNoForceFallback"), 0) // Set to non-zero to prevent NOWAY assert testing. Overrides COMPLUS_JitForceFallback and JIT stress flags. +CONFIG_INTEGER(JitNoHoist, W("JitNoHoist"), 0) +CONFIG_INTEGER(JitNoInline, W("JitNoInline"), 0) // Disables inlining of all methods +CONFIG_INTEGER(JitNoMemoryBarriers, W("JitNoMemoryBarriers"), 0) // If 1, don't generate memory barriers +CONFIG_INTEGER(JitNoRegLoc, W("JitNoRegLoc"), 0) +CONFIG_INTEGER(JitNoStructPromotion, W("JitNoStructPromotion"), 0) // Disables struct promotion in Jit32 +CONFIG_INTEGER(JitNoUnroll, W("JitNoUnroll"), 0) +CONFIG_INTEGER(JitOrder, W("JitOrder"), 0) +CONFIG_INTEGER(JitPInvokeCheckEnabled, W("JITPInvokeCheckEnabled"), 0) +CONFIG_INTEGER(JitPInvokeEnabled, W("JITPInvokeEnabled"), 1) +CONFIG_INTEGER(JitPrintInlinedMethods, W("JitPrintInlinedMethods"), 0) +CONFIG_INTEGER(JitRequired, W("JITRequired"), -1) +CONFIG_INTEGER(JitRoundFloat, W("JITRoundFloat"), DEFAULT_ROUND_LEVEL) +CONFIG_INTEGER(JitSkipArrayBoundCheck, W("JitSkipArrayBoundCheck"), 0) +CONFIG_INTEGER(JitSlowDebugChecksEnabled, W("JitSlowDebugChecksEnabled"), 1) // Turn on slow debug checks +CONFIG_INTEGER(JitSplitFunctionSize, W("JitSplitFunctionSize"), 0) // On ARM, use this as the maximum function/funclet size for creating function fragments (and creating multiple RUNTIME_FUNCTION entries) +CONFIG_INTEGER(JitSsaStress, W("JitSsaStress"), 0) // Perturb order of processing of blocks in SSA; 0 = no stress; 1 = use method hash; * = supplied value as random hash +CONFIG_INTEGER(JitStackChecks, W("JitStackChecks"), 0) +CONFIG_INTEGER(JitStress, W("JitStress"), 0) // Internal Jit stress mode: 0 = no stress, 2 = all stress, other = vary stress based on a hash of the method and this value +CONFIG_INTEGER(JitStressBBProf, W("JitStressBBProf"), 0) // Internal Jit stress mode +CONFIG_INTEGER(JitStressBiasedCSE, W("JitStressBiasedCSE"), 0x101) // Internal Jit stress mode: decimal bias value between (0,100) to perform CSE on a candidate. 100% = All CSEs. 0% = 0 CSE. (> 100) means no stress. +CONFIG_INTEGER(JitStressFP, W("JitStressFP"), 0) // Internal Jit stress mode +CONFIG_INTEGER(JitStressRegs, W("JitStressRegs"), 0) +CONFIG_INTEGER(JitStrictCheckForNonVirtualCallToVirtualMethod, W("JitStrictCheckForNonVirtualCallToVirtualMethod"), 1) +CONFIG_INTEGER(JitVNMapSelLimit, W("JitVNMapSelLimit"), 0) // If non-zero, assert if # of VNF_MapSelect applications considered reaches this +CONFIG_INTEGER(NgenHashDump, W("NgenHashDump"), -1) // same as JitHashDump, but for ngen +CONFIG_INTEGER(NgenHashDumpIR, W("NgenHashDumpIR"), -1) // same as JitHashDumpIR, but for ngen +CONFIG_INTEGER(NgenOrder, W("NgenOrder"), 0) +CONFIG_INTEGER(RunAltJitCode, W("RunAltJitCode"), 1) // If non-zero, and the compilation succeeds for an AltJit, then use the code. If zero, then we always throw away the generated code and fall back to the default compiler. +CONFIG_INTEGER(RunComponentUnitTests, W("JitComponentUnitTests"), 0) // Run JIT component unit tests +CONFIG_INTEGER(ShouldInjectFault, W("InjectFault"), 0) +CONFIG_INTEGER(StackProbesOverride, W("JitStackProbes"), 0) +CONFIG_INTEGER(StressCOMCall, W("StressCOMCall"), 0) +CONFIG_INTEGER(TailcallStress, W("TailcallStress"), 0) +CONFIG_INTEGER(TreesBeforeAfterMorph, W("JitDumpBeforeAfterMorph"), 0) // If 1, display each tree before/after morphing +CONFIG_METHODSET(JitBreak, W("JitBreak")) // Stops in the importer when compiling a specified method +CONFIG_METHODSET(JitDebugBreak, W("JitDebugBreak")) +CONFIG_METHODSET(JitDisasm, W("JitDisasm")) // Dumps disassembly for specified method +CONFIG_METHODSET(JitDump, W("JitDump")) // Dumps trees for specified method +CONFIG_METHODSET(JitDumpIR, W("JitDumpIR")) // Dumps trees (in linear IR form) for specified method +CONFIG_METHODSET(JitEHDump, W("JitEHDump")) // Dump the EH table for the method, as reported to the VM +CONFIG_METHODSET(JitExclude, W("JitExclude")) +CONFIG_METHODSET(JitForceProcedureSplitting, W("JitForceProcedureSplitting")) +CONFIG_METHODSET(JitGCDump, W("JitGCDump")) +CONFIG_METHODSET(JitHalt, W("JitHalt")) // Emits break instruction into jitted code +CONFIG_METHODSET(JitImportBreak, W("JitImportBreak")) +CONFIG_METHODSET(JitInclude, W("JitInclude")) +CONFIG_METHODSET(JitLateDisasm, W("JitLateDisasm")) +CONFIG_METHODSET(JitMinOptsName, W("JITMinOptsName")) // Forces MinOpts for a named function +CONFIG_METHODSET(JitNoProcedureSplitting, W("JitNoProcedureSplitting")) // Disallow procedure splitting for specified methods +CONFIG_METHODSET(JitNoProcedureSplittingEH, W("JitNoProcedureSplittingEH")) // Disallow procedure splitting for specified methods if they contain exception handling +CONFIG_METHODSET(JitStressOnly, W("JitStressOnly")) // Internal Jit stress mode: stress only the specified method(s) +CONFIG_METHODSET(JitUnwindDump, W("JitUnwindDump")) // Dump the unwind codes for the method +CONFIG_METHODSET(NgenDisasm, W("NgenDisasm")) // Same as JitDisasm, but for ngen +CONFIG_METHODSET(NgenDump, W("NgenDump")) // Same as JitDump, but for ngen +CONFIG_METHODSET(NgenDumpIR, W("NgenDumpIR")) // Same as JitDumpIR, but for ngen +CONFIG_METHODSET(NgenEHDump, W("NgenEHDump")) // Dump the EH table for the method, as reported to the VM +CONFIG_METHODSET(NgenGCDump, W("NgenGCDump")) +CONFIG_METHODSET(NgenUnwindDump, W("NgenUnwindDump")) // Dump the unwind codes for the method +CONFIG_STRING(JitDumpFg, W("JitDumpFg")) // Dumps Xml/Dot Flowgraph for specified method +CONFIG_STRING(JitDumpFgDir, W("JitDumpFgDir")) // Directory for Xml/Dot flowgraph dump(s) +CONFIG_STRING(JitDumpFgFile, W("JitDumpFgFile")) // Filename for Xml/Dot flowgraph dump(s) +CONFIG_STRING(JitDumpFgPhase, W("JitDumpFgPhase")) // Phase-based Xml/Dot flowgraph support. Set to the short name of a phase to see the flowgraph after that phase. Leave unset to dump after COLD-BLK (determine first cold block) or set to * for all phases +CONFIG_STRING(JitDumpIRFormat, W("JitDumpIRFormat")) // Comma separated format control for JitDumpIR, values = {types | locals | ssa | valnums | kinds | flags | nodes | nolists | nostmts | noleafs | trees | dataflow} +CONFIG_STRING(JitDumpIRPhase, W("JitDumpIRPhase")) // Phase control for JitDumpIR, values = {* | phasename} +CONFIG_STRING(JitLateDisasmTo, W("JITLateDisasmTo")) +CONFIG_STRING(JitRange, W("JitRange")) +CONFIG_STRING(JitStressModeNames, W("JitStressModeNames")) // Internal Jit stress mode: stress using the given set of stress mode names, e.g. STRESS_REGS, STRESS_TAILCALL +CONFIG_STRING(JitStressModeNamesNot, W("JitStressModeNamesNot")) // Internal Jit stress mode: do NOT stress using the given set of stress mode names, e.g. STRESS_REGS, STRESS_TAILCALL +CONFIG_STRING(JitStressRange, W("JitStressRange")) // Internal Jit stress mode +CONFIG_STRING(NgenDumpFg, W("NgenDumpFg")) // Ngen Xml Flowgraph support +CONFIG_STRING(NgenDumpFgDir, W("NgenDumpFgDir")) // Ngen Xml Flowgraph support +CONFIG_STRING(NgenDumpFgFile, W("NgenDumpFgFile")) // Ngen Xml Flowgraph support +CONFIG_STRING(NgenDumpIRFormat, W("NgenDumpIRFormat")) // Same as JitDumpIRFormat, but for ngen +CONFIG_STRING(NgenDumpIRPhase, W("NgenDumpIRPhase")) // Same as JitDumpIRPhase, but for ngen +#endif // defined(DEBUG) + +// AltJitAssertOnNYI should be 0 on targets where JIT is under developement or bring up stage, so as to facilitate fallback to main JIT on hitting a NYI. +#if defined(_TARGET_ARM64_) || defined(_TARGET_X86_) +CONFIG_INTEGER(AltJitAssertOnNYI, W("AltJitAssertOnNYI"), 0) // Controls the AltJit behavior of NYI stuff +#else // !defined(_TARGET_ARM64_) && !defined(_TARGET_X86_) +CONFIG_INTEGER(AltJitAssertOnNYI, W("AltJitAssertOnNYI"), 1) // Controls the AltJit behavior of NYI stuff +#endif // defined(_TARGET_ARM64_) || defined(_TARGET_X86_) + +#if defined(_TARGET_AMD64_) +CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Enable AVX instruction set for wide operations as default +#else // !defined(_TARGET_AMD64_) +CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 0) // Enable AVX instruction set for wide operations as default +#endif // defined(_TARGET_AMD64_) + +#if (!defined(DEBUG) && !defined(_DEBUG)) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) +CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 0) +#else // (defined(DEBUG) || defined(_DEBUG)) && (!defined(CROSSGEN_COMPILE) || defined(FEATURE_CORECLR)) +CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 1) +#endif // (!defined(DEBUG) && !defined(_DEBUG)) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) + +CONFIG_INTEGER(JitAggressiveInlining, W("JitAggressiveInlining"), 0) // Aggressive inlining of all methods +CONFIG_INTEGER(JitELTHookEnabled, W("JitELTHookEnabled"), 0) // On ARM, setting this will emit Enter/Leave/TailCall callbacks +CONFIG_INTEGER(JitInlineSIMDMultiplier, W("JitInlineSIMDMultiplier"), 3) + +#if defined(FEATURE_ENABLE_NO_RANGE_CHECKS) +CONFIG_INTEGER(JitNoRngChks, W("JitNoRngChks"), 0) // If 1, don't generate range checks +#endif // defined(FEATURE_ENABLE_NO_RANGE_CHECKS) + +CONFIG_INTEGER(JitRegisterFP, W("JitRegisterFP"), 3) // Control FP enregistration +CONFIG_INTEGER(JitTelemetry, W("JitTelemetry"), 1) // If non-zero, gather JIT telemetry data +CONFIG_INTEGER(JitVNMapSelBudget, W("JitVNMapSelBudget"), 100) // Max # of MapSelect's considered for a particular top-level invocation. +CONFIG_INTEGER(TailCallLoopOpt, W("TailCallLoopOpt"), 1) // Convert recursive tail calls to loops +CONFIG_METHODSET(AltJit, W("AltJit")) // Enables AltJit and selectively limits it to the specified methods. +CONFIG_METHODSET(AltJitNgen, W("AltJitNgen")) // Enables AltJit for NGEN and selectively limits it to the specified methods. + +#if defined(ALT_JIT) +CONFIG_STRING(AltJitExcludeAssemblies, W("AltJitExcludeAssemblies")) // Do not use AltJit on this semicolon-delimited list of assemblies. +#endif // defined(ALT_JIT) + +CONFIG_STRING(JitFuncInfoFile, W("JitFuncInfoLogFile")) // If set, gather JIT function info and write to this file. +CONFIG_STRING(JitTimeLogCsv, W("JitTimeLogCsv")) // If set, gather JIT throughput data and write to a CSV file. This mode must be used in internal retail builds. +CONFIG_STRING(TailCallOpt, W("TailCallOpt")) + +#undef CONFIG_INTEGER +#undef CONFIG_STRING +#undef CONFIG_METHODSET diff --git a/src/jit/jitpch.h b/src/jit/jitpch.h index a3c7e24464..58c9c6bd95 100644 --- a/src/jit/jitpch.h +++ b/src/jit/jitpch.h @@ -20,6 +20,7 @@ #include "corjithost.h" #include "jithost.h" #endif +#include "jitconfig.h" #include "jit.h" #include "iallocator.h" #include "hashbv.h" diff --git a/src/jit/jittelemetry.cpp b/src/jit/jittelemetry.cpp index cac324f6b2..1b79272991 100644 --- a/src/jit/jittelemetry.cpp +++ b/src/jit/jittelemetry.cpp @@ -158,8 +158,7 @@ void JitTelemetry::Initialize(Compiler* c) /* static */ bool JitTelemetry::IsTelemetryEnabled() { - static ConfigDWORD fJitTelemetry; - return fJitTelemetry.val(CLRConfig::EXTERNAL_JitTelemetry) != 0; + return JitConfig.JitTelemetry() != 0; } //------------------------------------------------------------------------ diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp index 9fbf0a9550..7541c36568 100644 --- a/src/jit/lsra.cpp +++ b/src/jit/lsra.cpp @@ -952,8 +952,7 @@ LinearScan::LinearScan(Compiler * theCompiler) initRefTypeNames(); // Get the value of the environment variable that controls stress for register allocation - static ConfigDWORD fJitStressRegs; - lsraStressMask = fJitStressRegs.val(CLRConfig::INTERNAL_JitStressRegs); + lsraStressMask = JitConfig.JitStressRegs(); #if 0 #ifdef DEBUG if (lsraStressMask != 0) @@ -990,8 +989,7 @@ LinearScan::LinearScan(Compiler * theCompiler) #endif // DEBUG #endif - static ConfigDWORD fJitDumpTerseLsra; - dumpTerse = (fJitDumpTerseLsra.val(CLRConfig::INTERNAL_JitDumpTerseLsra) != 0); + dumpTerse = (JitConfig.JitDumpTerseLsra() != 0); #endif // DEBUG refPositionCount = 0; diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 4591a03d41..016f432978 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -12854,8 +12854,7 @@ GenTreePtr Compiler::fgMorphTree(GenTreePtr tree, MorphAddrContext* mac #ifdef DEBUG if (verbose) { - static ConfigDWORD fBreakOnMorphTree; - if (fBreakOnMorphTree.val(CLRConfig::INTERNAL_JitBreakMorphTree) == tree->gtTreeID) + if ((unsigned)JitConfig.JitBreakMorphTree() == tree->gtTreeID) { noway_assert(!"JitBreakMorphTree hit"); } @@ -14240,8 +14239,7 @@ void Compiler::fgSetOptions() /* Should we force fully interruptible code ? */ #ifdef DEBUG - static ConfigDWORD fJitFullyInt; - if (fJitFullyInt.val(CLRConfig::INTERNAL_JitFullyInt) || + if (JitConfig.JitFullyInt() || compStressCompile(STRESS_GENERIC_VARN, 30)) { noway_assert(!codeGen->isGCTypeFixed()); diff --git a/src/jit/optcse.cpp b/src/jit/optcse.cpp index e1d78690fe..61f99047af 100644 --- a/src/jit/optcse.cpp +++ b/src/jit/optcse.cpp @@ -1290,9 +1290,8 @@ public: } // Obtain the bias value and reinterpret as decimal. - static ConfigDWORD fJitStressBiasedCSE; unsigned bias = ReinterpretHexAsDecimal( - fJitStressBiasedCSE.val(CLRConfig::INTERNAL_JitStressBiasedCSE)); + JitConfig.JitStressBiasedCSE()); // Invalid value, check if JitStress is ON. if (bias > 100) @@ -2286,8 +2285,7 @@ bool Compiler::optConfigDisableCSE(bool lexicalCSE) // Next check if COMPLUS_JitNoCSE is set and applies to this method // - static ConfigDWORD fJitNoCSE; - unsigned jitNoCSE = fJitNoCSE.val(CLRConfig::INTERNAL_JitNoCSE); + unsigned jitNoCSE = JitConfig.JitNoCSE(); if (jitNoCSE > 0) { @@ -2327,8 +2325,7 @@ bool Compiler::optConfigDisableCSE2() { static unsigned totalCSEcount = 0; - static ConfigDWORD fNoCSE2; - unsigned jitNoCSE2 = fNoCSE2.val(CLRConfig::INTERNAL_JitNoCSE2); + unsigned jitNoCSE2 = JitConfig.JitNoCSE2(); totalCSEcount++; diff --git a/src/jit/optimizer.cpp b/src/jit/optimizer.cpp index 3f6a8f656f..7cbc1c27de 100644 --- a/src/jit/optimizer.cpp +++ b/src/jit/optimizer.cpp @@ -17,8 +17,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #pragma warning ( disable : 4701 ) #endif -static ConfigDWORD fCloneLoops; - /*****************************************************************************/ #if COUNT_RANGECHECKS @@ -2697,8 +2695,7 @@ void Compiler::optUnrollLoops() return; #ifdef DEBUG - static ConfigDWORD fJitNoUnroll; - if (fJitNoUnroll.val(CLRConfig::INTERNAL_JitNoUnroll)) + if (JitConfig.JitNoUnroll()) { return; } @@ -4089,8 +4086,7 @@ bool Compiler::optComputeDerefConditions(unsigned loopNum, LoopCloneContext* con // void Compiler::optDebugLogLoopCloning(BasicBlock* block, GenTreePtr insertBefore) { - static ConfigDWORD fDebugLogLoopCloning; - if (fDebugLogLoopCloning.val(CLRConfig::INTERNAL_JitDebugLogLoopCloning) == 0) + if (JitConfig.JitDebugLogLoopCloning() == 0) { return; } @@ -4165,7 +4161,7 @@ bool Compiler::optCanCloneLoops() // Enabled for retail builds now. unsigned cloneLoopsFlag = 1; #ifdef DEBUG - cloneLoopsFlag = fCloneLoops.val(CLRConfig::INTERNAL_JitCloneLoops); + cloneLoopsFlag = JitConfig.JitCloneLoops(); #endif return (cloneLoopsFlag != 0); } @@ -5438,8 +5434,7 @@ void Compiler::optHoistLoopCode() return; #ifdef DEBUG - static ConfigDWORD fJitNoHoist; - unsigned jitNoHoist = fJitNoHoist.val(CLRConfig::INTERNAL_JitNoHoist); + unsigned jitNoHoist = JitConfig.JitNoHoist(); if (jitNoHoist > 0) { return; diff --git a/src/jit/regalloc.cpp b/src/jit/regalloc.cpp index da48a87256..63a3195e05 100644 --- a/src/jit/regalloc.cpp +++ b/src/jit/regalloc.cpp @@ -22,9 +22,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #if FEATURE_FP_REGALLOC Compiler::enumConfigRegisterFP Compiler::raConfigRegisterFP() { - static ConfigDWORD dwJitRegisterFP; - - DWORD val = dwJitRegisterFP.val(CLRConfig::EXTERNAL_JitRegisterFP); + DWORD val = JitConfig.JitRegisterFP(); return (enumConfigRegisterFP) (val & 0x3); } @@ -63,8 +61,7 @@ DWORD Compiler::getCanDoubleAlign() if (compStressCompile(STRESS_DBL_ALN, 20)) return MUST_DOUBLE_ALIGN; - static ConfigDWORD fJitDoubleAlign; - return fJitDoubleAlign.val_DontUse_(CLRConfig::INTERNAL_JitDoubleAlign, DEFAULT_DOUBLE_ALIGN); + return JitConfig.JitDoubleAlign(); #else return DEFAULT_DOUBLE_ALIGN; #endif @@ -6260,8 +6257,7 @@ void Compiler::rpPredictRegUse() #endif #ifdef DEBUG - static ConfigDWORD jitNoRegLoc; - BOOL fJitNoRegLoc = jitNoRegLoc.val(CLRConfig::INTERNAL_JitNoRegLoc); + BOOL fJitNoRegLoc = JitConfig.JitNoRegLoc(); if (fJitNoRegLoc) regAvail = RBM_NONE; #endif @@ -6395,8 +6391,7 @@ void Compiler::rpPredictRegUse() } #ifdef DEBUG - static ConfigDWORD fJitMaxRegAllocPasses; - if (fJitMaxRegAllocPasses.val(CLRConfig::INTERNAL_JitAssertOnMaxRAPasses)) + if (JitConfig.JitAssertOnMaxRAPasses()) { noway_assert(rpPasses < rpPassesMax && "This may not a bug, but dev team should look and see what is happening"); diff --git a/src/jit/regset.cpp b/src/jit/regset.cpp index 704c3f8b88..4d3efa3468 100644 --- a/src/jit/regset.cpp +++ b/src/jit/regset.cpp @@ -178,8 +178,7 @@ RegSet::rsStressRegsType RegSet::rsStressRegs() #ifndef LEGACY_BACKEND return RS_STRESS_NONE; #else // LEGACY_BACKEND - static ConfigDWORD fJitStressRegs; - rsStressRegsType val = (rsStressRegsType) fJitStressRegs.val(CLRConfig::INTERNAL_JitStressRegs); + rsStressRegsType val = (rsStressRegsType) JitConfig.JitStressRegs(); if (val == RS_STRESS_NONE && m_rsCompiler->compStressCompile(Compiler::STRESS_REGS, 15)) val = RS_PICK_BAD_REG; return val; #endif // LEGACY_BACKEND diff --git a/src/jit/sharedfloat.cpp b/src/jit/sharedfloat.cpp index db539d3dae..2864c54681 100644 --- a/src/jit/sharedfloat.cpp +++ b/src/jit/sharedfloat.cpp @@ -65,8 +65,7 @@ #ifdef DEBUG int CodeGenInterface::genStressFloat() { - static ConfigDWORD fJitStressRegs; - return compiler->compStressCompile(Compiler::STRESS_FLATFP, 40)?1:fJitStressRegs.val(CLRConfig::INTERNAL_JitStressFP); + return compiler->compStressCompile(Compiler::STRESS_FLATFP, 40)?1:JitConfig.JitStressFP(); } #endif diff --git a/src/jit/unwindarm.cpp b/src/jit/unwindarm.cpp index 4459a7253c..0852924aad 100644 --- a/src/jit/unwindarm.cpp +++ b/src/jit/unwindarm.cpp @@ -1595,8 +1595,7 @@ void UnwindInfo::Split() #ifdef DEBUG // Consider COMPLUS_JitSplitFunctionSize - static ConfigDWORD fJitSplitFunctionSize; - unsigned splitFunctionSize = (unsigned) fJitSplitFunctionSize.val(CLRConfig::INTERNAL_JitSplitFunctionSize); + unsigned splitFunctionSize = (unsigned) JitConfig.JitSplitFunctionSize(); if (splitFunctionSize != 0) if (splitFunctionSize < maxFragmentSize) diff --git a/src/jit/utils.cpp b/src/jit/utils.cpp index 85ccdb75c3..c38fc3ddc0 100644 --- a/src/jit/utils.cpp +++ b/src/jit/utils.cpp @@ -721,24 +721,18 @@ bool ConfigMethodRange::contains(ICorJitInfo* info, CORINFO_METHOD_HANDLE method } /**************************************************************************/ -void ConfigMethodRange::init(const CLRConfig::ConfigStringInfo & info) +void ConfigMethodRange::initRanges(const wchar_t* rangeStr) { // make sure that the memory was zero initialized _ASSERTE(m_inited == 0 || m_inited == 1); - LPWSTR str = CLRConfig::GetConfigValue(info); - initRanges(str); - CLRConfig::FreeConfigString(str); - m_inited = true; -} - -/**************************************************************************/ -void ConfigMethodRange::initRanges(__in_z LPCWSTR rangeStr) -{ - if (rangeStr == 0) + if (rangeStr == nullptr) + { + m_inited = true; return; + } - LPCWSTR p = rangeStr; + LPCWSTR p = const_cast<LPCWSTR>(rangeStr); unsigned char lastRange = 0; while (*p) { while (*p == ' ') //skip blanks @@ -767,6 +761,8 @@ void ConfigMethodRange::initRanges(__in_z LPCWSTR rangeStr) m_ranges[lastRange++] = MAX_RANGE; assert(lastRange < 100); m_lastRange = lastRange; + + m_inited = true; } #endif // DEBUG @@ -1412,7 +1408,7 @@ void HelperCallProperties::init() // MyAssembly;mscorlib;System // MyAssembly;mscorlib System -AssemblyNamesList2::AssemblyNamesList2(__in LPWSTR list, IAllocator* alloc) +AssemblyNamesList2::AssemblyNamesList2(const wchar_t* list, IAllocator* alloc) : m_alloc(alloc) { assert(m_alloc != nullptr); @@ -1421,7 +1417,7 @@ AssemblyNamesList2::AssemblyNamesList2(__in LPWSTR list, IAllocator* alloc) LPWSTR nameStart = nullptr; // start of the name currently being processed. nullptr if no current name AssemblyName** ppPrevLink = &m_pNames; - for (LPWSTR listWalk = list; prevChar != '\0'; prevChar = *listWalk, listWalk++) + for (LPWSTR listWalk = const_cast<LPWSTR>(list); prevChar != '\0'; prevChar = *listWalk, listWalk++) { WCHAR curChar = *listWalk; diff --git a/src/jit/utils.h b/src/jit/utils.h index 659c81623b..25ca684dc8 100644 --- a/src/jit/utils.h +++ b/src/jit/utils.h @@ -77,20 +77,19 @@ class ConfigMethodRange public: bool contains(class ICorJitInfo* info, CORINFO_METHOD_HANDLE method); - inline void ensureInit(const CLRConfig::ConfigStringInfo & info) + inline void ensureInit(const wchar_t* rangeStr) { // make sure that the memory was zero initialized _ASSERTE(m_inited == 0 || m_inited == 1); if (!m_inited) { - init(info); + initRanges(rangeStr); _ASSERTE(m_inited == 1); } } private: - void init(const CLRConfig::ConfigStringInfo & info); void initRanges(__in_z LPCWSTR rangeStr); private: @@ -426,7 +425,7 @@ class AssemblyNamesList2 public: // Take a Unicode string list of assembly names, parse it, and store it. - AssemblyNamesList2(__in LPWSTR list, __in IAllocator* alloc); + AssemblyNamesList2(const wchar_t* list, __in IAllocator* alloc); ~AssemblyNamesList2(); diff --git a/src/jit/valuenum.cpp b/src/jit/valuenum.cpp index 54ef578361..a1b3e9ef84 100644 --- a/src/jit/valuenum.cpp +++ b/src/jit/valuenum.cpp @@ -83,8 +83,7 @@ ValueNumStore::ValueNumStore(Compiler* comp, IAllocator* alloc) ChunkNum cn = m_chunks.Push(specialConstChunk); assert(cn == 0); - static ConfigDWORD fMapSelBudget; - m_mapSelectBudget = fMapSelBudget.val(CLRConfig::INTERNAL_JitVNMapSelBudget); + m_mapSelectBudget = JitConfig.JitVNMapSelBudget(); } // static. @@ -1243,8 +1242,7 @@ TailCall: // This printing is sometimes useful in debugging. // if ((m_numMapSels % 1000) == 0) printf("%d VNF_MapSelect applications.\n", m_numMapSels); #endif - static ConfigDWORD fMapSelLim; - unsigned selLim = fMapSelLim.val(CLRConfig::INTERNAL_JitVNMapSelLimit); + unsigned selLim = JitConfig.JitVNMapSelLimit(); assert(selLim == 0 || m_numMapSels < selLim); #endif ValueNum res; diff --git a/src/utilcode/jithost.cpp b/src/utilcode/jithost.cpp index 412cc47786..3174aa6188 100644 --- a/src/utilcode/jithost.cpp +++ b/src/utilcode/jithost.cpp @@ -41,7 +41,7 @@ int JitHost::getIntConfigValue(const wchar_t* name, int defaultValue) WRAPPER_NO_CONTRACT; // Translate JIT call into runtime configuration query - CLRConfig::ConfigDWORDInfo info{ name, defaultValue, CLRConfig::REGUTIL_default }; + CLRConfig::ConfigDWORDInfo info{ name, defaultValue, CLRConfig::EEConfig_default }; // Perform a CLRConfig look up on behalf of the JIT. return CLRConfig::GetConfigValue(info); @@ -52,7 +52,7 @@ const wchar_t* JitHost::getStringConfigValue(const wchar_t* name) WRAPPER_NO_CONTRACT; // Translate JIT call into runtime configuration query - CLRConfig::ConfigStringInfo info{ name, CLRConfig::REGUTIL_default }; + CLRConfig::ConfigStringInfo info{ name, CLRConfig::EEConfig_default }; // Perform a CLRConfig look up on behalf of the JIT. return CLRConfig::GetConfigValue(info); |