Ensure the Thumb bit is set for resumption stub relocs#125421
Ensure the Thumb bit is set for resumption stub relocs#125421jtschuster merged 9 commits intodotnet:mainfrom
Conversation
|
/azp run runtime-coreclr crossgen2 outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR addresses ARM32 Thumb-2 requirements for async resumption-related code pointers so ReadyToRun/crossgen2 can safely emit async methods again on ARM32 without illegal-instruction failures.
Changes:
- Remove the ARM32-specific exclusion that prevented async methods from being emitted in ReadyToRun mode (still excluded for composite builds).
- Update JIT emission of
CORINFO_AsyncResumeInforelocations to apply an additional delta on ARM32 so relocated code pointers have bit 0 (Thumb bit) set.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs |
Stops filtering out async methods on ARM32; keeps composite-build exclusion. |
src/coreclr/jit/emit.cpp |
Records async resume info relocations with an ARM32 addend delta to ensure Thumb-bit-correct code pointers. |
…t once" This reverts commit 47ee93d.
3e8fe1f to
62c80b7
Compare
|
/azp run runtime-coreclr crossgen2 outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
On ARM32, the JIT sets bit 0 on code pointers to indicate Thumb mode. When crossgen2's recordRelocation receives an external handle with the Thumb bit set, HandleToObject's integer division (by handleMultiplier=8) truncates the low bits, and the relocation delta is recorded as 0 instead of 1. At runtime, the resume stub pointer in the continuation layout lacks the Thumb bit, causing blx to switch the CPU to ARM mode where Thumb-encoded instructions are undefined — resulting in SIGILL. Fix: before calling HandleToObject, capture the low bits of the handle that would be lost to integer division and include them in relocDelta. This is architecture-agnostic: on non-ARM targets the low bits are always 0, so the mask is a no-op. Co-authored-by: Copilot <[email protected]>
|
/azp run runtime-nativeaot-outerloop |
|
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
(AzDo canceled the previous run. If |
|
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
The failure on nativeaot linux-arm outerloop looks unrelated but odd. The console logs don't show all tests passed without any error messages. |
There are actually two console logs: First one has the failure, the second is clean. As to why there are two logs: Looks like AzDo shows this somewhat better: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1341505&view=ms.vss-test-web.build-test-results-tab&runId=37468284&resultId=171773&paneView=dotnet-dnceng.dnceng-build-release-tasks.helix-test-information-tab But still shows the test as failed, but with multiple executions and multiple logs. Not sure what triggers the RERUN. But looks good, I got desensitized to networking test failures. |
|
/ba-g Failures are network flakes or #125757 |
ARM32 requires bit 0 to be set for Thumb-2 code. Without this bit set, we encountered illegal instruction failures in CI and disabled crossgenning async methods on ARM32.