Skip to content

[wasi] Remove quarantines for wasihost runtimeconfig properties - #11

Closed
lewing wants to merge 145 commits into
lewing-wasi-r2r-publishfrom
lewing-wasi-unquarantine-134954
Closed

lewing wants to merge 145 commits into
lewing-wasi-r2r-publishfrom
lewing-wasi-unquarantine-134954

Conversation

@lewing

@lewing lewing commented Oct 5, 2026

Copy link
Copy Markdown
Owner

dotnet#134964 makes wasihost pass the app's runtimeconfig properties to the runtime, which fixes dotnet#134954. This removes the 28 WASI ActiveIssue quarantines against dotnet#134954 that dotnet#134813 added. The re-enabled tests depend on AppContext switches:

  • System.Data.Common and System.Runtime.Serialization.Xml: DataSet XML serialization (DataSetXmlSerializationIsSupported now sees the trimmed switch value)
  • System.Diagnostics.DiagnosticSource switch tests: Activity ID format
  • System.Globalization.Calendars switch tests: Japanese calendar date parsing
  • System.Runtime.InvariantTimezone: IsInvariant
  • System.Text.Encoding: UTF-7 and code page/encoding name tests

Validation

Run locally on macOS arm64 with wasmtime 49.0.1, against a CoreCLR WASI Release product built from the base that dotnet#134813 merged on. Commands were ./dotnet.sh build <test.csproj> /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release, plus /p:TestWasmReadyToRun=true /p:EnableAggressiveTrimming=true for the trimmed composite R2R lane.

Suite Interpreter Trimmed composite R2R
System.Data.Common.Tests 11,661 run, 0 failed 11,281 run, 0 failed
System.Diagnostics.DiagnosticSource.Switches.Tests 4 run, 0 failed 4 run, 0 failed
System.Runtime.Serialization.Xml.Tests 341 run, 0 failed 341 run, 0 failed
System.Globalization.CalendarsWithConfigSwitch.Tests 1 run, 0 failed 1 run, 0 failed
System.Runtime.InvariantTimezone.Tests 36 run, 0 failed 36 run, 0 failed
System.Text.Encoding.Tests 14,612 run, 0 failed 14,564 run, 0 failed

The only DiagnosticSource skip is IdGenerationInternalParent, which requires multithreading.

Resolves dotnet#134954 follow-up quarantines.

Note

This PR description was generated with GitHub Copilot.

jkoritzinsky and others added 30 commits September 28, 2026 10:51
<!-- -->

## Motivation and approach

Single-threaded WASM mutex operations already optimize away, but
CoreCLR's higher-level lock flags, GC-mode transitions,
shutdown/debugger accounting, and inter-thread deadlock tracking still
generate work. This removes that redundant work while retaining
same-thread reentrancy detection.

- Specialize Crst and CrstBase under `!FEATURE_MULTITHREADING &&
!_DEBUG`: initialization, destruction, acquisition, and release are
inline no-ops, and mutex/flag storage is omitted. There is no blocking
wait requiring a GC-mode transition or competing thread requiring
shutdown/debugger lock accounting.
- Reduce DeadlockAwareLock to a held flag. Both acquisition queries
still reject reentry, including indirect cycles; rejected holders do not
release an outer owner's lock.
- Keep ListLock list/refcount management, cached initialization
exceptions, loader-allocator lifetime, and exception-safe cleanup
unchanged. Preserve Debug lock hierarchy/ownership/contract checks and
the explicit debugger-forbid-suspend holder.

`FEATURE_MULTITHREADING` is defined for all current non-WASM CoreCLR
targets, so no architecture check is necessary. Threaded configurations
retain the original implementation. This does not change DAC
mutex-size/build selection, SpinLock, SimpleRWLock, or managed Monitor.

## Performance evidence

Before/after measurements use independent builds from this worktree,
without the separate DAC mutex-size reduction:

| Release measurement | Before | After |
|---|---:|---:|
| `sizeof(Crst)` | 132 B | 1 B |
| `sizeof(DeadlockAwareLock)` | 4 B | 1 B |
| `sizeof(ListLock)` | 140 B | 12 B |
| `sizeof(ListLockEntry)` | 172 B | 44 B |
| `corerun.wasm` | 4,517,870 B | 4,493,540 B |
| `dotnet.native.wasm` | 4,689,892 B | 4,665,417 B |
| 4,096 fresh generic class initializations, median | 5.3659 ms | 4.6473
ms |

Native probes compiled against the real headers and Release compiler
flags reduce Crst construction/holder operations to `ret void`.
List-entry acquisition becomes a held-byte check/store, without calls,
TLS bookkeeping, or EH cleanup.

The execution measurement uses a custom Node/WASM timing harness, not
BenchmarkDotNet: 20 interleaved samples per version after warmups,
excluding generic-type preparation. The median decreased about 13.4%,
with substantial variability (baseline range 5.02-9.34 ms; changed range
4.33-8.10 ms). The changed version was faster in 16/20 pairs; this is
focused evidence, not an application-wide speedup claim.

## Validation

- Built browser-WASM `clr+libs` in Release before and after the change,
and in Debug with the change. Rebuilt both configurations after
simplifying the guards.
- Passed seven focused invocations on baseline Release, changed Release,
and Debug: the existing initializer test, four new direct/indirect
initializer success/failure cases, and two new recursive native-layout
cases. Checked generated runner enumeration and filtered test results.
- Covered repeated rejected reentry, partially initialized values,
exactly-once initialization, cached failure identity across repeated
access and GC, and repeated recursive-layout failure followed by valid
layout computation.
- Validated both changed Release WASM binaries with `wasm-tools
validate`.
- Verified original source remains selected in Debug/threaded branches.
A `FEATURE_MULTITHREADING` opt-out probe produced byte-identical IR to
baseline. Removing the redundant architecture guards also left the
linked Release corerun binary byte-identical.

Execution validation used Node, not a browser. No full non-WASM build or
actual multithreaded-WASM execution was performed.

> [!NOTE]
> This implementation and PR description were generated with GitHub
Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Android HPKE tests are failing because the Android implementations of
`ECDiffieHellman` cannot recover `Q` from `d` easily.
`X25519DiffieHellman` supports this, so it remains enabled.
Initialize the tracked-local count and bitset size before early
flowgraph optimizations can access live-out sets. Assert the
pre-liveness invariants during block compaction and add a regression
exercising compaction after inlining.
Also implement required changes to make our package validation tooling
happy.

Fixes dotnet#134763
The negative dual-mode accept tests start an accept operation and then
expect a mismatched-address-family connection to fail immediately. On
macOS, `DualModeAcceptSync.AcceptV6BoundToAnyV4_CantConnect` can instead
leave both operations pending indefinitely: the worker remains blocked
in native `accept`, while the connect never completes.

This is the same class of problem historically discussed in dotnet#16265.
These tests were later re-enabled as part of dotnet#1481 / dotnet#80715, but the
shared negative helper still has unbounded operations.

This change:

- extends `PortBlocker` to accept an explicit shadow address, since the
socket address family does not identify the bound endpoint family for
dual-mode sockets;
- bounds the expected failed connection with the existing `TryConnect`
helper;
- queues a valid same-family connection before invoking the accept
implementation, so synchronous accept completes normally rather than
relying on socket disposal for cancellation; and
- verifies that accept returned the valid client, normalizing IPv4 and
IPv4-mapped IPv6 addresses.

The change is test-only and covers the shared Sync, APM, EAP, and Task
implementations.

Validation:

```text
System.Net.Sockets.Tests  Total: 32, Errors: 0, Failed: 0, Skipped: 0
```

