From: Sergey Andreenko Date: Mon, 17 Sep 2018 21:59:07 +0000 (-0700) Subject: Fix spmi environment reset. (dotnet/coreclr#19943) X-Git-Tag: submit/tizen/20210909.063632~11030^2~3902 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=53ec973a4a16d59cd647f93fc2ec9d9347bedac8;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Fix spmi environment reset. (dotnet/coreclr#19943) * Dump spmi string environment variables with -d key. Sometimes it is not clear which environment variables are set during a replay. Add a possibility to dump all active string environment variables with "-v d" key. It is especially useful when you debug one method and can't get output that you want (for example JitDump) because altJit was set during the collection. * Dump int spmi environment variables with -d key. The same change but for int variables that need an additional parsing. * Fix environment reset in spmi. The previous changes revealed that we have a problem with environment reset. The reset was added in dotnet/coreclr#13596 to support a correct replay of mch files with mc that had different env variables during the collection. It was based on Environment that was later deprecated by dotnet/coreclr#13110. That caused the environment to be reset for each mc file. The fix updates env only when it is necessary and decreases the replay time of an mch file with 200000 methods from 500s to 370s. * Fix dumpHelp. Fix formating and adds note that all keys and values are case sensetive. * Delete retired packages logic. These packages were retired a long time ago and there is no value to have a special logic for them. Commit migrated from https://github.com/dotnet/coreclr/commit/1df22d9d8970215b99f96691336b9b49a223ec1b --- diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/lwmlist.h index df9f435..779a9b6 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -42,7 +42,6 @@ LWM(EmbedGenericHandle, Agnostic_EmbedGenericHandle, Agnostic_CORINFO_GENERICHAN LWM(EmbedMethodHandle, DWORDLONG, DLDL) LWM(EmbedModuleHandle, DWORDLONG, DLDL) DENSELWM(EmptyStringLiteral, DLD) -DENSELWM(Environment, Agnostic_Environment) DENSELWM(ErrorList, DWORD) LWM(FilterException, DWORD, DWORD) LWM(FindCallSiteSig, Agnostic_FindCallSiteSig, Agnostic_CORINFO_SIG_INFO) diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 97be26f..7dd7d15 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -17,26 +17,6 @@ #include "spmirecordhelper.h" #include "spmidumphelper.h" -struct -{ - int packetID; - const char* message; -} retiredPackets[] = { - {6, "CanEmbedModuleHandleForHelper id 6 superseded by GetLazyStringLiteralHelper id 147 on 12/20/2013"}, - {13, "CheckMethodModifier id 13 superseded by id 142 on 2013/07/04. Re-record input with newer shim."}, - {14, "CompileMethod id 14 superseded by id 141 on 2013/07/03. Re-record input with newer shim."}, - {24, "FindNameOfToken id 24 superseded by id 145 on 2013/07/19. Re-record input with newer shim. Adjusted members " - "to be proper."}, - {28, "GetArgClass id 28 superseded by id 139 on 2013/07/03. Re-record input with newer shim."}, - {30, "GetArgType id 30 superseded by id 140 on 2013/07/03. Re-record input with newer shim."}, - {93, "GetUnBoxHelper2 id 93 unused. 2016/02/19. Re-record input with newer shim."}, - {104, "IsValidToken id 104 superseded by id 144 on 2013/07/19. Re-record input with newer shim. Adjusted members " - "to be proper."}, - {141, "CompileMethod id 141 superseded by id 142 on 2013/07/09. Re-record input with newer shim. We basically " - "reset lots of other stuff too. :-)"}, -}; -int retiredPacketCount = 7; - #define sparseMC // Support filling in details where guesses are okay and will still generate good code. (i.e. helper // function addresses) @@ -306,7 +286,7 @@ void MethodContext::MethodInitHelper(unsigned char* buff2, unsigned int totalLen while (buffIndex < totalLen) { - unsigned char packetType = buff2[buffIndex++]; + mcPackets packetType = (mcPackets)buff2[buffIndex++]; memcpy(&localsize, &buff2[buffIndex], sizeof(unsigned int)); buffIndex += 4; @@ -321,11 +301,6 @@ void MethodContext::MethodInitHelper(unsigned char* buff2, unsigned int totalLen #include "crlwmlist.h" default: - for (int i = 0; i < retiredPacketCount; i++) - { - AssertCodeMsg(retiredPackets[i].packetID != packetType, EXCEPTIONCODE_MC, - "Ran into retired packet %u '%s'", packetType, retiredPackets[i].message); - } LogException(EXCEPTIONCODE_MC, "Read ran into unknown packet type %u. Are you using a newer recorder?", packetType); // break; @@ -496,10 +471,6 @@ void MethodContext::recGlobalContext(const MethodContext& other) } } -void MethodContext::dmpEnvironment(DWORD key, const Agnostic_Environment& value) -{ -} - void MethodContext::dumpToConsole(int mcNumber) { printf("*****************************************"); @@ -6290,52 +6261,157 @@ OnError: #endif // !FEATURE_PAL } -DenseLightWeightMap* MethodContext::prevEnviroment = nullptr; +MethodContext::Environment MethodContext::cloneEnvironment() +{ + MethodContext::Environment env; + if (GetIntConfigValue != nullptr) + { + env.getIntConfigValue = new LightWeightMap(*GetIntConfigValue); + } + if (GetStringConfigValue != nullptr) + { + env.getStingConfigValue = new LightWeightMap(*GetStringConfigValue); + } + return env; +} -bool MethodContext::wasEnviromentChanged() +// Check that there is a difference between the current enviroment variables maps and the prevEnv. +bool MethodContext::WasEnvironmentChanged(const Environment& prevEnv) { - bool changed = false; - if (prevEnviroment == nullptr) + if (!IsEnvironmentHeaderEqual(prevEnv)) { - changed = true; + return true; } - else if (Environment->GetCount() != prevEnviroment->GetCount()) + if (!IsEnvironmentContentEqual(prevEnv)) { - changed = true; + return true; } - else + return false; +} + +// Check that environment maps headers are equal to the prevEnv maps headers. +bool MethodContext::IsEnvironmentHeaderEqual(const Environment& prevEnv) +{ + if (!AreLWMHeadersEqual(prevEnv.getIntConfigValue, GetIntConfigValue)) + { + return false; + } + if (!AreLWMHeadersEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) + { + return false; + } + return true; +} + +// Check that environment maps content is equal to the prevEnv content. +bool MethodContext::IsEnvironmentContentEqual(const Environment& prevEnv) +{ + if (!IsIntConfigContentEqual(prevEnv.getIntConfigValue, GetIntConfigValue)) + { + return false; + } + if (!IsStringContentEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) + { + return false; + } + return true; +} + +// Check pointers to be both initizlized or null and number of keys to be equal. +template +bool MethodContext::AreLWMHeadersEqual(LightWeightMap* prev, LightWeightMap* curr) +{ + if (prev == nullptr && curr == nullptr) + { + return true; + } + if (prev != nullptr && curr != nullptr) { - for (unsigned int i = 0; i < Environment->GetCount(); i++) + if (prev->GetCount() == curr->GetCount()) { - Agnostic_Environment currEnvValue = Environment->Get(i); - LPCSTR currKey = (LPCSTR)Environment->GetBuffer(currEnvValue.name_index); - LPCSTR currVal = (LPCSTR)Environment->GetBuffer(currEnvValue.val_index); - - Agnostic_Environment prevEnvValue = prevEnviroment->Get(i); - LPCSTR prevKey = (LPCSTR)prevEnviroment->GetBuffer(prevEnvValue.name_index); - LPCSTR prevVal = (LPCSTR)prevEnviroment->GetBuffer(prevEnvValue.val_index); - if (strcmp(currKey, prevKey) != 0 || strcmp(currVal, prevVal) != 0) - { - changed = true; - break; - } + return true; } } - if (changed) + return false; +} + +bool MethodContext::IsIntConfigContentEqual(LightWeightMap* prev, + LightWeightMap* curr) +{ + if (prev != nullptr && curr != nullptr) { - if (prevEnviroment != nullptr) + if (prev->GetCount() != curr->GetCount()) { - delete prevEnviroment; + return false; } - if (Environment != nullptr) + + for (unsigned i = 0; i < prev->GetCount(); ++i) { - prevEnviroment = new DenseLightWeightMap(*Environment); + DWORD currValue = curr->GetItem(i); + DWORD prevValue = prev->GetItem(i); + if (currValue != prevValue) + { + return false; + } + + Agnostic_ConfigIntInfo currKey = curr->GetKey(i); + Agnostic_ConfigIntInfo prevKey = prev->GetKey(i); + + if (currKey.defaultValue != prevKey.defaultValue) + { + return false; + } + + DWORD currNameIndex = currKey.nameIndex; + LPCSTR currName = (LPCSTR)curr->GetBuffer(currNameIndex); + DWORD prevNameIndex = prevKey.nameIndex; + LPCSTR prevName = (LPCSTR)prev->GetBuffer(currNameIndex); + if (strcmp(currName, prevName) != 0) + { + return false; + } } - else + return true; + } + else + { + return (prev == curr); + } +} + +bool MethodContext::IsStringContentEqual(LightWeightMap* prev, LightWeightMap* curr) +{ + if (prev != nullptr && curr != nullptr) + { + if (prev->GetCount() != curr->GetCount()) + { + return false; + } + + for (unsigned i = 0; i < curr->GetCount(); ++i) { - prevEnviroment = nullptr; + DWORD currKeyIndex = curr->GetKey(i); + LPCSTR currKey = (LPCSTR)curr->GetBuffer(currKeyIndex); + DWORD prevKeyIndex = prev->GetKey(i); + LPCSTR prevKey = (LPCSTR)prev->GetBuffer(prevKeyIndex); + if (strcmp(currKey, prevKey) != 0) + { + return false; + } + + DWORD currValueIndex = curr->GetItem(i); + LPCSTR currValue = (LPCSTR)curr->GetBuffer(currValueIndex); + DWORD prevValueIndex = prev->GetItem(i); + LPCSTR prevValue = (LPCSTR)prev->GetBuffer(prevValueIndex); + if (strcmp(currValue, prevValue) != 0) + { + return false; + } } return true; } - return false; + else + { + return (prev == curr); + } } diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h index 739c1b2..0a71c8d 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -1275,14 +1275,34 @@ public: void dmpGetStringConfigValue(DWORD nameIndex, DWORD result); const wchar_t* repGetStringConfigValue(const wchar_t* name); - bool wasEnviromentChanged(); - static DenseLightWeightMap* prevEnviroment; + struct Environment + { + Environment() : getIntConfigValue(nullptr), getStingConfigValue(nullptr) + { + } + + LightWeightMap* getIntConfigValue; + LightWeightMap* getStingConfigValue; + }; + + Environment cloneEnvironment(); + + bool WasEnvironmentChanged(const Environment& prevEnv); CompileResult* cr; CompileResult* originalCR; int index; private: + bool IsEnvironmentHeaderEqual(const Environment& prevEnv); + bool IsEnvironmentContentEqual(const Environment& prevEnv); + + template + static bool AreLWMHeadersEqual(LightWeightMap* prev, LightWeightMap* curr); + static bool IsIntConfigContentEqual(LightWeightMap* prev, + LightWeightMap* curr); + static bool IsStringContentEqual(LightWeightMap* prev, LightWeightMap* curr); + #define LWM(map, key, value) LightWeightMap* map; #define DENSELWM(map, value) DenseLightWeightMap* map; #include "lwmlist.h" @@ -1322,7 +1342,7 @@ enum mcPackets Packet_EmbedMethodHandle = 19, Packet_EmbedModuleHandle = 20, Packet_EmptyStringLiteral = 21, - Packet_Environment = 136, // Deprecated 7/29/2017 + Retired9 = 136, Packet_ErrorList = 22, Packet_FilterException = 134, Packet_FindCallSiteSig = 23, diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp index ad9c126..84fdd6c 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontextreader.cpp @@ -122,10 +122,6 @@ MethodContextReader::MethodContextReader( MethodContextReader::~MethodContextReader() { - if (MethodContext::prevEnviroment != nullptr) - { - delete MethodContext::prevEnviroment; - } if (fileHandle != INVALID_HANDLE_VALUE) { CloseHandle(this->fileHandle); diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi/commandline.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi/commandline.cpp index 78af8cb..372ee84 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi/commandline.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi/commandline.cpp @@ -120,14 +120,14 @@ void CommandLine::DumpHelp(const char* program) #endif // USE_COREDISTOOLS printf("\n"); printf(" -jitoption [force] key=value\n"); - printf(" Set the JIT option named \"key\" to \"value\" for JIT 1 if the option was not set."); - printf(" With optional force flag overwrites the existing value if it was already set. NOTE: do not use a " - "\"COMPlus_\" prefix!\n"); + printf(" Set the JIT option named \"key\" to \"value\" for JIT 1 if the option was not set.\n"); + printf(" With optional force flag overwrites the existing value if it was already set.\n"); + printf(" NOTE: do not use a \"COMPlus_\" prefix, \"key\" and \"value\" are case sensitive!\n"); printf("\n"); printf(" -jit2option [force] key=value\n"); - printf(" Set the JIT option named \"key\" to \"value\" for JIT 2 if the option was not set."); - printf(" With optional force flag overwrites the existing value if it was already set. NOTE: do not use a " - "\"COMPlus_\" prefix!\n"); + printf(" Set the JIT option named \"key\" to \"value\" for JIT 2 if the option was not set.\n"); + printf(" With optional force flag overwrites the existing value if it was already set.\n"); + printf(" NOTE: do not use a \"COMPlus_\" prefix, \"key\" and \"value\" are case sensitive!\n"); printf("\n"); printf("Inputs are case sensitive.\n"); printf("\n"); diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.cpp index ef2d46e..520c793 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.cpp @@ -61,71 +61,90 @@ void JitHost::freeMemory(void* block) InitIEEMemoryManager(&jitInstance)->ClrVirtualFree(block, 0, 0); } +bool JitHost::convertStringValueToInt(const wchar_t* key, const wchar_t* stringValue, int& result) +{ + if (stringValue == nullptr) + { + return false; + } + + wchar_t* endPtr; + unsigned long longResult = wcstoul(stringValue, &endPtr, 16); + bool succeeded = (errno != ERANGE) && (endPtr != stringValue) && (longResult <= INT_MAX); + if (!succeeded) + { + LogWarning("Can't convert int config value from string, key: %ws, string value: %ws\n", key, stringValue); + return false; + } + + result = static_cast(longResult); + return true; +} + int JitHost::getIntConfigValue(const wchar_t* key, int defaultValue) { jitInstance.mc->cr->AddCall("getIntConfigValue"); + // First check the force options, then the mc value. If value is not presented there, probe the JIT options, then + // check + // the special cases and then the environment. + int result = defaultValue; - const wchar_t* forceValue = jitInstance.getForceOption(key); + bool valueFound; - if (forceValue != nullptr) + valueFound = convertStringValueToInt(key, jitInstance.getForceOption(key), result); + + if (!valueFound) { - wchar_t* endPtr; - result = static_cast(wcstoul(forceValue, &endPtr, 16)); - bool succeeded = (errno != ERANGE) && (endPtr != forceValue); - if (succeeded) + // Right now we can't distinguish between the default value that was set explicitly and the default value + // from the key that was not set. See comments in CLRConfig::GetConfigValue. + result = jitInstance.mc->repGetIntConfigValue(key, defaultValue); + if (result != defaultValue) { - return result; + valueFound = true; } } - result = jitInstance.mc->repGetIntConfigValue(key, defaultValue); - - if (result != defaultValue) + if (!valueFound) { - return result; + // Look for special case keys. + if (wcscmp(key, W("SuperPMIMethodContextNumber")) == 0) + { + result = jitInstance.mc->index; + valueFound = true; + } } - // Look for special case keys. - if (wcscmp(key, W("SuperPMIMethodContextNumber")) == 0) + if (!valueFound) { - return jitInstance.mc->index; + valueFound = convertStringValueToInt(key, jitInstance.getOption(key), result); } - // If the result is the default value, probe the JIT options and then the environment. If a value is found, parse - // it as a hex integer. - - const wchar_t* value = jitInstance.getOption(key); - - bool succeeded; - if (value != nullptr) + if (!valueFound) { - wchar_t* endPtr; - result = static_cast(wcstoul(value, &endPtr, 16)); - succeeded = (errno != ERANGE) && (endPtr != value); - } - else - { - wchar_t* complus = GetCOMPlusVariable(key, jitInstance); - if (complus == nullptr) + wchar_t* complusVar = GetCOMPlusVariable(key, jitInstance); + valueFound = convertStringValueToInt(key, complusVar, result); + if (complusVar != nullptr) { - return defaultValue; + jitInstance.freeLongLivedArray(complusVar); } - wchar_t* endPtr; - result = static_cast(wcstoul(complus, &endPtr, 16)); - succeeded = (errno != ERANGE) && (endPtr != complus); - jitInstance.freeLongLivedArray(complus); } - return succeeded ? result : defaultValue; + if (valueFound) + { + LogDebug("Environment variable %ws=%d", key, result); + } + + return valueFound ? result : defaultValue; } const wchar_t* JitHost::getStringConfigValue(const wchar_t* key) { jitInstance.mc->cr->AddCall("getStringConfigValue"); - const wchar_t* result = nullptr; + bool needToDup = true; + const wchar_t* result = nullptr; // First check the force options, then mc value. If value is not presented there, probe the JIT options and then the // environment. @@ -140,18 +159,28 @@ const wchar_t* JitHost::getStringConfigValue(const wchar_t* key) if (result == nullptr) { result = jitInstance.getOption(key); - if (result == nullptr) - { - return GetCOMPlusVariable(key, jitInstance); - } } - // Now we need to dup it, so you can call freeStringConfigValue() on what we return. - size_t resultLenInChars = wcslen(result) + 1; - wchar_t* dupResult = (wchar_t*)jitInstance.allocateLongLivedArray((ULONG)(sizeof(wchar_t) * resultLenInChars)); - wcscpy_s(dupResult, resultLenInChars, result); + if (result == nullptr) + { + result = GetCOMPlusVariable(key, jitInstance); + needToDup = false; + } - return dupResult; + if (result != nullptr && needToDup) + { + // Now we need to dup it, so you can call freeStringConfigValue() on what we return. + size_t resultLenInChars = wcslen(result) + 1; + wchar_t* dupResult = (wchar_t*)jitInstance.allocateLongLivedArray((ULONG)(sizeof(wchar_t) * resultLenInChars)); + wcscpy_s(dupResult, resultLenInChars, result); + result = dupResult; + } + + if (result != nullptr) + { + LogDebug("Environment variable %ws=%ws", key, result); + } + return result; } void JitHost::freeStringConfigValue(const wchar_t* value) diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.h b/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.h index 6391fc1..5bb1abd 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.h +++ b/src/coreclr/src/ToolBox/superpmi/superpmi/jithost.h @@ -14,6 +14,8 @@ public: #include "icorjithostimpl.h" private: + bool convertStringValueToInt(const wchar_t* key, const wchar_t* stringValue, int& result); + JitInstance& jitInstance; }; diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.cpp index 3333567..9f904a6 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -30,6 +30,9 @@ JitInstance* JitInstance::InitJit(char* nameOfJit, jit->options = options; + jit->environment.getIntConfigValue = nullptr; + jit->environment.getStingConfigValue = nullptr; + if (st1 != nullptr) st1->Start(); HRESULT hr = jit->StartUp(nameOfJit, false, breakOnAssert, firstContext); @@ -500,6 +503,9 @@ bool JitInstance::callJitStartup(ICorJitHost* jithost) } PAL_ENDTRY + Assert(environment.getIntConfigValue == nullptr && environment.getStingConfigValue == nullptr); + environment = mc->cloneEnvironment(); + return param.result; } @@ -511,6 +517,18 @@ bool JitInstance::resetConfig(MethodContext* firstContext) return false; } + if (environment.getIntConfigValue != nullptr) + { + delete environment.getIntConfigValue; + environment.getIntConfigValue = nullptr; + } + + if (environment.getStingConfigValue != nullptr) + { + delete environment.getStingConfigValue; + environment.getStingConfigValue = nullptr; + } + mc = firstContext; ICorJitHost* newHost = new JitHost(*this); @@ -523,3 +541,8 @@ bool JitInstance::resetConfig(MethodContext* firstContext) jitHost = newHost; return true; } + +const MethodContext::Environment& JitInstance::getEnvironment() +{ + return environment; +} diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.h b/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.h index e7b5fdb..f925e14 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.h +++ b/src/coreclr/src/ToolBox/superpmi/superpmi/jitinstance.h @@ -28,6 +28,8 @@ private: LightWeightMap* forceOptions; LightWeightMap* options; + MethodContext::Environment environment; + JitInstance(){}; void timeResult(CORINFO_METHOD_INFO info, unsigned flags); @@ -64,6 +66,8 @@ public: const wchar_t* getOption(const wchar_t* key); const wchar_t* getOption(const wchar_t* key, LightWeightMap* options); + const MethodContext::Environment& getEnvironment(); + void* allocateArray(ULONG size); void* allocateLongLivedArray(ULONG size); void freeArray(void* array); diff --git a/src/coreclr/src/ToolBox/superpmi/superpmi/superpmi.cpp b/src/coreclr/src/ToolBox/superpmi/superpmi/superpmi.cpp index 5e80854..558185a 100644 --- a/src/coreclr/src/ToolBox/superpmi/superpmi/superpmi.cpp +++ b/src/coreclr/src/ToolBox/superpmi/superpmi/superpmi.cpp @@ -329,7 +329,7 @@ int __cdecl main(int argc, char* argv[]) mc->cr = new CompileResult(); mc->originalCR = crl; - if (mc->wasEnviromentChanged()) + if (mc->WasEnvironmentChanged(jit->getEnvironment())) { if (!jit->resetConfig(mc)) {