Skip to content

Conversation

@jtschuster
Copy link
Owner

Encode Continuation types in R2R images using a new fixup kind (READYTORUN_FIXUP_Continuation_Layout = 0x37):

  • Include OwningMethod to associate the Continuation type with the correct loader allocator at runtime
  • Encode the GC ref map as a bit vector expanded to a byte array
  • Add AsyncContinuationLayoutAlgorithm for field layout computation

Add runtime support to read continuation type fixups from R2R images:

  • GetContinuationTypeFromLayout decodes the blob and creates the type
  • LoadDynamicInfoEntry handles the new fixup kind

Also adds helper constants for future continuation allocation helpers.

Note: These code paths are not yet exercised as async2 methods are not currently compiled to ReadyToRun images.

janvorli and others added 30 commits January 16, 2026 21:34
This fixes the
System.Runtime.Tests.ControlledExecutionTests.CancelItselfFromFinally
libraries test that was failing with the interpreter. The issue was that
finally block was being aborted due to the fact that instead of the
complex COMPlusCheckForAbort, the interpreter was only checking if abort
was requested.
Fixes dotnet#122472

From some inspection, it looks like `PerfMap::Initialize` does not
depend on the methods right above it.
```
#ifdef FEATURE_PERFTRACING
        DiagnosticServerAdapter::Initialize();
        DiagnosticServerAdapter::PauseForDiagnosticsMonitor();
#endif // FEATURE_PERFTRACING

#ifdef FEATURE_GDBJIT
        // Initialize gdbjit
        NotifyGdb::Initialize();
#endif // FEATURE_GDBJIT

#ifdef FEATURE_EVENT_TRACE
        // Initialize event tracing early so we can trace CLR startup time events.
        InitializeEventTracing();

        // Fire the EE startup ETW event
        ETWFireEvent(EEStartupStart_V1);
#endif // FEATURE_EVENT_TRACE

        InitGSCookie();

#ifdef LOGGING
        InitializeLogging()
#endif
```
`PerfMap::Initialize` depends on `SString::Startup()` which occurs
earlier in startup and some PAL/OS services.

Instead of adding more logic to handle a racing DiagnosticServer IPC
[`EnablePerfMap`
command](https://github.com/dotnet/diagnostics/blob/main/documentation/design-docs/ipc-protocol.md#enableperfmap)
and `PerfMap::Initialize` (e.g. lazy-init/queued commands), bump the
PerfMap initialization ahead of the DiagnosticServer initialization. The
DiagnosticServer also doesn't depend on PerfMap being initialized
afterwards, and PerfMap's `CrstStatic` and `PerfMap::Enable(type,
sendExisting)` suggests that the IPC enable perfmap command should occur
after `PerfMap::Initialize`.

This way, DiagnosticServer is still early in startup, and its
`PerfMap::Enable` will not crash the runtime.
As for the IPC command to set environment variables, it is unlikely that
it was used to `DOTNET_PerfMapEnabled` because that would either not
have applied early enough or have crashed the runtime like in the issue.
Instead, the `EnablePerfMap`/`DisablePerfMap` commands should be used to
toggle PerfMap status.
…forms (dotnet#123274)

## Description

NativeAOT runtime packs for iOS and other Apple mobile platforms were
missing required static libraries (libSystem.Globalization.Native.a,
libSystem.IO.Compression.Native.a, libSystem.Native.a, libbrotli*.a)
starting in version 11.0.0-alpha.1.26065.101.

## Changes

Modified `eng/liveBuilds.targets` in the
`ResolveLibrariesRuntimeFilesFromLocalBuild` target:

- Added `BuildNativeAOTRuntimePack != 'true'` condition to the
`ExcludeNativeLibrariesRuntimeFiles` item for Apple mobile platforms
- Updated comment to clarify that the exclusion does not apply to
NativeAOT

**Rationale**: Regular CoreCLR packs retrieve these libraries from the
CoreCLR shared framework directory, so they're excluded from
LibrariesRuntimeFiles to avoid duplicates. NativeAOT packs do not reach
back into CoreCLR shared framework artifacts and require these libraries
from LibrariesRuntimeFiles.

```xml
<!-- Before -->
<ExcludeNativeLibrariesRuntimeFiles Condition="'$(TargetsAppleMobile)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR'"

