DWORD MyICJI::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes)
{
jitInstance->mc->cr->AddCall("getJitFlags");
- return jitInstance->mc->repGetJitFlags(jitFlags, sizeInBytes);
+ DWORD ret = jitInstance->mc->repGetJitFlags(jitFlags, sizeInBytes);
+ if (jitInstance->forceClearAltJitFlag)
+ {
+ jitFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT);
+ }
+ else if (jitInstance->forceSetAltJitFlag)
+ {
+ jitFlags->Set(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT);
+ }
+ return ret;
}
// Runs the given function with the given parameter under an error trap
}
jit->forceOptions = forceOptions;
-
jit->options = options;
+ // The flag to cause the JIT to be invoked as an altjit is stored in the jit flags, not in
+ // the environment. If the user uses the "-jitoption force" flag to force AltJit off (it was
+ // probably on during collection), or to force it on, then propagate that to the jit flags.
+ jit->forceClearAltJitFlag = false;
+ jit->forceSetAltJitFlag = false;
+ const WCHAR* altJitFlag = jit->getForceOption(W("AltJit"));
+ if (altJitFlag != nullptr)
+ {
+ if (wcscmp(altJitFlag, W("")) == 0)
+ {
+ jit->forceClearAltJitFlag = true;
+ }
+ else
+ {
+ jit->forceSetAltJitFlag = true;
+ }
+ }
+ const WCHAR* altJitNgenFlag = jit->getForceOption(W("AltJitNgen"));
+ if (altJitNgenFlag != nullptr)
+ {
+ if (wcscmp(altJitNgenFlag, W("")) == 0)
+ {
+ jit->forceClearAltJitFlag = true;
+ }
+ else
+ {
+ jit->forceSetAltJitFlag = true;
+ }
+ }
+
jit->environment.getIntConfigValue = nullptr;
jit->environment.getStingConfigValue = nullptr;
void timeResult(CORINFO_METHOD_INFO info, unsigned flags);
public:
+
+ bool forceClearAltJitFlag;
+ bool forceSetAltJitFlag;
+
enum Result
{
RESULT_ERROR,
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
-constexpr GUID JITEEVersionIdentifier = { /* a0184d06-a562-43f6-94ad-44627db87310 */
- 0xa0184d06,
- 0xa562,
- 0x43f6,
- {0x94, 0xad, 0x44, 0x62, 0x7d, 0xb8, 0x73, 0x10}
+constexpr GUID JITEEVersionIdentifier = { /* 8031aa05-4568-40fc-a0d2-d971d8edba16 */
+ 0x8031aa05,
+ 0x4568,
+ 0x40fc,
+ {0xa0, 0xd2, 0xd9, 0x71, 0xd8, 0xed, 0xba, 0x16}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
CORJIT_FLAG_OSR = 13, // Generate alternate method for On Stack Replacement
- CORJIT_FLAG_UNUSED7 = 14,
+ CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT
CORJIT_FLAG_UNUSED8 = 15,
CORJIT_FLAG_UNUSED9 = 16,
set(oneValueArgs TARGET OS ARCH)
set(multiValueArgs ADDITIONAL_DESTINATIONS)
- set(options NOALTJIT)
+ set(options)
cmake_parse_arguments(TARGETDETAILS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
set(JIT_ARCH_LINK_LIBRARIES gcinfo_${TARGETDETAILS_OS}_${TARGETDETAILS_ARCH})
set_target_definitions_to_custom_os_and_arch(${ARGN})
set_target_properties(${TARGETDETAILS_TARGET} PROPERTIES IGNORE_FEATURE_MERGE_JIT_AND_ENGINE TRUE)
- if (NOT TARGETDETAILS_NOALTJIT)
- target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE ALT_JIT)
- endif (NOT TARGETDETAILS_NOALTJIT)
-
target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE FEATURE_NO_HOST)
target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE SELF_NO_HOST)
if(FEATURE_READYTORUN)
set(TARGET_OS_NAME win)
endif()
-create_standalone_jit(TARGET clrjit OS ${TARGET_OS_NAME} ARCH ${ARCH_TARGET_NAME} NOALTJIT ADDITIONAL_DESTINATIONS sharedFramework)
+create_standalone_jit(TARGET clrjit OS ${TARGET_OS_NAME} ARCH ${ARCH_TARGET_NAME} ADDITIONAL_DESTINATIONS sharedFramework)
# Enable profile guided optimization
add_pgo(clrjit)
{
printf("; discarded IBC profile data due to mismatch in ILSize\n");
}
+
+ if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALT_JIT))
+ {
+ printf("; invoked as altjit\n");
+ }
}
#endif // DEBUG
LONG Compiler::jitNestingLevel = 0;
#endif // defined(DEBUG)
-#ifdef ALT_JIT
// static
bool Compiler::s_pAltJitExcludeAssembliesListInitialized = false;
AssemblyNamesList2* Compiler::s_pAltJitExcludeAssembliesList = nullptr;
-#endif // ALT_JIT
#ifdef DEBUG
// static
/* static */
void Compiler::compShutdown()
{
-#ifdef ALT_JIT
if (s_pAltJitExcludeAssembliesList != nullptr)
{
s_pAltJitExcludeAssembliesList->~AssemblyNamesList2(); // call the destructor
s_pAltJitExcludeAssembliesList = nullptr;
}
-#endif // ALT_JIT
#ifdef DEBUG
if (s_pJitDisasmIncludeAssembliesList != nullptr)
pfAltJit = &JitConfig.AltJit();
}
-#ifdef ALT_JIT
- if (pfAltJit->contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args))
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALT_JIT))
{
- opts.altJit = true;
- }
+ if (pfAltJit->contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args))
+ {
+ opts.altJit = true;
+ }
- unsigned altJitLimit = ReinterpretHexAsDecimal(JitConfig.AltJitLimit());
- if (altJitLimit > 0 && Compiler::jitTotalMethodCompiled >= altJitLimit)
- {
- opts.altJit = false;
+ unsigned altJitLimit = ReinterpretHexAsDecimal(JitConfig.AltJitLimit());
+ if (altJitLimit > 0 && Compiler::jitTotalMethodCompiled >= altJitLimit)
+ {
+ opts.altJit = false;
+ }
}
-#endif // ALT_JIT
#else // !DEBUG
altJitVal = JitConfig.AltJit().list();
}
-#ifdef ALT_JIT
- // In release mode, you either get all methods or no methods. You must use "*" as the parameter, or we ignore it.
- // 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 != nullptr) && (strcmp(altJitVal, "*") == 0))
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALT_JIT))
{
- opts.altJit = true;
+ // In release mode, you either get all methods or no methods. You must use "*" as the parameter, or we ignore
+ // it. 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 != nullptr) && (strcmp(altJitVal, "*") == 0))
+ {
+ opts.altJit = true;
+ }
}
-#endif // ALT_JIT
#endif // !DEBUG
-#ifdef ALT_JIT
// Take care of COMPlus_AltJitExcludeAssemblies.
if (opts.altJit)
{
}
}
}
-#endif // ALT_JIT
#ifdef DEBUG
compInitOptions(compileFlags);
-#ifdef ALT_JIT
- if (!compIsForInlining() && !opts.altJit)
+ if (!compIsForInlining() && !opts.altJit && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALT_JIT))
{
// We're an altjit, but the COMPlus_AltJit configuration did not say to compile this method,
// so skip it.
return CORJIT_SKIPPED;
}
-#endif // ALT_JIT
#ifdef DEBUG
return CORJIT_SKIPPED;
}
-#ifdef ALT_JIT
#ifdef DEBUG
- if (JitConfig.RunAltJitCode() == 0)
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALT_JIT) && JitConfig.RunAltJitCode() == 0)
{
return CORJIT_SKIPPED;
}
#endif // DEBUG
-#endif // ALT_JIT
}
/* Success! */
#endif
} opts;
-#ifdef ALT_JIT
static bool s_pAltJitExcludeAssembliesListInitialized;
static AssemblyNamesList2* s_pAltJitExcludeAssembliesList;
-#endif // ALT_JIT
#ifdef DEBUG
static bool s_pJitDisasmIncludeAssembliesListInitialized;
}
}
-#if defined(ALT_JIT)
-
/*****************************************************************************/
void notYetImplemented(const char* msg, const char* filename, unsigned line)
{
+ Compiler* pCompiler = JitTls::GetCompiler();
+ if ((pCompiler == nullptr) || (pCompiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALT_JIT)))
+ {
+ NOWAY_MSG_FILE_AND_LINE(msg, filename, line);
+ return;
+ }
#if FUNC_INFO_LOGGING
#ifdef DEBUG
LogEnv* env = JitTls::GetLogEnv();
#endif // FUNC_INFO_LOGGING
#ifdef DEBUG
- Compiler* pCompiler = JitTls::GetCompiler();
- if (pCompiler != nullptr)
- {
- // Assume we're within a compFunctionTrace boundary, which might not be true.
- pCompiler->compFunctionTraceEnd(nullptr, 0, true);
- }
+ // Assume we're within a compFunctionTrace boundary, which might not be true.
+ pCompiler->compFunctionTraceEnd(nullptr, 0, true);
#endif // DEBUG
DWORD value = JitConfig.AltJitAssertOnNYI();
}
}
-#endif // #if defined(ALT_JIT)
-
/*****************************************************************************/
LONG __JITfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam)
{
DebugBreak();
}
-#ifdef ALT_JIT
- // If we hit an assert, and we got here, it's either because the user hit "ignore" on the
- // dialog pop-up, or they set COMPlus_ContinueOnAssert=1 to not emit a pop-up, but just continue.
- // If we're an altjit, we have two options: (1) silently continue, as a normal JIT would, probably
- // leading to additional asserts, or (2) tell the VM that the AltJit wants to skip this function,
- // thus falling back to the fallback JIT. Setting COMPlus_AltJitSkipOnAssert=1 chooses this "skip"
- // 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).
- if (JitConfig.AltJitSkipOnAssert() != 0)
+ Compiler* comp = JitTls::GetCompiler();
+
+ if (comp != nullptr && comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALT_JIT))
{
- fatal(CORJIT_SKIPPED);
+ // If we hit an assert, and we got here, it's either because the user hit "ignore" on the
+ // dialog pop-up, or they set COMPlus_ContinueOnAssert=1 to not emit a pop-up, but just continue.
+ // If we're an altjit, we have two options: (1) silently continue, as a normal JIT would, probably
+ // leading to additional asserts, or (2) tell the VM that the AltJit wants to skip this function,
+ // thus falling back to the fallback JIT. Setting COMPlus_AltJitSkipOnAssert=1 chooses this "skip"
+ // 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).
+ if (JitConfig.AltJitSkipOnAssert() != 0)
+ {
+ fatal(CORJIT_SKIPPED);
+ }
}
-#endif
}
/*********************************************************************/
#define unreached() noWayAssertBody("unreached", __FILE__, __LINE__)
#define NOWAY_MSG(msg) noWayAssertBodyConditional(msg, __FILE__, __LINE__)
+#define NOWAY_MSG_FILE_AND_LINE(msg, file, line) noWayAssertBodyConditional(msg, file, line)
// IMPL_LIMITATION is called when we encounter valid IL that is not
// supported by our current implementation because of various
#define unreached() noWayAssertBody()
#define NOWAY_MSG(msg) noWayAssertBodyConditional(NOWAY_ASSERT_BODY_ARGUMENTS)
+#define NOWAY_MSG_FILE_AND_LINE(msg, file, line) noWayAssertBodyConditional(NOWAY_ASSERT_BODY_ARGUMENTS)
#endif // !DEBUG
#if 1 // All platforms currently enable NYI; this should be a tighter condition to exclude some platforms from NYI
-#if defined(ALT_JIT)
-
// This can return based on Config flag/Debugger
extern void notYetImplemented(const char* msg, const char* file, unsigned line);
#define NYIRAW(msg) notYetImplemented(msg, __FILE__, __LINE__)
-#else // !defined(ALT_JIT)
-
-#define NYIRAW(msg) NOWAY_MSG(msg)
-
-#endif // !defined(ALT_JIT)
-
#define NYI(msg) NYIRAW("NYI: " msg)
#define NYI_IF(cond, msg) if (cond) NYIRAW("NYI: " msg)
#endif
#endif
-#if (defined(ALT_JIT) && (defined(UNIX_AMD64_ABI) || defined(UNIX_X86_ABI)) && !defined(TARGET_UNIX))
-// If we are building an ALT_JIT targeting Unix, override the TARGET_<os> to TARGET_UNIX
-#undef TARGET_WINDOWS
-#define TARGET_UNIX
-#endif
-
// --------------------------------------------------------------------------------
// IMAGE_FILE_MACHINE_TARGET
// --------------------------------------------------------------------------------
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_INTEGER(JitMeasureIR, W("JitMeasureIR"), 0) // If set, measure the IR size after some phases and report it in
// the time log.
JIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement
- JIT_FLAG_UNUSED7 = 14,
+ JIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT
JIT_FLAG_UNUSED8 = 15,
JIT_FLAG_UNUSED9 = 16,
#endif
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT, JIT_FLAG_ALT_JIT);
+
#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64)
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD, JIT_FLAG_FEATURE_SIMD);
CORJIT_FLAG_UNUSED4 = 10,
CORJIT_FLAG_UNUSED5 = 11,
CORJIT_FLAG_UNUSED6 = 12,
- CORJIT_FLAG_UNUSED7 = 13,
+ CORJIT_FLAG_OSR = 13, // Generate alternate version for On Stack Replacement
+ CORJIT_FLAG_ALT_JIT = 14, // JIT should consider itself an ALT_JIT
CORJIT_FLAG_FEATURE_SIMD = 17,
CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter.
CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation
builder.Add(new KeyValuePair<string, string>(name, value));
}
- // As we always use an AltJit to compile, tell the jit to always generate code
- builder.Add(new KeyValuePair<string, string>("AltJitNgen", "*"));
-
_ryujitOptions = builder.ToArray();
return this;
uint64_t corJitFlags;
};
-static const GUID JITEEVersionIdentifier = { /* a0184d06-a562-43f6-94ad-44627db87310 */
- 0xa0184d06,
- 0xa562,
- 0x43f6,
- {0x94, 0xad, 0x44, 0x62, 0x7d, 0xb8, 0x73, 0x10}
+static const GUID JITEEVersionIdentifier ={ /* 8031aa05-4568-40fc-a0d2-d971d8edba16 */
+ 0x8031aa05,
+ 0x4568,
+ 0x40fc,
+ {0xa0, 0xd2, 0xd9, 0x71, 0xd8, 0xed, 0xba, 0x16}
};
class Jit
CorJitResult ret = CORJIT_SKIPPED; // Note that CORJIT_SKIPPED is an error exit status code
- comp->setJitFlags(jitFlags);
-
#ifdef FEATURE_STACK_SAMPLING
static ConfigDWORD s_stackSamplingEnabled;
bool samplingEnabled = (s_stackSamplingEnabled.val(CLRConfig::UNSUPPORTED_StackSamplingEnabled) != 0);
#endif
)
{
+ CORJIT_FLAGS altJitFlags = jitFlags;
+ altJitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT);
+ comp->setJitFlags(altJitFlags);
ret = jitMgr->m_alternateJit->compileMethod( comp,
info,
CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
}
}
#endif // defined(ALLOW_SXS_JIT) && !defined(CROSSGEN_COMPILE)
+ comp->setJitFlags(jitFlags);
#ifdef FEATURE_INTERPRETER
static ConfigDWORD s_InterpreterFallback;
//
if (m_zapper->m_alternateJit)
{
+ m_jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT);
res = m_zapper->m_alternateJit->compileMethod( this,
&m_currentMethodInfo,
CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
ResetForJitRetry();
}
}
+ m_jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_ALT_JIT);
#endif // ALLOW_SXS_JIT_NGEN