Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
9a1ddd8
Add crossgen CI analysis agentic workflow (#9)
jtschuster Mar 27, 2026
87296e1
Crossgen2 ci triage workflow (#10)
jtschuster Mar 27, 2026
130a3c0
Crossgen2 ci triage workflow (#19)
jtschuster Mar 31, 2026
1606998
Add cross-module R2R reference resolution tests
jtschuster Mar 31, 2026
1493728
Add runtime-async method variants to cross-module resolution tests
jtschuster Mar 31, 2026
70ad8f0
Add R2R validation tool for cross-module resolution tests
jtschuster Mar 31, 2026
1575e66
Extract crossgen2 precommands into shared .targets file
jtschuster Mar 31, 2026
ee26040
Refactor crossgen2 orchestration into C# console app
jtschuster Mar 31, 2026
67ffdd6
Output runcrossgen to CORE_ROOT/runcrossgen/
jtschuster Mar 31, 2026
d5b2d3a
Use host SDK RID for runcrossgen build-time tool
jtschuster Mar 31, 2026
5514f1b
Merge branch 'dotnet:main' into main
jtschuster Apr 1, 2026
8029183
WIP: Add ILCompiler.ReadyToRun.Tests project
jtschuster Apr 1, 2026
3e1a6c8
Fix R2R test validation and remove opt-async-methods
jtschuster Apr 1, 2026
183262c
Add runtime-async functional tests for R2R
jtschuster Apr 1, 2026
7bb35e5
Refactor R2R test model: rename DependencyInfo to CompiledAssembly, a…
jtschuster Apr 1, 2026
804ec55
Replace R2RExpectations with Action<ReadyToRunReader> validation call…
jtschuster Apr 1, 2026
25ee0be
Fix R2R test runner: --opt-cross-module args and composite output naming
jtschuster Apr 2, 2026
b2e0f5b
Add InliningInfo2 structured parsing and method-targeted assertions
jtschuster Apr 2, 2026
c8c6a35
Add 10 new R2R cross-module/async/composite test cases
jtschuster Apr 2, 2026
805f042
Add test source files for new R2R test cases
jtschuster Apr 2, 2026
d90a6cd
Fix composite tests: add --optimize flag and cross-assembly inline as…
jtschuster Apr 2, 2026
67e8d19
Fix code review issues: parser bug, deadlock, file handle leak
jtschuster Apr 2, 2026
2ab55e0
Add CrossModuleGenericMultiInliner test for cross-module inliner parsing
jtschuster Apr 2, 2026
03d71ec
Validate resolved inliner names in HasCrossModuleInliners
jtschuster Apr 2, 2026
22e55bd
Remove unused Utility.GetName() from CrossModuleGenericLib test
jtschuster Apr 2, 2026
b6d5227
Remove session state and planning files from tracking
jtschuster Apr 2, 2026
61ea4a9
Remove crossmoduleresolution tests from src/tests/readytorun
jtschuster Apr 2, 2026
537cd1b
Fix stale and inaccurate comments across R2R test files
jtschuster Apr 2, 2026
54a3bb6
Enable async method variants in composite mode
jtschuster Apr 2, 2026
0aa5103
Remove unused using System directive in MultiStepAsyncConsumer
jtschuster Apr 2, 2026
40a61b2
Revert async method variant enablement in composite mode
jtschuster Apr 2, 2026
ce4ca00
WIP: Execution infrastructure, ActiveIssue, and MethodDefEntryPointsT…
jtschuster Apr 3, 2026
cc18125
Crossgen2 CI triage: cross-reference runtime pipeline and restrict to…
Copilot Apr 3, 2026
fa70608
Don't use MutableModuleWrappedMethodIL for async thunks
jtschuster Apr 8, 2026
e0613cc
Merge branch 'main' of https://github.com/jtschuster/runtime into com…
jtschuster Apr 8, 2026
8dc7ab0
Force OwningTypeNotDerivedFromToken for method references in async th…
jtschuster Apr 8, 2026
849c73b
Revert NativeArray changes
jtschuster Apr 8, 2026
b53da9f
Undo all changes related to the test infra change this was branched off
jtschuster Apr 9, 2026
1bab3b6
Remove .github changes
jtschuster Apr 9, 2026
505abeb
Revert more changes
jtschuster Apr 9, 2026
8edd9b9
Revert changes to .github to the right version?
jtschuster Apr 9, 2026
b733fad
one more try at the .github dir
jtschuster Apr 9, 2026
3d0f41d
Merge branch 'main' of https://github.com/dotnet/runtime into composi…
jtschuster Apr 14, 2026
8b63902
Extract EnsureDefTokensAreAvailable and related method to ExternalRef…
jtschuster Apr 14, 2026
f2704fb
Add details to stale IL-CG2 warning
jtschuster Apr 14, 2026
9fc88fa
Address copilot feedback
jtschuster Apr 14, 2026
182b580
Merge branch 'main' into composite-async-variants
jtschuster Apr 14, 2026
1aa38f9
Fix PR comments
jtschuster Apr 15, 2026
c66c646
Properly get the EcmaMethod in CreateCrossModuleInlineableTokensForIL…
jtschuster Apr 16, 2026
303dcdc
Get IL for the (possible instantiated) method, not the definition
jtschuster Apr 17, 2026
bb834fe
Merge branch 'main' of https://github.com/dotnet/runtime into composi…
jtschuster Apr 17, 2026
0ef7dfc
Expand R2R composite-async test coverage and refactor R2RAssert to bo…
jtschuster Apr 17, 2026
0f5280d
Add CompositeAsyncGenericTypes regression test
jtschuster Apr 17, 2026
c224b67
Dedupe R2R test fixtures: LocalsCapturedAcrossAwait & InlinableAsyncM…
jtschuster Apr 20, 2026
ef70780
Dedupe R2R async devirt test fixtures: AwaitsThroughInterface
jtschuster Apr 20, 2026
49bb774
Dedupe R2R transitive test fixtures: share leaf between sync + async …
jtschuster Apr 20, 2026
d3fe5b8
Rename R2R basic-inlining test fixtures to describe code, not scenario
jtschuster Apr 20, 2026
4998999
Rename remaining R2R test fixtures to describe code, not scenario
jtschuster Apr 20, 2026
2203bd7
Rename R2R test deps to <WhatsInFile>.cs; merge InlinableAsyncMethods…
jtschuster Apr 20, 2026
fdcb6c2
Revert R2R test fixture dedup/rename to keep follow-up PR isolated
jtschuster Apr 20, 2026
f641339
Replace ad-hoc header comments in R2R test fixtures with MIT license …
jtschuster Apr 20, 2026
22d2b51
Restore original headers on R2R test fixtures unchanged by this branch
jtschuster Apr 20, 2026
0b97456
Remove redundant OwningType comparison in MethodWithToken.CompareTo
jtschuster Apr 20, 2026
4251106
Clarify EnsureDefTokensAreAvailable XML docs
jtschuster Apr 20, 2026
4f380b5
Add positive composite cross-module inlining test
jtschuster Apr 20, 2026
faa8ce1
Simplify test comments, remove redundant test
jtschuster Apr 20, 2026
b85e2d2
Refine documentation for CompositeProducesCrossModuleInliningInfoForE…
jtschuster Apr 20, 2026
37d3d6a
Include OwningTypeNotDerivedFromToken in FieldWithToken.Equals
jtschuster Apr 20, 2026
04352ad
Forward strippedInstantiation to FieldWithToken in shared generic lookup
jtschuster Apr 20, 2026
47e4e25
Assert strippedInstantiation is false in FieldDesc helper-arg path
jtschuster Apr 20, 2026
99b84bc
Fix FieldWithToken.CompareTo
jtschuster Apr 20, 2026
7f15da0
Add asserts, revert extra change
jtschuster Apr 21, 2026
81dac5f
Remove redundant CreatingTokensForAsyncMethod set in EnsureAsyncThunk…
jtschuster Apr 22, 2026
cefc723
Merge branch 'main' of https://github.com/dotnet/runtime into composi…
jtschuster Apr 28, 2026
a902c89
Get Field token with compilation ModuleTokenResolver
jtschuster Apr 28, 2026
9a6f3f7
Use IL availability as determining factor for whether to create Mutab…
jtschuster Apr 28, 2026
8290b2c
Enable getting PrimaryMethodDesc for ReturnDroppingThunks
jtschuster Apr 28, 2026
f38e8da
Compare forceOwningTypeNotDerivedFromToken in XWithTokien types
jtschuster Apr 28, 2026
ad8fa51
Allow empty string to be resolved for inlinees of ILStubs
jtschuster Apr 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,11 @@ public static MethodDesc GetTargetOfAsyncVariant(this MethodDesc method)
Debug.Assert(method.IsAsyncVariant());
return ((CompilerTypeSystemContext)method.Context).GetTargetOfAsyncVariantMethod(method);
}

public static MethodDesc GetTargetOfReturnDroppingAsyncThunk(this MethodDesc method)
{
Debug.Assert(method.IsReturnDroppingAsyncThunk());
return ((CompilerTypeSystemContext)method.Context).GetTargetOfReturnDroppingThunk(method);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,26 @@ public MethodDesc GetAsyncVariantMethod(MethodDesc taskReturningMethod)
return result;
}

public MethodDesc GetTargetOfReturnDroppingThunk(MethodDesc returnDroppingThunk)
{
Debug.Assert(returnDroppingThunk.IsReturnDroppingAsyncThunk());
var returnDroppingThunkDefinition = (ReturnDroppingAsyncThunk)returnDroppingThunk.GetTypicalMethodDefinition();
MethodDesc result = returnDroppingThunkDefinition.AsyncVariantTarget;

// If there are generics involved, we need to specialize
if (returnDroppingThunk != returnDroppingThunkDefinition)
{
TypeDesc owningType = returnDroppingThunk.OwningType;
if (owningType != returnDroppingThunkDefinition.OwningType)
result = GetMethodForInstantiatedType(result, (InstantiatedType)owningType);

if (returnDroppingThunk.HasInstantiation && !returnDroppingThunk.IsMethodDefinition)
result = GetInstantiatedMethod(result, returnDroppingThunk.Instantiation);
}

return result;
}

private sealed class AsyncVariantHashtable : LockFreeReaderHashtable<EcmaMethod, AsyncMethodVariant>
{
protected override int GetKeyHashCode(EcmaMethod key) => key.GetHashCode();
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1872,6 +1872,7 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken)
else
{
recordToken = (_compilation.CompilationModuleGroup.VersionsWithType(owningType) || _compilation.CompilationModuleGroup.CrossModuleInlineableType(owningType)) && owningType is EcmaType;
recordToken &= methodIL.GetMethodILScopeDefinition() is IMethodTokensAreUseableInCompilation || methodIL.GetMethodILScopeDefinition() is IEcmaMethodIL;
}
#endif

Expand All @@ -1884,7 +1885,8 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken)
#if READYTORUN
if (recordToken)
{
ModuleToken methodModuleToken = HandleToModuleToken(ref pResolvedToken);
ModuleToken methodModuleToken = HandleToModuleToken(ref pResolvedToken, out bool strippedInstantiation);
Debug.Assert(!strippedInstantiation);
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HandleToModuleToken(..., out strippedInstantiation) can legitimately set strippedInstantiation=true for faux MethodIL (e.g., compiler-generated IL stubs) when it strips method instantiation (see CorInfoImpl.ReadyToRun.cs where it compares primary vs typical method definition). Since recordToken explicitly allows IMethodTokensAreUseableInCompilation, Debug.Assert(!strippedInstantiation) here can fire when compiling those stubs (including async thunk scenarios this PR enables). Consider removing this assert or adjusting the logic to tolerate stripped instantiation (and rely on the MethodDesc/type context when building signatures).

Suggested change
Debug.Assert(!strippedInstantiation);
// Faux/stub MethodIL can legitimately strip method instantiation when producing a module token.
// Record the token anyway and rely on the resolved MethodDesc for signature-based operations.
_ = strippedInstantiation;

Copilot uses AI. Check for mistakes.
var resolver = _compilation.NodeFactory.Resolver;
resolver.AddModuleTokenForMethod(method, methodModuleToken);
ValidateSafetyOfUsingTypeEquivalenceInSignature(method.Signature);
Expand Down Expand Up @@ -1951,7 +1953,8 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken)
#if READYTORUN
if (recordToken)
{
_compilation.NodeFactory.Resolver.AddModuleTokenForType(type, HandleToModuleToken(ref pResolvedToken));
_compilation.NodeFactory.Resolver.AddModuleTokenForType(type, HandleToModuleToken(ref pResolvedToken, out bool strippedInstantiation));
Debug.Assert(!strippedInstantiation);
}
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ internal class TypeSystemMetadataEmitter
_metadataBuilder = new MetadataBuilder();
_ilBuilder = new BlobBuilder();
_methodBodyStream = new MethodBodyStreamEncoder(_ilBuilder);
_ = _metadataBuilder.GetOrAddString(string.Empty);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't do anything:

public StringHandle GetOrAddString(string value)
{
if (value is null)
{
Throw.ArgumentNull(nameof(value));
}
StringHandle handle;
if (value.Length == 0)
{
handle = default(StringHandle);
}
else if (!_strings.TryGetValue(value, out handle))
{
handle = StringHandle.FromWriterVirtualIndex(_strings.Count + 1); // idx 0 is reserved for empty string
_strings.Add(value, handle);
}
return handle;
}

StringHandle assemblyNameHandle = _metadataBuilder.GetOrAddString(assemblyName.Name);
if (assemblyName.CultureName != null)
throw new ArgumentException("assemblyName");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using System.Threading.Tasks;

public static class AsyncInlineCallers
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static async Task CallReturnTaskNoAwait()
{
await AsyncInlineCandidatesLib.ReturnTaskNoAwait();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static async Task<int> CallReturnTaskPrimitiveNoAwait()
{
return await AsyncInlineCandidatesLib.ReturnTaskPrimitiveNoAwait();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static async Task<string> CallReturnTaskClassNoAwait()
{
return await AsyncInlineCandidatesLib.ReturnTaskClassNoAwait();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static async Task CallReturnTaskWithAwait()
{
await AsyncInlineCandidatesLib.ReturnTaskWithAwait();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static async Task<int> CallReturnTaskPrimitiveWithAwait()
{
return await AsyncInlineCandidatesLib.ReturnTaskPrimitiveWithAwait();
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static async Task<string> CallReturnTaskClassWithAwait()
{
return await AsyncInlineCandidatesLib.ReturnTaskClassWithAwait();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using System.Threading.Tasks;

public static class AsyncInlineCandidatesLib
{
// --- Awaitless variants: should be inlinable ---

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task ReturnTaskNoAwait()
{
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<int> ReturnTaskPrimitiveNoAwait() => 42;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<string> ReturnTaskClassNoAwait() => "no_await";

// --- Variants containing an actual await: cannot be inlined by the JIT ---

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task ReturnTaskWithAwait()
{
await Task.Yield();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<int> ReturnTaskPrimitiveWithAwait()
{
await Task.Yield();
return 42;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<string> ReturnTaskClassWithAwait()
{
await Task.Yield();
return "with_await";
}
}
Loading
Loading