<!-- After -->
<ExcludeNativeLibrariesRuntimeFiles Condition="'$(TargetsAppleMobile)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR' and '$(BuildNativeAOTRuntimePack)' != 'true'"
```

## Testing

The fix will be validated when NativeAOT runtime packs for Apple mobile
platforms are built in CI/CD, verifying that the static libraries are
included in the package output.

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Latest .NET 11 NativeAOT packs missing some static
libraries</issue_title>
> <issue_description>The `11.0.0-alpha.1.26065.101` version of the
`microsoft.netcore.app.runtime.nativeaot.ios-arm64` pack (and probably
other packs for other RIDs as well, I haven't checked) are missing the
following files:
> 
>  * libSystem.Globalization.Native.a
>  * libSystem.IO.Compression.Native.a
>  * libSystem.Native.a
>  * libbrotlicommon.a
>  * libbrotlidec.a
>  * libbrotlienc.a
> 
> They were present in `11.0.0-alpha.1.26062.101`
> 
> Complete file list:
https://gist.github.com/rolfbjarne/7f42f3cf3ed3a815e2e9fe2b28c580fb#file-gistfile1-txt-L76-L82
> 
> This started happening in this maestro PR:
dotnet/macios#24508
> 
> specifically this commit:
dotnet/macios@ee15359
> 
> I tried looking through the relevant dotnet/runtime commits, but I
didn't see anything obvious causing this.</issue_description>
> 
> <agent_instructions>In the ResolveLibrariesRefAssembliesFromLocalBuild
target in eng/livebuilds.targets, add BuildNativeAOTRuntimePack !=
'true' to the condition in the ExcludeNativeLibrariesRuntimeFiles. It
should only apply to the item where TargetsAppleMobile == 'true'.
> 
> Additionally, update the comment above the item to indicate that it
does not apply to nativeaot because we do not reach back into coreclr
sharedFramework artifacts.</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@MichalStrehovsky</author><body>
> > and probably other packs for other RIDs as well, I haven't checked
> 
> I checked
Microsoft.NETCore.App.Runtime.NativeAOT.linux-arm64.11.0.0-preview.1.26065.113
and that one has these.
Microsoft.NETCore.App.Runtime.NativeAOT.ios-arm64.11.0.0-preview.1.26065.113
doesn't have these.
> 
> So looks to be iDevice specific. I can't build these things locally as
I don't have a mac.</body></comment_new>
> <comment_new><author>@steveisok</author><body>
> In the local build, it looks like coreclr and nativeaot are supposed
to look back to
`artifacts/bin/coreclr/ios.<arch>.<config>/sharedFramework` for the
native lib artifacts. NativeAOT does not appear to be doing that, hence
the reason the static libs aren't included. </body></comment_new>
> <comment_new><author>@steveisok</author><body>
> `ResolveLibrariesRuntimeFilesFromLocalBuild` typically copies all the
libraries and native lib bits. There's a step to exclude some native
bits if the runtime is coreclr or nativeaot because they are supposed to
be accounted for in `ResolveRuntimeFilesFromLocalBuild`. That's not
happening for nativeaot due to `BuildNativeAOTRuntimePack=true`.
</body></comment_new>
> <comment_new><author>@steveisok</author><body>
> @kotlarmilos if you want, I can fix it. It's no problem, so let me
know.</body></comment_new>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes dotnet#123253

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: steveisok <[email protected]>
…t slowpatheltleave.sh catched on 2K3000. (dotnet#123250)

like [PR#122714](dotnet#122714), use
`pData->buffer` to return `struct{single, single}` in
`ProfileArgIterator::GetReturnBufferAddr()`.
… platforms (dotnet#122789)

We had a couple of places that were using `__builtin_available` to guard
against some platform version features. Now that our Apple platform
floor is macOS 12 and iOS/tvOS 13, we can remove some of them.

Co-authored-by: Jeremy Barton <[email protected]>
Adding 3 constants that represent C#, F#, and Visual Basic to the
StringSyntaxAttribute

Fix dotnet#122604
…23270)

I've decided to do a bespoke function for WASM, mainly due to the
awkwardness of porting the register mask code that would be of
questionable value. Instead, we place an allocation constraint on the
RA.

With these changes, we are very close to getting a functional "add(x,
y)". The only remaining part is the SP arg, being worked on in
dotnet#123262.

This is not a fully sound implementation since we have a limit on the
number of instructions in the prolog (and here we're generating a
potentially unbounded number of instruction). I've put a point about
this into dotnet#121865. It seems this single-IG restriction ought to be
fixable...
…122758)

The `nonExpansive` parameter in `Dictionary::PopulateEntry` was always
passed as `FALSE` from its only call site in `jithelpers.cpp`. This
change removes the dead parameter and simplifies the implementation by
eliminating unreachable code paths.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: jkotas <[email protected]>
This PR adds a fast path in `IEnumerableSkipTakeIterator.TryGetLast`.
When source is an Iterator and `GetCount(onlyIfCheap: true)` returns a
valid count (not -1), check if count <= _minIndexInclusive. In this
case, immediately return with found=false.

---------

Co-authored-by: Stephen Toub <[email protected]>
…t#123333)

Sometimes code is placed at a higher native offset than the code at IL
offsets adjacent to it. Our debugger algorithm deals with this by,
during traversal of mappings, [setting the IL offset
back](https://github.com/dotnet/runtime/blob/6afecd4adc64210e5b46767d02a6495af1a08c46/src/coreclr/vm/debugdebugger.cpp#L1321)
if one is encountered that is lower than the current IL offset in the
traversal. Native AOT does not have this mechanism, which leads to such
code being misattributed to higher-than-actual source lines.

This change reproduces this mechanism in NativeAOT by inserting a native
sequence point whenever the IL offset drops below the previous offset.

Repro issue (line attribution of DoWork):

```csharp
using System.Runtime.CompilerServices;

