From 23bf8d3c52c27a32809a14cba59cb2659cff5350 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 12 Mar 2026 15:42:48 -0700
Subject: [PATCH 1/3] Add large-version-bubble test to crossgen2-composite
pipeline
---
.../common/templates/runtimes/run-test-job.yml | 5 +++++
.../templates/runtimes/send-to-helix-step.yml | 2 ++
eng/pipelines/coreclr/crossgen2-composite.yml | 18 ++++++++++++++++++
src/tests/Common/helixpublishwitharcade.proj | 4 ++++
4 files changed, 29 insertions(+)
diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml
index 3efa4a5944f7ae..34351420b99805 100644
--- a/eng/pipelines/common/templates/runtimes/run-test-job.yml
+++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml
@@ -11,6 +11,7 @@ parameters:
hotColdSplitting: false
liveLibrariesBuildConfig: ''
compositeBuildMode: false
+ largeVersionBubble: false
useCodeFlowEnforcement: ''
helixQueues: ''
condition: true
@@ -129,6 +130,9 @@ jobs:
- ${{ if eq(parameters.hotColdSplitting, true) }}:
- name: LogNamePrefix
value: TestRunLogs_R2R_CG2_HotColdSplitting
+ - ${{ if eq(parameters.largeVersionBubble, true) }}:
+ - name: LogNamePrefix
+ value: TestRunLogs_R2R_CG2_LargeVersionBubble
- name: testFilterArg
value: ''
@@ -316,6 +320,7 @@ jobs:
runInterpreter: ${{ parameters.runInterpreter }}
tieringTest: ${{ parameters.tieringTest }}
hotColdSplitting: ${{ parameters.hotColdSplitting }}
+ largeVersionBubble: ${{ parameters.largeVersionBubble }}
${{ if eq(variables['System.TeamProject'], 'internal') }}:
# Access token variable for internal project from the
diff --git a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
index fa99f7e5597212..9e66956a3c2547 100644
--- a/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
+++ b/eng/pipelines/common/templates/runtimes/send-to-helix-step.yml
@@ -24,6 +24,7 @@ parameters:
runInterpreter: ''
tieringTest: ''
hotColdSplitting: ''
+ largeVersionBubble: false
nativeAotTest: ''
longRunningGcTests: ''
gcSimulatorTests: ''
@@ -59,6 +60,7 @@ steps:
_RunInterpreter: ${{ parameters.runInterpreter }}
_TieringTest: ${{ parameters.tieringTest }}
_HotColdSplitting: ${{ parameters.hotColdSplitting }}
+ _LargeVersionBubble: ${{ parameters.largeVersionBubble }}
_NativeAotTest: ${{ parameters.nativeAotTest }}
_LongRunningGcTests: ${{ parameters.longRunningGcTests }}
_GcSimulatorTests: ${{ parameters.gcSimulatorTests }}
diff --git a/eng/pipelines/coreclr/crossgen2-composite.yml b/eng/pipelines/coreclr/crossgen2-composite.yml
index 5d0712ca2eabf4..23bb12d4af4d8f 100644
--- a/eng/pipelines/coreclr/crossgen2-composite.yml
+++ b/eng/pipelines/coreclr/crossgen2-composite.yml
@@ -80,3 +80,21 @@ extends:
displayNameArgs: Composite
liveLibrariesBuildConfig: Release
unifiedArtifactsName: BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig)
+
+ # Composite mode with large version bubble (inputbubble)
+ - template: /eng/pipelines/common/platform-matrix.yml
+ parameters:
+ jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml
+ helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml
+ buildConfig: checked
+ platforms:
+ - linux_x64
+ - windows_x64
+ jobParameters:
+ testGroup: innerloop
+ readyToRun: true
+ compositeBuildMode: true
+ largeVersionBubble: true
+ displayNameArgs: Composite_LargeVersionBubble
+ liveLibrariesBuildConfig: Release
+ unifiedArtifactsName: BuildArtifacts_$(osGroup)$(osSubgroup)_$(archType)_$(_BuildConfig)
diff --git a/src/tests/Common/helixpublishwitharcade.proj b/src/tests/Common/helixpublishwitharcade.proj
index 00aad5810c43ce..a6105b68c3b843 100644
--- a/src/tests/Common/helixpublishwitharcade.proj
+++ b/src/tests/Common/helixpublishwitharcade.proj
@@ -42,6 +42,7 @@
<_RunInterpreter>false
<_TieringTest>false
<_HotColdSplitting>false
+ <_LargeVersionBubble>false
<_NativeAotTest>false
<_TimeoutPerTestCollectionInMinutes>123
<_TimeoutPerTestInMinutes>234
@@ -107,6 +108,7 @@
RunInterpreter=$(_RunInterpreter);
TieringTest=$(_TieringTest);
HotColdSplitting=$(_HotColdSplitting);
+ LargeVersionBubble=$(_LargeVersionBubble);
NativeAotTest=$(_NativeAotTest);
TimeoutPerTestCollectionInMinutes=$(_TimeoutPerTestCollectionInMinutes);
TimeoutPerTestInMinutes=$(_TimeoutPerTestInMinutes);
@@ -594,6 +596,7 @@
+
@@ -649,6 +652,7 @@
+
From 075a72b953d3c00dff90345d60d28dac7e23db70 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 12 Mar 2026 13:12:34 -0700
Subject: [PATCH 2/3] Don't try to compile async methods in CompositeBuildMode
---
.../ReadyToRunCodegenNodeFactory.cs | 2 +-
.../JitInterface/CorInfoImpl.ReadyToRun.cs | 12 ++++++++++--
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
index 8a9602d24f51ef..2b610bdc110b56 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs
@@ -487,7 +487,7 @@ public IEnumerable EnumerateCompiledMethods(EcmaModule moduleT
// ARM32 relocs require the thumb bit set, and the JIT/crossgen doesn't set it properly for the usages in async methods.
// https://github.com/dotnet/runtime/issues/125337
// https://github.com/dotnet/runtime/issues/125338
- if ((CompilationModuleGroup.IsCompositeBuildMode || Target.Architecture == TargetArchitecture.ARM)
+ if (Target.Architecture == TargetArchitecture.ARM
&& (method.IsAsyncVariant() || method.IsCompilerGeneratedILBodyForAsync()))
{
continue;
diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
index c5e2d1f8ca40c3..6709cbc7fb8d5a 100644
--- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
+++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
@@ -535,7 +535,7 @@ private static mdToken FindGenericMethodArgTypeSpec(EcmaModule module)
throw new NotSupportedException();
}
- public static bool ShouldSkipCompilation(InstructionSetSupport instructionSetSupport, MethodDesc methodNeedingCode)
+ public static bool ShouldSkipCompilation(InstructionSetSupport instructionSetSupport, MethodDesc methodNeedingCode, ReadyToRunCodegenCompilation compilation = null)
{
bool targetAllowsRuntimeCodeGeneration = ((ReadyToRunCompilerContext)methodNeedingCode.Context).TargetAllowsRuntimeCodeGeneration;
if (methodNeedingCode.IsAggressiveOptimization && targetAllowsRuntimeCodeGeneration)
@@ -569,6 +569,14 @@ public static bool ShouldSkipCompilation(InstructionSetSupport instructionSetSup
// Special methods on delegate types
return true;
}
+ // Async resumption stubs use faux IL with synthetic tokens. When CoreLib is in the
+ // version bubble the stubs are not wrapped with ManifestModuleWrappedMethodIL, so
+ // token resolution for InstantiatedType / ParameterizedType falls through to a path
+ // that cannot handle them. Skip compilation and let the runtime JIT these stubs.
+ if (methodNeedingCode.IsCompilerGeneratedILBodyForAsync() && compilation != null && compilation.NodeFactory.CompilationModuleGroup.IsCompositeBuildMode)
+ {
+ return true;
+ }
if (ShouldCodeNotBeCompiledIntoFinalImage(instructionSetSupport, methodNeedingCode))
{
return true;
@@ -770,7 +778,7 @@ public void CompileMethod(MethodWithGCInfo methodCodeNodeNeedingCode, Logger log
try
{
- if (ShouldSkipCompilation(_compilation.InstructionSetSupport, MethodBeingCompiled))
+ if (ShouldSkipCompilation(_compilation.InstructionSetSupport, MethodBeingCompiled, _compilation))
{
if (logger.IsVerbose)
logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it is skipped.");
From c94f2e565489d9be814a0fb51b53c0834be8d754 Mon Sep 17 00:00:00 2001
From: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
Date: Thu, 12 Mar 2026 18:28:55 -0700
Subject: [PATCH 3/3] Add referencepath to COREROOT to r2rdump when running
coreclr tests with crossgen
---
src/tests/Common/CLRTest.CrossGen.targets | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/tests/Common/CLRTest.CrossGen.targets b/src/tests/Common/CLRTest.CrossGen.targets
index 8b45eb30ddec36..ceaa10324ca08b 100644
--- a/src/tests/Common/CLRTest.CrossGen.targets
+++ b/src/tests/Common/CLRTest.CrossGen.targets
@@ -96,7 +96,7 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then
__R2RDumpCommand+=" dotnet"
fi
__R2RDumpCommand+=" $CORE_ROOT/R2RDump/R2RDump.dll"
- __R2RDumpCommand+=" --header --sc --in $__OutputFileFinal --out $__OutputFileFinal.r2rdump --val"
+ __R2RDumpCommand+=" --header --sc --in $__OutputFileFinal --out $__OutputFileFinal.r2rdump --val --rp $CORE_ROOT"
__Command="$_DebuggerFullPath $CORE_ROOT/crossgen2/crossgen2"
__Command+=" @$__ResponseFile"
@@ -289,7 +289,7 @@ if defined RunCrossGen2 (
set __DotNet="dotnet"
)
set __R2RDumpCommand=!_DebuggerFullPath! !__DotNet! "!CORE_ROOT!\r2rdump\r2rdump.dll"
- set __R2RDumpCommand=!__R2RDumpCommand! --header --sc --in !__OutputFile! --out !__OutputFile!.r2rdump --val
+ set __R2RDumpCommand=!__R2RDumpCommand! --header --sc --in !__OutputFile! --out !__OutputFile!.r2rdump --val --rp "!CORE_ROOT!"
set __Command=!_DebuggerFullPath! "!CORE_ROOT!\crossgen2\crossgen2.exe"
set __Command=!__Command! @"!__ResponseFile!"