A full libraries baseline was not run; the focused `System.Net.Sockets`
test project built successfully while running the affected classes.

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…[0]; quarantine newly running runtime tests (dotnet#134767)

The CoreCLR Apple host (`runtime-coreclr.m`) built managed arguments
from `NSProcessInfo.arguments`, whose element 0 is the executable path.
It passed the whole array to `coreclr_execute_assembly`, whose `argv`
becomes `Main`'s `args`. corerun and the dotnet host pass only the
arguments after the program name, and the Mono Apple host is unaffected
because `mono_jit_exec` treats `argv[0]` as the program name.

The merged runtime-test runner passes `args[0]` to `AppleEntryPoint` as
the single method to run. So on every CoreCLR Apple runtime-test lane
(iOS, iOS simulator, tvOS, maccatalyst), all tests were filtered out and
reported as skipped with "No Known Skip Reason", while xharness reported
success. See dotnet#134766.

This change passes `argi - 1, managed_argv + 1` in the Apple host. The
Android CoreCLR host (`monodroid-coreclr.c`) had the same bug: it
prepended the bundle path to `managed_argv`. The fix drops it. The Mono
hosts are unchanged, because `mono_jit_exec` expects the program name in
`argv[0]`.

## Bundling FSharp.Core in mobile test apps

F# tests load FSharp.Core from `CORE_ROOT` everywhere else, including
wasm, which runs through `corerun`. Apple and Android merged runners
bundle only their own publish output, so F# tests failed with
`FileNotFoundException`. Merged runners that reference an `.fsproj` now
resolve FSharp.Core from the `test_dependencies_fs` restore and bundle
it. That's the same source `CORE_ROOT` uses, and `CORE_ROOT` itself
isn't laid out until after the managed test build.

## Interpreter and ReadyToRun detection on Apple

- `CoreClrConfigurationDetection.IsCoreClrInterpreter` (behind
`RuntimeTestModes.InterpreterActive`) keeps meaning "some code may be
interpreted". Its WebAssembly special case becomes a general no-JIT
check. The result on wasm is unchanged, and it now also covers Apple
mobile, which has no JIT.
- Apple mobile CoreCLR ReadyToRun test apps, library and runtime tests
alike, now set `TEST_READY_TO_RUN_MODE=1` in `tests.ioslike.targets`,
mirroring `tests.browser.targets`.
`PlatformDetection.IsReadyToRunCompiled` is therefore true there.
`AssemblyTests.GetEntryAssembly`'s single-file R2R branch now excludes
Apple mobile, so it keeps expecting `AppleTestRunner`.

## Validation (local, CoreCLR)

Both full Pri0 suites were run locally, all 82 work items each:
maccatalyst-arm64 Release, and android-arm64 Release on the emulator.

| Suite | Before | After |
|---|---|---|
| maccatalyst-arm64, all 82 work items | Every test skipped | No
failures or hangs remaining after the changes below |
| android-arm64 emulator, all 82 work items | Every test skipped | 3,968
passed, 1 failed (`Runtime_90219`, now skipped), 372 skipped in the
77-group run; the other 5 groups pass as well. No hangs |

Selected work items:

| App | Before | After |
|---|---|---|
| `JIT/Regression_o_3` (maccatalyst) | 167 run, 0 passed, 167 skipped |
167 run, 158 passed, 0 failed, 9 conditionally skipped |
| `JIT/Regression_2` (maccatalyst) | — | 107 run, 99 passed, 0 failed, 8
skipped (`Runtime_87393` passes with FSharp.Core bundled) |
| `GC` (maccatalyst R2R) | — | 53 passed, including `GetGeneration` |
| `System.Reflection.Tests` (library, maccatalyst R2R) | — | 1,771
passed, 0 failed |
| `System.Buffers.Tests` (library runner, maccatalyst) | — | 85 run, 76
passed, 0 failed |
| Android: `JIT/JIT_r` | 30 run, 0 passed, 30 skipped | 30 run, 30
passed |
| Android: `JIT/Regression_2` | — | 107 run, 101 passed, 0 failed |
| Android: `JIT/Directed/Directed_do` | — | 42 run, 41 passed, 0 failed
(includes `mutual_recursion`) |
| Android: `JIT/Regression/Regression_5` | — | `Test_HndIndex_10_*` pass
(JIT present) |
| Android: `JIT/Regression_o_3` | — | 168 run, 158 passed, 0 failed |

## Newly running tests: quarantines and skips

These lanes had not run any runtime tests, so turning them on surfaces
failures. Quarantines are scoped to CoreCLR on Apple mobile
(`IsAppleMobile` AND `IsCoreCLR`) unless noted:

| Test | Failure | Change |
|---|---|---|
| `b425314` (`Regression_d`), `b426654` (`Regression_1`) | Hang: a GC
suspension never completes because the runtime can't suspend a tight R2R
loop, which also blocks the test's timeout timer | `ActiveIssue` dotnet#134770
|
| `JIT/Directed/tailcall/mutual_recursion` (`Directed_do`) | Fatal stack
overflow: tail calls between R2R and interpreted code grow the stack |
`ActiveIssue` dotnet#134775 |
| `Test_HndIndex_10_Plain`, `Test_HndIndex_10_Reordered`
(`Regression_5`) | The tests expect the JIT to reject invalid IL;
without a JIT the interpreter runs it | Existing
`SkipOnCoreClr(InterpreterActive)` now applies on Apple |
| `GC/API/GC/GetGeneration` (`GC`) | Interpreted frames and WebAssembly
report stack roots as pinned | Runs only when its own code is compiled
(not interpreted, or ReadyToRun); skipped on Browser/Wasi (see dotnet#134803).
Keeps running on Apple R2R |
| `Runtime_90219` (`Regression_o_3`) | Loads its own assembly from
`Assembly.Location`, which is empty in an app bundle |
`ConditionalFact(Utilities.HasAssemblyFiles)` replaces the platform list
|

CI should catch device-only failures (iOS, tvOS).

Resolves dotnet#134766

> [!NOTE]
> This PR description was generated with GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…3265)

## Summary

Enable composite ReadyToRun (R2R) publishing for CoreCLR on WASI. This
builds on the self-installing WebCIL R2R images from dotnet#134312, which is
now in `main`.

Per review feedback, this PR covers publishing and composition only. The
WASI R2R runtime-test and trimmed library-test CI lanes, their test
harness plumbing, and the related library test quarantines are in
dotnet#134813, which is stacked on this PR.

## Implementation

- The WASI app builder compiles the app and framework closure into a
composite R2R image plus per-assembly forwarding stubs using Crossgen2.
The per-app WASI host (`wasihost`) reserves an image buffer and
function-table slice sized to that composite, and exports the symbols
the composite imports.
- A C# `ComposeWasiReadyToRun` WasmAppBuilder task composes the
self-installing composite into the linked host component. It reuses the
WebCIL reader infrastructure, and uses `wasm-tools` and Binaryen for the
post-link merge and global folding. Crossgen2's finished R2R Wasm is not
a relocatable `wasm-ld` input, so this step cannot move into the native
link. Before merging, the task checks the image buffer size and the
table reservation against the host's exported values.
- The `wasihost` external assembly probe serves the embedded composite
and the per-assembly WebCIL stubs that are extracted at build time.
- In-tree publishing acquires pinned `wasm-tools`/Binaryen versions into
the shared wasm tool cache (`eng/AcquireWasiR2RTools.targets`).
- Docs: `docs/workflow/building/coreclr/wasi-r2r.md` and a WASI host
composition section in `docs/design/mono/webcil.md`.

## Validation

- `./build.sh -s clr+libs+packs -os wasi -arch wasm -c Release`: 0
warnings, 0 errors.
- Clean `PublishTrimmed` + `PublishReadyToRun=true` publish of
`src/mono/sample/wasi/console` with an empty tool cache. The pinned
tools were acquired, composition succeeded, and the app ran under
wasmtime. `DOTNET_ReadyToRunLogFile` showed `Ready to Run initialized
successfully` for all six loaded assemblies (CoreLib, the app,
System.Runtime, System.Console, System.Threading,
System.Runtime.InteropServices).
- A non-R2R CoreCLR WASI publish of the same sample still links against
the weak placeholder buffer and runs.

Related: dotnet#130129. Follow-up: dotnet#134813.

> [!NOTE]
> This pull request description was prepared with assistance from GitHub
Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 919fdde7-f547-4bfb-86ad-7ac02c626980
…otnet#134735)

# Description

`docs/workflow/trimming/feature-switches.md` lists an MSBuild property
`DisableDependencyInjectionDynamicEngine` for the
`Microsoft.Extensions.DependencyInjection.DisableDynamicEngine` feature
switch. No such property exists, so setting it in a project does nothing
and DI keeps using `System.Reflection.Emit`.

The switch itself is internal: the review on dotnet#91133
(dotnet#91133 (review))
asked for the .md change to be removed, and that feedback was never
addressed. Per @MichalStrehovsky's suggestion, this PR removes the whole
row.

Evidence the property does not exist:
- The switch is read only as an AppContext switch:
`src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs:41-43`.
- Neither `Microsoft.NET.ILLink.targets` nor dotnet/sdk's
`Microsoft.NET.Sdk.targets` defines it. dotnet/android sets the switch
from its own `AndroidAvoidEmitForPerformance` property.

Docs-only, one line removed.

Prepared with AI assistance (Claude Code) and reviewed with GitHub
Copilot.

> [!NOTE]
> This PR description and change were AI-generated (Claude Code).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…t#133571)

## Summary
- Require platform **AND** target framework **AND** runtime to match the
four-argument `ActiveIssue` overload. Check framework/runtime before
applying the existing platform decorator, preserving runtime OS checks
for AnyOS builds.
- Apply the same semantics to conditional `OuterLoop` attributes at
priority zero; preserve higher-priority inclusion and existing skip
reasons/reporters.
- Add 46 host-side xUnit generator tests, registered in
`clr.toolstests`, covering ordinary, process-isolated, and merged
runners, including referenced legacy entry points.
- Mark `calli_excep.il` explicitly Windows-only. Fixing the over-skip
exposed its `kernel32` dependency on Linux; directly running its body
confirmed `DllNotFoundException`.

## Root cause
The old implementation chained three independent skip transformations. A
match in any dimension could permanently remove the test body;
`TargetFrameworkMonikers.Any` matched `Netcoreapp` regardless of the
runtime/platform restrictions. The fix follows the conjunction in the
[pinned Arcade
implementation](https://github.com/dotnet/dotnet/blob/73ec55960bb496e6b2541b2fcf0a59576d1f8cd3/src/arcade/src/Microsoft.DotNet.XUnitExtensions.Shared/DiscovererHelpers.cs).

dotnet#126517 addressed a different switch branch: unspecified `SkipOnCoreClr`
dimensions defaulting to `Any` instead of zero. Its zero defaults remain
unchanged.

## Validation
- Checked CoreCLR/release libraries baseline succeeded: `build.sh
clr+libs -lc release -rc checked`.
- **46 passed, zero failed/skipped**, through both VSTest and the
repository `/t:Test` target. Tests compile generated runners, inspect
actual invocation syntax and skip reasons, and execute ordinary runners
with a test-body counter to reject successful no-ops.
- Restoring only the original four-argument composition caused **22
failures**, including the referenced-assembly cases; restoring the fix
returned all 46 to passing.
- Built Linux `Directed_ro`, inspected the restored call to
`calli_excep` before adding its Windows restriction, and verified that
the final Linux runner excludes this Windows-only test.
- Independent code review found no actionable issues. Secret scanning
and the added dependency advisory check passed.

### Limitations
Actual Windows/Mono SEH execution was not available; those generator
configurations were tested on the Linux host. Later builds retained
unavailable NuGet-audit-endpoint warnings using local
`WarningsNotAsErrors=NU1900;NU1905`; audit remained enabled. The
baseline also reported existing `Microsoft.DiaSymReader.Native`
advisories. Automated code review was unavailable, and CodeQL skipped
analysis because its database was too large.

> [!NOTE]
> This pull request was generated by GitHub Copilot.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MichalStrehovsky <13110571+MichalStrehovsky@users.noreply.github.com>
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
Supersedes dotnet#126633. This brings the minimal diff that lets us start
building the native portion of the runtime.

The first commit is me asking copilot to bring over the minimal part of
dotnet#126633. I didn't like some of the decisions because they don't match
what CoreCLR does, so subsequent commits then tweaked things.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 82b79dc1-18fc-4c04-9748-ea5b7ff3dc0b
Copilot-Session: 27009bcd-0b03-42cc-a37a-42d4cfeff5d8
Copilot-Session: 56ce0dc4-30ad-4c7a-99f5-c31a1a6adedc
## Summary

- inspect `DebuggableAttribute` directly with
`System.Reflection.Metadata` instead of `MetadataLoadContext`
- avoid resolving dependencies of the inspected assembly
- validate the supported `DebuggableAttribute` constructor signatures
- remove the `System.Reflection.MetadataLoadContext` package dependency

## Testing

- `./build.sh clr+libs+host`
- `./build.sh clr.tools`
- verified `--is-debug` against Debug and Release assemblies after
removing an assembly referenced by an unrelated assembly-level custom
attribute

Fixes dotnet#134296

> [!NOTE]
> This pull request description was generated by GitHub Copilot.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Removes the `clrinterpreter` scenario from
`src/tests/Common/testenvironment.proj`: the `TestEnvironment` entry and
the `_TestEnvFileLine` items (both the Windows `set` and Unix `export`
variants) that were conditioned on it.

The scenario is dead:

- It sets `DOTNET_Interpret`,
`DOTNET_InterpreterHWIntrinsicsIsSupportedFalse`,
`DOTNET_InterpreterJITThreshold`, and `DOTNET_InterpreterDoLoopMethods`.
None of these exist as runtime config values today; `clrconfigvalues.h`
only defines `Interpreter`, `InterpMode`, `InterpreterName`, and
`InterpreterPath`. They came from the legacy CoreCLR interpreter, which
was removed long ago. The only later change to these lines was the
mechanical `COMPlus_` → `DOTNET_` rename (dotnet#76997).
- No pipeline uses the scenario. The current CoreCLR interpreter lanes
use `interpmode1`–`interpmode3`, which set `DOTNET_InterpMode`. The
`-clrinterpreter` build flag used in `runtime-diagnostics.yml` is a
separate thing and this PR doesn't change it.

Validation: ran `CreateTestEnvFile` for `interpmode1` and `jitstress1`
with both Windows and osx targets, before and after the change. The
generated env files are byte-identical.

> [!NOTE]
> This PR description was generated with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ater code coverage (dotnet#133188)

Creating a new PR to replace dotnet#131509.

<!-- -->

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot-Session: 69313a92-28b5-4e32-8be8-ea4f6e44a5c8
Copilot-Session: 2fb9f1ef-f721-49e0-bf48-4a7a9458d53a
Copilot-Session: 106f96fe-da32-41d4-8aa5-7431edb36fc6
Copilot-Session: 286b5b04-7d1b-4228-ad6b-dac025ce91a7
Copilot-Session: 4307156b-37a7-495d-9af6-fe9174c05b0b
Copilot-Session: adc580d5-8f1c-4772-bfc2-7a943aa0959d
Copilot-Session: 806a996a-9fcc-42b7-a902-cac954582b24
…net#134754)

## Summary

State-machine (V1) async profiler callstack frames identify methods by
`AsyncStateMachineDiagnostics<T>.MethodId`, which comes from
`RuntimeMethodHandle_GetNativeCode` on `MoveNext`. On Wasm ReadyToRun, a
method's entry point is a `PortableEntryPoint` whose actual code is a
function-table index. `EECodeInfo` can't resolve that index, so
`StackFrame.GetMethodFromNativeIP` returned nothing and the frame names
were lost.

EventPipe method events already mapped these entry points to the
synthetic virtual IP registered through
`ExecutionManager::AddVirtualIPRange` (dotnet#134026). This PR moves that
mapping into a shared `GetDiagnosticCodeStartFromEntryPoint` helper in
`precode.cpp`, used by both EventPipe and
`RuntimeMethodHandle_GetNativeCode`. The only managed caller of that
QCall is `AsyncStateMachineDiagnostics`.

- The mapping is gated on both `TARGET_WASM` and
`FEATURE_PORTABLE_ENTRYPOINTS`. Treating the actual code as a
function-table index is a Wasm fact, and
`GetWasmVirtualIPFromFunctionTableIndex` is declared only under
`TARGET_WASM`. Other portable-entrypoint targets would store a real code
address that `EECodeInfo` already resolves.
- `PortableEntryPoint::GetActualCode` goes from `STANDARD_VM_CONTRACT`
to `LIMITED_METHOD_CONTRACT`. It only reads a field, and its callers
include this `NOTHROW`/`GC_NOTRIGGER` helper and the cooperative-mode
interpreter. That matches its siblings `HasNativeEntryPoint` and
`SetActualCode`.
- The three `ActiveIssue` annotations for dotnet#134145 are removed.

## Validation

Browser CoreCLR, Release, `TestWasmReadyToRun=true`,
`EnableAggressiveTrimming=true`, Chrome:

- The three re-enabled `StateMachineAsync_*_ChainEventsAndCallstack`
tests: **3/3 pass**. With only the `runtimehandles.cpp` change reverted
and the runtime rebuilt: **0/3**.
- Whole `AsyncProfilerTests` class: 136 run, **61 passed, 0 failed**, 75
skipped by existing platform conditions.

Not validated: a Debug/Checked browser build, where contracts are
enforced. Non-Wasm builds compile the new mapping out.

## Follow-up

The cDAC has the same gap for SOS native code addresses on
portable-entrypoint targets: dotnet#134753.

Resolves dotnet#134145

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
## Summary

- Add the repository-scoped KBE issue-search wrapper used by the CI
scanner eval.
- Add the candidate-read grader and focused Node tests.
- Provision these evaluator inputs from the trusted base checkout and
wire the focused test and grader into the eval runner.
- Keep the trusted helper, grader, and focused tests outside the
agent-writable eval workspace.

## Role in the stacked change

This is the prerequisite for
[dotnet#133684](dotnet#133684).
It must merge before dotnet#133684 so the trusted evaluator files are
available from `main`. The `/ci-eval` workflow restores evaluator inputs
from `main` before checking out a pull request; without these files on
`main`, the dependent PR's wrapper, grader, and focused tests cannot be
trusted or exercised by the evaluator.

After this PR merges, dotnet#133684 can retain the production workflow,
instruction, and eval-spec changes that consume this support.

## Validation

- `npm test --prefix .github/workflows/evals` — 13 tests passed.
- Isolated-temp execution of the trusted helper/grader tests — 13 tests
passed.
- JavaScript syntax checks, YAML parsing, and `git diff --check` passed.

> [!NOTE]
> This pull request description was generated by GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use mixed type-handle hashes in CoreCLR, preserving COM identity hashing
(Windows only).

```cs
using System;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);

public class Bench {
    private readonly Dictionary<Type, int> _dictionary = new() { [typeof(string)] = 42 };

    [Benchmark]
    public int Lookup() => _dictionary[typeof(string)];
}
```
up to [25% faster](EgorBot/Benchmarks#623).

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3ed54863-8a13-437b-aa0a-a6f356b253ed
Copilot-Session: 033db876-d232-451a-94ab-ed732694508a
## Description

Update the shared KBE instructions to preserve complete lookup results
and author metadata, stop filing when an issue or fix-PR lookup is
inconclusive, and follow duplicate links to the original KBE before
treating a closed duplicate as a recurrence. Keep the caller tool policy
and existing skip reasons unchanged. The change is limited to
`.github/workflows/shared/create-kbe.instructions.md`, with no scripts
or workflow configuration changes.

The duplicate path is visible in
https://github.com/dotnet/runtime/actions/runs/35511300359. The searches
omit `user`, and shell projections discard the resulting `[Filtered]`
markers before the scanner creates new issues.

Contributes to dotnet#134302 and dotnet#134304.

> [!NOTE]
> This pull request was generated with GitHub Copilot.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 853fa924-7d9d-4d5b-9990-f7ac0d9d5e88
Copilot-Session: 06bd27cd-bf15-4fd8-9f4d-911464827963
…34048)

Before this PR the model in physical promotion is that promoted locals
are always up-to-date in their replacement locals at the end of basic
blocks. In certain cases, however, that causes us to be overly eager in
insertion of readbacks.

One common case is for struct parameters. Currently the above model
means we will always extract fields from the parameters at the end of
the entry basic block. If the parameter has many fields in it this leads
to creating a lot of live state. Also, if some fields are only used
rarely it is wasteful to extract them in the entry block (the extraction
may require bitwise operations).

This PR tries to improve the situation. It changes physical promotion to
run the replacement phase in RPO. Then, it introduces logic to delay the
readbacks:
1. If at the beginning of a basic block all predecessors agree that the
local is up to date in the struct, then inherit that in the current
basic block and avoid inserting readbacks.
2. If not, insert a reconciling readback at the end of the predecessors
where the replacement field is not up to date.

Backedges are handled conservatively by always ensuring replacement
fields are up to date into blocks that are targets of backedges.

The above may result in suboptimal insertion of reconciling readbacks in
some cases compared to the current behavior. To handle this we
additionally have a plan phase where we compute the dominator of all
blocks where we expect to insert reconciling readbacks. Then, we use
profile information to evaluate whether inserting a common readback in
the dominator would be beneficial instead of inserting the multiple
reconciling readbacks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implements the cleanup proposed in dotnet#6218.

In practice, this flag has been more of a maintenance burden than a
useful diagnostic aid (Debug only).

Remove `GTF_DEBUG_NODE_MORPHED`,
`SetMorphed`/`WasMorphed`/`ClearMorphed`, per-node morph counts, both
tracking walkers, and related debug-dump plumbing. Remove redundant
wrappers and branches while preserving actual morphing and assertion
propagation.

Copilot-Session: 525afe63-5b42-44ea-981b-54d32edaf418
## Summary

- replace the obsolete local-agent SOS test jobs with the
`dotnet/diagnostics` `SOS.Tests` Helix harness
- run SOS coverage on the same eight platforms as the cDAC dump tests,
with both legacy DAC and cDAC rows handled by the harness
- reuse each platform's existing `CdacBuildArtifacts` for the private
runtime and copy the private universal cDAC binaries directly beside SOS
- start each SOS job after its matching platform build rather than
waiting for every platform

This depends on the private-runtime Helix support in
dotnet/diagnostics#6068. Normal pipeline runs continue to use
diagnostics `main`; coordinated validation can set `diagnosticsBranch`
to that PR's GitHub ref.

## Testing

- parsed the modified pipeline YAML and ran `git diff --check`
- built diagnostics Release x64 with `PackageWithCDac=false`
- verified the copied universal cDAC and DBI hashes match the runtime
build outputs
- ran `eng/helix/SendToHelix.proj /t:GatherHelixWorkItems` locally with
the private runtime override
- verified the generated payload contains the private runtime and
matching private cDAC
- verified Linux ARM32 selects the runtime package rather than the
unavailable SDK package

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

---------

Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com>
Copilot-Session: 3f8294bb-306d-4f13-84c5-f8ecbe58ce02
…et#134861)

This is a test for bad codegen so we do not need to validate that
conditional escape analysis is actually kicking in.
At the same time, it is hard to do that because we have various config
where we don't expect this to kick in (like interpreter). So just remove
this.
## Summary

Avoid emitting and loading ReadyToRun metadata that CoreCLR WebAssembly
cannot consume.

- Remove CoreCLR runtime support for the legacy `InliningInfo` section
while retaining R2RDump support.
- Derive `FEATURE_INLINE_TRACKING_ENABLED` from the profiling, ReJIT,
and code-versioning feature macros, which leaves inline tracking
disabled in WebAssembly builds.
- Skip loading modern inline-tracking sections when no runtime feature
consumes them.
- Strip inline and debug information by default from Browser and WASI
ReadyToRun images, including `System.Private.CoreLib.wasm` and
framework-library `.wasm` files. The existing
`PublishReadyToRunStripInliningInfo=false` and
`PublishReadyToRunStripDebugInfo=false` opt-outs remain available.
- Remove R2R version checks that are always true now that the minimum
supported major version is 26.

## Validation

- `./build.sh clr -c Checked`
- `./build.sh clr+libs -os browser -c Release`
- Temporarily added a compile-time `#error` for `TARGET_WASM &&
FEATURE_INLINE_TRACKING_ENABLED`; the Browser/Wasm CoreCLR build
succeeded, confirming the feature is disabled.
- Verified the Crossgen2 command for `System.Private.CoreLib.wasm`
contains both `--strip-inlining-info` and `--strip-debug-info`.
- Used R2RDump to confirm `System.Private.CoreLib.wasm` and all 101
Release framework-library `.wasm` images contain none of:
  - `DebugInfo`
  - `InliningInfo`
  - `InliningInfo2`
  - `CrossModuleInlineInfo`
- Compared CoreCLR section readers with Crossgen2 emission sites; no
other runtime-consumed R2R section lacks a corresponding emitter.

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…terpreter thunks (dotnet#134676)

## Problem

For shared-generic runtime-async methods, crossgen2's Wasm thunks passed
the hidden generic context and the async continuation in each other's
slots.

`WasmLowering.RaiseSignature` has no way to mark a parameter as the
hidden generic context, so it returns it as the first entry of the
`MethodSignature` parameter list, with `this` and the return buffer
implied by the signature flags and return type. The thunks built their
`ArgIterator` from that signature without `methodRequiresInstArg`, so
`ArgIterator` laid the frame out as `[this][continuation][ctx][args]`.
The interpreter, the VM `ArgIterator` and the callee's GC ref map
(`GCRefMapBuilder.GetCallRefMap`) all expect
`[this][ctx][continuation][args]`.

Andy diagnosed this in dotnet#133627 and proposed modeling the context as the
hidden instantiation argument; this PR follows that suggestion.

Symptoms:
- dotnet#133953: `SanityCheck()` in interpreted
`AsyncHelpers.Await<__Canon>(ValueTask<T>)` (R2R→interpreter).
- dotnet#134660: `numGenericArgs > 0` in `ProcessDynamicDictionaryLookup` for
a generic virtual async method.
- dotnet#133627: memory access out of bounds in
`WasmR2RToInterpreterThunk(iiaS8p)` (`AwaitAwaiter<TAwaiter>`).
- dotnet#128626 (removing `[BypassReadyToRun]` from `AsyncHelpers`) hits the
interpreter→R2R direction of the same bug on both the R2R and non-R2R
browser legs.

## Fix

- When a generic context precedes the async continuation, drop it from
the layout signature and build the `ArgIterator` with
`methodRequiresInstArg: true`. The context is then stored and loaded
through `GetParamTypeArgOffset()`, and the continuation through
`GetAsyncContinuationArgOffset()`. Without an async continuation the
context occupies the same slot as a leading pointer argument, so it
keeps the pointer encoding (`i`/`l`). `InitHelpers.CallClassConstructor`
relies on that when it calls a shared generic class constructor as
`delegate*<void*, void>`.
- Share one argument layout across the three thunks that spill
arguments: `WasmR2RToInterpreterThunkNode`,
`WasmInterpreterToR2RThunkNode` and `WasmImportThunk`. Each used to
hand-code the hidden-argument sequence, which is how the slots got
swapped. `WasmThunkArgLayout` walks the Wasm signature string in Wasm
parameter order, `[this] [retbuf] [generic context] [continuation]
[args]` per
[clr-abi.md](https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/botr/clr-abi.md#passing-continuation-argument),
takes each offset from that `ArgIterator`, and asserts that the two
agree. Each thunk keeps its own emission and loops over the entries.
- For `WasmImportThunk`, the swapped spill disagreed with the delay-load
GC ref map, which `GCRefMapNode` builds from the callee's `MethodDesc`
via `GCRefMapBuilder.GetCallRefMap`. A GC during the fixup would have
reported the generic context slot as an object reference and missed the
continuation. The thunk now spills both to the offsets the GC ref map
describes, and `WasmThunkArgLayoutMatchesCallRefMapLayout` asserts the
two layouts are identical.
- Move the three copies of `HasGenericContextBeforeAsync` into
`WasmLowering`, and use it from `RaiseSignature` so the encoding is
parsed in one place.

## Testing

- Reproduced the dotnet#133953 and dotnet#134660 failures locally from the CI Helix
payload of `run_test_p0_coreclr_R2R_CG2_browser_wasm_checked` (the
`async` work item), with an osx-arm64 crossgen2 and wasm JIT.
- With this change, the full `async` work item passes 132/132 in both
R2R (`RunCrossGen2=1`, no tiered compilation) and non-R2R modes. Without
it, both failures reproduce.
- dotnet#128626's diff on top of this change also passes 132/132 in both
modes.
- New `WasmArgumentLayoutTests` cases assert the kind, offset and Wasm
parameter index of every thunk argument for `iiaip`, `iTiaip`, `S16iaip`
and `S16Tiaip`, the no-context cases, and multi-slot and by-reference
arguments. `GenericContextEncodesAsLeadingPointerArgument` pins the
`CallClassConstructor` invariant: without an async continuation, a
context and a leading pointer argument lower to the same key.
`WasmArgumentLayoutTests` passes 98/98 locally with a browser-wasm
target.
- `WasmThunkArgLayoutMatchesCallRefMapLayout` compares every slot of the
thunk layout with the `ArgIterator` that `GetCallRefMap` uses, for
shared generic, async and shared generic async CoreLib methods.
- The shared layout produces byte-identical crossgen2 output to the
previous head of this PR (4e66ef0) for System.Private.CoreLib and
the 78 assemblies in the `async` work item (`--parallelism:1`), and the
`async` work item passes 132/132 in R2R mode.
- Re-enabled `AsyncProfilerTests.RuntimeAsync_WhenAny_TracksAllBranches`
(dotnet#133627). It runs only in the full browser CoreCLR R2R library lane,
which PRs can't reach today: `runtime-extra-platforms` adds Wasm jobs
only for scheduled builds, and `runtime-wasm-libtests` is disabled in
AzDO. It hasn't run in CI for this PR. The first scheduled
`runtime-extra-platforms` build after merge will run it; dotnet#134613
restored that lane.

## Notes

- dotnet#134643 adds ActiveIssues for dotnet#133953 and dotnet#134660; those shouldn't be
needed with this change.
- dotnet#134211 touches the members right above the removed
`HasGenericContextBeforeAsync` properties, so whichever lands second
will have a small textual conflict.
- The two interpreter transition thunks are shared across images by
signature string, first registration wins (`WasmImportThunk` is not;
each image references its own). An image compiled by an older crossgen2
would still carry the old layout under the same key. That only matters
for mixing crossgen2 versions, which Wasm R2R doesn't ship yet.
- A dedicated `g` token for the context (dotnet#134716) was folded in and then
reverted. The VM computed `Ivgp` for a shared generic class constructor
while R2R code registered only `Ivip` from `CallClassConstructor`, so
the portable entry point got no interpreter thunk and every app in the
browser R2R smoke lane failed at startup. Emitting `g` only before `a`
would carry no more information than the pointer char in that position.

cc @AndyAyersMS @davidwrighton

Resolves dotnet#133953
Resolves dotnet#134660
Resolves dotnet#133627

> [!NOTE]
> This PR description was drafted with GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…134313)

On Linux the client TLS session cache kept exactly one SSL_SESSION per
SNI host. For TLS 1.3 that is wrong in two compounding ways. We can get
unnecessary tuen when server sends more tickets and we also have problem
with concurrency as we cannot use the same ticket twice for TLS 1.3. The
cache design was done for TLS 1.2 where using same ticket over and over
again is fine. Also we have possible lock ordering problem.

| Concurrent connections | TLS 1.2 | TLS 1.3 run 1 | run 2 | run 3 | TLS
1.3 mean |
|---:|---:|---:|---:|---:|---:|
| 1 | 100% | 100% | 100% | 100% | 100% |
| 2 | 100% | 100% | 100% | 100% | 100% |
| 4 | 100% | 100% | 100% | 100% | 100% |
| 8 | 100% | 100% | 100% | 100% | 100% |
| 16 | 100% | 96.9% | 92.2% | 95.3% | **94.8%** |
| 32 | 100% | 97.7% | 95.3% | 88.3% | **93.8%** |
| 64 | 100% | 84.0% | 93.8% | 91.4% | **89.7%** |

Measured with the concurrent handshake benchmark from
dotnet/performance#5314 over loopback sockets, TLS 1.3 with resumption:
14% faster at 64 concurrent connections and 12% at 128. TLS 1.2 and the
non-resuming cases are unchanged; low concurrency costs 2-3%.

Note that this really depends on machine and timing. The problem is
nearly invisible when using Memory stream and everything is super fast.
But that is not the real world scenario.

This PR separates the behavior so we can have multiple (up to 8) tickets
so we have better chance of resumption during parallel processing. We
would hold eactly one ticket for cases when site is visited once and
never again after e.g. crawlers.

### Effect of the fix

Measured with `SslStreamConcurrencyTests.ConcurrentHandshake` from
dotnet/performance#5314, which performs concurrent TLS handshakes over
loopback
sockets. Both runtimes were driven by BenchmarkDotNet's CoreRun
toolchain in a
single run on the same machine, with the unmodified build as the
baseline, so
the ratios are directly comparable. Linux x64, OpenSSL 3.0.13, RSA-2048
server
certificate. Ratio below 1.00 means the fix is faster.

**TLS 1.3 with resumption enabled**

| Concurrent connections | before | after | ratio |
|---:|---:|---:|---:|
| 1 | 4345.7 µs | 4495.7 µs | 1.03 ± 0.02 |
| 8 | 320.0 µs | 326.1 µs | 1.02 ± 0.01 |
| 64 | 318.4 µs | **273.2 µs** | **0.86 ± 0.03** |
| 128 | 326.1 µs | **285.6 µs** | **0.88 ± 0.05** |

14% faster at 64 concurrent connections and 12% at 128.

**Cases the change should not affect**

| Arm | N=1 | N=8 | N=64 | N=128 |
|---|---:|---:|---:|---:|
| TLS 1.2, resumption enabled | 0.99 | 1.00 | 0.99 | 1.01 |
| TLS 1.2, resumption disabled | 0.98 | 0.96 | 0.97 | 1.01 |
| TLS 1.3, resumption disabled | 0.98 | 1.00 | 0.98 | 0.97 |

**Cost**

At low concurrency TLS 1.3 resumption is 2–3% slower (1.03 at N=1, 1.02
at
N=8) and allocates about 1% more (12.44 KB vs 12.33 KB at N=64). This is
the
extra `SSL_SESSION_up_ref` call and the list lookup replacing a
dictionary
lookup. 

**Eviction and cache cleanup**
OpenSSL continues to enforce its own global cap of
`DefaultTlsCacheSizeClient`
sessions across all hostnames, unchanged by this PR. When the cache is
full
`SSL_CTX_add_session` evicts from `ctx->session_cache_tail` until it is
back
under the limit, and since `SSL_SESSION_list_add` keeps the list ordered
by
effective expiry rather than by insertion or use, the victim is always
the
session nearest to expiring — effectively oldest-first, so idle hosts
shed
entries before active ones. Every removal path invokes
`remove_session_cb`,
which is how the managed dictionary stays in sync and how its size stays
transitively bounded by that same cap: the callback finds the entry by
the
hostname stashed on the session and by pointer identity, then drops
exactly one
reference. OpenSSL raises it even when the session was not in its own
hash, so
the removal is guarded to release once per cached reference.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary

- avoid treating `isinst Nullable<T>` success branches as unreachable
based on the absence of a constructed `Nullable<T>` MethodTable
- keep substituted IL generation and dependency scanning consistent for
nullable type tests
- add a new regression test for NativeAOT coverage for generic nullable
type-test branches with matching, mismatching, and null inputs

Resolves dotnet#134799

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

Copilot-Session: 318157b0-8bdc-4d1e-b18e-25341047f8c3
Fixes dotnet#134693
Fixes dotnet#134694

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eed5c782-c8db-4601-b10a-dafbb249ba73
…all (dotnet#134826)

On browser CoreCLR,
`JIT/Directed/callconv/{Cdecl,StdCall,PlatformDefault}MemberFunction`
and `ThisCall` fail with a `GetCookieForCalliSig: unknown thunk
signature` assert. The MemberFunction tests print `WASM calli missing
for key: MS8ii`, which comes from `delegate* unmanaged[Cdecl,
MemberFunction]<C*, int, SizeF>`. That signature only shows up as a
`calli`, so the thunk generator never sees it. ThisCall gets rejected by
the callconv switch before a key is even built.

dotnet#133571 disabled these tests on browser. This PR fixes the cause and
re-enables all four tests.

## Changes
- `PortableCallHelpers/PInvokeCollector.cs`: the new
`CollectUnmanagedCalliSignatures` scans IL for `calli` through unmanaged
function pointers. It adds their signatures to the interp-to-native
thunk table. Managed and varargs calli, generic-shaped signatures, and
signatures that can't be lowered are skipped, with a Verbose log.
- `JitInterface/WasmLowering.cs`: `GetSignature` treated
`UnmanagedCallingConvention` (`0x9`) as a bit flag, so Cdecl, StdCall
and ThisCall signatures (`0x1`–`0x3`) were lowered as managed. It now
checks the masked calling convention, and the collector no longer has to
pass `IsUnmanagedCallersOnly` to compensate.
- `vm/wasm/helpers.cpp`: `ComputeCalliSigThunk` now accepts
`IMAGE_CEE_CS_CALLCONV_THISCALL`.
- `PortableCallHelpers/PInvokeTableGenerator.cs`: when a reverse thunk
returns a struct that the wasm C ABI returns by reference, the thunk now
takes the hidden leading `sret` pointer and hands it to the interpreter
as the return buffer. This applies to `[UnmanagedCallersOnly]` wrappers
and exports. Before, it was declared as returning `void *`. Native code
calling `GetSize` through the vtable (`SizeF` return) then trapped with
`function signature mismatch`, and the interpreter would have written 8
bytes into a 4-byte local. The P/Invoke declaration path already handled
this. This also removes the rejection of callbacks that return through a
hidden buffer, which dotnet#134355 added because the wrapper didn't model that
ABI yet (cc @pavelsavara). The export-only R2R dispatch from dotnet#134355
forwards `sret` the same way.
- `WasmArgumentLayoutTests.cs`: new tests
`PortableCallHelpersGeneratorEmitsThunksForUnmanagedCalliSites`,
`PortableCallHelpersGeneratorReturnsStructsThroughHiddenPointerInReverseThunks`
and `SignatureCallingConventionSelectsLowering`.
- `src/tests/JIT/Directed/callconv/`: reverts the `ActiveIssue`,
`WasmBuildTestCorerun=false`, and `CLRTestTargetUnsupported` disables
that dotnet#133571 added. The files now match their state before dotnet#133571. The
exception is `ThisCallTest.cs`: its
`Marshal.GetFunctionPointerForDelegate` reverse cases are now skipped on
wasm. CoreCLR wasm can't allocate the stub those need at run time, and
it isn't reliable on Mono either (dotnet#104391). Its forward and
`UnmanagedCallersOnly` cases still run there.

## Validation
- I ran the patched crossgen2 with `--generate-portable-callhelpers`
over the Helix payloads of the three MemberFunction tests. Each one now
emits `S8ii` from `Test8ByteHFA`.
- ThisCall already had `S8ii` through an `UnmanagedFunctionPointer`
delegate, so only the runtime switch change matters for it.
- The new unit test fails without the collector change and passes with
it. All 68 `WasmArgumentLayoutTests` pass. They ran against a browser
CoreLib/libs layout staged from the Helix correlation payload.
- After the first CI run, all three MemberFunction tests trapped with
`function signature mismatch` in `Test8ByteHFAUnmanagedCallersOnly`. I
reproduced that locally with the Helix payload. The native
`call_indirect` expects `(i32, i32, i32) -> void`. After the
reverse-thunk fix, the regenerated `GetSize` thunk is `void(void* sret,
void*, int32_t)`. The new unit test covers this, and all 69
`WasmArgumentLayoutTests` pass.
- End to end: I did a local browser build (`./build.sh -os browser -c
Debug -subset clr+libs`, which compiles the `helpers.cpp` change) and
built `JIT/Directed/callconv` with `src/tests/build.sh -browser Debug`.
All four tests exit 100 under node. I reran this after merging main,
which brought in dotnet#134355, dotnet#134676 and dotnet#134690. All 112
`ILCompiler.ReadyToRun.Tests` in `WasmArgumentLayoutTests` pass, and so
do the four callconv tests.
- After the `WasmLowering` fix, all 88 `WasmArgumentLayoutTests` pass.
The rebuilt crossgen2 regenerates call helpers for the four callconv
tests that are byte-identical to the ones linked in the end-to-end run.

## Note on checked-in tables
The checked-in `src/coreclr/vm/wasm/{browser,wasi}/callhelpers-*.cpp`
tables may now be missing framework calli signatures until they are
regenerated with `generate-coreclr-helpers.sh`. A missing entry is not a
broken one. They were not regenerated in this PR.

> [!NOTE]
> This PR description was generated with AI assistance (GitHub Copilot).

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Radek Doulik <radek.doulik@gmail.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
## Summary

- add AppDomain-managed external memory handles for GC-scanning managed
references stored outside the GC heap and managed stacks
- enumerate external memory handles through DAC and a dedicated cDAC
`ExternalMemoryHandles` contract, including byref-like field walking and
interior-pointer resolution
- protect unboxed byref-like func-eval results for the lifetime of the
returned `ICorDebugValue`

## Testing

- `build.cmd tools+tools.cdactests -test`
- `build.cmd clr`

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot-Session: 3900c560-18f8-4900-9840-ae7022248647
lewing and others added 28 commits October 2, 2026 13:05
… section (dotnet#135059)

Native `ReadyToRunInfo::GetDebugInfo`
(`src/coreclr/vm/readytoruninfo.cpp`) returns `NULL` immediately when
`m_pSectionDebugInfo == NULL`. The cDAC mirror,
`ReadyToRunJitManager.GetDebugInfo`, dereferenced
`ReadyToRunInfo.DebugInfoSection` without that check and built a
`NativeArray` from whatever was at address 0.

This now matters because dotnet#134690 makes Browser/WASI ReadyToRun publishes
pass `--strip-debug-info` by default, including CoreLib and the
framework. iOS, tvOS, and MacCatalyst already default to it. On wasm,
linear address 0 is readable, so cDAC decoded garbage. A live run
against a stripped browser image threw `BadImageFormatException: offset
out of bounds` (`NativeReader.DecodeUnsigned` ← `NativeArray..ctor` ←
`ReadyToRunJitManager.GetDebugInfo` ← `DebugInfo_1.GetMethodVarInfo`)
instead of reporting that there was no debug info. On native targets,
the same path fails with a read exception.

## Changes

- `ReadyToRunJitManager.GetDebugInfo` returns `TargetPointer.Null` (with
`hasFlagByte = false`) when `DebugInfoSection` is null, matching native.
- `docs/design/datacontracts/ExecutionManager.md`: the R2R
`GetDebugInfo` description now includes the null-section early return.
- No caller changes were needed. `DebugInfo_1.HasDebugInfo`,
`GetMethodNativeMap`, `GetMethodVarInfo`, and `GetAsyncSuspensionPoints`
already treat a null debug-info pointer as "no debug info". The two
map/var methods still compute `codeOffset`.

## Tests

New test
`ExecutionManagerTests.GetDebugInfo_R2R_NoDebugInfoSection_ReturnsNull`
runs as a `[Theory]` over `StdArchAllVersions` (4 arch cases). It builds
an R2R module whose `DebugInfoSection` is null and makes the low 4 KB of
the address space readable as zeros, the way wasm linear memory is, so
the unfixed code decodes instead of hitting a read fault. It asserts
that:
- `IExecutionManager.GetDebugInfo` returns `TargetPointer.Null` and
`hasFlagByte == false`
- `IDebugInfo.HasDebugInfo` is `false`
- `GetMethodVarInfo` and `GetMethodNativeMap` return empty sequences
with `codeOffset == 4`

Results:
- `./build.sh -s tools.cdactests -test`: passed. UnitTests 3236/3236,
DataGeneratorTests 46/46, UsageTests 4/4 (no stale generated docs).
- `./.dotnet/dotnet test src/native/managed/cdac/tests/UnitTests
--filter "FullyQualifiedName~GetDebugInfo_R2R_NoDebugInfoSection"`:
passed, 4/4.
- Mutation check: I removed the null check and reran the same filtered
command. It failed 4/4 with `System.BadImageFormatException : offset out
of bounds` at `NativeReader.DecodeUnsigned` ← `NativeArray..ctor` ←
`ReadyToRunJitManager.GetDebugInfo`, the same failure as the live wasm
run. With the fix restored, it passes 4/4.

This PR has a single concern. It leaves wasm stack-walk and
variable-location work to dotnet#133890, dotnet#135044, and dotnet#135055.

> [!NOTE]
> This PR description was generated with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
## Summary

Small non-collectible thread-static blocks can be allocated directly
inside `ThreadLocalData`. The allocator works from the end of the
direct-TLS region and aligns each allocation according to its size.

The allocator previously marked this path successful even when the
unaligned allocation fit but the required alignment padding did not. In
that boundary case, the code retained an invalid direct-TLS result
instead of falling back to the dynamically allocated non-collectible
thread-static array.

This change marks direct-TLS allocation successful only after the
aligned allocation is confirmed to fit. Rejected allocations now use the
existing non-collectible array path.

## Testing

- Windows x86 Checked CoreCLR build.
- Added and ran `threadstatic09`, which starts fresh child processes
with different amounts of direct-TLS padding and verifies an eight-byte
`[ThreadStatic] long` across the allocation boundary.
- Verified during development that the regression fails against the
unfixed runtime and passes with this change.

This is a follow-up to dotnet#129733 and dotnet#129749.
The original issue is already closed by the earlier PR.

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Removes GenTree flags that are dead or redundant:

- `GTF_ICON_CIDMID_HDL` – never set or read.
- `GTF_ARRLEN_NONFAULTING`, `GTF_MDARRLEN_NONFAULTING`,
`GTF_MDARRLOWERBOUND_NONFAULTING` – aliases of `GTF_IND_NONFAULTING`,
only referenced by `static_assert`s.
- `GTF_DEBUG_VAR_CSE_REF` – debug-only, only read by the JitDump flag
printer.
- `GTF_CALL_M_STACK_ARRAY` – redundant with the
`WellKnownArg::StackArrayLocal` arg added at the same time; VN now
checks the arg (helper expansion already does).
- `GTF_BOX_VALUE` – set on every `GT_BOX` node, so `IsBoxedValue()` is
just `OperIs(GT_BOX)`.

No asm diffs expected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4da926d5-0c75-45b4-b175-a69def43db37
…t#134185)

Copy the replacement local's node type along with its local and SSA
numbers. This allows the resulting self-comparison to fold instead of
retaining a truncated load of an int local.

Fixes dotnet#133859.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c20aa474-545f-4b8c-8143-b50e15f04910
Bail out before unrolling when the analyzed loop test is not the branch
condition, avoiding a Checked assert and Release MinOpts fallback.Fixes
dotnet#134934


[Diffs](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1618374&view=ms.vss-build-web.run-extensions-tab)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9cae45a2-8eb1-4625-a0bf-fbe425c2dac8
…otnet#135083)

<!-- -->

Resumed initial TLS handshakes intentionally skip certificate validation
callbacks. Several SslStream tests still depend on those callbacks,
which can cause callback-count failures or silently bypass assertions
after another connection populates the session cache.

Fixes: dotnet#135057

This also addresses the incorrect-server-name isolation problem reported
in dotnet#135031.

- Require full handshakes in validation-focused tests, including the
empty target-hostname case, renegotiation, client certificate chains,
delayed certificate selection, connection information, SNI, custom
trust, and remote validation/OCSP.
- Assert callback execution where validation assertions previously
existed only inside the callback.
- Give incorrect-server-name tests a unique mismatching hostname while
preserving their existing authentication overloads.

These are test-only changes. Runtime behavior, generic stream I/O
helpers, and intentional resumption coverage remain unchanged. The
repeated client-chain test still exercises credential caching, but not
TLS session resumption.

### Validation

Built and tested on Windows x86 with Checked CoreCLR and Debug
libraries, using a `subst` short path:

- `.\build.cmd clr+libs -arch x86 -rc checked`: passed.
- `.\.dotnet\dotnet.exe build
src\libraries\System.Net.Security\tests\FunctionalTests\System.Net.Security.Tests.csproj
/t:Test /p:TargetArchitecture=x86 /p:RuntimeConfiguration=Checked`:
final run passed, 5,289 passed and 36 skipped.
- `.\.dotnet\dotnet.exe build
src\libraries\System.Net.Security\tests\UnitTests\System.Net.Security.Unit.Tests.csproj
/t:Test /p:TargetArchitecture=x86 /p:RuntimeConfiguration=Checked`:
passed, 117 passed and four skipped.
- Focused functional selection: 70 passed, including all three
target-hostname rows, all five incorrect-name implementations, and all
12 resumption-switch rows. Affected external-server outer-loop
selection: nine passed.

The original CI failure was not reproduced locally; Windows Server 2016
and non-Windows platforms were not tested. Earlier pristine and patched
full-suite runs had intermittent credential/resumption failures. Both
subsequently passed, and the affected resumption method passed all 18
rows in isolation on both versions. The exact first patched resumption
failure's cause remains unproven.

Resolves dotnet#135057

> [!NOTE]
> This PR description and code changes were generated with GitHub
Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
## Summary

Use `PROFILING_SUPPORTED_DATA` instead of `PROFILING_SUPPORTED` to guard
the `PEAssembly::m_pImporter` and `m_pEmitter` instance fields.

dotnet#134875 made these fields conditional on `PROFILING_SUPPORTED`, which is
not defined in native DAC builds. This shifted the DAC's view of
subsequent fields, including `m_pAssemblyBinder`, and caused `dumpalc`
to report `Failed to get the AssemblyLoadContext`.

`PROFILING_SUPPORTED_DATA` is defined for both the profiling-enabled
runtime and its DAC, preserving their matching layouts without enabling
profiler functionality in the DAC.

## Validation

- Windows x64 Release runtime/DAC build: `.\build.cmd -subset
clr.runtime -c Release` succeeded with zero warnings or errors.
- Captured a dump of a minimal managed object in the default ALC using
the unfixed runtime. Native SOS `dumpalc` reproduced `Failed to get the
AssemblyLoadContext`.
- Replaced only `mscordaccore.dll` with the fixed DAC and analyzed the
same dump with the same SOS. `dumpalc` returned `Name:
System.Runtime.Loader.DefaultAssemblyLoadContext`.
- The full SOS suite and other architectures were not run locally.

Resolves dotnet#135075

> [!NOTE]
> This PR description and fix were prepared with GitHub Copilot.

Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com>
Copilot-Session: 593f81fe-227d-480b-9da0-38ddeea24fd9
…et#134964)

The CoreCLR WASI host (`wasihost`) initializes the runtime with only
`TRUSTED_PLATFORM_ASSEMBLIES`, `APP_PATHS` and the host runtime
contract. It never reads the app's runtime configuration, so none of the
`configProperties` from `<app>.runtimeconfig.json` reach `AppContext`:
feature switches, `RuntimeHostConfigurationOption` items and so on. For
example, `System.Text.Encoding.EnableUnsafeUTF7Encoding` never arrives,
so UTF-7 tests throw `NotSupportedException : Support for UTF-7 is
disabled`. When trimming,
`System.Data.DataSet.XmlSerializationIsSupported` is seen as missing by
test `PlatformDetection`.

## Change

- `src/native/corehost/wasihost/wasihost.cpp`: read `runtimeconfig.bin`
from next to the entry assembly and append its properties to the init
properties passed to `coreclr_initialize`. Properties the host sets
itself take precedence. `get_runtime_property` already serves from the
same vectors, so the contract callback returns the same values. A
missing file is ignored, and a malformed one fails startup with a
message.
- `src/mono/wasi/build/WasiApp.CoreCLR.targets`: copy
`runtimeconfig.bin` into `managed/`, next to the entry assembly, the
framework, `icudt.dat` and the host. `WasiAppBuilder` places it at the
bundle root, which `run-wasmtime.sh` (`cd managed && wasmtime --dir .
...`) does not preopen.

`runtimeconfig.bin` is the file `RuntimeConfigParserTask` already
produces for WASI apps, and Mono's WASI driver consumes the same file.
Its format is an ECMA-335 compressed count followed by key/value
serialized strings, so the host needs no JSON parser. The browser
CoreCLR host follows the same model: `configProperties` first, with
host-set properties overriding them.

## Validation

Local, macOS arm64 host, wasi-sdk 33, wasmtime 45.

- `./build.sh -os wasi -arch wasm -rf CoreCLR -s clr+libs+host -c
Release` on clean upstream `main` → succeeded, 0 warnings, 0 errors.
- `./build.sh -os wasi -arch wasm -rf CoreCLR -s host.native -c Release`
with the change → succeeded; `wasihost.cpp` compiles with no warnings.

**System.Text.Encoding.Tests** (untrimmed, `./dotnet.sh build
src/libraries/System.Runtime/tests/System.Text.Encoding.Tests/System.Text.Encoding.Tests.csproj
-f net11.0 /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm
/p:RuntimeFlavor=CoreCLR /p:Configuration=Release`)

On `main`, the full suite hangs in
`TranscodingStreamTests.ReadAsync_LoopsWhenPartialDataReceived`, a
blocking wait on single-threaded WASI that is handled in dotnet#134813. So I
compared the UTF-7-related classes directly with wasmtime on the bundle
(`-class` for EncodingMiscTests, EncodingGetEncodingTest,
NegativeEncodingTests and the seven `UTF7Encoding*` classes):

| | Tests run | Passed | Failed |
|---|---|---|---|
| Without fix | 1692 | 1654 | **38** (all `Support for UTF-7 is
disabled`) |
| With fix | 1720 | 1720 | **0** |

Full suite with the fix, with the hanging test skipped locally only (not
part of this PR): 14614 run, 14605 passed, 4 failed, 5 skipped, 0 UTF-7
failures. The 4 failures are unrelated:
`FromUtf16Tests`/`ToUtf16Tests.SomeNonAsciiInput` need
System.Security.Cryptography (dotnet#99126), and
`TranscodingStreamTests.ReadApm`/`WriteApm` throw
`PlatformNotSupportedException` from `TaskToAsyncResult.Begin`.

**System.Data.Common.Tests** (untrimmed, same command with the
System.Data.Common.Tests project)

- With fix: 11734 run, 11658 passed, 67 failed, 9 skipped. The same
bundle run with `managed/runtimeconfig.bin` removed, which reproduces
the pre-fix behavior, gives the identical 67 failures. So there are no
regressions. 54 of the failures are `IOException : Success : '/tmp/'`
(dotnet#134958), and the rest are DbProviderFactories and serialization-guard
failures unrelated to runtimeconfig.
- The DataSet switch only lands in runtimeconfig when trimming, and
trimmed CoreCLR-WASI test builds don't work on `main` yet (ILLink can't
resolve System.Private.CoreLib; dotnet#134813 sets that up). To confirm the
switch now reaches both the product and `PlatformDetection`, I added
`System.Data.DataSet.XmlSerializationIsSupported=false` to the bundle's
`runtimeconfig.bin` and ran `-class System.Data.Tests.DataSetTest -class
System.Data.Tests.DataTableTest5`. The original config gave 63 run, 48
passed, 14 failed (`/tmp`), 1 skipped. With the switch it gave 63 run,
44 passed, 0 failed, 19 skipped: the guarded tests skip and nothing
fails from a product/test mismatch.

This is split out from the WASI R2R test-standup work in dotnet#134813, where
the missing properties account for the 38 UTF-7 failures and about 360
System.Data.Common failures in trimmed runs.

Resolves dotnet#134954

> [!NOTE]
> This PR was authored with assistance from GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…tnet#135044)

Fixes four cDAC failures found by walking stacks on a live CoreCLR
browser-wasm target (nightly `12.0.0-alpha.1.26480.103`) through
`IStackWalk`. On `main`, the walk fails on its first step, or never
ends, and no MethodDesc can be named.

## Changes

**MethodDesc validation rejects every MethodDesc (dotnet#135035).** With
`FEATURE_PORTABLE_ENTRYPOINTS`, the runtime has no precode stubs and
doesn't describe `PrecodeMachineDescriptor`, so constructing
`PrecodeStubs` threw. `MethodValidation` swallowed the exception and
reported every MethodDesc as invalid.
- New `PrecodeStubs` version `c2` (`PrecodeStubs_2`) for portable entry
points. `GetMethodDescFromStubAddress` reads
`PortableEntryPoint.MethodDesc`, matching native
`MethodDesc::GetMethodDescFromPrecode`. The runtime advertises `c2`
under `FEATURE_PORTABLE_ENTRYPOINTS`, and `PrecodeStubs_1` is unchanged.

**Stack walks require the Debugger contract (dotnet#135034).** WASM didn't
advertise `Debugger`, but `StackWalk_1` calls it for every
native-context frame.
- WASM now advertises the existing `Debugger` `c1` contract. The
in-process debugger isn't built there, so `g_pDebugger` stays null and
`CLRJitAttachState` stays 0. `Debugger_1` already reports that as "not
initialized": no debugger data, no hijacks.
- The mistyped `int g_pDebugger` linker stub is replaced with correctly
typed definitions.

**Walk never ends on an R2R InlinedCallFrame (dotnet#135036).**
`WasmFrameHandler` now handles the `INLINED_PINVOKE_FROM_R2R` marker as
native `InlinedCallFrame::UpdateRegDisplay_Impl` does. SP comes from
`CallSiteSP`, IP is the R2R virtual IP of the shadow frame there, and FP
is that frame's base. The frame pointer doesn't account for funclets
yet; that comes with dotnet#133890. If an active InlinedCallFrame's context
still isn't managed code (no virtual IP could be recovered), the walk
fails with `StackWalkState.Error`, as native `NextRaw` returns
`SWA_FAILED`, rather than repeating.

**Interpreter-only walk repeats forever (dotnet#135037).** This now matches
native `StackFrameIterator`:
- An active InlinedCallFrame for an interpreted P/Invoke
(`InlinedCallFrame::IsInInterpreter`) moves straight to the
InterpreterFrame that owns it, without touching the context.
- A walk that starts in interpreted code moves the Frame cursor to the
`Next` of the owning InterpreterFrame named in the first-argument
register, as native `Init`/`ResetRegDisp` do. If the register is null or
doesn't name an InterpreterFrame, the walk throws, where native asserts.

The `StackWalk.md`, `PrecodeStubs.md` (new Version 2 section) and
`Debugger.md` specs are updated, and the generated usage tables are
regenerated.

WASM isn't a shipping cDAC scenario for .NET 11, so readers built from
this PR don't support WASM runtimes built before it: those don't
advertise `Debugger` and still advertise `PrecodeStubs` `c1` with
portable entry points.

Follow-up: moving the ExecutionManager portable-entry-point special
cases (`NonVirtualEntry2MethodDesc`,
`GetDiagnosticCodeStartFromEntryPoint`) next to `PrecodeStubs_2`. I've
left that out of this PR to avoid colliding with dotnet#133890's
ExecutionManager changes.

## Validation

- `./dotnet.sh test
src/native/managed/cdac/tests/UnitTests/Microsoft.Diagnostics.DataContractReader.Tests.csproj`:
**passed**, 3245/3245.
- `pwsh src/native/managed/cdac/tools/CdacUsageGraph/generate-docs.ps1
-Check`: **passed**, docs up to date.
- `./build.sh -os browser -c Debug -subset clr.runtime`: **passed**. The
generated WASM contract descriptor advertises `Debugger` `c1` with its
globals and `PrecodeStubs` `c2`.
- `./build.sh -os browser -subset clr+libs+packs -c Release
/p:BuildCrossgen2HostPackForWorkloadTesting=true`: **passed**. These are
the packs used for the live run below.
- New tests:
  - portable entry point lookup through `c2`;
  - the R2R InlinedCallFrame virtual IP;
- a WASM walk ending, with the `Debugger` contract advertised and a null
`g_pDebugger`;
- an interpreted P/Invoke chain walked once from both kinds of starting
point.

The tests from the original fixes each failed with the corresponding fix
removed. I didn't repeat that check after the review changes. The throw
for a missing owning InterpreterFrame has no dedicated test.
- Live browser-wasm runs at `289085e0e06` (before the last review round
removed the older-runtime fallbacks) through Blazor-Playground/nesm,
with nesm's workarounds and its frame guard turned off. Five configs, 5
walks each: R2R paused at a breakpoint (seeded from the frame chain and
from a leaf `$sp`), R2R paused in a `[JSImport]` call, and
interpreter-only paused in a tight loop and in a `[JSImport]` call.
- Against nightly `12.0.0-alpha.1.26480.103`, which advertises no
`Debugger` contract and `PrecodeStubs` `c1`, so the since-removed
fallback paths ran: **all pass**.
- Against Release packs built from this branch, which advertise
`Debugger` `c1` and `PrecodeStubs` `c2`: **all pass**. Frame names,
states and kinds match the nightly run exactly, and nesm's own
`Debugger` and `PrecodeStubs` workarounds are never called.
- In every run, walks complete with no errors and every frame is named.
The R2R names match a separate static ReadyToRun lookup.
- Live re-run at the current head `b996b7187da` with the same branch
packs (the runtime code is unchanged since `289085e0e06`), nesm
workarounds and frame guard off: R2R paused at a breakpoint (all seeds)
and interpreter-only paused in a `[JSImport]` call **pass**, including
the interpreted-code seed that now requires the owning InterpreterFrame.
Against the nightly, the reader fails with `ContractMissingException`
(`Debugger`) unless nesm's workarounds are on, as expected now that
older WASM runtimes aren't supported.

`TestPlaceholderTarget.TryGetThreadContext` now returns `false` (no OS
context, as on WASM) instead of throwing, so tests can exercise the
walk's fallback to the Frame chain.

Resolves dotnet#135034
Resolves dotnet#135035
Resolves dotnet#135036
Resolves dotnet#135037

> [!NOTE]
> This PR description was generated with assistance from GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
<!-- -->

Managed ilasm accepts `/FOLD` but currently emits duplicate method
bodies separately.

## Changes
- Reuse the offset of an existing body when the complete serialized
body—including its header and exception regions—is byte-identical.
- Preserve existing emission when `/FOLD` is off and update the option
documentation.
- Cover identical bodies, differing headers and handlers, branches, and
error-tolerant emission.

> [!NOTE]
> This description was generated by GitHub Copilot.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
<!-- -->
CoreCLR's in-memory Reflection.Emit implementation uses PE-style
sections and relocation records just to retain method IL and FieldRVA
bytes. Store those bytes directly in loader-owned memory and reuse the
existing token-to-address map, so shared and static CoreCLR no longer
need to link `ceefgen`.

## Changes

- Allocate emitted IL and aligned, zero-initialized field data on the
module's loader allocator. Preserve IL/EH encoding and collectible
field-data lifetime tracking.
- Use MethodDef tokens as non-address values in the dynamic module's
metadata RVA column, retaining the nonzero-body invariant. Resolve field
data using the existing `FIELD_OFFSET_DYNAMIC_RVA` sentinel and token
map, including reflection's fast field-access path.
- Remove generator ownership, PE section allocation, and native/managed
token-relocation bookkeeping. Preserve ILAsm's separate `ceefgen_nohost`
dependency and PE-writing implementation.
- Add emission, field-content/alignment, and diagnostic coverage. Update
the canonical cDAC descriptor descriptions and generated documentation.

Existing token-aware diagnostic paths resolve the new storage. Raw
`ISOSDacInterface.GetILForModule` support for Reflection.Emit remains
unchanged: it is unsupported by the native DAC.

## Validation

Windows x64 Release and Checked builds passed. Local coverage includes:

- All 2,968 Reflection.Emit, ILGeneration, and Lightweight library
tests.
- 408 cDAC Loader/MethodTable tests, including mock 32/64-bit and
little/big-endian layouts and legacy-facing entry points.
- 18 runtime reflection wrappers, collectible byref/span lifetime
coverage, profiler ModuleLoad and ReJIT tests, and 24 existing EnC
tests.
- The 12 new behavior-preservation cases on both the frozen baseline and
changed Release runtime.
- Documentation generation/drift checks and actual Checked/Release Ninja
link inputs confirming that shared/static CoreCLR exclude ceefilegen
while ILAsm retains it.

Other runtime architectures and metadata-updater-disabled builds were
not run. The pre-existing commented-out EnC `TestAddFieldRVA` case was
left unchanged and was not included in the EnC count.

## Local measurements and trade-off

Dependency-free, ad hoc Windows x64 Release harness; A/B/B/A process
order, 18 measurements per operation per host, and tiered compilation
disabled for both. These are shared-machine measurements, not
BenchmarkDotNet results.

**The slowdown below is limited to the non-intrinsic runtime fallback
path for FieldRVA data defined by `System.Reflection.Emit`. It is not a
loss of intrinsic expansion: these benchmark cases use the fallback in
both the baseline and changed builds.**

| Metric | Baseline | Changed |
| --- | ---: | ---: |
| `coreclr.dll` size | 4,835,840 bytes | 4,823,552 bytes (-12 KiB) |
| Release browser `dotnet.native.wasm` size | 4,711,053 bytes |
4,700,549 bytes (-10,504 bytes, -0.223%) |
| Release browser `dotnet.native.wasm` Brotli q11 size | 1,350,926 bytes
| 1,348,055 bytes (-2,871 bytes, -0.213%) |
| Release browser `dotnet.native.wasm` code section | 3,667,990 bytes |
3,658,132 bytes (-9,858 bytes, -0.269%) |
| Release browser `dotnet.native.wasm` data section | 1,016,977 bytes |
1,016,475 bytes (-502 bytes, -0.049%) |
| Release browser `dotnet.native.wasm` defined functions | 9,596 | 9,556
(-40) |
| Managed allocation for a 32-method emission workload | ~36.1 KB/module
| ~32.7 KB/module |
| Non-intrinsic `InitializeArray`, SRE field | 141.563 ns | 153.904 ns
(+8.7%) |
| Non-intrinsic `CreateSpan`, SRE field | 142.519 ns | 155.601 ns
(+9.2%) |

Module-creation medians were approximately 0.3%-4.1% lower across four
workloads. Process-private-memory growth while retaining emitted modules
was approximately 24%-39% lower; this is not a pure native-allocation
metric.

The slow benchmark supplies field handles obtained through reflection
and reuses an existing array. Its fallback now resolves emitted field
data through a locked token-map lookup instead of unlocked
section-offset translation. Follow-up disassembly confirmed identical
managed fallback instruction sequences in both builds.

Intrinsic-friendly `ldtoken`/`CreateSpan` and constant-size
`newarr`/`dup`/`ldtoken`/`InitializeArray` patterns still expand to
direct data access in both builds, with no per-invocation token lookup;
the address is resolved at JIT time. Ordinary PE-backed fields also
retain their existing lookup path. Follow-up controls for those cases
were approximately unchanged, so the slowdown percentages above do not
apply to them.

> [!NOTE]
> This implementation and PR description were prepared with GitHub
Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
<!-- -->
Wasm codegen is now sufficiently complete that crossgen2 should no
longer silently omit methods when the JIT reaches `NYI_WASM`. Surfacing
these cases as normal JIT compilation failures makes any remaining gaps
visible.

This removes `JitWasmNyiToR2RUnsupported` from the JIT and all CoreLib
crossgen, runtime-pack, SDK publish, test, and SuperPMI plumbing.
Existing `NYI_WASM` sites remain intact and now use the standard NYI
path. The stale SIMD fallback arguments on the browser publish surfaces
are also removed.

> [!NOTE]
> This pull request description was generated by GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
## Summary

- Add rolling-only Debug `CoreCLR_AllSubsets` builds for Linux x64,
Linux musl x64, and macOS arm64, matching the corresponding PR build
arguments.
- Separate Debug and Release Roslyn cache entries so both rolling
configurations can seed immutable caches independently. Existing v1
entries remain a restore fallback.

## Measurements

The earlier Roslyn cache validation in dotnet#133748 measured
`libs.tests` at 4m53s with the cache versus 6m32s without it (25.25%
faster). Debug-specific hit rates cannot be measured until the first
rolling Debug build seeds its cache.

> [!NOTE]
> This pull request description was generated with GitHub Copilot.

Copilot-Session: 6b47078d-4fe1-4db0-93fd-264f9a651be7
## Summary

- Add enterprise coverage for synchronous `FtpWebRequest`
`ListDirectoryDetails` requests with and without TLS.
- Verify that the returned listing is plaintext, contains the uploaded
fixture, and completes with `FtpStatusCode.ClosingData`.
- Clean up the uploaded fixture even when the listing assertion fails.
- Document the additional FTPS directory-listing coverage.

This directly covers the scenario reported in dotnet#134130. The
product fix is already present on `main` via dotnet#123234; this PR adds
coverage for the specific listing operation from the newer report.

## Testing

- `./build.sh clr+libs -rc release` in the Linux enterprise test client:
succeeded with 0 warnings and 0 errors.
- `/repo/dotnet.sh build /t:Test
/p:XunitMethodName=System.Net.Tests.FtpWebRequestStreamDisposalTest.FtpListDirectoryDetails_ReturnsPlainText`:
2 passed, 0 failed, 0 skipped.
- Negative control: temporarily restored the old synchronous
stream-selection expression and rebuilt `System.Net.Requests`; the
non-TLS case passed while the TLS case failed in
`StreamReader.ReadToEnd` with `ObjectDisposedException`.
- The attached issue repro's request sequence was also verified against
controlled ProFTPD: .NET 10.0.0 returned TLS ciphertext despite status
226, while .NET 11 RC1 returned the expected plaintext listing.

> [!NOTE]
> This pull request description was generated with GitHub Copilot.
## Summary

- Route CI failure scanner issue searches through a repository-scoped
MCP script that returns only issue numbers and author logins.
- Require every returned candidate to be inspected with `issue_read`
before making semantic duplicate decisions.
- Remove direct built-in issue-search access and strengthen the scanner
eval to enforce the wrapper path and fail-closed behavior.

## Dependency

This PR depends on
[dotnet#133958](dotnet#133958),
which must merge first. The `/ci-eval` workflow restores evaluator
inputs from `main` before checking out the PR head; without the
prerequisite files already present on `main`, the wrapper, grader, and
focused tests are removed during restoration and this PR's evaluator
changes are not exercised.

## Motivation

The built-in issue search result projection can omit author metadata.
When that happens, existing bot-authored KBEs can be hidden from
duplicate detection even though prompt guidance requests the author
field. This makes the transport deterministic while leaving non-exact
query formulation and semantic comparison to the model.

This is narrower than dotnet#132619 for issue lookup: pull request searches
continue to use the GitHub MCP tools, while issue searches use the
dedicated wrapper.

## Scope limitation

The eval's direct-search protection is pattern-based and cannot
recognize every possible shell spelling or equivalent command. This is
an existing limitation of the eval setup and is out of scope for this
PR; the workflow's network policy and mandatory wrapper checks remain
the enforcement mechanisms for this change.

## Validation

- Compiled `ci-failure-scan` with gh-aw v0.86.2 and actionlint enabled.
- Passed Vally 0.14 strict lint for `ci-failure-scan.eval.yaml`.
- Passed actionlint v1.7.12 for `ci-eval.yml`.
- Exercised the wrapper against live KBE searches and confirmed
bot-authored candidates include their author logins.
- Passed the focused Node test suite with 10 tests.

> [!NOTE]
> This pull request description was generated by GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Pull request created by AI Agent

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
….8059.12, mac: 155.0.8059.12 (dotnet#135175)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Fixing new instance of the build break fixed by
dotnet#134967
NativeAOT reflection invocation can return a byref into a helper’s
temporary argument storage. Dereferencing it after the helper returns
can yield a stale or incorrect object.

- **Lifetime:** All five invocation helpers now return `object?`,
transforming results before their argument storage expires or GC
registrations are removed. Copy-back and exception wrapping remain
unchanged.
- **Regression coverage:** Extend the existing reflection smoke test
with one-, four-, and five-argument ref-return cases across
`MethodInfo.Invoke` and `MethodInvoker` span/fixed-argument paths,
checking object identity and null results.

Fixes dotnet#135170

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
NativeAOT returned `null` for `Type.Namespace` on nested generic types,
despite their namespace-qualified `FullName`.

- **Metadata:** Stop emitting namespace definitions for nested types and
document the schema invariant.
- **Reflection:** Resolve namespaces through enclosing types; exclude
nested types from top-level well-known attribute matching.
- **Coverage:** Add cases for nested generic definitions and
constructions, global-namespace nesting, and nested attribute
lookalikes.

Fixes dotnet#135106

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
…#135089)

Apple proxy handling can crash in `CFNumberGetValue` when running under
the CoreCLR interpreter. `CFNumberType` was declared as a 32-bit enum,
but native CoreFoundation uses `CFIndex`, which is 64-bit on all
supported .NET Apple targets. The simulator repro received `0x100000009`
instead of the requested type value `9`.

This fixes the native declaration by using a `long`-backed enum and a
`byte` return matching Apple's one-byte `Boolean`. No proxy logic or
interpreter implementation changes are needed.

Adds six Apple-only theory cases to the existing HTTP unit-test project.
They evaluate an in-memory PAC script and exercise the source-linked
production `CFProxy.PortNumber` implementation, covering ports 1, 80,
443, 8080, 65535, and `DIRECT`. They require neither system proxy
changes nor network connections.

### Validation

- Before product changes, reproduced the crash on an iOS 26.5 arm64
simulator through the actual production `MacProxy` PAC callback. The new
regression also crashed against the unfixed declaration. With the fix,
the original repro completed all ten lookups.
- Full iOS simulator unit suite under the CoreCLR interpreter: 2,558
passed, 40 existing skips; all six new cases passed.
- Full macOS unit suite: 2,683 passed, 4 existing skips. After moving
the new source-inclusion group to the end of the project, the targeted
regression was rebuilt and rerun: 6 passed.
- macOS functional suite: 4,766 passed, 43 skipped, 3 IPv6 link-local
failures. All three failures also reproduced against the exactly unfixed
production declaration.

Resolves dotnet#134617

> [!NOTE]
> This pull request was prepared with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
<!-- -->

## Motivation

The existing Agent Merge instructions tell Copilot to "open or update" a
Known Build Error issue when a CI failure is unrelated to the PR. The
`create-kbe` skill repeats that instruction without requiring
publication approval, while the shared KBE guidance leaves confirmation
to the caller.

This guidance was added to make Agent Merge useful by recording
legitimate unrelated CI failures instead of repeatedly retriggering CI.
Preserve that intentional automation, while making clear that an
ordinary coding task does not grant permission to create additional
issues or post comments.

Unexpected issue-filing behavior was reported in
[dotnet#134870](dotnet#134870 (comment)).
Assigning a PR or granting write access alone should not authorize
additional publications, and an AI disclosure is not a substitute for
authorization.

## Changes

Define a consistent publication-authorization rule for repository
instructions and the affected skills:

- For incidental issue creation, issue updates, and comments, require
explicit user authorization. Without it, prepare a local draft and ask
before publishing; if asking is unavailable, leave the draft and report
the pending decision.
- Accept advance permission in an interactive prompt. Authorization to
compose and publish a specified artifact is sufficient within its scope,
without another confirmation or separate approval of generated text.
- Preserve intentional publication by configured agentic workflows
through their declared outputs and limits, and by explicitly requested
or enabled specialized workflows through their documented publication
contracts. Merely loading a skill or reading a workflow does not grant
that authority. Draft-only, dry-run, and review-before-publication
requests take precedence.
- Define Agent Merge's publication scope in its existing
repository-instruction section. Enabling it authorizes review replies on
the current PR when review handling is authorized, and creation or
updates of eligible Known Build Error issues in `dotnet/runtime` for
unrelated failures on that PR when CI fixing is authorized. These
operations do not require another approval prompt; unrelated publication
remains unauthorized.

Make publication depend on scoped authorization, with local drafts when
authorization is missing. Align the KBE, shared KBE, PR failure-scan,
and mobile reporting instructions so they honor the caller's authorized
outputs. Keep the Agent Merge no-rerun rule and KBE eligibility
requirements intact. Clarify that a user-requested breaking-change
documentation task includes its source-PR documentation comment, while
creating the docs issue remains a separate publication decision.

These are Markdown guidance changes only. Runtime code, KBE eligibility
rules, and configured workflow outputs and limits are unchanged.

> [!NOTE]
> This PR and its description were prepared with GitHub Copilot
assistance.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
<!-- -->

Stops agentic workflow failures from automatically creating issues such
as dotnet#135150. Failures remain visible in the Actions run.

Sets `safe-outputs.report-failure-as-issue: false` and
`safe-outputs.report-failed-jobs: false` in all six agentic workflows,
regenerates their lock files with the existing gh-aw v0.86.2 compiler,
and documents the policy. Intended outputs, including Known Build Error
issues filed by the CI failure scanner, are unchanged.

Local validation: all six workflows passed compilation and Actions
schema validation. A comparison of the original and regenerated
workflows confirmed that prompts, triggers, intended outputs, and other
job behavior are unchanged. `git diff --check` passed. No live workflow
runs were triggered.

Resolves dotnet#135150

> [!NOTE]
> This pull request was generated with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Unix uid_t/gid_t are unsigned. Reading a GNU base-256 or PAX uid/gid
above Int32.MaxValue threw OverflowException. Reinterpret such values
as int without an overflow check, matching what TarWriter already does
for file system ids, and write negative ids back as unsigned in the GNU
header field and PAX extended attributes so they roundtrip.

Fixes dotnet#127006
…5174)

On ARM64, independent header and table loads can pair a newly published
sync index with an older, undersized table. Acquire reads of the header
order subsequent table accesses after index publication.

Fixes dotnet#135173

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
…ifact (dotnet#135204)

The new composite R2R microbenchmark lane in dotnet/performance#5324
(`coreclr_r2r_composite_v8`) publishes CoreCLR browser-wasm with
`PublishReadyToRunComposite`. dotnet#134618's
`_WasmCoreClrValidateCompositeTasks` rejects that publish unless the SDK
ReadyToRun tasks name the owner `<entry>.r2r.wasm`. The SDK tasks only
learn to do that in dotnet/sdk#56395, which hasn't reached runtime's
global.json SDK yet (11.0.100-rc.1.26420.103).

This PR copies the in-tree wasm-aware task shim, the same one
Wasm.Build.Tests use via
`Crossgen2SdkOverridePropsPath`/`Crossgen2SdkOverrideTargetsPath`, into
the `BrowserWasmCoreCLR` perf artifact. The shim comes from
`artifacts/bin/Crossgen2Tasks/<config>/`, which `Build.proj` already
produces.

Staged layout (flat, no config subfolder; this is the path
dotnet/performance consumes):

```
staging/Crossgen2Tasks/Crossgen2Tasks.dll
staging/Crossgen2Tasks/Microsoft.NET.CrossGen.props
staging/Crossgen2Tasks/Microsoft.NET.CrossGen.targets
```

The step fails if the source directory or any of these three files is
missing. Only the CoreCLR leg (`includeCoreClrToolchainPacks: true`)
changes; the Mono artifact is untouched.

This is temporary: remove it once dotnet/sdk#56395 reaches global.json.
Tracked by dotnet#135023.

Validation: YAML parses (`python3 yaml.safe_load`) and `git diff
--check` is clean. The pipeline itself hasn't run yet.

> [!NOTE]
> This PR was generated with the help of GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a287cfc0-a881-4272-9024-bdaf9d9db4ef
)

## Summary

Adds test coverage and CI for CoreCLR WASI composite ReadyToRun (R2R),
now based directly on `main` after the publishing support merged in
dotnet#133265. The CI lanes and the test guards they depend on stay together
so the coverage is self-contained.

## Changes

- **CI lanes:**
  - A Checked WASI `R2R_CG2` runtime-test job.
- A `LibraryTestsCoreCLR_WASI_R2R` job that runs a trimmed composite R2R
`System.Collections.Tests` smoke suite.
  - The existing interpreter jobs are unchanged.
- **Runtime-test harness:**
  - Crossgen2 composite compilation of each merged runner.
  - A per-test composed host.
- `APP_ASSEMBLIES=EXTERNAL` and `TEST_READY_TO_RUN_MODE=1` passed to the
guest.
- Staging of the pinned Binaryen and wasm-tools archives into the Helix
correlation payload.
- **Standalone corerun:** strong definitions for the aligned R2R image
buffer and its capacity, overriding the weak placeholders used by
published apps.
- **Windows build hosts:**
- Acquire the Windows Binaryen and wasm-tools archives, including the
Windows-specific archive format and executable names.
- Verify the pinned x64 and arm64 archives with SHA-256 before
extraction.
- **Library tests:**
- Test guards changed from `IsBrowser` to `IsWasm` where the tracking
issue applies to all WebAssembly targets.
- WASI R2R quarantines under dotnet#130129 where trimmed composite compilation
exposes unsupported test assumptions.
- Browser-only guards (fetch, DOM, VFS, globalization, crypto) are
unchanged.

## Validation

After rebasing onto `main`:

- `./build.sh -s clr+libs+packs -os wasi -arch wasm -c Release`: 0
warnings, 0 errors.
- `./build.sh -s clr+libs+packs -os wasi -arch wasm -c Checked`: 0
warnings, 0 errors.
- Downloaded the exact pinned Binaryen and wasm-tools Windows x64/arm64
archives and verified their SHA-256 values.
- `git diff --check` passed.

Functional validation completed before opening this PR:

- Trimmed composite R2R `System.Collections.Tests`: 33,958/33,958
passed.
- Merged JIT runtime-test wrapper: 186 tests passed.
- The runtime log contained 162 `Ready to Run initialized successfully`
entries, confirming R2R activation rather than interpreter fallback.
- Helix tool staging passed.

Related: dotnet#130129.

> [!NOTE]
> This pull request description was prepared with assistance from GitHub
Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
dotnet#134964 makes wasihost pass the app's runtimeconfig properties to the runtime,
fixing dotnet#134954. Re-enable the WASI tests that depended on AppContext switches:
DataSet XML serialization, DiagnosticSource ID format switches, the Japanese
calendar and invariant time zone switches, and the UTF-7 and encoding tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@lewing

lewing commented Oct 5, 2026

Copy link
Copy Markdown
Owner Author

Opened against the wrong repository/base by mistake; replaced by an upstream dotnet/runtime PR.

Note

This comment was generated with GitHub Copilot.

@lewing lewing closed this Oct 5, 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.