From ec357438ba537e30005b2189daeea75e95e4255b Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 5 Feb 2026 14:56:58 +0200 Subject: [PATCH 1/5] Make clr + crossgen2 ioslike via --clrnodynamiccodegen --- eng/build.ps1 | 3 +++ eng/build.sh | 7 +++++++ src/coreclr/clr.featuredefines.props | 1 + src/coreclr/clrdefinitions.cmake | 1 + src/coreclr/clrfeatures.cmake | 12 ++++++++---- src/coreclr/inc/clrconfigvalues.h | 8 ++++---- src/coreclr/runtime.proj | 1 + .../Compiler/ReadyToRunCompilerContext.cs | 4 ++++ .../ILCompiler.ReadyToRun.csproj | 1 + src/coreclr/utilcode/executableallocator.cpp | 6 +++--- src/coreclr/vm/peimagelayout.cpp | 2 +- .../CompilerServices/RuntimeFeature.NonNativeAot.cs | 2 +- 12 files changed, 35 insertions(+), 13 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index 9aead19dcdd9ff..6d4255d13ac5ca 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -27,6 +27,7 @@ Param( [switch]$bootstrap, [switch]$useBoostrap, [switch]$clrinterpreter, + [switch]$clrnodynamiccodegen, [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties ) @@ -59,6 +60,7 @@ function Get-Help() { Write-Host " [Default: Builds the entire repo.]" Write-Host " -usemonoruntime Product a .NET runtime with Mono as the underlying runtime." Write-Host " -clrinterpreter Enables CoreCLR interpreter for Release builds of targets where it is a Debug only feature." + Write-Host " -clrnodynamiccodegen Build CoreCLR/crossgen2 in a mode that simulates iOS-like configuration (interpreter enabled, no dynamic code generation)." Write-Host " -verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]." Write-Host " [Default: Minimal]" Write-Host " --useBootstrap Use the results of building the bootstrap subset to build published tools on the target machine." @@ -345,6 +347,7 @@ foreach ($argument in $PSBoundParameters.Keys) "fsanitize" { $arguments += " /p:EnableNativeSanitizers=$($PSBoundParameters[$argument])"} "useBootstrap" { $arguments += " /p:UseBootstrap=$($PSBoundParameters[$argument])" } "clrinterpreter" { $arguments += " /p:FeatureInterpreter=true" } + "clrnodynamiccodegen" { $arguments += " /p:FeatureInterpreter=true /p:FeatureNoDynamicCodeGen=true" } default { $arguments += " /p:$argument=$($PSBoundParameters[$argument])" } } } diff --git a/eng/build.sh b/eng/build.sh index 93a4525aee79e4..c8434839d2ef3a 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -47,6 +47,7 @@ usage() echo " [Default: Builds the entire repo.]" echo " --usemonoruntime Product a .NET runtime with Mono as the underlying runtime." echo " --clrinterpreter Enables CoreCLR interpreter for Release builds of targets where it is a Debug only feature." + echo " --clrnodynamiccodegen Build CoreCLR/crossgen2 in a mode that simulates iOS-like configuration (interpreter enabled, no dynamic code generation)." echo " --verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]." echo " [Default: Minimal]" echo " --use-bootstrap Use the results of building the bootstrap subset to build published tools on the target machine." @@ -390,6 +391,12 @@ while [[ $# -gt 0 ]]; do shift 1 ;; + -clrnodynamiccodegen) + arguments+=("/p:FeatureInterpreter=true") + arguments+=("/p:FeatureNoDynamicCodeGen=true") + shift 1 + ;; + -librariesconfiguration|-lc) if [ -z ${2+x} ]; then echo "No libraries configuration supplied. See help (--help) for supported libraries configurations." 1>&2 diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index a0c78493a4492d..d766163ba71033 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -63,6 +63,7 @@ $(DefineConstants);FEATURE_EVENTSOURCE_XPLAT $(DefineConstants);FEATURE_TYPEEQUIVALENCE $(DefineConstants);FEATURE_INTERPRETER + $(DefineConstants);FEATURE_NO_DYNAMIC_CODEGEN $(DefineConstants);FEATURE_PORTABLE_ENTRYPOINTS $(DefineConstants);FEATURE_PORTABLE_HELPERS $(DefineConstants);FEATURE_WASM_MANAGED_THREADS diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 3811b7844d2d68..0389599999ff3a 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -109,6 +109,7 @@ if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ endif (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) add_compile_definitions($<${FEATURE_INTERPRETER}:FEATURE_INTERPRETER>) +add_compile_definitions($<${FEATURE_NO_DYNAMIC_CODEGEN}:FEATURE_NO_DYNAMIC_CODEGEN>) if (FEATURE_PORTABLE_ENTRYPOINTS) add_compile_definitions(FEATURE_PORTABLE_ENTRYPOINTS) endif() diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 46a31e230b41b1..c3ded711832927 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -1,10 +1,10 @@ -if (NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_MACCATALYST) +if (NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT FEATURE_NO_DYNAMIC_CODEGEN) set(FEATURE_TIERED_COMPILATION 1) set(FEATURE_REJIT 1) set(FEATURE_JIT 1) endif() -if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST) +if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST OR FEATURE_NO_DYNAMIC_CODEGEN) set(FEATURE_STATICALLY_LINKED 1) endif() @@ -36,6 +36,10 @@ if(NOT DEFINED FEATURE_DBGIPC) endif() endif(NOT DEFINED FEATURE_DBGIPC) +if(NOT DEFINED FEATURE_NO_DYNAMIC_CODEGEN) + set(FEATURE_NO_DYNAMIC_CODEGEN 0) +endif(NOT DEFINED FEATURE_NO_DYNAMIC_CODEGEN) + if(NOT DEFINED FEATURE_INTERPRETER) if(CLR_CMAKE_TARGET_ANDROID) set(FEATURE_INTERPRETER 0) @@ -86,11 +90,11 @@ if (CLR_CMAKE_TARGET_WIN32) set(FEATURE_TYPEEQUIVALENCE 1) endif(CLR_CMAKE_TARGET_WIN32) -if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) +if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR FEATURE_NO_DYNAMIC_CODEGEN) set(FEATURE_STUBPRECODE_DYNAMIC_HELPERS 1) endif() -if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_ARCH_WASM) +if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_ARCH_WASM OR FEATURE_NO_DYNAMIC_CODEGEN) set(FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH 1) set(FEATURE_CORECLR_VIRTUAL_STUB_DISPATCH 0) else() diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 8d2652c6c0fbc8..363c572d0f49ac 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -242,11 +242,11 @@ CONFIG_DWORD_INFO(INTERNAL_FastGCCheckStack, W("FastGCCheckStack"), 0, "") CONFIG_DWORD_INFO(INTERNAL_FastGCStress, W("FastGCStress"), 0, "Reduce the number of GCs done by enabling GCStress") RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCBreakOnOOM, W("GCBreakOnOOM"), 0, "Does a DebugBreak at the soonest time we detect an OOM") RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConcurrent, W("gcConcurrent"), (DWORD)-1, "Enables/Disables concurrent GC") -#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) +#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_UseGCWriteBarrierCopy, W("UseGCWriteBarrierCopy"), 0, "Use a copy of the write barrier for the GC. This is somewhat faster and for optimizations where the barrier is mutated as the program runs. Setting this to 0 removes scenarios where the write barrier is ever mutable.") #else RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_UseGCWriteBarrierCopy, W("UseGCWriteBarrierCopy"), 1, "Use a copy of the write barrier for the GC. This is somewhat faster and for optimizations where the barrier is mutated as the program runs. Setting this to 0 removes scenarios where the write barrier is ever mutable.") -#endif // defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) +#endif // defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) #ifdef FEATURE_CONSERVATIVE_GC RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConservative, W("gcConservative"), 0, "Enables/Disables conservative GC") @@ -555,11 +555,11 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_VirtualCallStubLogging, W("VirtualCallStubLogg CONFIG_DWORD_INFO(INTERNAL_VirtualCallStubMissCount, W("VirtualCallStubMissCount"), 100, "Used only when STUB_LOGGING is defined, which by default is not.") CONFIG_DWORD_INFO(INTERNAL_VirtualCallStubResetCacheCounter, W("VirtualCallStubResetCacheCounter"), 0, "Used only when STUB_LOGGING is defined, which by default is not.") CONFIG_DWORD_INFO(INTERNAL_VirtualCallStubResetCacheIncr, W("VirtualCallStubResetCacheIncr"), 0, "Used only when STUB_LOGGING is defined, which by default is not.") -#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) +#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) CONFIG_DWORD_INFO(INTERNAL_UseCachedInterfaceDispatch, W("UseCachedInterfaceDispatch"), 1, "If cached interface dispatch is compiled in, use that instead of virtual stub dispatch") #else CONFIG_DWORD_INFO(INTERNAL_UseCachedInterfaceDispatch, W("UseCachedInterfaceDispatch"), 0, "If cached interface dispatch is compiled in, use that instead of virtual stub dispatch") -#endif // defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) +#endif // defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) /// /// Watson /// diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index f3c181fbc005cd..5233794e2d92d7 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -54,6 +54,7 @@ <_CoreClrBuildArg Condition="'$(HasCdacBuildTool)' == 'true'" Include="-cmakeargs "-DCDAC_BUILD_TOOL_BINARY_PATH=$(RuntimeBinDir)cdac-build-tool\cdac-build-tool.dll"" /> <_CoreClrBuildArg Condition="'$(FeatureXplatEventSource)' == 'false'" Include="-cmakeargs "-DFEATURE_EVENTSOURCE_XPLAT=0"" /> <_CoreClrBuildArg Condition="'$(FeatureInterpreter)' == 'true'" Include="-cmakeargs "-DFEATURE_INTERPRETER=1"" /> + <_CoreClrBuildArg Condition="'$(FeatureNoDynamicCodeGen)' == 'true'" Include="-cmakeargs "-DFEATURE_NO_DYNAMIC_CODEGEN=1"" /> diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs index e0aa30e78165ea..13f585a47b46f1 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs @@ -104,6 +104,9 @@ public bool TargetAllowsRuntimeCodeGeneration { get { +#if FEATURE_NO_DYNAMIC_CODEGEN + return false; +#else if (Target.OperatingSystem is TargetOS.iOS or TargetOS.iOSSimulator or TargetOS.MacCatalyst or TargetOS.tvOS or TargetOS.tvOSSimulator) { return false; @@ -115,6 +118,7 @@ public bool TargetAllowsRuntimeCodeGeneration } return true; +#endif } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index fddee4c4ac976e..ad17fd4cce34cb 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -5,6 +5,7 @@ $(NetCoreAppToolCurrent) true READYTORUN;$(DefineConstants) + $(DefineConstants);FEATURE_NO_DYNAMIC_CODEGEN false x64;x86;arm;arm64 AnyCPU diff --git a/src/coreclr/utilcode/executableallocator.cpp b/src/coreclr/utilcode/executableallocator.cpp index 631331652b0919..0632fc5da2721f 100644 --- a/src/coreclr/utilcode/executableallocator.cpp +++ b/src/coreclr/utilcode/executableallocator.cpp @@ -498,7 +498,7 @@ void* ExecutableAllocator::Commit(void* pStart, size_t size, bool isExecutable) } else { -#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) +#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) return ClrVirtualAlloc(pStart, size, MEM_COMMIT, PAGE_READWRITE); #else return ClrVirtualAlloc(pStart, size, MEM_COMMIT, isExecutable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); @@ -714,7 +714,7 @@ void* ExecutableAllocator::ReserveWithinRange(size_t size, const void* loAddress else { DWORD allocationType = MEM_RESERVE; -#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) +#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) && !defined(FEATURE_NO_DYNAMIC_CODEGEN) // Tell PAL to use the executable memory allocator to satisfy this request for virtual memory. // This will allow us to place JIT'ed code close to the coreclr library // and thus improve performance by avoiding jump stubs in managed code. @@ -804,7 +804,7 @@ void* ExecutableAllocator::Reserve(size_t size) else { DWORD allocationType = MEM_RESERVE; -#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) +#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) && !defined(FEATURE_NO_DYNAMIC_CODEGEN) // Tell PAL to use the executable memory allocator to satisfy this request for virtual memory. // This will allow us to place JIT'ed code close to the coreclr library // and thus improve performance by avoiding jump stubs in managed code. diff --git a/src/coreclr/vm/peimagelayout.cpp b/src/coreclr/vm/peimagelayout.cpp index 1ab369f8c650ce..5164bef9b732b9 100644 --- a/src/coreclr/vm/peimagelayout.cpp +++ b/src/coreclr/vm/peimagelayout.cpp @@ -834,7 +834,7 @@ void* FlatImageLayout::LoadImageByCopyingParts(SIZE_T* m_imageParts) const #endif // FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION DWORD allocationType = MEM_RESERVE | MEM_COMMIT; -#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) +#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) && !defined(FEATURE_NO_DYNAMIC_CODEGEN) // Tell PAL to use the executable memory allocator to satisfy this request for virtual memory. // This is required on MacOS and otherwise will allow us to place native R2R code close to the // coreclr library and thus improve performance by avoiding jump stubs in managed code. diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs index 8d0e0d94dad035..1a02e9900f26cc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs @@ -22,7 +22,7 @@ public static bool IsDynamicCodeCompiled #if MONO [Intrinsic] // the Mono AOT compiler and Interpreter will change this flag to false for FullAOT and interpreted scenarios, otherwise this code is used #endif -#if CORECLR && (TARGET_WASM || TARGET_IOS || TARGET_TVOS || TARGET_MACCATALYST) +#if CORECLR && (TARGET_WASM || TARGET_IOS || TARGET_TVOS || TARGET_MACCATALYST || FEATURE_NO_DYNAMIC_CODEGEN) get => false; #else get => IsDynamicCodeSupported; From adb6b2b2eb49e56e41f4e232d1dd50ca8559fbb3 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Tue, 10 Feb 2026 10:31:50 +0200 Subject: [PATCH 2/5] Add --dynamiccodecompiled that results in FEATURE_DYNAMIC_CODE_COMPILED being defined FEATURE_JIT uses are removed and FEATURE_DYNAMIC_CODE_COMPILED is used instead FEATURE_DYNAMIC_CODE_COMPILED will also set knobs that we expect to use on all platforms where jit-ing is not allowed. If `--dynamiccodecompiled` value is not passed to the build, then it will be set to the default value based on the target. The build will always end up receiving the final property value in `FeatureDynamicCodeCompiled`. --- eng/build.ps1 | 21 +++++++++-- eng/build.sh | 37 ++++++++++++++++--- src/coreclr/clr.featuredefines.props | 2 +- src/coreclr/clrdefinitions.cmake | 8 ++-- src/coreclr/clrfeatures.cmake | 13 ++----- src/coreclr/debug/daccess/daccess.cpp | 4 +- .../dlls/mscoree/coreclr/CMakeLists.txt | 8 ++-- src/coreclr/inc/clrconfigvalues.h | 8 ++-- src/coreclr/inc/dacvars.h | 4 +- src/coreclr/inc/switches.h | 2 +- src/coreclr/inc/vptr_list.h | 4 +- src/coreclr/interpreter/eeinterp.cpp | 2 +- src/coreclr/runtime.proj | 2 +- .../Compiler/ReadyToRunCompilerContext.cs | 16 ++------ .../ILCompiler.ReadyToRun.csproj | 2 +- src/coreclr/utilcode/executableallocator.cpp | 6 +-- src/coreclr/vm/appdomain.cpp | 4 +- src/coreclr/vm/codeman.cpp | 18 ++++----- src/coreclr/vm/dllimport.cpp | 4 +- src/coreclr/vm/eeconfig.cpp | 4 +- src/coreclr/vm/eventtrace.cpp | 4 +- src/coreclr/vm/jitinterface.cpp | 6 +-- src/coreclr/vm/peimagelayout.cpp | 2 +- src/coreclr/vm/stubmgr.cpp | 12 +++--- src/coreclr/vm/stubmgr.h | 4 +- .../RuntimeFeature.NonNativeAot.cs | 2 +- 26 files changed, 112 insertions(+), 87 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index 6d4255d13ac5ca..1401f5c72b55ca 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -27,7 +27,7 @@ Param( [switch]$bootstrap, [switch]$useBoostrap, [switch]$clrinterpreter, - [switch]$clrnodynamiccodegen, + [ValidateSet("true","false")][string]$dynamiccodecompiled, [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties ) @@ -60,7 +60,9 @@ function Get-Help() { Write-Host " [Default: Builds the entire repo.]" Write-Host " -usemonoruntime Product a .NET runtime with Mono as the underlying runtime." Write-Host " -clrinterpreter Enables CoreCLR interpreter for Release builds of targets where it is a Debug only feature." - Write-Host " -clrnodynamiccodegen Build CoreCLR/crossgen2 in a mode that simulates iOS-like configuration (interpreter enabled, no dynamic code generation)." + Write-Host " -dynamiccodecompiled Enable or disable dynamic code compilation support. Accepts true or false." + Write-Host " Also enables the interpreter when dynamic code compilation is disabled." + Write-Host " [Default: true for most platforms, false for ios/tvos/browser/wasi]" Write-Host " -verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]." Write-Host " [Default: Minimal]" Write-Host " --useBootstrap Use the results of building the bootstrap subset to build published tools on the target machine." @@ -347,11 +349,24 @@ foreach ($argument in $PSBoundParameters.Keys) "fsanitize" { $arguments += " /p:EnableNativeSanitizers=$($PSBoundParameters[$argument])"} "useBootstrap" { $arguments += " /p:UseBootstrap=$($PSBoundParameters[$argument])" } "clrinterpreter" { $arguments += " /p:FeatureInterpreter=true" } - "clrnodynamiccodegen" { $arguments += " /p:FeatureInterpreter=true /p:FeatureNoDynamicCodeGen=true" } + "dynamiccodecompiled" {} default { $arguments += " /p:$argument=$($PSBoundParameters[$argument])" } } } +# Default dynamiccodecompiled based on target OS if not explicitly set +if (-not $dynamiccodecompiled) { + if ($os -eq "maccatalyst" -or $os -eq "ios" -or $os -eq "iossimulator" -or $os -eq "tvos" -or $os -eq "tvossimulator" -or $os -eq "browser" -or $os -eq "wasi") { + $dynamiccodecompiled = "false" + } else { + $dynamiccodecompiled = "true" + } +} +$arguments += " /p:FeatureDynamicCodeCompiled=$dynamiccodecompiled" +if ($dynamiccodecompiled -eq "false") { + $arguments += " /p:FeatureInterpreter=true" +} + if ($env:TreatWarningsAsErrors -eq 'false') { $arguments += " -warnAsError `$false" } diff --git a/eng/build.sh b/eng/build.sh index c8434839d2ef3a..52d6286f8ff744 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -47,7 +47,9 @@ usage() echo " [Default: Builds the entire repo.]" echo " --usemonoruntime Product a .NET runtime with Mono as the underlying runtime." echo " --clrinterpreter Enables CoreCLR interpreter for Release builds of targets where it is a Debug only feature." - echo " --clrnodynamiccodegen Build CoreCLR/crossgen2 in a mode that simulates iOS-like configuration (interpreter enabled, no dynamic code generation)." + echo " --dynamiccodecompiled Enable or disable dynamic code compilation support. Accepts true or false." + echo " Also enables the interpreter when dynamic code compilation is disabled." + echo " [Default: true for most platforms, false for ios/tvos/browser/wasi]" echo " --verbosity (-v) MSBuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]." echo " [Default: Minimal]" echo " --use-bootstrap Use the results of building the bootstrap subset to build published tools on the target machine." @@ -162,6 +164,7 @@ crossBuild=0 portableBuild=1 bootstrap=0 bootstrapConfig='Debug' +dynamiccodecompiled="" source $scriptroot/common/native/init-os-and-arch.sh @@ -391,10 +394,18 @@ while [[ $# -gt 0 ]]; do shift 1 ;; - -clrnodynamiccodegen) - arguments+=("/p:FeatureInterpreter=true") - arguments+=("/p:FeatureNoDynamicCodeGen=true") - shift 1 + -dynamiccodecompiled) + if [ -z ${2+x} ]; then + echo "No value for dynamiccodecompiled is supplied. See help (--help) for supported values." 1>&2 + exit 1 + fi + dynamiccodecompiled="$(echo "$2" | tr "[:upper:]" "[:lower:]")" + if [[ "$dynamiccodecompiled" != "true" && "$dynamiccodecompiled" != "false" ]]; then + echo "Unsupported value '$2' for dynamiccodecompiled." + echo "The allowed values are true and false." + exit 1 + fi + shift 2 ;; -librariesconfiguration|-lc) @@ -580,6 +591,22 @@ if [[ "$os" == "wasi" ]]; then arch=wasm fi +# Default dynamiccodecompiled based on target OS if not explicitly set +if [[ -z "$dynamiccodecompiled" ]]; then + case "$os" in + maccatalyst|ios|iossimulator|tvos|tvossimulator|browser|wasi) + dynamiccodecompiled="false" + ;; + *) + dynamiccodecompiled="true" + ;; + esac +fi +arguments+=("/p:FeatureDynamicCodeCompiled=$dynamiccodecompiled") +if [[ "$dynamiccodecompiled" == "false" ]]; then + arguments+=("/p:FeatureInterpreter=true") +fi + if [[ "${TreatWarningsAsErrors:-}" == "false" ]]; then arguments+=("-warnAsError" "false") fi diff --git a/src/coreclr/clr.featuredefines.props b/src/coreclr/clr.featuredefines.props index d766163ba71033..23e5e360b0ae32 100644 --- a/src/coreclr/clr.featuredefines.props +++ b/src/coreclr/clr.featuredefines.props @@ -63,7 +63,7 @@ $(DefineConstants);FEATURE_EVENTSOURCE_XPLAT $(DefineConstants);FEATURE_TYPEEQUIVALENCE $(DefineConstants);FEATURE_INTERPRETER - $(DefineConstants);FEATURE_NO_DYNAMIC_CODEGEN + $(DefineConstants);FEATURE_DYNAMIC_CODE_COMPILED $(DefineConstants);FEATURE_PORTABLE_ENTRYPOINTS $(DefineConstants);FEATURE_PORTABLE_HELPERS $(DefineConstants);FEATURE_WASM_MANAGED_THREADS diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 0389599999ff3a..2b3137b35641a0 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -1,9 +1,5 @@ include(${CMAKE_CURRENT_LIST_DIR}/clrfeatures.cmake) -if(FEATURE_JIT) - add_compile_definitions(FEATURE_JIT) -endif(FEATURE_JIT) - add_compile_definitions($<$>:DACCESS_COMPILE>) if (CLR_CMAKE_TARGET_UNIX) @@ -109,7 +105,9 @@ if (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ endif (CLR_CMAKE_TARGET_WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM64)) add_compile_definitions($<${FEATURE_INTERPRETER}:FEATURE_INTERPRETER>) -add_compile_definitions($<${FEATURE_NO_DYNAMIC_CODEGEN}:FEATURE_NO_DYNAMIC_CODEGEN>) +if (FEATURE_DYNAMIC_CODE_COMPILED) + add_compile_definitions(FEATURE_DYNAMIC_CODE_COMPILED) +endif() if (FEATURE_PORTABLE_ENTRYPOINTS) add_compile_definitions(FEATURE_PORTABLE_ENTRYPOINTS) endif() diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index c3ded711832927..0970b8e767550d 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -1,10 +1,9 @@ -if (NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT FEATURE_NO_DYNAMIC_CODEGEN) +if (FEATURE_DYNAMIC_CODE_COMPILED) set(FEATURE_TIERED_COMPILATION 1) set(FEATURE_REJIT 1) - set(FEATURE_JIT 1) endif() -if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST OR FEATURE_NO_DYNAMIC_CODEGEN) +if (NOT FEATURE_DYNAMIC_CODE_COMPILED) set(FEATURE_STATICALLY_LINKED 1) endif() @@ -36,10 +35,6 @@ if(NOT DEFINED FEATURE_DBGIPC) endif() endif(NOT DEFINED FEATURE_DBGIPC) -if(NOT DEFINED FEATURE_NO_DYNAMIC_CODEGEN) - set(FEATURE_NO_DYNAMIC_CODEGEN 0) -endif(NOT DEFINED FEATURE_NO_DYNAMIC_CODEGEN) - if(NOT DEFINED FEATURE_INTERPRETER) if(CLR_CMAKE_TARGET_ANDROID) set(FEATURE_INTERPRETER 0) @@ -90,11 +85,11 @@ if (CLR_CMAKE_TARGET_WIN32) set(FEATURE_TYPEEQUIVALENCE 1) endif(CLR_CMAKE_TARGET_WIN32) -if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR FEATURE_NO_DYNAMIC_CODEGEN) +if (NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT FEATURE_DYNAMIC_CODE_COMPILED) set(FEATURE_STUBPRECODE_DYNAMIC_HELPERS 1) endif() -if (CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_ARCH_WASM OR FEATURE_NO_DYNAMIC_CODEGEN) +if (NOT FEATURE_DYNAMIC_CODE_COMPILED) set(FEATURE_CORECLR_CACHED_INTERFACE_DISPATCH 1) set(FEATURE_CORECLR_VIRTUAL_STUB_DISPATCH 0) else() diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index a1dd220373ebb0..44a7a651ba9bb4 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -5804,7 +5804,7 @@ ClrDataAccess::RawGetMethodName( EX_END_CATCH } } -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED else if (pStubManager == JumpStubStubManager::g_pManager) { @@ -5826,7 +5826,7 @@ ClrDataAccess::RawGetMethodName( return hr; } } -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED LPCWSTR wszStubManagerName = pStubManager->GetStubManagerName(TO_TADDR(address)); _ASSERTE(wszStubManagerName != NULL); diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 6d793bc65e48a7..3e09134119290d 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -145,17 +145,17 @@ if(FEATURE_EVENT_TRACE) endif(FEATURE_EVENT_TRACE) if (FEATURE_STATICALLY_LINKED) - if (FEATURE_JIT) + if (FEATURE_DYNAMIC_CODE_COMPILED) set(CLRJIT_STATIC clrjit_static gcinfo) - endif(FEATURE_JIT) + endif(FEATURE_DYNAMIC_CODE_COMPILED) if (FEATURE_INTERPRETER) set(CLRINTERPRETER_STATIC clrinterpreter_objects dn-containers gcinfo) endif(FEATURE_INTERPRETER) endif(FEATURE_STATICALLY_LINKED) -if(FEATURE_JIT) +if(FEATURE_DYNAMIC_CODE_COMPILED) set(CORECLR_STATIC_CLRJIT_STATIC clrjit_static) -endif(FEATURE_JIT) +endif(FEATURE_DYNAMIC_CODE_COMPILED) if(CLR_CMAKE_HOST_ARCH_WASM) set(CEE_WKS_STATIC cee_wks) diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h index 363c572d0f49ac..ef9365291861ee 100644 --- a/src/coreclr/inc/clrconfigvalues.h +++ b/src/coreclr/inc/clrconfigvalues.h @@ -242,11 +242,11 @@ CONFIG_DWORD_INFO(INTERNAL_FastGCCheckStack, W("FastGCCheckStack"), 0, "") CONFIG_DWORD_INFO(INTERNAL_FastGCStress, W("FastGCStress"), 0, "Reduce the number of GCs done by enabling GCStress") RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCBreakOnOOM, W("GCBreakOnOOM"), 0, "Does a DebugBreak at the soonest time we detect an OOM") RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConcurrent, W("gcConcurrent"), (DWORD)-1, "Enables/Disables concurrent GC") -#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) +#if !defined(FEATURE_DYNAMIC_CODE_COMPILED) RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_UseGCWriteBarrierCopy, W("UseGCWriteBarrierCopy"), 0, "Use a copy of the write barrier for the GC. This is somewhat faster and for optimizations where the barrier is mutated as the program runs. Setting this to 0 removes scenarios where the write barrier is ever mutable.") #else RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_UseGCWriteBarrierCopy, W("UseGCWriteBarrierCopy"), 1, "Use a copy of the write barrier for the GC. This is somewhat faster and for optimizations where the barrier is mutated as the program runs. Setting this to 0 removes scenarios where the write barrier is ever mutable.") -#endif // defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) +#endif // !defined(FEATURE_DYNAMIC_CODE_COMPILED) #ifdef FEATURE_CONSERVATIVE_GC RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConservative, W("gcConservative"), 0, "Enables/Disables conservative GC") @@ -555,11 +555,11 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_VirtualCallStubLogging, W("VirtualCallStubLogg CONFIG_DWORD_INFO(INTERNAL_VirtualCallStubMissCount, W("VirtualCallStubMissCount"), 100, "Used only when STUB_LOGGING is defined, which by default is not.") CONFIG_DWORD_INFO(INTERNAL_VirtualCallStubResetCacheCounter, W("VirtualCallStubResetCacheCounter"), 0, "Used only when STUB_LOGGING is defined, which by default is not.") CONFIG_DWORD_INFO(INTERNAL_VirtualCallStubResetCacheIncr, W("VirtualCallStubResetCacheIncr"), 0, "Used only when STUB_LOGGING is defined, which by default is not.") -#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) +#if !defined(FEATURE_DYNAMIC_CODE_COMPILED) CONFIG_DWORD_INFO(INTERNAL_UseCachedInterfaceDispatch, W("UseCachedInterfaceDispatch"), 1, "If cached interface dispatch is compiled in, use that instead of virtual stub dispatch") #else CONFIG_DWORD_INFO(INTERNAL_UseCachedInterfaceDispatch, W("UseCachedInterfaceDispatch"), 0, "If cached interface dispatch is compiled in, use that instead of virtual stub dispatch") -#endif // defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) +#endif // !defined(FEATURE_DYNAMIC_CODE_COMPILED) /// /// Watson /// diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h index 5803ae1f33b3b5..d7805ec5b4da69 100644 --- a/src/coreclr/inc/dacvars.h +++ b/src/coreclr/inc/dacvars.h @@ -96,9 +96,9 @@ DEFINE_DACVAR(VMHELPDEF *, dac__hlpDynamicFuncTable, ::hlpDynamicFuncTable) DEFINE_DACVAR(PTR_StubManager, StubManager__g_pFirstManager, StubManager::g_pFirstManager) DEFINE_DACVAR(PTR_PrecodeStubManager, PrecodeStubManager__g_pManager, PrecodeStubManager::g_pManager) DEFINE_DACVAR(PTR_StubLinkStubManager, StubLinkStubManager__g_pManager, StubLinkStubManager::g_pManager) -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED DEFINE_DACVAR(PTR_JumpStubStubManager, JumpStubStubManager__g_pManager, JumpStubStubManager::g_pManager) -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED DEFINE_DACVAR(PTR_RangeSectionStubManager, RangeSectionStubManager__g_pManager, RangeSectionStubManager::g_pManager) DEFINE_DACVAR(PTR_VirtualCallStubManagerManager, VirtualCallStubManagerManager__g_pManager, VirtualCallStubManagerManager::g_pManager) #ifdef FEATURE_TIERED_COMPILATION diff --git a/src/coreclr/inc/switches.h b/src/coreclr/inc/switches.h index a5ccfee195e612..3c2c17d6bbaf01 100644 --- a/src/coreclr/inc/switches.h +++ b/src/coreclr/inc/switches.h @@ -166,7 +166,7 @@ #endif // FEATURE_VIRTUAL_STUB_DISPATCH // FEATURE_PORTABLE_SHUFFLE_THUNKS depends on CPUSTUBLINKER that is de-facto JIT -#if defined(FEATURE_JIT) && !defined(TARGET_X86) +#if defined(FEATURE_DYNAMIC_CODE_COMPILED) && !defined(TARGET_X86) #define FEATURE_PORTABLE_SHUFFLE_THUNKS #endif diff --git a/src/coreclr/inc/vptr_list.h b/src/coreclr/inc/vptr_list.h index e505e18870644d..29f48005e30a7a 100644 --- a/src/coreclr/inc/vptr_list.h +++ b/src/coreclr/inc/vptr_list.h @@ -30,9 +30,9 @@ VPTR_CLASS(StubLinkStubManager) VPTR_CLASS(ThePreStubManager) VPTR_CLASS(VirtualCallStubManager) VPTR_CLASS(VirtualCallStubManagerManager) -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED VPTR_CLASS(JumpStubStubManager) -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED VPTR_CLASS(RangeSectionStubManager) VPTR_CLASS(ILStubManager) VPTR_CLASS(InteropDispatchStubManager) diff --git a/src/coreclr/interpreter/eeinterp.cpp b/src/coreclr/interpreter/eeinterp.cpp index d9b7366981a3fc..50f97a43775dc5 100644 --- a/src/coreclr/interpreter/eeinterp.cpp +++ b/src/coreclr/interpreter/eeinterp.cpp @@ -85,7 +85,7 @@ CorJitResult CILInterp::compileMethod(ICorJitInfo* compHnd, break; } -#if !defined(FEATURE_JIT) +#if !defined(FEATURE_DYNAMIC_CODE_COMPILED) // interpret everything when we do not have a JIT doInterpret = true; #else diff --git a/src/coreclr/runtime.proj b/src/coreclr/runtime.proj index 5233794e2d92d7..2c42bc9e1f9ad5 100644 --- a/src/coreclr/runtime.proj +++ b/src/coreclr/runtime.proj @@ -54,7 +54,7 @@ <_CoreClrBuildArg Condition="'$(HasCdacBuildTool)' == 'true'" Include="-cmakeargs "-DCDAC_BUILD_TOOL_BINARY_PATH=$(RuntimeBinDir)cdac-build-tool\cdac-build-tool.dll"" /> <_CoreClrBuildArg Condition="'$(FeatureXplatEventSource)' == 'false'" Include="-cmakeargs "-DFEATURE_EVENTSOURCE_XPLAT=0"" /> <_CoreClrBuildArg Condition="'$(FeatureInterpreter)' == 'true'" Include="-cmakeargs "-DFEATURE_INTERPRETER=1"" /> - <_CoreClrBuildArg Condition="'$(FeatureNoDynamicCodeGen)' == 'true'" Include="-cmakeargs "-DFEATURE_NO_DYNAMIC_CODEGEN=1"" /> + <_CoreClrBuildArg Condition="'$(FeatureDynamicCodeCompiled)' == 'true'" Include="-cmakeargs "-DFEATURE_DYNAMIC_CODE_COMPILED=1"" /> diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs index 13f585a47b46f1..de78b52749c2c2 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs @@ -104,20 +104,10 @@ public bool TargetAllowsRuntimeCodeGeneration { get { -#if FEATURE_NO_DYNAMIC_CODEGEN - return false; -#else - if (Target.OperatingSystem is TargetOS.iOS or TargetOS.iOSSimulator or TargetOS.MacCatalyst or TargetOS.tvOS or TargetOS.tvOSSimulator) - { - return false; - } - - if (Target.Architecture is TargetArchitecture.Wasm32) - { - return false; - } - +#if FEATURE_DYNAMIC_CODE_COMPILED return true; +#else + return false; #endif } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index ad17fd4cce34cb..cb7b001082722b 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -5,7 +5,7 @@ $(NetCoreAppToolCurrent) true READYTORUN;$(DefineConstants) - $(DefineConstants);FEATURE_NO_DYNAMIC_CODEGEN + $(DefineConstants);FEATURE_DYNAMIC_CODE_COMPILED false x64;x86;arm;arm64 AnyCPU diff --git a/src/coreclr/utilcode/executableallocator.cpp b/src/coreclr/utilcode/executableallocator.cpp index 0632fc5da2721f..11c1af97f79770 100644 --- a/src/coreclr/utilcode/executableallocator.cpp +++ b/src/coreclr/utilcode/executableallocator.cpp @@ -498,7 +498,7 @@ void* ExecutableAllocator::Commit(void* pStart, size_t size, bool isExecutable) } else { -#if defined(TARGET_IOS) || defined(TARGET_TVOS) || defined(TARGET_MACCATALYST) || defined(FEATURE_NO_DYNAMIC_CODEGEN) +#if !defined(FEATURE_DYNAMIC_CODE_COMPILED) return ClrVirtualAlloc(pStart, size, MEM_COMMIT, PAGE_READWRITE); #else return ClrVirtualAlloc(pStart, size, MEM_COMMIT, isExecutable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); @@ -714,7 +714,7 @@ void* ExecutableAllocator::ReserveWithinRange(size_t size, const void* loAddress else { DWORD allocationType = MEM_RESERVE; -#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) && !defined(FEATURE_NO_DYNAMIC_CODEGEN) +#if defined(HOST_UNIX) && defined(FEATURE_DYNAMIC_CODE_COMPILED) // Tell PAL to use the executable memory allocator to satisfy this request for virtual memory. // This will allow us to place JIT'ed code close to the coreclr library // and thus improve performance by avoiding jump stubs in managed code. @@ -804,7 +804,7 @@ void* ExecutableAllocator::Reserve(size_t size) else { DWORD allocationType = MEM_RESERVE; -#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) && !defined(FEATURE_NO_DYNAMIC_CODEGEN) +#if defined(HOST_UNIX) && defined(FEATURE_DYNAMIC_CODE_COMPILED) // Tell PAL to use the executable memory allocator to satisfy this request for virtual memory. // This will allow us to place JIT'ed code close to the coreclr library // and thus improve performance by avoiding jump stubs in managed code. diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index ca670e4152adff..952c311ba4209c 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -722,9 +722,9 @@ void SystemDomain::Attach() #ifndef FEATURE_PORTABLE_ENTRYPOINTS PrecodeStubManager::Init(); #endif // !FEATURE_PORTABLE_ENTRYPOINTS -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED JumpStubStubManager::Init(); -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED RangeSectionStubManager::Init(); ILStubManager::Init(); InteropDispatchStubManager::Init(); diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index a1bf0bc4c6bfa2..c36c69394596a6 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1655,11 +1655,11 @@ EXTERN_C ICorJitCompiler* getJit(); #endif // FEATURE_STATICALLY_LINKED -#if !defined(FEATURE_STATICALLY_LINKED) || defined(FEATURE_JIT) +#if !defined(FEATURE_STATICALLY_LINKED) || defined(FEATURE_DYNAMIC_CODE_COMPILED) -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED JIT_LOAD_DATA g_JitLoadData; -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED #ifdef FEATURE_INTERPRETER JIT_LOAD_DATA g_interpreterLoadData; @@ -1834,7 +1834,7 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName DEBUGARG(LPCWSTR pwzJitPath) LogJITInitializationError("LoadAndInitializeJIT: failed to load %s, hr=0x%08X", utf8JitName, hr); } } -#endif // !FEATURE_STATICALLY_LINKED || FEATURE_JIT +#endif // !FEATURE_STATICALLY_LINKED || FEATURE_DYNAMIC_CODE_COMPILED #ifdef FEATURE_STATICALLY_LINKED static ICorJitCompiler* InitializeStaticJIT() @@ -1857,7 +1857,7 @@ static ICorJitCompiler* InitializeStaticJIT() } #endif // FEATURE_STATICALLY_LINKED -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED BOOL EEJitManager::LoadJIT() { STANDARD_VM_CONTRACT; @@ -1990,7 +1990,7 @@ BOOL EEJitManager::LoadJIT() // In either failure case, we'll rip down the VM (so no need to clean up (unload) either JIT that did load successfully. return IsJitLoaded(); } -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED //************************************************************************** @@ -3685,9 +3685,9 @@ BOOL InterpreterJitManager::LoadInterpreter() // If both JIT and interpret are available, statically link the JIT. Interpreter can be loaded dynamically // via config switch for testing purposes. -#if defined(FEATURE_STATICALLY_LINKED) && !defined(FEATURE_JIT) +#if defined(FEATURE_STATICALLY_LINKED) && !defined(FEATURE_DYNAMIC_CODE_COMPILED) newInterpreter = InitializeStaticJIT(); -#else // FEATURE_STATICALLY_LINKED && !FEATURE_JIT +#else // FEATURE_STATICALLY_LINKED && !FEATURE_DYNAMIC_CODE_COMPILED g_interpreterLoadData.jld_id = JIT_LOAD_INTERPRETER; LPWSTR interpreterPath = NULL; @@ -3695,7 +3695,7 @@ BOOL InterpreterJitManager::LoadInterpreter() IfFailThrow(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_InterpreterPath, &interpreterPath)); #endif LoadAndInitializeJIT(ExecutionManager::GetInterpreterName() DEBUGARG(interpreterPath), &m_interpreterHandle, &newInterpreter, &g_interpreterLoadData, getClrVmOs()); -#endif // FEATURE_STATICALLY_LINKED && !FEATURE_JIT +#endif // FEATURE_STATICALLY_LINKED && !FEATURE_DYNAMIC_CODE_COMPILED // Publish the interpreter. m_interpreter = newInterpreter; diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 6df80eca0eaaa7..b3f66972222604 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -5723,7 +5723,7 @@ PCODE JitILStub(MethodDesc* pStubMD) // pCode = pStubMD->PrepareInitialCode(); -#if defined(FEATURE_INTERPRETER) && defined(FEATURE_JIT) +#if defined(FEATURE_INTERPRETER) && defined(FEATURE_DYNAMIC_CODE_COMPILED) // Interpreter-TODO: Figure out how to create the call stub for the IL stub only when it is // needed, like we do for the regular methods. InterpByteCodeStart *pInterpreterCode = pStubMD->GetInterpreterCode(); @@ -5731,7 +5731,7 @@ PCODE JitILStub(MethodDesc* pStubMD) { CreateNativeToInterpreterCallStub(pInterpreterCode->Method); } -#endif // FEATURE_INTERPRETER && FEATURE_JIT +#endif // FEATURE_INTERPRETER && FEATURE_DYNAMIC_CODE_COMPILED _ASSERTE(pCode == pStubMD->GetNativeCode()); } diff --git a/src/coreclr/vm/eeconfig.cpp b/src/coreclr/vm/eeconfig.cpp index 3ac8563207491a..7f66ea1b15d18e 100644 --- a/src/coreclr/vm/eeconfig.cpp +++ b/src/coreclr/vm/eeconfig.cpp @@ -451,7 +451,7 @@ HRESULT EEConfig::sync() pReadyToRunExcludeList = NULL; #ifdef FEATURE_INTERPRETER -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED LPWSTR interpreterConfig; IfFailThrow(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Interpreter, &interpreterConfig)); if (interpreterConfig == NULL) @@ -467,7 +467,7 @@ HRESULT EEConfig::sync() } #else enableInterpreter = true; -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED #endif // FEATURE_INTERPRETER enableHWIntrinsic = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableHWIntrinsic) != 0); diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp index 66a39c08a98870..7a02c59885c15d 100644 --- a/src/coreclr/vm/eventtrace.cpp +++ b/src/coreclr/vm/eventtrace.cpp @@ -4965,7 +4965,7 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAlloc _ASSERTE(pLoaderAllocatorFilter == nullptr || pLoaderAllocatorFilter->IsCollectible()); _ASSERTE(pLoaderAllocatorFilter == nullptr || !fGetCodeIds); -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED SendEventsForJitMethodsHelper2( ExecutionManager::GetEEJitManager()->GetCodeHeapIterator(pLoaderAllocatorFilter), dwEventOptions, @@ -4975,7 +4975,7 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAlloc fSendILToNativeMapEvent, fSendRichDebugInfoEvent, fGetCodeIds); -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED #ifdef FEATURE_INTERPRETER SendEventsForJitMethodsHelper2( diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index f4a17d840d5f51..72ed6e806c614c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -13568,12 +13568,12 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, } #endif // FEATURE_INTERPRETER -#ifndef FEATURE_JIT +#ifndef FEATURE_DYNAMIC_CODE_COMPILED if (!ret) { _ASSERTE(!"this platform does not support JIT compilation"); } -#else // !FEATURE_JIT +#else // !FEATURE_DYNAMIC_CODE_COMPILED if (!ret) { EEJitManager *jitMgr = ExecutionManager::GetEEJitManager(); @@ -13632,7 +13632,7 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, break; } } -#endif // !FEATURE_JIT +#endif // !FEATURE_DYNAMIC_CODE_COMPILED #ifdef _DEBUG static BOOL fHeartbeat = -1; diff --git a/src/coreclr/vm/peimagelayout.cpp b/src/coreclr/vm/peimagelayout.cpp index 5164bef9b732b9..32b0da60b993c9 100644 --- a/src/coreclr/vm/peimagelayout.cpp +++ b/src/coreclr/vm/peimagelayout.cpp @@ -834,7 +834,7 @@ void* FlatImageLayout::LoadImageByCopyingParts(SIZE_T* m_imageParts) const #endif // FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION DWORD allocationType = MEM_RESERVE | MEM_COMMIT; -#if defined(HOST_UNIX) && !defined(TARGET_IOS) && !defined(TARGET_TVOS) && !defined(TARGET_MACCATALYST) && !defined(FEATURE_NO_DYNAMIC_CODEGEN) +#if defined(HOST_UNIX) && defined(FEATURE_DYNAMIC_CODE_COMPILED) // Tell PAL to use the executable memory allocator to satisfy this request for virtual memory. // This is required on MacOS and otherwise will allow us to place native R2R code close to the // coreclr library and thus improve performance by avoiding jump stubs in managed code. diff --git a/src/coreclr/vm/stubmgr.cpp b/src/coreclr/vm/stubmgr.cpp index cf594cf213df75..a2aef346f138a3 100644 --- a/src/coreclr/vm/stubmgr.cpp +++ b/src/coreclr/vm/stubmgr.cpp @@ -1433,7 +1433,7 @@ BOOL StubLinkStubManager::TraceManager(Thread *thread, #endif // #ifndef DACCESS_COMPILE -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED // ------------------------------------------------------- // JumpStub stubs // @@ -1482,7 +1482,7 @@ BOOL JumpStubStubManager::DoTraceStub(PCODE stubStartAddress, return TRUE; } -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED // // Stub manager for code sections. It forwards the query to the more appropriate @@ -1546,10 +1546,10 @@ BOOL RangeSectionStubManager::DoTraceStub(PCODE stubStartAddress, TraceDestinati switch (GetStubKind(stubStartAddress)) { -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED case STUB_CODE_BLOCK_JUMPSTUB: return JumpStubStubManager::g_pManager->DoTraceStub(stubStartAddress, trace); -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED case STUB_CODE_BLOCK_STUBLINK: return StubLinkStubManager::g_pManager->DoTraceStub(stubStartAddress, trace); @@ -2262,7 +2262,7 @@ StubLinkStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) GetRangeList()->EnumMemoryRegions(flags); } -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED void JumpStubStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) { @@ -2271,7 +2271,7 @@ JumpStubStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) DAC_ENUM_VTHIS(); EMEM_OUT(("MEM: %p JumpStubStubManager\n", dac_cast(this))); } -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED void RangeSectionStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) diff --git a/src/coreclr/vm/stubmgr.h b/src/coreclr/vm/stubmgr.h index 971fc73e8b3da5..e7c3c160cccae2 100644 --- a/src/coreclr/vm/stubmgr.h +++ b/src/coreclr/vm/stubmgr.h @@ -504,7 +504,7 @@ class StubLinkStubManager : public StubManager #endif } ; -#ifdef FEATURE_JIT +#ifdef FEATURE_DYNAMIC_CODE_COMPILED // // Stub manager for jump stubs created by ExecutionManager::jumpStub() // @@ -542,7 +542,7 @@ class JumpStubStubManager : public StubManager { LIMITED_METHOD_CONTRACT; return W("JumpStub"); } #endif }; -#endif // FEATURE_JIT +#endif // FEATURE_DYNAMIC_CODE_COMPILED // // Stub manager for code sections. It forwards the query to the more appropriate diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs index 1a02e9900f26cc..eac1f45c16d9a3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.NonNativeAot.cs @@ -22,7 +22,7 @@ public static bool IsDynamicCodeCompiled #if MONO [Intrinsic] // the Mono AOT compiler and Interpreter will change this flag to false for FullAOT and interpreted scenarios, otherwise this code is used #endif -#if CORECLR && (TARGET_WASM || TARGET_IOS || TARGET_TVOS || TARGET_MACCATALYST || FEATURE_NO_DYNAMIC_CODEGEN) +#if CORECLR && !FEATURE_DYNAMIC_CODE_COMPILED get => false; #else get => IsDynamicCodeSupported; From 557ba3270ff8b921f07915f799c96df4de62ac89 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Tue, 10 Feb 2026 21:36:54 +0200 Subject: [PATCH 3/5] Link clrinterpreter library to coreclr_static build if jit is disabled --- src/coreclr/clrfeatures.cmake | 2 +- src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 0970b8e767550d..98b6bc198da206 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -3,7 +3,7 @@ if (FEATURE_DYNAMIC_CODE_COMPILED) set(FEATURE_REJIT 1) endif() -if (NOT FEATURE_DYNAMIC_CODE_COMPILED) +if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST) set(FEATURE_STATICALLY_LINKED 1) endif() diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 3e09134119290d..6c77034832c0dc 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -155,7 +155,9 @@ endif(FEATURE_STATICALLY_LINKED) if(FEATURE_DYNAMIC_CODE_COMPILED) set(CORECLR_STATIC_CLRJIT_STATIC clrjit_static) -endif(FEATURE_DYNAMIC_CODE_COMPILED) +elseif(FEATURE_INTERPRETER) + set(CORECLR_STATIC_CLRINTERPRETER_STATIC clrinterpreter_objects) +endif() if(CLR_CMAKE_HOST_ARCH_WASM) set(CEE_WKS_STATIC cee_wks) @@ -178,7 +180,7 @@ if(TARGET coreclr) ${FOUNDATION}) endif() -target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} ${CORECLR_STATIC_CLRJIT_STATIC} ${CLRINTERPRETER_STATIC} cee_wks_core ${CEE_WKS_STATIC} ${FOUNDATION}) +target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} ${CORECLR_STATIC_CLRJIT_STATIC} ${CORECLR_STATIC_CLRINTERPRETER_STATIC} cee_wks_core ${CEE_WKS_STATIC} ${FOUNDATION}) target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED) if (CLR_CMAKE_HOST_ANDROID) From 6abb7b50c454d5bb4ec9d2c1e544c0d65fc0303e Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 11 Feb 2026 15:02:24 +0200 Subject: [PATCH 4/5] fix wasm build --- src/coreclr/clrfeatures.cmake | 12 ++++++------ src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coreclr/clrfeatures.cmake b/src/coreclr/clrfeatures.cmake index 98b6bc198da206..1cd3d98ec74335 100644 --- a/src/coreclr/clrfeatures.cmake +++ b/src/coreclr/clrfeatures.cmake @@ -35,15 +35,15 @@ if(NOT DEFINED FEATURE_DBGIPC) endif() endif(NOT DEFINED FEATURE_DBGIPC) +if(CLR_CMAKE_TARGET_ARCH_WASM) + # FEATURE_INTERPRETER is already enabled by default + set(FEATURE_PORTABLE_ENTRYPOINTS 1) + set(FEATURE_PORTABLE_HELPERS 1) +endif(CLR_CMAKE_TARGET_ARCH_WASM) + if(NOT DEFINED FEATURE_INTERPRETER) if(CLR_CMAKE_TARGET_ANDROID) set(FEATURE_INTERPRETER 0) - elseif(CLR_CMAKE_TARGET_ARCH_WASM) - set(FEATURE_INTERPRETER 1) - set(FEATURE_PORTABLE_ENTRYPOINTS 1) - set(FEATURE_PORTABLE_HELPERS 1) - elseif(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS OR CLR_CMAKE_TARGET_MACCATALYST) - set(FEATURE_INTERPRETER 1) else() if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_RISCV64) set(FEATURE_INTERPRETER $,1,0>) diff --git a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt index 6c77034832c0dc..c0cf0a1ff4176b 100644 --- a/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt +++ b/src/coreclr/dlls/mscoree/coreclr/CMakeLists.txt @@ -156,7 +156,7 @@ endif(FEATURE_STATICALLY_LINKED) if(FEATURE_DYNAMIC_CODE_COMPILED) set(CORECLR_STATIC_CLRJIT_STATIC clrjit_static) elseif(FEATURE_INTERPRETER) - set(CORECLR_STATIC_CLRINTERPRETER_STATIC clrinterpreter_objects) + set(CORECLR_STATIC_CLRINTERPRETER_STATIC clrinterpreter_objects dn-containers gcinfo) endif() if(CLR_CMAKE_HOST_ARCH_WASM) From d57b83dd9978c7074ec1621c1b1003ede669d4cf Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 11 Feb 2026 15:05:48 +0200 Subject: [PATCH 5/5] Fix crossgen2 handling of `TargetAllowsRuntimeCodeGeneration` iOS build will use crossgen2 built on desktop, which will always have `FEATURE_DYNAMIC_CODE_COMPILED` defined. We still need to resolve this property by checking the actual target platform. If we build the runtime without `FEATURE_DYNAMIC_CODE_COMPILED` then we can hardcode the behavior in crossgen2, as always false. --- .../Compiler/ReadyToRunCompilerContext.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs index de78b52749c2c2..cd6bc5040fd10e 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs @@ -105,6 +105,16 @@ public bool TargetAllowsRuntimeCodeGeneration get { #if FEATURE_DYNAMIC_CODE_COMPILED + if (Target.OperatingSystem is TargetOS.iOS or TargetOS.iOSSimulator or TargetOS.MacCatalyst or TargetOS.tvOS or TargetOS.tvOSSimulator) + { + return false; + } + + if (Target.Architecture is TargetArchitecture.Wasm32) + { + return false; + } + return true; #else return false;