static class Program
{
#line 53
	[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
	public async static Task Main()
	{
		await DoWork(0);
	}
	[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
	public async static Task BackgroundWorker1()
	{
		// await Task.Delay(10000);
		// await Task.Yield();
		throw new InvalidOperationException("BackgroundWorker1 exception.");
	}
	[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
	public async static Task BackgroundWorker2()
	{
		await Task.Delay(10);
		Console.WriteLine("BackgroundWorker2 completed.");
	}
	[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
	public async static Task BackgroundWorker3()
	{
		await Task.Delay(10);
		Console.WriteLine("BackgroundWorker3 completed.");
	}
	
	[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
	static async Task DoWork(int i)
	{
		Task worker1 = BackgroundWorker1();
		Task worker2 = BackgroundWorker2();
		Task worker3 = BackgroundWorker3();
		await Task.WhenAll(worker1, worker2, worker3);
		Console.WriteLine("All background workers completed.");
	}
}
```
Config: Windows x64 Debug, .NET 11.0.100-alpha.1.25618.104,
runtime-async on
<table>
  <tr>
    <th>NativeOffset</th>
    <td>0</td>
    <td>106</td>
    <td>107</td>
    <td>107</td>
    <td>116</td>
    <td>124</td>
    <td>124</td>
    <td>133</td>
    <td>141</td>
    <td>141</td>
    <td>150</td>
    <td>158</td>
    <td>169</td>
    <td>183</td>
    <td>192</td>
    <td>205</td>
    <td>222</td>
    <td>231</td>
    <td>244</td>
    <td>261</td>
    <td>270</td>
    <td>283</td>
    <td>307</td>
    <td>312</td>
    <td>357</td>
    <td>379</td>
    <td>380</td>
    <td>387</td>
    <td>392</td>
    <td>393</td>
    <td>420</td>
    <td>431</td>
    <td>867</td>
    <td>878</td>
    <td>1067</td>
    <td>1096</td>
  </tr>
  <tr>
    <th>ILOffset</th>
    <td>0</td>
    <td>0</td>
    <td>1</td>
    <td>1</td>
    <td>6</td>
    <td>7</td>
    <td>7</td>
    <td>12</td>
    <td>13</td>
    <td>13</td>
    <td>18</td>
    <td>19</td>
    <td>27</td>
    <td>30</td>
    <td>35</td>
    <td>37</td>
    <td>40</td>
    <td>45</td>
    <td>47</td>
    <td>50</td>
    <td>55</td>
    <td>57</td>
    <td>60</td>
    <td>65</td>
    <td>70</td>
    <td>75</td>
    <td>76</td>
    <td>81</td>
    <td>86</td>
    <td>87</td>
    <td>87</td>
    <td>70</td>
    <td>87</td>
    <td>70</td>
    <td>0</td>
    <td>87</td>
  </tr>
</table>

<table>
  <tr>
    <th>ILOffset</th>
    <td>0</td>
    <td>1</td>
    <td>7</td>
    <td>13</td>
    <td>19</td>
    <td>76</td>
  </tr>
  <tr>
    <th>LineNumber</th>
    <td>80</td>
    <td>81</td>
    <td>82</td>
    <td>83</td>
    <td>84</td>
    <td>85</td>
  </tr>
</table>

Before:
<table>
  <tr>
    <th>NativeOffset</th>
    <td>0</td>
    <td>106</td>
    <td>107</td>
    <td>124</td>
    <td>141</td>
    <td>158</td>
    <td>380</td>
    <td>1067</td>
  </tr>
  <tr>
    <th>LineNumber</th>
    <td>80</td>
    <td>80</td>
    <td>81</td>
    <td>82</td>
    <td>83</td>
    <td>84</td>
    <td>85</td>
    <td>80</td>
  </tr>
</table>
Notice in particular that code after native offset 431, the suspension
code for DoWork, is mistakenly attributed to line 85
(Console.WriteLine).

After:
<table>
  <tr>
    <th>NativeOffset</th>
    <td>0</td>
    <td>106</td>
    <td>107</td>
    <td>124</td>
    <td>141</td>
    <td>158</td>
    <td>380</td>
    <td>431</td>
    <td>878</td>
    <td>1067</td>
  </tr>
  <tr>
    <th>LineNumber</th>
    <td>80</td>
    <td>80</td>
    <td>81</td>
    <td>82</td>
    <td>83</td>
    <td>84</td>
    <td>85</td>
    <td>84</td>
    <td>84</td>
    <td>80</td>
  </tr>
</table>
Here we see that 380-431 is attributed to Console.WriteLine, while the
suspension code that follows is correctly attributed to the previous
line of await.

[aot.txt](https://github.com/user-attachments/files/24697543/aot.txt)
Read binary psinfo for System.Diagnostic.Process on SunOS (Solaris or
illumos).
No failures in System.Diagnostic.Process.Tests (but lots of skip)

---------

Co-authored-by: Austin Wise <[email protected]>
Co-authored-by: Adeel Mujahid <[email protected]>
Co-authored-by: Jan Kotas <[email protected]>
…cand methods (dotnet#123288)

## Description

`BFloat16.TryWriteSignificandBigEndian` and
`TryWriteSignificandLittleEndian` initially reported `bytesWritten = 4`
(sizeof(uint)) instead of the correct value. Upon further investigation,
it was discovered that BFloat16's significand should be byte-sized (8
bits: 7 trailing bits + 1 implicit bit), not ushort-sized (16 bits).

## Changes

- **BFloat16.cs**: 
- Changed `Significand` property from `ushort` to `byte` to correctly
represent the 8-bit significand
- Updated `GetSignificandByteCount()` to return `sizeof(byte)` (1)
instead of `sizeof(ushort)` (2)
- Updated `TryWriteSignificandBigEndian` to write 1 byte directly
(endianness is irrelevant for single byte)
- Updated `TryWriteSignificandLittleEndian` to write 1 byte directly
(endianness is irrelevant for single byte)

- **BFloat16Tests.cs**: Added test coverage for
`TryWriteSignificandBigEndian` and `TryWriteSignificandLittleEndian`
using `[Theory]` with `[MemberData]` to provide BFloat16 test values
directly. Tests verify correct byte count (1 byte) and output values for
various BFloat16 values (NegativeInfinity, MinValue, NaN, Epsilon, Zero,
MaxValue, PositiveInfinity). Empty destination edge cases are tested in
separate `[Fact]` methods. Test data methods use modern C# collection
literal syntax `[ ... ]` for cleaner, more maintainable code.

**Technical Details**: BFloat16 format has 1 sign bit + 8 exponent bits
+ 7 trailing significand bits. The `Significand` property includes the
implicit leading 1 bit for normal numbers, resulting in 8 bits total (1
byte). For a single byte value, endianness doesn't apply, so both
BigEndian and LittleEndian methods write the byte directly to
`destination[0]`.

**Note**: Tests use `[MemberData]` instead of `[InlineData]` to pass
BFloat16 objects directly, avoiding float-to-BFloat16 conversion issues
that could produce different values than expected.

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>BFloat16.TryWriteSignificand{Big,Little}Endian report 4
for bytesWritten</issue_title>
> <issue_description>The `BFloat16` implementation of
`TryWriteSignificandBigEndian` and `TryWriteSignificandLittleEndian`
write 16-bit integers, but report `4` as the number of bytes written
(32-bit), even though only two bytes were written:
> 
>
https://github.com/dotnet/runtime/blob/0bb28890029bb15c6d08a3ee11a62fc828097f41/src/libraries/System.Private.CoreLib/src/System/Numerics/BFloat16.cs#L1047-L1051
> 
> I'm not exactly a numerics person but should this be a `ushort`? (That
is what `Half` does).</issue_description>
> 
> <agent_instructions>Please fix bytesWritten for BFloat16, add
tests</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes dotnet#123286

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/dotnet/runtime/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: EgorBo <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Co-authored-by: Egor Bogatov <[email protected]>
Remove extra redudant load.
ins->dreg is always fpr and sreg is always r13 so they can't be aliased
as well, so it's a redundant load.
`Rune` had a typo, `SYSTEM_PRIVATE_CORLIB` instead of
`SYSTEM_PRIVATE_CORELIB`. This led to the very minor issue that the
ArgumentException would not use the expected exception message.

We don't typically unit the text of exception of exception messages, but
if we want to do something we can.
…#123353)

Terser 5.39 introduced an optimization that removes console.assert(true,
...) as "unnecessary"
https://github.com/terser/terser/blob/master/CHANGELOG.md#v5390.

In runtime we are counting on the assert to keep `base64String`:

https://github.com/dotnet/runtime/blob/1af7e1a9b7d659fdb9e2bc7aa52197fd5d272ec6/src/mono/browser/runtime/debug.ts#L37

The assert removal caused the `base64String` to be optimized away,
breaking the `BrowserDebugProxy's `, breaking the ability to read them
from the paused scope.

<img width="2725" height="204" alt="image"
src="https://github.com/user-attachments/assets/a55233c9-fe3e-4c5e-99fb-36a5f02b7dba"
/>

This affects net11 debugging, net10 works correctly.

This PR replaces `true` with `!!Date.now()` which Terser cannot
statically evaluate.
…ips more elements than exist (dotnet#123295)

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Co-authored-by: eiriktsarpalis <[email protected]>
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Co-authored-by: tannergooding <[email protected]>
Co-authored-by: Tanner Gooding <[email protected]>
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Co-authored-by: MihaZupan <[email protected]>
Co-authored-by: Miha Zupan <[email protected]>
## Description

Adds `*.exe` to `.gitignore` to prevent accidental commits of executable
files like `nuget.exe`.

**Changes:**
- Added `*.exe` pattern to ignore all executable files
- Added exceptions for existing test resource `.exe` files that must
remain tracked:
-
`src/libraries/System.Diagnostics.FileVersionInfo/tests/.../NativeConsoleApp.exe`
-
`src/libraries/System.Reflection.Metadata/tests/Resources/NetModule/AppCS.exe`
-
`src/libraries/System.Reflection.Metadata/tests/Resources/Misc/Signed.exe`

<!-- START COPILOT CODING AGENT SUFFIX -->



<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> copilot has an unfortunate habit of trying to merge nuget.exe into the
repo. Please ensure that the .gitignore file ignores all .exe files.


</details>



<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
…tnet#123345)

`FromStack(1)` and `FromStackDMI(1)` rely on the test entry points to
not be inlined into the test executor, so ensure these are NoInlining.
…123213)

Marshalled calli is not supported with the interpreter
…22430)

This is dotnet#122134 but with the NuGet
source moved from the test directory to the repo root's NuGet.config.

I briefly explored using `dotnet-trace` from the dotnet-tools nuget
source, but extra hurdles were popping up with that approach, from
installing the tool which also brought
`.store/dotnet-trace/9.0.660901/dotnet-trace/9.0.660901/tools/net8.0/any/`
and invoking it would need to resolve sdk location. Even if all were
resolved, the added benefit is fairly minimal, since dotnet-trace is
just a wrapper around record-trace.

----------------------------------------------------------------
# Repeating dotnet#122134's Description

With user_events support added in
dotnet#115265, this PR looks to test a
few end-to-end user_events scenario.

## Alternative testing approaches considered

### **Existing EventPipe runtime tests**
Existing EventPipe tests under `src/tests/tracing/eventpipe` are
incompatible with testing the user_events scenario due to:

1. Starting EventPipeSessions through DiagnosticClient ❌ 
DiagnosticClient does not have the support to send the IPC command to
start a user_events based EventPipe session, because it requires the
user_events_data file descriptor to be sent using SCM_RIGHTS (see
https://github.com/dotnet/diagnostics/blob/main/documentation/design-docs/ipc-protocol.md#passing_file_descriptor).

2. Using an EventPipeEventSource to validate events streamed through
EventPipe ❌
User_events based EventPipe sessions do not stream events. Instead,
events are written to configured TraceFS tracepoints, and currently only
RecordTrace from https://github.com/microsoft/one-collect/ is capable of
generating `.nettrace` traces from tracepoint user_events.

### **Native EventPipe Unit Tests**
There are Mono Native EventPipe tests under
`src/mono/mono/eventpipe/test` that are not hooked up to CI. These unit
tests are built through linking the shared EventPipe interface library
against [Mono's EventPipe runtime
shims](https://github.com/dotnet/runtime/tree/main/src/mono/mono/eventpipe)
and using [Mono's test
runner](https://github.com/dotnet/runtime/tree/main/src/mono/mono/eglib/test).
To update these unit tests into the [standard runtime tests
structure](https://github.com/dotnet/runtime/tree/main/src/tests), a
**larger investment** is needed to either migrate EventPipe from using
runtime shims to a OS Pal source shared by coreclr/nativeaot/mono (see
dotnet#118874 (comment)) or
build an EventPipe shared library specifically for the runtime test
using a runtime-agnostic shim.
As existing mono unit tests don't currently test IPC commands, coupled
with no existing runtime infrastructure to read events from tracepoints,
there would be even more work on top of updating mono native eventpipe
unit tests to even test the user_events scenario.

## End-to-End Testing Added
A low-cost approach to testing .NET Runtime's user_events functionality
leverages RecordTrace from https://github.com/microsoft/one-collect/,
which is already capable of starting user_events based EventPipe
sessions and generating `.nettrace`s. (Note: [dotnet-trace wraps around
RecordTrace](dotnet/diagnostics#5570))
Despite adding an external dependency which allows RecordTrace failures
to fail the end-to-end test, user_events was initially added with the
intent to depend on RecordTrace for the end-to-end scenario, and there
are no other ways to functionally test a user_events based eventpipe
session.

### Approach

Each scenario uses the same pattern:

1. **Scenario invokes the shared test runner**

User events scenarios can differ in their tracee logic, the events
expected in the .nettrace, the record-trace script used to collect those
events, and how long it takes for the tracee to emit them and for
record-trace to resolve symbols and write the .nettrace. To handle this
variance, UserEventsTestRunner lets each scenario pass in its
scenario-specific record-trace script path, the path to its test
assembly (used to spawn the tracee process), a validator that checks for
the expected events from the tracee, and optional timeouts for both the
tracee and record-trace to exit gracefully.

2. **`UserEventsTestRunner` orchestrates tracing and validation**

Using this configuration, UserEventsTestRunner first checks whether user
events are supported. It then starts record-trace with the scenario’s
script and launches the tracee process so it can emit events. After the
run completes, the runner stops both the tracee and record-trace, opens
the resulting .nettrace with EventPipeEventSource, and applies the
scenario’s validator to confirm that the expected events were recorded.
Finally, it returns an exit code indicating whether the scenario passed
or failed.

### Dependencies:
- Environment with a kernel 6.4+, .NET 10, glibc 2.35+
- Microsoft.OneCollect.RecordTrace (transitively resolved through a
dotnet diagnostics public feed)
- Microsoft.Diagnostics.Tracing.TraceEvent 3.1.24+ (to read [NetTrace
V6](https://github.com/microsoft/perfview/blob/main/src/TraceEvent/EventPipe/NetTraceFormat.md))

## Helix Nuances

UserEvents functional runtime tests differ from other runtime tests
because it depends on OneCollect's Record-Trace tool to enable a
userevents-based eventpipe session and to collect events. By design,
Record-Trace requires elevated privileges, so these tests invoke a
record-trace executable with sudo.

When tests run on Helix, test artifacts are stripped of their
permissions, so the test infrastructure was modified to give
record-trace execute permissions (helix-extra-executables.list).
Moreover, to avoid having one copy of record-trace per scenario, which
in turn requires re-adding execute permissions for each, more
modifications were added to copy over a single record-trace executable
that would be used by all scenarios (OutOfProcess marker).

Additionally, in Helix environments, TMPDIR is set to a helix specific
temporary directory like /datadisks/disk1/work/<id>/t, and at this time,
record-trace only scans /tmp/ for the runtime's diagnostic ports. So as
a workaround, the tracee apps are spawned with TMPDIR set to /tmp.

Lastly, the job steps to run tests on AzDO prevents restoring individual
runtime test projects. Because record-trace is currently only resolvable
through the dotnet-diagnostics-tests source, userevents_common.csproj
was added to the group of projects restored at the beginning of copying
native test components to restore Microsoft.OneCollect.RecordTrace.
Generate src/coreclr/vm/wasm/callhelpers-pinvoke.cpp and use it instead
of hardcoded native libs entrypoints.c

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Pavel Savara <[email protected]>
Co-authored-by: Aaron R Robinson <[email protected]>
Fixes dotnet#123361

The CI probably won't be happy to run the test repro
_ASSERTE(objRefsSize == (dataSize + (TARGET_POINTER_SIZE - 1)) / TARGET_POINTER_SIZE);
LoaderAllocator* allocator = asyncMethod->GetLoaderAllocator();
AsyncContinuationsManager* asyncConts = allocator->GetAsyncContinuationsManager();
MethodTable* result = asyncConts->LookupOrCreateContinuationMethodTable((unsigned)dataSize, objRefs, asyncMethod);

Choose a reason for hiding this comment

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

We should update LookupOrCreateContinuationMethodTable to work off of a Module owner, not from a MethodDesc as an owner. From looking at LookupOrCreateContinuationMethodTable, it only needs the MethodDesc so that it can get a LoaderModule to stuff the ContinuationMethodTable into. The existing jit scenario can continue to use the Module of the MethodDesc being compiled, but the R2R scenario can just use the System module, since we don't support R2R of collectible assemblies. In addition, we won't need #if READYTORUN logic in AsyncContinuationType.cs, and I don't see why we'll need the AllocContinuationMethod/AllocContinuationClass R2R fixups.

If you make this change, then, the R2R format will not need to record a MethodDesc with each ContinuationType, which will allow us to get better file size for R2R images.

Copilot AI and others added 24 commits January 24, 2026 01:59
…ocumentation (dotnet#123518)

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: MihaZupan <[email protected]>
Co-authored-by: Miha Zupan <[email protected]>
## Description

Updates Windows build pool images from VS2022 to VS2026 preview across
CI pipelines, including main build infrastructure and stress test
pipelines.

## Changes

- **`eng/pipelines/common/xplat-setup.yml`**:
- Official builds: `windows.vs2022.amd64` →
`windows.vs2026preview.scout.amd64`
- Public builds: `windows.vs2022.amd64.open` →
`windows.vs2026preview.scout.amd64.open`

- **`eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml`**:
- Fuzzing jobs: `windows.vs2022.amd64` →
`windows.vs2026preview.scout.amd64`

- **`eng/pipelines/libraries/stress/ssl.yml`**:
- SSL stress tests: `1es-windows-2022-open` →
`windows.vs2026preview.scout.amd64.open`

- **`eng/pipelines/libraries/stress/http.yml`**:
- HTTP stress tests: `1es-windows-2022-open` →
`windows.vs2026preview.scout.amd64.open`

All VS2022 and 1es-windows-2022 image references in pipeline
configurations have been migrated to the VS2026 preview scout image.

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Switch from VS2022 to VS2026 image</issue_title>
> <issue_description>At least in main but probably also in
release/10.0.</issue_description>
> 
> <agent_instructions>Let's start by changing the public and official
build windows pools to windows.vs2026preview.scout.amd64. That should be
found in eng/pipelines/common/xplat-setup.yml. We'll figure out whatever
else is needed as we go.</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes dotnet#123550

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: steveisok <[email protected]>
Co-authored-by: hoyosjs <[email protected]>
This PR addresses some review feedback in dotnet#122301 and fills in more
codegen for casts on Wasm.
Notably:
- Casts to and from all int types (byte, short) are now supported with
proper sign extension
- Some generic casting code, in particular `GenIntCastDesc` was moved
out of ifdefs and adapted for Wasm to support this. We don't yet support
containment of casts in loads (i.e., the `GenIntCastDesc::LOAD_*` type
casts).
- float->int casts are implemented using the saturating non-trapping
conversion instructions
- This required changing the type of our Wasm opcodes to be 2 bytes
instead of 1

---------

Co-authored-by: Katelyn Gadd <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: SingleAccretion <[email protected]>
…nericLookupResult` (dotnet#123512)

We broke outerloops in dotnet#122012. Looks like the outerloop run was already
broken in that PR but nobody went over the results.

```
  Process terminated. Assertion failed.
  !owningType.IsCanonicalSubtype(CanonicalFormKind.Any)
     at System.Diagnostics.DebugProvider.Fail(String, String) + 0x37
     at System.Diagnostics.Debug.Fail(String, String) + 0x49
     at ILCompiler.DependencyAnalysis.TypeGenericDictionaryNode..ctor(TypeDesc, NodeFactory) + 0x4c

...

D:\a\_work\1\s\artifacts\bin\coreclr\windows.x64.Checked\build\Microsoft.NETCore.Native.targets(332,5): error MSB3073: The command ""D:\a\_work\1\s\artifacts\bin\coreclr\windows.x64.Checked\x64\ilc\\ilc" @"D:\a\_work\1\s\artifacts\obj\Microsoft.Extensions.Logging.Tests\Release\net11.0-windows\native\Microsoft.Extensions.Logging.Tests.ilc.rsp"" exited with code 57005. [D:\a\_work\1\s\src\libraries\Microsoft.Extensions.Logging\tests\Common\Microsoft.Extensions.Logging.Tests.csproj::TargetFramework=net11.0-windows]
```

This is because we're trying to obtain generic dictionaries of something
in a canonical form from here. The callsite identifier parameter is not
necessary when referencing from NonConcrete methods because we're not
going to build an associated generic dictionary anyway.
Now a small amount of matches are stack allocated and the array is only optionally allocated.

---------

Co-authored-by: Tarek Mahmoud Sayed <[email protected]>
Co-authored-by: Jan Kotas <[email protected]>
…ef token tables (dotnet#123557)

We have logic which loads a typedef, and if the typedef is loaded then
we assume the method can be loaded via lookup in the MethodDef/FieldDef
token map tables. HOWEVER, what this boils down to is we do a load from
the TypeDef table, and if that succeeds we will do a load from the
FieldDef/MethodDef token map tables, but that second load is done
without an explicit memory barrier. Unfortunately, through the wonder of
memory ordering behavior, its legal (and not actually all that uncommon)
for the CPU to do the load from the FieldDef/MethodDef tables BEFORE it
actually loads from the TypeDef table. So what can happen is that the
fielddef table read can happen, then the typedef table read can happen,
then the CPU does the if check to see if its ok to do the fielddef table
read, then we use the value from the fielddef table read which happened
earlier.

This fix should fix that problem by using a VolatileLoad for all reads
from the lookup maps. This is slightly slower but avoids the extremely
easy to mess up dependency ordering rules.

Fixes dotnet#120754

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Aaron R Robinson <[email protected]>
…g unneeded method parameters and simplifying type resolution logic.
…hods (dotnet#123265)

## Description

Refactored JIT codebase to use existing GenTree helper methods
(`IsUnsigned()`, `SetUnsigned()`, `ClearUnsigned()`) instead of direct
GTF_UNSIGNED flag manipulation.

## Changes

**Replaced 55 explicit flag operations across 22 files:**
- `gtFlags |= GTF_UNSIGNED` → `SetUnsigned()` (13 occurrences)
- `gtFlags &= ~GTF_UNSIGNED` → `ClearUnsigned()` (3 occurrences)  
- `(gtFlags & GTF_UNSIGNED)` → `IsUnsigned()` (39 occurrences)

**Moved SetUnsigned/ClearUnsigned to gentree.cpp:**
- Implementations moved from inline methods in gentree.h to gentree.cpp
- gentree.h now contains only method declarations for cleaner separation
- Added debug assertions that print the node operator type on failure
for easier debugging
- Assertions validate that GTF_UNSIGNED is only set on appropriate node
types:
  - Arithmetic operations: GT_ADD, GT_SUB
  - Casts: GT_CAST
- All comparison operators (using `OperIsCompare()` helper): GT_EQ,
GT_NE, GT_LE, GT_LT, GT_GT, GT_GE, GT_TEST_EQ, GT_TEST_NE, and on XARCH
also GT_BITTEST_EQ, GT_BITTEST_NE
- Multiply operations (via `OperIsMul()` helper): GT_MUL, GT_MULHI,
GT_MUL_LONG

## Testing

- CoreCLR builds successfully
- Enhanced assertions provide helpful diagnostic output during
development
- No functional changes

<!-- START COPILOT CODING AGENT SUFFIX -->



<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> # A small clenaup task in JIT codebase around GTF_UNSIGNED
> in `src/coreclr/jit/*` replace explicit usages of GTF_UNSIGNED over
tree objects (e.g. `tmp->gtFlags |= GTF_UNSIGNED;`) with the following
methods on GenTree:
> 
> ```
> bool GenTree::IsUnsigned() const
> void GenTree::SetUnsigned()
> void GenTree::ClearUnsigned()
> ```
> 
> Make sure code compiles and runtime tests pass.


</details>



<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/dotnet/runtime/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: EgorBo <[email protected]>
Co-authored-by: Egor Bogatov <[email protected]>
… and remove obsolete availability checks (dotnet#123200)

# Description

macOS 12 is out of support. Updated minimum deployment target to 14.0
and Mac Catalyst to 17.0 (which shipped with macOS 14.0 Sonoma) across
build configuration, native compilation, installers, and tests.
Additionally, removed obsolete runtime availability checks
(`__builtin_available` in Objective-C and `@available` in Swift) that
are no longer necessary with the new minimum requirements.

**Core configuration:**
- `Directory.Build.props`: `macOSVersionMin` and `MacCatalystVersionMin`
properties
- `eng/native/configurecompiler.cmake`: `CMAKE_OSX_DEPLOYMENT_TARGET`
and Mac Catalyst compiler targets
- `eng/native/build-commons.sh`: Mac Catalyst deployment target

**Build targets:**
-
`src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets`
- `src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets`

**Mono AOT compilation:**
- `src/mono/msbuild/common/MonoAOTCompiler.props`: Mac Catalyst mtriple
arguments
- `src/mono/msbuild/apple/build/AppleBuild.targets`: Mac Catalyst
mtriple arguments

**Installers:**
- Distribution templates (arm64 and x64): `os-version min` requirement

**Tests:**
- 8 Swift interop CMakeLists.txt files

**Removed obsolete availability checks:**
-
`src/native/libs/System.Security.Cryptography.Native.Apple/pal_networkframework.m`:
Removed checks for macOS 12.3, iOS 15.4, tvOS 15.4
- `src/native/libs/System.Security.Cryptography.Native.Apple/pal_rsa.c`:
Removed check for macOS 10.15, iOS 13, tvOS 13
- `src/native/libs/System.Security.Cryptography.Native.Apple/pal_sec.c`:
Removed check for iOS 11.3, tvOS 11.3
- `src/native/libs/System.Security.Cryptography.Native.Apple/pal_ecc.c`:
Removed check for macOS 10.15, iOS 13, tvOS 13
-
`src/native/libs/System.Security.Cryptography.Native.Apple/pal_swiftbindings.swift`:
HKDF functions retain `@available(iOS 14, tvOS 14, *)` annotations
(macOS annotation removed since HKDF was introduced in macOS 11, below
our new minimum)
- `src/native/minipal/memorybarrierprocesswide.c`: Removed check for
macOS 10.14, iOS 12, tvOS 9 and fallback code
- `src/mono/mono/utils/mono-codeman.c`: Removed checks for macOS 11 in
write protection functions
- `src/mono/mono/utils/mono-mmap.c`: Removed check for macOS 11 in
MAP_JIT flag handling

# Customer Impact

Customers on macOS 12 will no longer be able to run .NET. Customers on
Mac Catalyst versions older than 17.0 will also be affected. This aligns
with Apple's current support lifecycle.

# Regression

No. This is a forward-looking change to drop support for an EOL
operating system version and align Mac Catalyst with the corresponding
macOS release.

# Testing

Configuration changes updated version constants from 12.0 to 14.0 for
macOS across 14 files and from 15.2 to 17.0 for Mac Catalyst across 7
files. Additionally, removed obsolete runtime availability checks across
8 files, simplifying the codebase by eliminating unnecessary fallback
code paths for OS versions below the new minimums. HKDF functions retain
appropriate `@available` annotations for iOS 14 and tvOS 14 where these
APIs are above the minimum supported versions.

# Risk

Low. Changes consist of version constant updates and removal of obsolete
runtime checks for OS versions we no longer support. All updates are
consistent and the removed checks were for versions below our new
minimums, so the previously guarded code will now always execute. HKDF
availability annotations are correctly maintained for iOS and tvOS where
needed.

<!-- START COPILOT CODING AGENT SUFFIX -->



<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> The repo currently sets 
> <macOSVersionMin>12.0</macOSVersionMin>. 12 is out of support. We
should update to 14.


</details>



<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: agocke <[email protected]>
Co-authored-by: jkoritzinsky <[email protected]>
The count of switch targets does not include the default.
…otnet#123613)

Trying to make it more deterministically build before trying to test and
commit.
…es (dotnet#123600)

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
…atch tracking. (dotnet#117148)

(By default) Linux allows 128 inotify instances per user. By sharing the
inotify instance between the FileSystemWatchers we reduce contention
with other applications.

Fixes dotnet#62869.
…ments (dotnet#123599)

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
…um when isFinalBlock=false (dotnet#123313)

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: MihaZupan <[email protected]>
Co-authored-by: Miha Zupan <[email protected]>
In such cases we won't have set up a stack pointer.
## Description

`AND` between a mask and constant zero was incorrectly folded to return
the mask value instead of zero in the JIT's `gtFoldExprHWIntrinsic`.

```csharp
// Expected: <0, 0, 0, ...>  Actual (buggy): <-1, -1, -1, ...>
Vector512.Equals(v, v) & Vector512.LessThan(v.AsUInt32(), Vector512<uint>.Zero).AsInt32();
```

### Changes

- **`src/coreclr/jit/gentree.cpp`**: For mask types in `GT_AND` case,
changed `resultNode = otherNode` to `resultNode =
gtWrapWithSideEffects(cnsNode, otherNode, GTF_ALL_EFFECT)` — matching
the non-mask vector case
- **`src/tests/JIT/Regression/JitBlue/Runtime_123399/`**: Added
regression test (requires AVX-512)

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>JIT: Mask AND with zero incorrectly folded</issue_title>
> <issue_description>### Description
> 
> `AND` between a mask and a constant zero is incorrectly folded to the
mask value in net10.0.
> 
>
https://github.com/dotnet/runtime/blob/2075e8ffaa8cf598dac9c09f5f690778ef1a6c8e/src/coreclr/jit/gentree.cpp#L32988-L32992
> 
> ### Reproduction Steps
> 
> ```c#
> using System.Runtime.CompilerServices;
> using System.Runtime.Intrinsics;
> 
> Console.WriteLine(AndMaskZero(Vector512<int>.One));
> 
> [MethodImpl(MethodImplOptions.NoInlining)]
> static Vector512<int> AndMaskZero(Vector512<int> v) =>
> Vector512.Equals(v, v) & Vector512.LessThan(v.AsUInt32(),
Vector512<uint>.Zero).AsInt32();
> ```
> 
> ### Expected behavior
> 
> ```bash
> > dotnet run -c release -f net9.0
> ```
> 
> `<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>`
> 
> ### Actual behavior
> 
> ```bash
> > dotnet run -c release -f net10.0
> ```
> `<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1>`
> 
> ### Regression?
> 
> Yes, worked in 9.0
> 
> ### Configuration
> 
> Requires AVX-512
> 
> </issue_description>
> 
> <agent_instructions>Fix the bug in jit (see comments in the issue) +
add a regression test (JitBlue)</agent_instructions>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@JulieLeeMSFT</author><body>
> Thanks, @saucecontrol, for the report.
> @anthonycanino, can your team please take a look? 
> CC @kg. </body></comment_new>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes dotnet#123399

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: EgorBo <[email protected]>
Fixes dotnet#123583

## Description

Adds a FileCheck test that verifies codegen doesn't contain bounds
checks (`CORINFO_HELP_RNGCHKFAIL`) for patterns where the JIT should
prove access is in-bounds.

### Test Methods

- **ComplexBinaryOperators** - Masking/shifting restricts index to 0-63
for 65-element span
- **LastCharCheck** - String length comparison before indexed access
- **CountDigits** - `ulong.Log2()` result (0-63) indexes 64-element span
- **AndByConst** - Bitwise AND with constant
- **AndByLength** - Bitwise AND with `(span.Length - 1)` pattern

### Files Added

- `src/tests/JIT/opt/RangeChecks/ElidedBoundsChecks.cs` - Test methods
with `X64-NOT` and `ARM64-NOT` FileCheck annotations
- `src/tests/JIT/opt/RangeChecks/ElidedBoundsChecks.csproj` - Project
with `HasDisasmCheck=true`

```csharp
[MethodImpl(MethodImplOptions.NoInlining)]
static byte AndByLength(int i)
{
    // X64-NOT: CORINFO_HELP_RNGCHKFAIL
    // ARM64-NOT: CORINFO_HELP_RNGCHKFAIL
    ReadOnlySpan<byte> span = new byte[] { 1, 2, 3, 4 };
    return span[i & (span.Length - 1)];
}
```

<!-- START COPILOT CODING AGENT SUFFIX -->



<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> Add a test that uses FileCheck to varify that codegen doesn't contain
bounds checks at all
> 
> the test should be located in `src\tests\JIT\opt\RangeChecks` folder
> 
> Check on x64 and arm64, here are the asm examples how bounds checks
look like:
> ```
> ; x64:
> call     CORINFO_HELP_RNGCHKFAIL
> ; arm64:
> bl      CORINFO_HELP_RNGCHKFAIL
> ```
> 
> Use .cs and .csproj in
`C:\prj\runtime-main2\src\tests\JIT\opt\Subtract\` as a reference on how
to create FileCheck tests (HasDisasmCheck)
> 
> Here are the functions I want to make sure they don't have bounds
checks under optimizations:
> 
> ```csharp
> public class ElidedBoundsChecks
> {
>     [MethodImpl(MethodImplOptions.NoInlining)]
>     static int ComplexBinaryOperators(byte inData)
>     {
> ReadOnlySpan<byte> base64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="u8;
> return base64[((inData & 0x03) << 4) | ((inData & 0xf0) >> 4)];
>     }
> 
>     [MethodImpl(MethodImplOptions.NoInlining)]
>     static bool LastCharCheck(string prefix, string path)
>     {
>         if (prefix.Length < path.Length)
>             return (path[prefix.Length] == '/');
>         return false;
>     }
> 
>     [MethodImpl(MethodImplOptions.NoInlining)]
>     static nint CountDigits(ulong value)
>     {
>         ReadOnlySpan<byte> log2ToPow10 =
>         [
> 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
> 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
> 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
> 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20
>         ];
>         return log2ToPow10[(int)ulong.Log2(value)];
>     }
> 
>     [MethodImpl(MethodImplOptions.NoInlining)]
>     static byte AndByConst(int i)
>     {
>         ReadOnlySpan<byte> span = new byte[] { 1, 2, 3, 4 };
>         return span[i & 2];
>     }
> 
>     [MethodImpl(MethodImplOptions.NoInlining)]
>     static byte AndByLength(int i)
>     {
>         ReadOnlySpan<byte> span = new byte[] { 1, 2, 3, 4 };
>         return span[i & (span.Length - 1)];
>     }
> }
> ```


</details>



<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/dotnet/runtime/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: EgorBo <[email protected]>
Co-authored-by: Egor Bogatov <[email protected]>
…otnet#123319)

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Co-authored-by: adamsitnik <[email protected]>
Co-authored-by: EgorBo <[email protected]>
…oryFile (dotnet#122947)

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: Stephen Toub <[email protected]>
Co-authored-by: jozkee <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Copy link

@davidwrighton davidwrighton left a comment

Choose a reason for hiding this comment

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

LGTM for now. Please file an issue to unify the ContinuationMethodTable creation path so we don't have a path for jitting and a path for R2R, but this will do for now. Assign the issue to me or @VSadov

jtschuster and others added 2 commits January 26, 2026 13:44
Emits Task-returning async method thunks in crossgen2 as
MethodSignatures with the AsyncVariant flag set

Adds `GetPrimaryMethodDesc` to get the most natural "primary" method
desc for MethodDesc's that point to the same Ecma/Instantiated method.
This is used in the places where we cast to EcmaMethod to get relevant
metadata information.

GCRefMap emission also needed to be updated to account for the
continuation parameter. Runtime's `FakeGcScanRoots` (used to verify the
ReadyToRun images GCRefMap in debug config) also needed to updated to
handle the continuation parameter.

In R2R exception info clauses, a new flag is added to use when the
handler catches System.Exception. It's not guaranteed that a token for
System.Exception exists in the context of the EH info struct, and there
is no equivalent of a module override for the structs.

In the MethodWithToken constructor, it's expected that callers pass the
Token that points to the exact method that is being called on the
correct instantiated type. It's again not guaranteed that we have valid
tokens for the method being called in the context of an instantiated
type (technically any call to `G<MyClass>.M()` will have a token for
G<Class>, but when we compile the canonicalize method, we call the async
`G<!0>.M()` in the IL, and we don't have a token for `G<!0>`). For this
reason, we wrap the MethodIL in a ManifestModuleWrappedMethodIL, and
when we construct a MethodWithToken, we resolve the OwningType with the
MutableModule token, but swap out the Token for the typical method
definition token and force emission of a full MethodSignature in the
Fixup.

---------

Co-authored-by: David Wrighton <[email protected]>
Co-authored-by: Jan Kotas <[email protected]>
@jtschuster
Copy link
Owner Author

Made a new PR to target the dotnet repo: dotnet#123643

@jtschuster jtschuster closed this Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.