From d3b8751930693d7df2b6567ff113ddb544f765b9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 30 Sep 2026 10:41:27 -0700 Subject: [PATCH 1/2] Skip interpreter selection when dynamic compilation is unavailable Guard interpreter-versus-JIT selection and module tracking with FEATURE_DYNAMIC_CODE_COMPILED. Retain invalid InterpMode rejection for interpreter-only builds and preserve JIT-enabled selection behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/coreclr/interpreter/eeinterp.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/coreclr/interpreter/eeinterp.cpp b/src/coreclr/interpreter/eeinterp.cpp index 111dca4b03dc89..d417ee6ac622dd 100644 --- a/src/coreclr/interpreter/eeinterp.cpp +++ b/src/coreclr/interpreter/eeinterp.cpp @@ -60,7 +60,9 @@ extern "C" INTERP_API ICorJitCompiler* getJit() } +#if defined(FEATURE_DYNAMIC_CODE_COMPILED) static CORINFO_MODULE_HANDLE g_interpModule = NULL; +#endif // FEATURE_DYNAMIC_CODE_COMPILED //**************************************************************************** CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd, @@ -70,9 +72,17 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd, uint32_t* nativeSizeOfCode) { - bool doInterpret = false; ArenaAllocatorWithDestructorT arenaAllocator; +#if !defined(FEATURE_DYNAMIC_CODE_COMPILED) + // Without a JIT, all valid modes must use the interpreter. + if (static_cast(InterpConfig.InterpMode()) > 3) + { + NO_WAY("Unsupported value for DOTNET_InterpMode"); + } +#else + bool doInterpret = false; + if ((g_interpModule != NULL) && (methodInfo->scope == g_interpModule)) doInterpret = true; @@ -108,10 +118,6 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd, break; } -#if !defined(FEATURE_DYNAMIC_CODE_COMPILED) - // interpret everything when we do not have a JIT - doInterpret = true; -#else // NOTE: We do this check even if doInterpret==true in order to populate g_interpModule const char *methodName = compHnd->getMethodNameFromMetadata(methodInfo->ftn, nullptr, nullptr, nullptr, 0); if (InterpConfig.Interpreter().contains(compHnd, methodInfo->ftn, compHnd->getMethodClass(methodInfo->ftn), &methodInfo->args)) @@ -119,13 +125,13 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd, doInterpret = true; g_interpModule = methodInfo->scope; } -#endif } if (!doInterpret) { return CORJIT_SKIPPED; } +#endif // FEATURE_DYNAMIC_CODE_COMPILED try { From cb43740d711703da8031350872c00492b9884ab9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 1 Oct 2026 14:10:39 -0700 Subject: [PATCH 2/2] Remove InterpMode validation from interpreter-only builds Keep mode selection and validation within FEATURE_DYNAMIC_CODE_COMPILED, avoiding unnecessary mode checks when JIT fallback is unavailable. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/coreclr/interpreter/eeinterp.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/coreclr/interpreter/eeinterp.cpp b/src/coreclr/interpreter/eeinterp.cpp index d417ee6ac622dd..e485b50f59f07b 100644 --- a/src/coreclr/interpreter/eeinterp.cpp +++ b/src/coreclr/interpreter/eeinterp.cpp @@ -74,13 +74,7 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd, ArenaAllocatorWithDestructorT arenaAllocator; -#if !defined(FEATURE_DYNAMIC_CODE_COMPILED) - // Without a JIT, all valid modes must use the interpreter. - if (static_cast(InterpConfig.InterpMode()) > 3) - { - NO_WAY("Unsupported value for DOTNET_InterpMode"); - } -#else +#if defined(FEATURE_DYNAMIC_CODE_COMPILED) bool doInterpret = false; if ((g_interpModule != NULL) && (methodInfo->scope == g_interpModule))