Pull Request on 2026年10月15日

dotnet/runtimeにマージされたPull RequestをAIで日本語要約

注意点

このページは、dotnet/runtimeリポジトリにマージされたPull Requestを自動的に収集し、その内容をAIが要約した内容を表示しています。そのため、必ずしも正確な要約ではない場合があります。


目次

  1. #135885 Fix PEM parsing resumption for empty labels
  2. #135884 [release/9.0-staging] Update MsQuic to 2.5.12
  3. #135878 Fix helperildll build race in Crossgen2 determinism test
  4. #135875 Exclude mobile targets from Helix dump-doc generation
  5. #135867 Fix HighNumberedFd_NotLeakedAfterLoweringRLimit on 32-bit musl
  6. #135858 Fix ILVerify crash on a branch target outside the method
  7. #135838 coreclr: PAL build fixes for OpenHarmony
  8. #135835 JIT: preserve GTF_IND_INITCLASS when inlining BOX of Nullable<T>
  9. #135834 JIT: spill pending side effects before signed Log2 expansion
  10. #135833 JIT: sign-extend folded 32-bit RotateLeft/RotateRight constants
  11. #135829 Fix ILVerify crash when a method ends with a conditional branch or switch
  12. #135827 JIT: check for a conditional branch that falls off the end of the method before linking its false edge
  13. #135826 Delete dead code in EventProvider
  14. #135808 coreclr: disable the LTTng event source on OpenHarmony
  15. #135793 Emit base-only LEAs as register moves
  16. #135778 Fix shared mutex privliges/permissions/defaults to be secure
  17. #135774 Fix ILVerification argument lookup on results without arguments
  18. #135769 Do not attempt to start finalizer thread on WASM
  19. #135766 Fix remaining linking failures on native AOT/WASI
  20. #135764 Fix up FCalls on native AOT/WASM
  21. #135761 Do not emit try table on native AOT
  22. #135739 JIT: Remove redundant Span.Slice/Vector128.Create checks in vectorized loops
  23. #135730 [release/11.0] Correct decimal conversions to Half and BFloat16
  24. #135657 Run GC.GetGeneration test in its own process
  25. #135625 [mono][interp] Preserve live locals across finally OSR
  26. #135602 JIT: reject method entry inside handlers or filters
  27. #135577 [wasm] Avoid Spilling Many GC-ref Typed Tree Temps
  28. #135491 [mono] Prevent theoretical overflow due to excessive aggregation of cmods
  29. #135440 Reduce WebAssembly managed method prologs
  30. #135297 Managed ilasm: per-point PDB documents, the input file and .line files as documents, LocalSignature row id
  31. #135293 [wasm][JIT] Remove assertions assuming the SP arg of a fast tail call is a GT_PHYSREG
  32. #134664 Delete SUPPORT_LOCAL_DEBUGGING ifdef
  33. #134210 Enable building a stubbed NativeAOT WASM CoreLib
  34. #133665 Reject bare CR in managed HttpListener request parsing
  35. #132637 Collapse VM contracts to STANDARD_VM_CONTRACT where equivalent

#135885 Fix PEM parsing resumption for empty labels

  • 作成者: @vcsjones
  • 作成日時: 2026年10月15日 19:07:12(UTC)
  • マージ日時: 2026年10月15日 22:45:55(UTC)
  • ラベル: area-System.Security

概要

PEMパース処理において、ラベルが空(-----BEGIN -----)の場合に、パース再開位置が進みすぎて有効なPEMを検出できなくなる問題を修正するPRです。#133137 で導入された「失敗が確定している内容の再パースを避ける」ための再開位置の最適化が、空ラベルという限定的なケースで先に進みすぎていました。

例えば次のようなPEMで問題が発生していました。

-----BEGIN -----BEGIN TEST-----\nZm9v\n-----END TEST-----
  • 最初に -----BEGIN -----(空ラベルの有効なPreEB)が見つかるが、直後の BEGIN TEST----- が不正なBase64として扱われる。
  • 修正前は BEGIN TEST-----\n... からパースを再開していたため一致せず、有効なPEMを見逃していた。
  • 2つのPreEBは境界を共有しているため、空ラベルが最初に見つかった位置から再開する必要がある。
  • 同様の修正が終端(EndEB)の探索側にも適用されています。

変更内容

  • src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/PemEncoding.cs: 再開位置の計算を修正(+11/-9)
  • src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PemEncoding.cs: 同様の修正(+11/-9)
  • src/libraries/Microsoft.Bcl.Cryptography/tests/PemEncodingFindTests.cs: 回帰テストを追加(+30)
  • src/libraries/System.Security.Cryptography/tests/PemEncodingFindTests.cs: 回帰テストを追加(+30)

パフォーマンスへの影響

影響なし(再開位置の補正のみで、ベンチマーク結果の記載もありません)。

関連Issue

  • #135845(本PRで修正)
  • #133137(先行PR。再開位置の最適化を導入)

その他

PemEncoding の内部実装の修正であり、公開APIの変更や破壊的変更の記載はありません。Microsoft.Bcl.Cryptography と System.Security.Cryptography の両方に同じ修正が適用されています。


#135884 [release/9.0-staging] Update MsQuic to 2.5.12

概要

release/9.0-staging ブランチで使用する MsQuic パッケージを、非公開の 2.5.11-ci.159417053 から公開パッケージの 2.5.12 に更新します。非公開(private)から公開(public)へのセキュリティ修正のハンドオフを完了させる目的で、internal-to-public マージ後も非公開バージョンの識別子が残らないようにします。これにより、公開 CI が非公開パッケージを復元できずに NU1603 で restore が失敗する問題を解消します。

変更内容

  • eng/Versions.props(+1/-1): MsQuic のバージョン指定を 2.5.12 に更新(パッチバージョンの依存関係更新のみで、マネージドコードの変更なし)

パフォーマンスへの影響

影響なし

関連Issue

  • #135880(本 PR で修正)
  • #135749(main ブランチの対応 PR)

その他

  • 製品コードのリグレッションではなく、公開後の依存関係ハンドオフ時に発生するビルド失敗への対応です。
  • 影響範囲は release/9.0 の公開ビルドで、未対応の場合は restore が NU1603 で失敗し、クリーンな servicing ビルドがブロックされます。
  • 作成者による確認: System.Net.Quic.csproj に対し --no-cache で restore を実行し、NU1603 なしで MsQuic 2.5.12 が解決されることを確認済みです。機能面の網羅的なテストは CI に委ねられています。
  • リスクは低いと評価されています(1行のパッチバージョン更新)。

#135878 Fix helperildll build race in Crossgen2 determinism test

  • 作成者: @Copilot
  • 作成日時: 2026年10月15日 18:28:33(UTC)
  • マージ日時: 2026年10月15日 22:21:44(UTC)
  • ラベル: area-Infrastructure

概要

Crossgen2 determinismテストで発生していた helperildll.dll のビルド競合を修正するPRです。従来は crossgen2smoke をグローバルな OutputPath 上書き付きの独自MSBuild呼び出しで再ビルドしており、別々のMSBuildインスタンスが中間ファイルを共有していました。その結果、helperildll.dll への同時書き込みが発生し、参照側が不完全なメタデータを読み込む可能性がありました。カスタムのMSBuild呼び出しを標準の ProjectReference に置き換え、ビルドを共有するようにしています。

変更内容

  • src/tests/readytorun/determinism/crossgen2determinism.csproj (+12/-4)
    • 独自のMSBuild呼び出しを標準の ProjectReference に置換
    • ビルド後、determinismテストの既存の入力ディレクトリに必要な3つのDLLをコピーし、従来のレイアウトを維持(スモークテスト用のラッパーはコピーしない)

パフォーマンスへの影響

影響なし(テストプロジェクトのビルド構成の修正であり、ランタイムの実行性能には関係しません)

関連Issue

#135717

その他

  • 公開APIや互換性への影響はなく、テストのビルドプロセスのみの変更です。
  • 提供された情報には、ベンチマーク結果やセキュリティに関する記載はありません。

#135875 Exclude mobile targets from Helix dump-doc generation

概要

モバイルターゲット(TargetsMobile が true)の場合、Helixの gen-debug-dump-docs.py ポストコマンドをスキップするよう変更するPRです。このスクリプトはデスクトップ用のtesthostレイアウトを前提としたホスト側ダンプのデバッグ手順を生成するもので、モバイルのクラッシュ診断には適用できません。モバイルジョブで実行すると、Windowsホストでは未展開のシェル変数エラー、Unixホストではスクリプト不在エラーが発生していました。

変更内容

  • src/libraries/sendtohelixhelp.proj (+1/-1)
    • ダンプドキュメント生成のポストコマンドに TargetsMobile の除外条件を追加
    • AndroidおよびAppleのモバイルターゲットが除外対象
    • デスクトップでのダンプドキュメント生成と、既存のbrowser/WASI除外は維持
    • テスト実行およびクラッシュの収集/アップロードは変更なし

パフォーマンスへの影響

影響なし

関連Issue

  • #131382(関連)
    • 本PRで解消されるのは診断コマンドのエラーのみで、同Issueに含まれる別のテスト失敗は対象外です。

その他

なし


#135867 Fix HighNumberedFd_NotLeakedAfterLoweringRLimit on 32-bit musl

概要

PR #135753 で追加されたテスト HighNumberedFd_NotLeakedAfterLoweringRLimit が、32-bit musl(Alpine.324.Arm32)で setrlimit が -1 を返して失敗する問題の修正です。

原因は、テストが独自に宣言した nuint 2フィールドの RLimit 構造体を libc の getrlimit/setrlimit に P/Invoke していた点です。この構造体は arm32 で 8 バイトですが、musl は全アーキテクチャで rlim_t を unsigned long long と定義しており、struct rlimit は 16 バイトになります。このため getrlimit が構造体の範囲外に書き込み、setrlimit は newLimit の後続 8 バイトからハードリミットを読んで失敗することがありました。glibc の arm32 では rlim_t が 32-bit のため一致していました。

修正は、System.IO.FileSystem 等のテストと同様に、System.Native の Interop.Sys.GetRLimit/SetRLimit を使う形に変更するものです。System.Native が2つの ulong の RLimit をプラットフォームの struct rlimit に変換します。

変更内容

  • src/libraries/System.Diagnostics.Process/tests/ProcessHandlesTests.Unix.cs(+16/-25)
    • 独自の RLimit 宣言と libc への P/Invoke を、Interop.Sys.GetRLimit/SetRLimit に置き換え
    • リソースを PAL の RLIMIT_NOFILE(9)に変更
    • スキップ判定を Interop.Sys.RLIM_INFINITY との比較に変更
    • 下げたリミットは返された MaximumLimit を維持
    • 呼び出し失敗時は errno 付きの Win32Exception をスロー(dup2 の既存処理と同様)
  • src/libraries/System.Diagnostics.Process/tests/System.Diagnostics.Process.Tests.csproj(+2/-0)
    • Interop.ResourceLimits.cs の共有インターロップをコンパイル対象に追加

パフォーマンスへの影響

影響なし(テストコードのみの変更)。

関連Issue

#135795(本PRで解決)。関連: #135753(テストを追加したPR)。

その他

  • 変更はテストとそのプロジェクトファイルのみです。
  • 検証結果(作成者による報告):
    • linux-x64 では System.Diagnostics.Process.Tests が成功(681件中 675件成功、6件スキップ、失敗0)。
    • pal_process.c を意図的に変更してリークを再現した場合、修正後のテストも従来どおり失敗し、リーク検出能力は維持されています。
    • Alpine arm32 の実機では未実行です。qemu-arm 上で musl/glibc のレイアウト不一致を再現・確認していますが、CI環境そのものの再現ではありません。
  • AI(Anthropic Claude と OpenAI Codex)の支援で作成され、作成者がレビューしたと記載されています。

#135858 Fix ILVerify crash on a branch target outside the method

概要

ILVerify において、メソッドの IL 範囲外を指す分岐ターゲットがあると、記録された BadBranch 診断を返す代わりに IndexOutOfRangeException をスローして CLI がそのメソッドで停止する問題を修正します。ReportInvalidBranchTarget で BadBranch を報告した後にそのメソッドの検証を中断するようにしました。これは ReportInvalidExceptionRegion や ReportMethodEndInsideInstruction と同じ扱いです。

原因は、共有コードの FindJumpTargets が範囲外ターゲットに対して ReportInvalidBranchTarget を呼ぶものの、ILVerify 側の実装は BadBranch を記録して戻るだけで、その後の InitialPass / インポートパスがターゲットで _basicBlocks にインデックスアクセスしていたことです。

再現例:

.method public hidebysig static void BranchOutOfIlSpace() cil managed
{
    // IL_0000: br.s +0x10 (target IL_0012; the method is 3 bytes long)
    br.s 0x10
    ret
}

変更内容

  • src/coreclr/tools/ILVerification/ILImporter.Verify.cs (+2): ReportInvalidBranchTarget で BadBranch 報告後に検証を中断
  • src/coreclr/tools/ILVerification.Tests/ILTests/BranchingTests.il (+65): 以下のテストを追加
    • Branch.ToEndOfMethod_Invalid_BadBranch (br.s、メソッド末尾)
    • Branch.PastEndOfMethod_Invalid_BadBranch (br)
    • BrTrue.PastEndOfMethod_Invalid_BadBranch (brtrue.s)
    • Switch.PastEndOfMethod_Invalid_BadBranch (switch)
    • Leave.PastEndOfMethod_Invalid_BadBranch (leave.s)
    • Branch.BeforeStartOfMethod_Invalid_BadBranch (br.s、メソッド先頭より前)
    • Branch.IntoOperand_Invalid_BadJumpTarget / Leave.IntoOperand_Invalid_BadJumpTarget (オペランド内部を指すターゲット)

検証結果:

  • ILVerification.Tests: 修正前 475/475、修正後 483/483 (Release/Debug とも)
  • 修正を戻した状態では、新規6つの BadBranch テストが IndexOutOfRangeException で失敗
  • ILVerify CLI: 修正前は IndexOutOfRangeException で終了コード1、修正後は BadBranch と ReturnVoid を報告して終了コード2

なお、IntoOperand の2テストは main でも既に通っており、既存の BadJumpTarget テストがカバーしていなかった「オペランド途中へのターゲット」を補うものです。

パフォーマンスへの影響

影響なし

関連Issue

#116139 を解決します。 関連: #63227(条件分岐や switch で終わるメソッドでの別のクラッシュ。#135829 で修正済みで、本PRでは変更なし)

その他

  • 変更は ILVerify 側の ReportInvalidBranchTarget のみで、共有の ILImporter.cs は未変更のため、NativeAOT スキャナ(InvalidProgramException をスロー)には影響しません。
  • BadBranch は FindJumpTargets のスキャン中に報告されるため、結果のオフセットは分岐位置に関わらず 0 になります。
  • 作成者によると、本PRは AI(Anthropic Claude と OpenAI Codex)の支援のもとで作成されています。

#135838 coreclr: PAL build fixes for OpenHarmony

概要

OpenHarmony (OHOS) 向けのcoreclr PALのビルド修正です。Androidと同様に、OHOSでは gcc_s、pthread、rt のリンクをスキップするようにしました。これらはOpenHarmonyツールチェーンがsysrootを通じて提供するためです。

作成者によるテスト方法は、openharmony-arm64 向けにCLRをクロスビルドし、coreclrpal がリンクできることの確認です。

変更内容

  • src/coreclr/pal/src/CMakeLists.txt (+2/-2): PALのリンク設定で、Android向けの扱いに合わせてOHOSでも gcc_s、pthread、rt のリンクをスキップするよう変更

パフォーマンスへの影響

影響なし

関連Issue

なし

その他

  • ビルド設定(CMake)のみの変更で、ランタイムの実装や公開APIへの変更はありません。
  • 提供された情報からは、互換性への影響や破壊的変更は確認できません。
  • OpenHarmony向けクロスビルド時のPALリンク問題の修正という位置づけです。

#135835 JIT: preserve GTF_IND_INITCLASS when inlining BOX of Nullable<T>

  • 作成者: @EgorBo
  • 作成日時: 2026年10月15日 01:54:29(UTC)
  • マージ日時: 2026年10月15日 23:58:03(UTC)
  • ラベル: area-CodeGen-coreclr

概要

JITが Nullable<T> の BOX をインライン展開する際、GTF_IND_INITCLASS フラグが失われていたバグの修正です。impImportAndPushBoxForNullable は impGetNodeAddr から被ボックス値の間接参照フラグを取得(クラス初期化ヘルパーは別ステートメントに分離)していましたが、分解後の hasValue / value のロードにフラグを適用していませんでした。その結果、ループ不変コード移動(ループホイスティング)により、static な Nullable<T> フィールドのロードが静的コンストラクタのチェックより前に移動される可能性がありました。修正では、両方のロードにフラグを渡すようにしています。

変更内容

  • src/coreclr/jit/importer.cpp(+2/-2): 分解された hasValue と value の両方のロードに、取得済みの間接参照フラグを渡すよう変更
  • src/tests/JIT/Regression_ro_2/Runtime_135817.cs(+35/-0): ループ内で static な Nullable フィールドを box するシナリオの回帰テストを追加

パフォーマンスへの影響

影響なし(提供された情報にベンチマーク結果の記載はありません。作成者によると生成コードの diff もありません)。

関連Issue

#135817(このPRで修正)

その他

  • 影響範囲は CoreCLR の JIT(インポーター)の内部実装で、公開APIの変更や互換性への影響はありません。
  • Copilot のレビュー概要によると、JIT のビルド検証と、修正前にテストが失敗し修正後に成功することの確認は未検証とされています。

#135834 JIT: spill pending side effects before signed Log2 expansion

  • 作成者: @EgorBo
  • 作成日時: 2026年10月15日 01:54:11(UTC)
  • マージ日時: 2026年10月15日 18:11:41(UTC)
  • ラベル: area-CodeGen-coreclr

概要

JITが符号付き整数の Log2(負数の場合に ArgumentOutOfRangeException をスローするフォールバックを持つQMARK展開)を行う際、IL評価スタックに残っている副作用を持つ式(呼び出しや先行オペランドの境界チェックなど)が、スローの後に評価されてしまう問題を修正します。展開結果を一時変数へ格納する際のスピル指定を CHECK_SPILL_NONE から CHECK_SPILL_ALL に変更し、保留中の副作用を先にスピルすることで評価順序を保証します。

変更内容

  • src/coreclr/jit/importercalls.cpp(+1/-1): 符号付き Log2 展開の一時変数への格納で CHECK_SPILL_ALL を使用するよう変更
  • src/tests/JIT/Regression_ro_2/Runtime_135816.cs(+37/-0): 回帰テストを追加。int と long で、先行する呼び出しがスキップされないこと、および例外の発生順序が正しいことを検証(PR情報によればビルド・テストは未実行)

パフォーマンスへの影響

影響なし(Diffs でも差分なしと報告されています)。

関連Issue

#135816(本PRで修正)

その他

  • 公開APIの変更や互換性への影響はなく、JIT内部(インポーター)の評価順序に関するバグ修正です。
  • 既存のスピル機構を利用した小規模で焦点を絞った修正です。Copilotのレビューでは未解決の指摘は0件で、承認推奨とされています。

#135833 JIT: sign-extend folded 32-bit RotateLeft/RotateRight constants

  • 作成者: @EgorBo
  • 作成日時: 2026年10月15日 01:53:55(UTC)
  • マージ日時: 2026年10月15日 18:11:46(UTC)
  • ラベル: area-CodeGen-coreclr

概要

JITの impRotateHelper が、定数に対する32ビットの RotateLeft/RotateRight を畳み込む際、結果を uint32_t のまま gtNewIconNode に渡していたため、64ビットホストでゼロ拡張されてしまう問題を修正します。TYP_INT 定数は符号拡張されている必要があり、31ビット目が立つ結果(例: int.RotateLeft(1, 31))が +2^31 として扱われ、その値との比較が誤って畳み込まれていました。結果を int32_t にキャストすることで修正しています。

変更内容

  • src/coreclr/jit/importercalls.cpp(+1/-1): 畳み込んだ結果を int32_t にキャストしてから定数ノードを生成するよう修正
  • src/tests/JIT/Regression_ro_2/Runtime_135814.cs(+30/-0): 符号付き比較と符号なし回転の回帰テストを追加

パフォーマンスへの影響

影響なし(作成者によれば diffs なし)。

関連Issue

その他

  • Copilotのレビューでは「Changes recommended」とされ、追加した符号なしテストに、報告されたChecked-buildのアサーション失敗を再現するための複数回使用パターンが含まれておらず、その経路をカバーできていないという指摘が1件(重要度: Medium)あります。
  • Copilotの概要によれば、ビルドとテストは実行されていません。

#135829 Fix ILVerify crash when a method ends with a conditional branch or switch

概要

メソッドの最後の命令が条件分岐または switch である場合に、ILVerify が IndexOutOfRangeException(CreateBasicBlock 由来)でクラッシュする問題を修正します。fall-through ブロックの作成を、分岐の後に命令が存在する場合のみに限定し、存在しない場合は ReportFallthroughAtEndOfMethod を呼び出すようにしました。

変更内容

  • src/coreclr/tools/Common/TypeSystem/IL/ILImporter.cs: 共有の FindJumpTargets で、分岐後に命令が続く場合のみ fall-through ブロックを作成。続かない場合は ReportFallthroughAtEndOfMethod を呼ぶ。短い形式・長い形式の条件分岐と switch が対象。
  • src/coreclr/tools/ILVerification/ILImporter.Verify.cs: ReportFallthroughAtEndOfMethod が ReportInvalidExceptionRegion と同様にメソッドの検証を打ち切るよう変更(import パスが同じブロックを再度参照するのを防ぐため)。
  • src/coreclr/tools/ILVerification.Tests/ILTests/FallthroughTests.il / .ilproj: 新規テスト追加。brtrue.s、brfalse.s、brtrue、blt、switch が最終命令のケース(MethodFallthrough を期待)と、正常系のコントロール(BrTrueS.BeforeReturn_Valid)を含む。ilasm の最適化で長い分岐が短縮されないよう Optimize は false。

各 importer への影響

  • ILVerify: 該当メソッドで MethodFallthrough を報告(FindJumpTargets は命令オフセット追跡前に動くためオフセットは 0)し、次のメソッドの検証へ進む。
  • ILVerify の既存ケース: import パスが MethodFallthrough を報告した場合、そのメソッドの検証はそこで停止し、未 import のブロックのエラーは報告されなくなる。既存テストに変更はなし。
  • NativeAOT scanner: ReportFallthroughAtEndOfMethod は既に InvalidProgramException を投げるため、IndexOutOfRangeException の代わりにこれが投げられる。ILScanner.CompileSingleMethod は throwing body を生成する。これはコード読解に基づくもので、ilc は未実行(ILCompiler.Compiler のビルドのみ確認)。

パフォーマンスへの影響

影響なし

関連Issue

#135828(Resolves)、#63227(作成者の記述では、#122056 後も main で再現していた報告)。同様の修正を試みて非アクティブでクローズされた #112082 のレビュー指摘を踏まえた変更。

その他

  • 作成者による検証結果(linux-x64、SDK 11.0.100-rc.1.26420.103):
    • ILVerification.Tests: 修正前 468/468、修正後 Release/Debug とも 474/474。
    • 修正を revert した状態では新規 5 件の invalid テストが IndexOutOfRangeException で失敗(469/474)。
    • ILVerify CLI のリポジトリ再現コードでは、修正前は IndexOutOfRangeException(exit code 1)、修正後は MethodFallthrough(FallsOffEnd)と Later の ReturnVoid エラーを報告(exit code 2)。
  • 作成者の注記: AI 支援(Anthropic Claude / OpenAI Codex)を利用し、作成者がレビュー済み。

#135827 JIT: check for a conditional branch that falls off the end of the method before linking its false edge

概要

JITのfgLinkBasicBlocksにおいて、メソッド末尾の条件分岐(BBJ_COND)が最終ブロックだった場合(制御がメソッド末尾から抜け落ちる不正なIL)に、本来発生すべきBADCODE("Fall thru the end of a method")チェックが到達不能になっていた問題を修正します。#95773以降、BBJ_CONDケースではcurBBdesc->IsLast()の判定より前にcurBBdesc->Next()(最終ブロックではnull)へのfalseエッジ追加が行われており、Checked JITではblock != nullptrのアサート失敗、Release JITではnull参照によるSIGSEGVが発生していました。IsLast()チェックをBBJ_CONDケースの先頭(両方のfgAddRefPred呼び出しより前)へ移動し、.NET 8と同様にInvalidProgramExceptionがスローされるようになります。条件分岐が最終ブロックでない場合の挙動は変わりません。新たな検証の追加ではありません。

変更内容

  • src/coreclr/jit/fgbasic.cpp(+7/-5): BBJ_CONDケースでIsLast()チェックをfgAddRefPred呼び出しより前に移動

パフォーマンスへの影響

影響なし

関連Issue

#135825(Resolves)

その他

  • 対象は無効なILであり、「undefined behaviorであるため」レビューでテストは削除されました(テスト追加なし)。
  • 検証(linux-x64、main 56ba1c0be24c、Checked runtime):
    • 末尾が条件分岐で終わる5種のメソッド(brtrue.s、2ブロックのbrtrue.s、brfalse.s、長形式brtrue、beq.s)をRuntimeHelpers.PrepareMethodでコンパイル(デフォルト、TieredCompilation=0、JitMinOpts=1の3条件):
      • 修正前: Checked JITはアサート失敗(fgflow.cpp:101)、Release JITはSIGSEGV
      • 修正後: いずれもInvalidProgramException
    • 同位置のswitchは修正前後ともInvalidProgramException、同じループ+retは修正前後ともコンパイル成功
    • JIT/IL_Conformanceは112/112成功。JIT/Regression_2は削除されたテストを除き100件成功(Runtime_33972とRuntime_34937は共有フレームワーク未導入によるFileCheck起動不可のため、修正前後とも失敗)
  • 作成者によれば、本PRはAI(Anthropic Claude、OpenAI Codex)の支援を受けて作成され、作成者自身がレビュー済みです。

#135826 Delete dead code in EventProvider

概要

EventProvider および EventPipeEventProvider から不要なコード(デッドコード)を削除する整理目的のPull Requestです。合計で19行が削除され、追加はありません。

変更内容

  • src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventPipeEventProvider.cs: 6行削除
  • src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs: 13行削除

どのメンバーが削除されたかなど、具体的なコード内容は提供された情報からは確認できません。いずれも System.Private.CoreLib 内の内部実装(System.Diagnostics.Tracing)に関する変更です。

パフォーマンスへの影響

影響なし(ベンチマーク結果の記載もありません)

関連Issue

なし

その他

  • 作成者による概要・Copilotによる概要は提供されていないため、削除の詳細な背景や理由は不明です。
  • 追加行がなく削除のみの変更であることから、公開APIや互換性への影響は提供情報からは読み取れません。

#135808 coreclr: disable the LTTng event source on OpenHarmony

概要

OpenHarmony向けビルドでLTTngベースのイベントソース(FEATURE_EVENTSOURCE_XPLAT)を無効化する変更です。OpenHarmonyのsysrootには liblttng-ust が存在せず、LTTngの対象プラットフォームでもないため、OHOSビルドではAndroidと同様にEventPipeのみのイベント出力にフォールバックします。

変更内容

  • src/coreclr/clrfeatures.cmake
    • FEATURE_EVENTSOURCE_XPLAT を有効化するガード条件に CLR_CMAKE_TARGET_OPENHARMONY の除外を追加
    • 対応プラットフォームを説明するコメントを更新

ランタイム(CoreCLR)のビルド構成(CMake)に対する内部的な変更であり、公開APIへの影響はありません。既存のAndroid向け除外パターンを踏襲しています。

パフォーマンスへの影響

影響なし

関連Issue

なし

その他

  • 作成者のテスト内容: OHOSツールチェーンで openharmony-arm64 向けにCoreCLRをクロスビルドし、configureステップで FEATURE_EVENTSOURCE_XPLAT が未設定になることを確認
  • Copilotのレビュー概要では未解決の指摘は0件で、承認推奨とされています(ビルド・テストは未実行との記載あり)

#135793 Emit base-only LEAs as register moves

概要

xarch向けJITエミッタにおいて、インデックスなし・ディスプレースメントがゼロ・ソースとデスティネーションのレジスタが異なる、base-onlyの lea dst, [base] を mov dst, base に書き換える変更です。この書き換えはエミッタのエントリポイントで適用されます。

  • self-LEA(同一レジスタ)の除去は維持されます。
  • インデックス付き、ディスプレースメント付き、baseなしの形式は変更されません。
  • AMD64の lea rsp, [rbp] は、エピローグの正しさのためLEAのまま残されます。

サンプルコードは提供された情報に含まれていません。

変更内容

  • src/coreclr/jit/emitxarch.cpp: 条件を満たすLEAをMOVに変換するガード付きロジックを追加(+18/-5)
  • src/coreclr/jit/codegenxarch.cpp: LEAのエミッタ単体テスト用ケースを追加(+24/-2)
  • src/coreclr/jit/codegenlinear.cpp: LEAテストセクションの登録とドキュメントを追加(+5/-1)
  • src/coreclr/jit/codegen.h: LEAテスト用ヘルパーの宣言を追加(+1/-0)

AMD64のエミッタ単体テストでは、オペランド幅、特殊レジスタ、self-LEA、インデックス付き/ディスプレースメント付き/baseなしの形式、エピローグの例外を扱っています。

パフォーマンスへの影響

エンコーディングレベルでは、ほとんどのレジスタペアで命令サイズは同じです。LEAがSIBバイトまたはゼロディスプレースメントバイトを必要とする場合は、1バイト節約できることがあります。代表的なマネージドワークロードは見つからなかったため、SuperPMIやスループットの全体的な改善は主張されていません。ベンチマーク結果はありません。

関連Issue

  • #135686(ローカルアドレス最適化に関連。本PRはそれを補完する位置づけ)

その他

Copilotのレビューでは未解決の指摘は0件ですが、共有エミッタの変更であるため、エンコーディングとアンワインドの正しさについて人間による確認が必要とされています。このレビューではビルドとランタイムテストは実施されていません。


#135778 Fix shared mutex privliges/permissions/defaults to be secure

概要

Unix上の名前付きMutex(共有メモリ/ロックファイル)のセキュリティ強化を目的とした変更です。主な方針は以下のとおりです。

  • 既定でユーザースコープのMutexを使用する
  • システム定義のユーザー単位ディレクトリ配下のファイルを既定で使用する(可能であれば一時的(ephemeral)なディレクトリを優先)
  • バックファイルへのパスにシンボリックリンクを許可しない
  • フォルダーのパーミッションは変更せず、正しく設定されていることを前提とする

あわせて、パス差し替え攻撃への耐性を高めるため、openat / mkdirat / unlinkat によるディレクトリディスクリプタ基準のファイル操作を導入しています。

変更内容

  • ネイティブ層(System.Native)
    • pal_io.h / pal_io.c: 新しいフラグとAPI(ディスクリプタ相対操作)を宣言・実装
    • entrypoints.c: 新規ネイティブエントリポイントを公開
  • Interop(Unix/System.Native)
    • Interop.OpenAt.cs、Interop.MkDirAt.cs、Interop.UnlinkAt.cs: openat / mkdirat / unlinkat のバインディングを追加
    • Interop.OpenFlags.cs: O_DIRECTORY を追加
    • System.Private.CoreLib.Shared.projitems: 新規Interopソースをプロジェクトに追加
  • CoreLib
    • SharedMemoryManager.Unix.cs: 共有メモリのパスとパーミッション処理を再構成(+415/-247)
    • Mutex.Unix.cs: Unixでの既定のMutexスコープを変更(互換性用の切り替えスイッチあり)
    • NamedMutex.Unix.cs: ロックファイルをアンカーされたディレクトリハンドル経由で扱うよう変更
  • テスト
    • MutexTests.cs: Linux向けに、フォールバックパスやディレクトリ差し替え時のセキュアなディレクトリ動作を検証するテストを追加

パフォーマンスへの影響

提供された情報にはベンチマーク結果やパフォーマンスに関する記載がなく、影響は不明です。

関連Issue

なし

その他

  • 互換性: 既定のMutexスコープがユーザースコープに変わるため、従来のグローバル共有を前提とした挙動に影響する可能性があります。互換性用の切り替えスイッチが追加されています。
  • Copilotレビューの指摘(未解決2件)
    • Medium: 旧来の共有メモリ用環境変数をフォールバックとして維持すべき
    • Low: 既定のユーザースコープとグローバル互換スイッチに対するテストの追加が必要
  • Copilotは「ユーザースコープの権限検証が、全ユーザーがアクセス可能なディレクトリを許容してしまっている」点も、互換性・初期化面のリグレッションとあわせて指摘しており、変更推奨(🟡)の判定です。

#135774 Fix ILVerification argument lookup on results without arguments

概要

ILVerification の VerificationResult.ErrorArguments が TypeVerifier 由来の結果や一部の例外由来の結果で null になっており、TryGetArgumentValue / GetArgumentValue が NullReferenceException を投げる問題を修正します。あわせて、TypeVerifier が報告する結果に Type が設定されていなかった点も修正します。

  • ErrorArguments の既定値を Array.Empty<ErrorArgument>() に初期化
  • TypeVerifier が報告する結果にも Type を設定(同メソッド内の例外由来の結果と同様)

変更内容

  • src/coreclr/tools/ILVerification/VerificationResult.cs
    • ErrorArguments を空配列で初期化
    • TryGetArgumentValue を foreach ループに変更
  • src/coreclr/tools/ILVerification/Verifier.cs
    • TryResolveMetadataHandle、VerifyMethod、VerifyType の VerifierException ハンドラで、空配列を無条件に代入していた箇所を削除(既定値に依存)
    • TypeVerifier が報告する結果に Type を設定
  • src/coreclr/tools/ILVerification.Tests/VerificationResultTests.cs
    • 引数を持たない結果で TryGetArgumentValue が false、GetArgumentValue が既定値を返すことを検証する ArgumentLookupOnResultWithoutArguments を追加
  • src/coreclr/tools/ILVerification.Tests/ILTypeVerificationTester.cs
    • invalid-type の theory で各結果の Type と、TryGetArgumentValue("Offset") が false であることも検証
  • src/coreclr/tools/ILVerification.Tests/ILVerification.Tests.csproj
    • 新規テストファイルの追加に伴う更新

型検証結果の位置引数は引き続き Args に保持され、CLI のメッセージ整形に使われます。コード、メッセージ、結果の件数は変わりません。

パフォーマンスへの影響

影響なし(記載された情報の範囲では、パフォーマンスに関する変更やベンチマークはありません)。

関連Issue

#135773(Resolves)

その他

  • 互換性への影響: 公開プロパティ VerificationResult.ErrorArguments の既定値が null から空配列に変わります。ライブラリ利用側で構築した結果も同様です。null を番兵値として使っていた呼び出し側は挙動が変わるため、引数の有無は配列の長さで確認する必要があります。公開 setter で null を明示的に代入することは引き続き可能です。
  • TypeVerifier が報告する結果に、検証対象の型のハンドルが付与されるようになります。
  • テスト結果: Linux x64、SDK 11.0.100-rc.1.26420.103 で、変更適用後は Release / Debug とも 469/469 が成功しました。修正を戻した状態では、新規テストが NullReferenceException で失敗し、38 件の invalid-type ケースが Type チェックで失敗します。
  • PR 作成者によると、本 PR は AI(Anthropic Claude と OpenAI Codex)の支援を受けて作成され、作成者がレビュー済みです。

#135769 Do not attempt to start finalizer thread on WASM

概要

WASM向けNativeAOTで、ファイナライザスレッドの作成呼び出しのみをスキップする変更です。Console.WriteLine の hello world を WASI/NativeAOT 上でコンパイル・リンク・実行できるようにするための一連のPRの一部です。

シングルスレッドでの立ち上げ段階の制限への対応であり、ファイナライゼーションの代替実装ではありません。自動ファイナライゼーションは引き続き未サポートで、保留中のファイナライザの待機も本変更では機能しません。

変更内容

  • src/coreclr/nativeaot/Runtime/FinalizerHelpers.cpp(+2/-0)
    • Wasm上でのみファイナライザスレッド作成の呼び出しをスキップ
    • ファイナライゼーションイベントの初期化は継続
    • 未使用のファイナライザスレッドのエントリと、未サポートの処理依存関係はリンカGCで除去可能に
    • 他のプラットフォームでは既存のワーカー起動を維持

パフォーマンスへの影響

影響なし(ベンチマーク等の記載はありません)。

関連Issue

なし

その他

  • 検証: .\build.cmd clr.nativeaotruntime -rc Checked -os wasi -arch wasm は成功しました。
  • 一連のPR全体を適用した状態で、実CoreLibを使う2つのHelloプログラムが、リンカ警告をfatalにした設定でリンクでき、Wasmtime上で期待どおりのテキストを出力して終了コード0で動作しました。
  • ただし、これらの結果は前提となるNativeAOT/Wasm対応を含むローカルの統合ツリーによるもので、このmainベースの独立ブランチをクリーンビルドした結果ではありません。
  • ファイナライザの動作自体は検証されていません。
  • PR説明文はGitHub Copilotにより生成されたものです。

#135766 Fix remaining linking failures on native AOT/WASI

概要

WASI上のNativeAOTで Console.WriteLine の Hello World をコンパイル・リンク・実行可能にする一連のPRの一部で、残っていたリンクエラーを解消します。WASIのポータブルランタイムに必要なネイティブ互換定義を補う変更です。

  • stdcppshim.cpp に、libc++abi を必要としない __cxa_thread_atexit を提供します。WASI かつ pthread なしの場合のみ、プライベートな WASI_SINGLE_THREADED 定義で有効化されます。クリーンアップコールバックは、プロセス終了時に登録の逆順で実行され、破棄中に登録されたコールバックも含まれます。
  • unix/cgroupcpu.cpp をフルランタイム向けリストから、PalUnix.cpp と同じ共通Unixソースリストへ移動しました。Wasm では Linux の cgroup サポートではなく、既存の非Linux向けフォールバックが使われます。

なお、WASI SDK の libcabi には __cxa_thread_atexit が定義されていますが、今回の互換実装は libcabi を意図的に省くNativeAOTのリンク構成向けです。TLSクリーンアップを何もしない代替実装ではありません。

変更内容

  • src/coreclr/nativeaot/Runtime/CMakeLists.txt(+1/-1): unix/cgroupcpu.cpp を共通Unixソースリストへ移動しています。
  • src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp(+8/-6): 変更ファイル一覧にありますが、diff の詳細が提供されていないため、具体的な変更内容は不明です。

※PR説明では stdcppshim.cpp への変更にも言及していますが、提供された変更ファイル一覧には含まれていません。

パフォーマンスへの影響

影響なし(ベンチマーク等の記載もありません)。

関連Issue

なし

その他

作成者による検証結果は以下のとおりです。

  • .\build.cmd clr.nativeaotruntime -rc Checked -os wasi -arch wasm が警告・エラーなしで成功しました。
  • libc++abi を暗黙リンクしないC driverと libstdc++compat.a でリンクしたプローブが、Wasmバリデーションを通過し、期待される4つのデストラクタコールバックをすべて実行しました。
  • 分離したCMakeのターゲット/ガードの確認では、TLSシンボルが単一スレッドのWASIには存在し、pthread有効構成と非WASI構成には存在しませんでした。これらはシムのガード確認であり、スレッド有効構成や非WASIのフルランタイムビルドではありません。
  • 生成されたコンパイルコマンドに cgroupcpu.cpp のコンパイルが1回だけ含まれていました。
  • 実際のCoreLibを使った Hello オブジェクト2種を、リンカ警告を致命扱いにして再リンクしました。Preview 1 のCoreLibモジュールと Preview 2 のConsoleコンポーネントは、期待どおりのテキストを出力して終了コード0で終了しました。CoreLibモジュールはWABT検証も通過しています。

これらの結果は、前提となるNativeAOT/Wasm対応を含む統合ローカルブートストラップツリーで得られたものです。このmainベースの独立ブランチをクリーンビルドした結果ではありません。また、プローブはローカルのフィクスチャであり、このPRで追加されたテストではありません。


#135764 Fix up FCalls on native AOT/WASM

概要

NativeAOT/WASM(WASI)で Console.WriteLine の hello world をコンパイル・リンク・実行可能にするための一連のPRの一部です。Wasmのマネージド/ネイティブABIを合わせ、clangが生成したネイティブコードがリニアメモリ上にスタックフレームを確保する前に、マネージドスタックポインタ(SP)を公開(publish)するようにします。これにより、ネイティブ側のアロケーションが生きているマネージドフレームと重なって起きる起動時のメモリ破壊を修正します。Wasm GCのスタックスキャンは実装していません。

変更内容

  • CommonMacros.h(+113/-10): CoreCLRのnaked FCallのsave/publish/call/restoreラッパーをコメントごと移植しました。NativeAOT用の宣言とリンケージを使い、portable-entrypointのコンテキスト引数は持ちません。浮動小数点/int64を含む各バリアントに対応し、write barrierのネイティブABIは維持します。
  • portable.cpp(+17/-5): ポインタ配列用のportableアロケーションを追加しました。アロケータ間の呼び出しは _IMPL に直接転送し、生きているネイティブフレーム上でのラッパー再入を避けます。
  • thread.cpp(+4/-4): portable P/Invokeヘルパーの名前を修正し、CoreCLRに合わせた特別な境界を実装しました。beginではネイティブターゲットのためにSPを公開したままにし、デバッグ版のreturnでは同期をチェックします。Reverse-P/InvokeヘルパーはFCallラッパーを継承します。
  • wasm/PInvoke.cpp(+62/-0): Wasm向けのP/Invoke関連実装を追加しました。
  • GCHelpers.cpp(+4/-5)、CMakeLists.txt(+2/-0): NativeAOTビルドにWasmのwrite barrierを含めるための調整です。
  • runtime/wasm/writebarriers.cpp(+11/-7): NativeAOT互換のinclude/宣言を追加しました。

パフォーマンスへの影響

ベンチマーク結果は記載されていません。FCall境界でSPの保存・公開・復元が追加されるため、呼び出しごとのわずかなオーバーヘッドが生じる可能性がありますが、PR内に具体的な数値はありません。

関連Issue

なし

その他

  • 検証: clr.nativeaotruntime(Checked, wasi/wasm)のビルドは成功しています。FCallスタック回帰テスト(9種類のシグネチャと4096バイトのマネージドフレームを模擬)は修正前に失敗し、修正後に成功しました。ローカルの verify-stack-boundaries.ps1(Release構成含む)、Wasm ABI/TLSプローブ、Windows x64マクロABIコントロールも成功しています。
  • これらの結果は前提となるNativeAOT/Wasm対応を含むローカル統合ツリーでのものです。このブランチ単独の新規ビルドではなく、プローブスクリプトはPRに追加されたテストではありません。GC負荷やルート生存についての主張はありません。
  • Copilotレビューの指摘(未解決2件):
    • High: スタックポインタ関連のランタイムimportにABI不一致があります。ネイティブABIのエクスポートが、新しいFCallラッパー経由で互換性のないマネージドSP引数を受け取ります。
    • Low: FCallおよびP/Invokeのスタック公開に対する回帰テストの追加が推奨されています。

#135761 Do not emit try table on native AOT

概要

WASI/NativeAOT上で Console.WriteLine の Hello world をコンパイル・リンク・実行可能にするための一連のPRの一部です。NativeAOTの try 区間に対して、CoreCLR 用の try_table/catch再開方式ではなく、通常の Wasm block を出力するように変更します。これにより、NativeAOTのオブジェクト書き出しパスが未対応の WASM_CLR_RESTORE_CONTEXT_EXCEPTION_TAG_LEB を出力しなくなります。

作成者は、これは例外処理の実装ではなくブリングアップ(立ち上げ)用の暫定対応であると明記しています。マネージドの catch/filter 実行や例外からの再開は引き続き未サポートです。

変更内容

  • src/coreclr/jit/codegenwasm.cpp(+6/-0): NativeAOT の場合に try 区間を通常の block として出力する処理を追加。
  • 区間のネスト、funclet の出力、スキャナーの依存関係、通常パスでの finally 実行は維持されます。
  • CoreCLR 側の既存動作は変更されません。

パフォーマンスへの影響

影響なし(パフォーマンスに関する記載はありません)。

関連Issue

なし

その他

  • 作成者による検証内容:
    • .\src\coreclr\build-runtime.cmd -checked -x64 -component wasmjit が成功。
    • ILC のデバッグ情報を無効化(compile-hello.ps1 -NoDebug、-Variant CoreLib の対照を含む)した状態で、実際の CoreLib を使う2種類のローカル Hello プローブがコンパイルに成功。
    • 一連のPRと組み合わせた状態で、CoreLib の Preview 1 モジュールと Console の Preview 2 コンポーネントが Wasmtime 上で Hello world from WASI CoreLib! を出力し、終了コード 0 で終了。
  • これらの結果は、前提となる NativeAOT/Wasm 対応を含む統合済みのローカルブリングアップ用ツリーで得られたものであり、この分離された main ベースのブランチを新規ビルドした結果ではありません。
  • プローブ用スクリプトはローカルのフィクスチャであり、このPRで追加されたテストではありません。

#135739 JIT: Remove redundant Span.Slice/Vector128.Create checks in vectorized loops

概要

JITの範囲ベースのrelop(関係演算)畳み込みを改善し、ベクトル化されたSpanループで典型的に現れる冗長な境界チェックを除去します。Span.Sliceの(uint)X > (uint)Bndチェックや、Vector128.Createの長さチェックBnd - X >= cnsが畳み込まれ、a.Length - Vector128<ushort>.Countを上限とするループで境界チェックがすべて除去されます。

対象となるコード例(作成者提示):

static bool Equal(ReadOnlySpan<ushort> a, ReadOnlySpan<ushort> b)
{
    if (a.Length != b.Length)
        return false;

    int i = 0;
    if (Vector128.IsHardwareAccelerated)
    {
        for (; i <= a.Length - Vector128<ushort>.Count; i += Vector128<ushort>.Count)
        {
            var va = Vector128.Create(a.Slice(i));
            var vb = Vector128.Create(b.Slice(i));
            if (va != vb)
                return false;
        }
    }

    for (; i < a.Length; i++)
    {
        if (a[i] != b[i])
            return false;
    }

    return true;
}

変更内容

  • src/coreclr/jit/assertionprop.cpp (+143/-10): Bnd1 == Bnd2アサーションを利用して、Bnd1の限界を優先するBnd2で表現する処理を追加。Bnd - Xの範囲をXをBndからの相対範囲として計算する解析を追加
  • src/coreclr/jit/compiler.h (+2/-0): 新しい範囲解析ヘルパーの宣言を追加
  • src/coreclr/jit/rangecheck.cpp (+138/-5): 負の定数下限に対する単調性解析のリトライ(Widen)、等価な境界の扱いを改善
  • src/coreclr/jit/rangecheck.h (+24/-8): シンボリックrelopの畳み込みを拡張

主な変更点:

  • (uint)X > (uint)Bnd(Span.Slice)を、Bndに対する相対的なシンボリック範囲で畳み込み
  • Bnd - X >= cns(Vector128.Create長さチェック)を、XのBnd相対範囲を計算して畳み込み
  • EvalRelopで、同一Bndに対するBnd + cns形式の限界同士を比較
  • Widenで、負の定数下限に対して単調性解析を再試行

パフォーマンスへの影響

上記Equalメソッドのx64 JIT出力(FullOpts)で改善が示されています。

  • コードサイズ: 236バイト → 110バイト
  • PerfScore: 104.77 → 75.24
  • 命令数: 87 → 38
  • 境界チェックと、それに伴うThrowArgumentOutOfRangeException/CORINFO_HELP_RNGCHKFAILの呼び出しパス、およびループの重複(負のインデックス用)が除去され、ホットループがベクトル比較と加算のみになっています。
  • 作成者によると、診断結果(Diffs)はかなり大規模です。

関連Issue

なし

その他

  • Copilotのレビューでは、「変更を推奨」と判定され、次の2点が指摘されています。
    • 高: 新しい範囲導出でINT32_MINを符号反転する際にオーバーフローする可能性があり、ガードが必要
    • 中: ベクトル化Spanループの範囲チェック除去に対する、専用のコード生成回帰テストが不足している

#135730 [release/11.0] Correct decimal conversions to Half and BFloat16

概要

decimal から Half / BFloat16 への変換で発生していた二重丸め(double-rounding)を修正する、main の #135668 の release/11.0 向けバックポートです。厳密なフォールバック処理が、中間型を経由せず変換先の形式へ直接丸めるようになりました。また、Half のパースでは tie-to-even の指数境界が修正されています。

これにより、Half / BFloat16 の中間値(midpoint)付近の decimal 値が、中間値の誤った側にある隣接表現値へ変換される問題が解消されます。

変更内容

  • Decimal.DecCalc.cs(+89/-25): 変換先の形式へ直接丸める厳密なフォールバック処理に変更
  • Decimal.cs(+4/-0): 上記に伴う変更
  • Half.cs(+2/-5): パース時の tie-to-even 指数境界を修正
  • BFloat16.cs(+1/-3): decimal 変換の修正に対応
  • HalfTests.cs / BFloat16Tests.cs: 中間値に隣接する値、tie、subnormal を対象としたリグレッションテストを追加

影響範囲は System.Private.CoreLib 内の decimal 浮動小数点丸めと Half のパーサーに限られます。公開APIの変更はありません。

パフォーマンスへの影響

main の PR での比較によると、BFloat16 への decimal キャストは 6.368 ns で、double 経由のキャスト(4.096 ns)より遅くなっています。ただし計測のばらつきが大きく、別のベースラインランタイムでのビルドとの比較でもないため、決定的なリグレッションの証拠ではなく、観測されたコストとの位置づけです。release ブランチ固有のベンチマークは実施されていません。

関連Issue

#135659(main の修正PR: #135668)

その他

  • カスタマーへの影響: 中間値付近の decimal を Half / BFloat16 に変換するアプリケーションで、誤った隣接値が返る可能性がありました。一部の Half の subnormal 値にも影響します。
  • リグレッション: ではありません。.NET 11 RC で再現し、Half は .NET 10 でも同じ二重丸めの問題があり、BFloat16 は .NET 11 で新規追加された型です。
  • リスク: Low
  • テスト: clr+libs ビルド(checked)に成功し、System.Runtime.Tests は 77,859 件中、失敗 0、スキップ 87 でした。

#135657 Run GC.GetGeneration test in its own process

概要

GC/API/GC/GetGeneration テストがCoreCLR環境で断続的に失敗する問題への対処です。GC.Collect() 直前に確保したオブジェクトが、収集後もgen0に残る場合があるためです(CIログでは 0 0 / arrayTest Failed!)。 原因は #126108 で RequiresProcessIsolation が外れ、マージ済みの GC ランナー内で他テストの後にインプロセス実行されるようになったことと推測されています(#132076 で Collect / Collect0 / Collect1 に同様の修正が入っており、GetGeneration は対象外でした)。 本PRは GetGeneration.csproj に同じプロパティグループ(プロセス分離)を追加します。テストをgen0残留を許容する形に緩めることは意図的に避けています(昇格の検証が目的のため)。

変更内容

  • src/tests/GC/API/GC/GetGeneration.csproj(+4/-0): #132076 と同じプロパティグループ・コメントを追加し、テストを専用の子プロセスで実行するようにしました。
    • CI上の結果名は GetGeneration.dll から GetGeneration.cmd に変わります。
    • GetGenerationWR、GetGenerationWR2、GetGeneration_box、GetGeneration_fail は昇格を検証しないため、マージ済みランナーに残しています。

パフォーマンスへの影響

実行時の性能への影響はなく、テストプロジェクトのみの変更です。分離により、呼び出しごとにテストプロセスが1つ増えます。 ローカルでの計測(linux-x64 Checked、200回×2セット、12並列)では、ランナー全体の中央値は変更あり98.25秒、変更なし97.65秒でした。ただし、これは並列ローカル実行のタイミングであり、CIでのコストを示すものではありません。

関連Issue

#132291(Fixes)。関連PRとして #126108、#132076 があります。

その他

  • 検証は、既存のローカルruntime(#135520調査時のコントロールビルド。未改変のmainビルドではない)で行われています。
  • マージ済みランナーを変更前後それぞれ200回実行し、いずれも全53テストが成功しました。したがって、失敗の減少は示されていません。従来調査では、400回中1回の GetGeneration 失敗が記録されていました。
  • メカニズム確認では、ホストプロセスから GetGeneration.dll の TestEntryPoint を30,000回呼びました。収集前後にpinされた配列を保持した場合、56回失敗し、CIと同じ出力が再現しました。pinなしや直前のpinのみでは失敗しませんでした。これは、同一プロセス内のpinと過去のGCが失敗を引き起こしうることを示すものの、実際のCI失敗の原因がpinであるとは断定していません。
  • 変更はAI支援(Anthropic Claude、OpenAI Codexによる確認)で準備され、作成者がレビューしています。

#135625 [mono][interp] Preserve live locals across finally OSR

概要

Mono インタープリタで、finally ハンドラー内でOSR(On-Stack Replacement)が発生した際にローカル変数の値が破損する問題を修正するPRです。

SSAのコピー伝播により、保存済みのILローカルが別のフレームオフセットにある一時変数に置き換えられることがあります。finally 内のループによって現在のフレームがtier upされると、最適化後の継続コードが元のローカルではなく一時変数を読んでしまい、保留中の戻り値やハンドラー後に使われるローカルが誤った値になります。

EHブロックはSSAのCFGの外側にあるため既存のtiering定義では保護されていませんでした。本PRでは、finally ハンドラーの継続マーカーで MINT_DEF_TIER_VAR を再利用し、呼び出し元ブロックからlive-outとなるSSA対象のILローカルを保護します。この追加保護はEHバックエッジのパッチポイントを持つメソッドにのみ適用され、SSA・tiering・OSRは有効なままです。

再現コード(PR記載の最小化したもの)の要点:

[MethodImpl(MethodImplOptions.NoInlining)]
private static int ThroughFinally(int value)
{
    try
    {
        return Identity(value);
    }
    finally
    {
        for (int i = 0; i < 1_000; i++)
        {
            Thread.SpinWait(1);
        }
    }
}

修正前のMonoインタープリタでは 42 を返すべきところ 1 が返り(5回中5回再現)、修正後は 42 が返ります。

変更内容

  • src/mono/mono/mini/interp/transform-opt.c:finally ハンドラー継続マーカーでのライブローカル保護に関する処理を追加・変更(+39/-13)
  • src/mono/mono/mini/interp/transform.c:関連する変更(+11/-1)
  • src/mono/mono/mini/interp/transform.h:フィールド等の追加(+1/-0)
  • src/tests/JIT/opt/OSR/handlerloop.cs:既存の handlerloop 回帰テストに、保留中の戻り値とライブローカルのtheoryを追加。0、正、負、最大整数値をカバー(+135/-2)

パフォーマンスへの影響

  • ローカルのBenchmarkDotNet測定(WSL)ではノイズが大きく、スループットの向上/劣化を信頼できる形で主張できないとされています。
  • MONO_INTERPRETER_OPTIONS=-tiering,-inline でのコード生成比較では、単純なreturnおよびループなし finally のカーネルでバイトコードが同一(それぞれ3命令・8命令)であることを確認しています。
  • 保護はEHパッチポイントを持つメソッドに限定されるため、通常の finally メソッドには保護バリアが追加されません。このバリア自体はコンパイル時のみで、命令は生成されません。
  • 参考測定値(平均, ns):単純return 24.98→24.34、ループなしfinally 35.73→43.12(StdDev 9.40)、4回クリーンアップ 121.81→105.16。

関連Issue

#135096(Resolves)

その他

  • 検証結果(Linux x64, Ubuntu 25.10 on WSL):
    • 同一の handlerloop.dll が修正前のMonoインタープリタでは失敗し(0 が 999 になる)、修正後は成功。Mono JITでも成功。
    • System.Net.Security 機能テストスイート:5,100件中5,092件成功、失敗0、既存の環境依存スキップ8件。
    • OSRサブツリー:38件成功、0件失敗。
  • System.Net.Security側の回避策やテストの隔離は行っていません。
  • Windows、macOS、ARM64、browser、モバイルでの実行はローカルでは未検証です。
  • PRおよびその説明はGitHub Copilotの支援で作成されています。

#135602 JIT: reject method entry inside handlers or filters

概要

JITが、メソッドのエントリポイント(IL offset 0)がハンドラまたはフィルタの内部にあるメソッドを受け入れてしまう問題を修正します。ECMA-335 I.12.4.2.8.1 では、これらのリージョンへの進入は例外処理機構が制御するものとされています。修正後は、このようなメソッドを InvalidProgramException として拒否します。

修正前の挙動(PR作者の報告):

  • linux-x64 の main Release JIT では、EntryInFinally / EntryInFault / EntryInCatch がコンパイルされ、戻ってしまう
  • main Checked JIT では fgDebugCheckBBlist で block->bbRefs == blockRefs のアサートが発生する
  • 出荷済みの .NET 10.0.12(linux-x64)では、コンパイルは成功するが呼び出すとスタックオーバーフローする
  • pop で始まる catch / filter のバリアントは、インポータのスタックアンダーフローチェックで既に拒否されている

変更内容

  • src/coreclr/jit/fgbasic.cpp(+12/-0)
    • fgFindBasicBlocks で EH 句を読み込む際に、offset 0 から始まるハンドラ、または offset 0 から始まるフィルタをメソッドエントリを含むものとして拒否するチェックを追加
    • 既存の「try/handler の終端がメソッド末尾を超える」チェックの隣に配置し、同様に BADCODE3 経由で InvalidProgramException を報告

パフォーマンスへの影響

影響なし

関連Issue

#135593(本PRで Resolve)

その他

  • テストは追加されていません(レビューで削除されたと記載されています)。
  • 検証結果(作者による報告):
    • Checked JIT(main 8630d89)で、finally / fault / catch(pop なし)/ filter の4メソッドを RuntimeHelpers.PrepareMethod でコンパイルする IL プログラムを使用
    • linux-x64、osx-arm64、windows-x64、windows-arm64、linux-arm64 の全レーンで、修正前は EntryInFinally でアサート、修正後は4メソッドすべて拒否(戻り値100)
    • linux-x64 の Release JIT でも4メソッドすべて拒否されることを確認
  • 出荷済みランタイムでの修正前の挙動はプラットフォームごとに異なります。
    • linux-x64(10.0.12):コンパイルは成功し、呼び出しでスタックオーバーフロー
    • osx-arm64(10.0.12):コンパイルは成功し、呼び出しで SIGTRAP クラッシュ
    • windows-x64(10.0.11):コンパイルは成功し、呼び出しで fail fast(0xC0000409)
    • windows-arm64(10.0.9 / 10.0.11)と linux-arm64(10.0.11):すでに InvalidProgramException
    • windows-arm64 の 11.0.0-preview.5.26302.115 では、PrepareMethod が OutOfMemoryException で失敗
  • 別PR(#135592)のテスト Runtime_135592 は、本変更の前後とも失敗し続けます(想定どおりと記載)。
  • 作者によると、本PRは AI(Anthropic Claude と OpenAI Codex)の支援を受けて作成され、作者がレビューしてから投稿したとのことです。

#135577 [wasm] Avoid Spilling Many GC-ref Typed Tree Temps

概要

WebAssembly(Wasm)ターゲットのJITにおける fgWasmSpillRefs パスの最適化です。これまでは未消費のGC参照型の一時値をすべてスピルしていましたが、直近の呼び出しにそのまま引数として渡される値についてはスピルを省略します。GC安全性の維持は呼び出し先(callee)の責務とする方針です(R2Rのfixup thunkも着信引数を既定でGC保護するとされています)。

MyClass x = Allocate();
Use(x);   // x は直近の呼び出しに渡されるだけなので、スピル不要になる

一方、ネストした呼び出しなど、参照が直近の親以外で未消費のまま残る場合は、従来どおりスピルが必要です。

MyClass x = Allocate();
M(x, F()); // x は M のオペランドだが、F() の実行中(GCが起こりうる)も生存するためスピルが必要

変更内容

  • src/coreclr/jit/fgwasm.cpp (+55/-40)
    • オペランド使用の除去処理を再利用可能なヘルパーとして切り出し
    • マネージド呼び出しの引数を、他の生存参照をスピルする前にスピル対象から除外
    • ネストした呼び出し、ヘルパー呼び出し、アンマネージド呼び出しについては従来どおりスピルを維持

パフォーマンスへの影響

作成者による計測結果です。

  • SuperPMI: コードサイズが 8,771,651 → 8,555,629 バイトとなり、-216,022 バイト (-2.46%) 削減されました。
  • ローカルベンチマーク(CoreCLR baseline → after):
    • Mobile cold startup: 7,474 ms → 6,901 ms (7.7% 高速化)
    • Desktop walkthrough: 5.60 s → 6.05 s (8.1% 低速化。ただし1回のみの実行でばらつきが大きいため、作成者は重視していません)
    • Desktop cold download: 10.324 MB → 10.215 MB (1.1% 縮小)
    • Havit publish: 150.81 s → 149.21 s (1.1% 高速化)

コードサイズの削減により、起動時間とダウンロードサイズが改善しています。

関連Issue

  • #135543(スピル自体を回避する可能性についての言及)

その他

  • Copilotのレビューでは、High severityの指摘が1件未解決です。明示的なnullチェック(NeedsNullCheck)を伴う呼び出しでは、calleeが新たにスピルされなくなった引数を保護する前に、GCを引き起こしうるthrowヘルパーが呼ばれる可能性があります。そのため、このケースでは一時値のスピルを維持すべきという推奨になっています(該当コメント)。
  • 本変更は公開APIではなく、JIT内部(Wasmターゲット)の実装変更で、破壊的変更の記載はありません。

#135491 [mono] Prevent theoretical overflow due to excessive aggregation of cmods

  • 作成者: @BrzVlad
  • 作成日時: 2026年10月09日 12:26:15(UTC)
  • マージ日時: 2026年10月15日 14:10:07(UTC)
  • ラベル: area-VM-meta-mono

概要

Mono ランタイムで、ジェネリックの inflate 時にカスタム修飾子(cmod)の数が無制限に積み上がり、個数を保持する uint8_t がオーバーフローして、後続のコピーで確保済みバッファを超えて書き込む可能性がある問題を防ぐ修正です。

  • 型が持つ cmod は通常少数で、Mono には上限(MONO_MAX_EXPECTED_CMODS)が定義されています。しかし generic inflation では上限をチェックせずに修飾子が追加されます。
  • 合計数を size_t で計算し、uint8_t に縮小する前に上限を超えていないことを assert します。
  • 上限を超える型は元々一貫してサポートされておらず(AOT の decode_type も同じ上限を assert)、サポート範囲の拡大ではなく、失敗を決定的(deterministic)にする変更です。

再現パターンの例(IL 上の概念的な表現):

D1<T> : Base<T modopt(A1) ... modopt(A60)>
D2<T> : D1<T modopt(B1) ... modopt(B60)>
D3<T> : D2<T modopt(C1) ... modopt(C60)>
D4<T> : D3<T modopt(D1) ... modopt(D60)>
D5<T> : D4<T modopt(E1) ... modopt(E60)>

変更内容

  • src/mono/mono/metadata/metadata.c(+13/-13)
    • generic inflation 時の cmod 数の集計を size_t で行うように変更
    • uint8_t へ縮小する前に MONO_MAX_EXPECTED_CMODS 未満であることを assert
    • 影響範囲は Mono ランタイムの内部実装(メタデータ処理)で、公開 API の変更はありません

パフォーマンスへの影響

影響なし(ベンチマーク結果の記載もありません)

関連Issue

なし

その他

  • 理論上のオーバーフロー(バッファオーバーランにつながりうる)への堅牢化で、CVE 番号などの情報は提供されていません。
  • 上限を超える型に対する挙動は、未定義な状態から assert による明示的な失敗に変わります。極端な数の modifier を持つ型を扱う場合のみ影響しますが、そのようなケースは従来から正式にはサポートされていません。

#135440 Reduce WebAssembly managed method prologs

  • 作成者: @davidwrighton
  • 作成日時: 2026年10月08日 18:05:36(UTC)
  • マージ日時: 2026年10月15日 22:49:55(UTC)
  • ラベル: area-ReadyToRun

概要

CoreCLR の WebAssembly R2R マネージドメソッドのプロローグを縮小するため、メソッドごとの関数テーブルインデックス生成をやめ、コンパクトな「フレームアイデンティティ」に置き換える変更です。JIT・R2R コンパイラ・VM・cDAC のスタックウォーカーにまたがる変更で、インタプリタは変更されていません。

フレームアイデンティティの形式:

  • 通常のマネージドメソッド: 受け取った portable entrypoint(PEP)をそのまま保存
  • マネージド JIT ヘルパー: CoreLib のランタイム関数を示す定数の負の奇数を保存
  • funclet: タグ付けされた establishing-frame ポインタを保存
  • reverse P/Invoke メソッド: PEP 引数を持たないため、正の奇数の関数テーブルインデックスを維持

スタック処理側でこれらのアイデンティティをメソッドの仮想 IP に解決します。アイデンティティの再配置(relocation)は対象メソッドを明示的に保持するため、JIT インターフェースは「常にコンパイル中のメソッドを指す」前提を置かなくなり、将来のメソッド間直接呼び出しにも対応できます。

変更内容

  • JIT (src/coreclr/jit)
    • lclvars.cpp/compiler.h: 受け取った PEP 引数を記録
    • codegenwasm.cpp/emitwasm.cpp/instrswasm.h/emitfmtswasm.h: ルートと funclet のコンパクトなアイデンティティを出力する命令・フォーマットを追加
    • jitee.h/corjitflags.h: マネージドヘルパー用フラグを追加
  • JIT/EE インターフェース・R2R ツール
    • corinfo.h に新しい relocation 種別を追加
    • CorInfoImpl*.cs でマネージドヘルパーを識別し、relocation の対象メソッドを明示的に使用
    • 新規 WasmMethodFrameIdentityNode.cs が負のランタイム関数アイデンティティを算出
    • Relocation.cs、WebCilObjectWriter.cs、WasmRelocatableObjectWriter.cs、WasmFunctionBodyDeduplicator.cs で符号付きアイデンティティ relocation の解決・縮小に対応
  • VM (src/coreclr/vm)
    • wasm/helpers.cpp/callhelpers.hpp: ネイティブのスタック処理でアイデンティティをデコード
    • codeman.cpp/codeman.h: CoreLib のヘルパーアイデンティティを解決し、テーブルインデックスの範囲を検証
    • readytoruninfo.cpp: 旧 Wasm フレームエンコードの R2R イメージを拒否
  • バージョニング: readytorun.h、ModuleHeaders.h/.cs、jiteeversionguid.h のフォーマットバージョン/GUID を更新
  • SuperPMI: マネージドヘルパーフラグの名前表示を追加
  • cDAC (src/native/managed/cdac)
    • WasmUnwinder/WasmR2RInfo/WasmContext: 全フォームのアイデンティティをデコードし、funclet では establishing-frame ポインタを辿り、reverse P/Invoke ではネイティブ呼び出し元の境界を維持
    • ExecutionManager に、現在の仮想 IP から共有ルックアップ経由でアンワインド情報を取得するメソッドを追加
    • WasmFunctionTableIndexLookup.cs を追加
  • テスト: WasmUnwinderTests、WasmR2RInfoTests、StackWalkTests、ExecutionManagerTests、WasmArgumentLayoutTests、WasmR2RAssert(プロローグの検証)を追加・更新
  • ドキュメント: clr-abi.md、StackWalk.md、ExecutionManager.md にエンコードとアンワインドの挙動を記載

パフォーマンスへの影響

サイズ(System.Private.CoreLib.wasm、同一の Release browser ビルドで upstream main と比較):

構成 生バイト数 Brotli (quality 11, window 22)
main 24,427,372 4,091,906
新プロローグ 22,072,267 3,913,764
差分 -2,355,105 (9.64%) -178,142 (4.35%)

呼び出し性能(R2R コンパイルした Wasm を Node.js で測定、1/2/4/8 回の連続呼び出し、9 プロセスの中央値):

1 反復あたりの呼び出し数 ベースライン/呼び出し 新プロローグ/呼び出し 差分
1 20.5859 ns 13.8341 ns -32.80%
2 13.0693 ns 13.2345 ns +1.26%
4 12.6670 ns 12.8688 ns +1.59%
8 12.4607 ns 12.6702 ns +1.68%

1 回呼び出しのケースは V8 の最適化の影響とされ、収束した複数回呼び出しのケースとは一致しません。2/4/8 回のケースでは一貫して 約 1.5%(1.26〜1.68%)の Wasm 呼び出し性能の低下が見られ、サイズ削減とのトレードオフになります。Copilot の概要


#135297 Managed ilasm: per-point PDB documents, the input file and .line files as documents, LocalSignature row id

概要

managed 版 ilasm(src/tools/ilasm)が生成する Portable PDB を、ネイティブ ilasm の挙動に近づける変更です(#135212 の一環で、別ファイル .pdb 出力の #135289 はマージ済み)。ドキュメントの扱いをポイント単位に改め、入力ファイルと .line ファイルをドキュメントとして記録し、LocalSignature の行 ID を正しく書き出します。あわせて --pathmap オプションを追加しています。

変更内容

  • ポイント単位のドキュメント: これまでは「メソッドごとに1ドキュメント」(最初の .line のファイル)でしたが、各シーケンスポイントが、ディレクティブ適用時点の現在ドキュメントを記録するようになりました。複数ドキュメントにまたがるメソッドは Document = nil とし、blob ヘッダに InitialDocument を持ち、非 hidden ポイントでドキュメントが変わる前に document-record を出力します(ネイティブの DefineSequencePoints と同様)。
  • '' は「同一ファイル」: .line N : C '' はドキュメント名 '' を作らず、現在のドキュメントを維持します(ネイティブの SetSourceFileName と同様)。
  • ドキュメントの定義規則:
    • 入力 .il ファイル(フルパス)が #1 のドキュメントになります。
    • .line/#line で指定された全ファイルは、ディレクティブ適用時に(ポイントで使われるかどうかに関わらず)定義されます。
    • 順序は出現順で、名前は大文字小文字を区別します。
    • 各ドキュメントは最初に定義された時点の言語を保持し、既定は IL assembly(af046cd3-d0e1-11d2-977c-00a0c9b4d50c)です。
  • LocalSignature: sequence-points blob ヘッダに、本体のローカルシグネチャの StandAloneSig 行 ID を書き込みます(ローカルなしなら 0)。/FOLD で共有される本体も対象です。
  • 本体を持たないメソッド: abstract や pinvokeimpl、命令のない本体では IL オフセット 0 のシーケンスポイントを作らなくなりました(ディレクティブ自体はファイル名を指定します)。
  • --pathmap: --pathmap <path>=<sourcePath>[,...] で、PDB のドキュメント名と CodeView エントリ内の PDB パスの接頭辞を置換できます。C# コンパイラの -pathmap と同じ規則(末尾区切り文字補完、最初に一致したエントリが優先、結果の区切り文字は置換側に従う)です。/DET と併用すると、配置場所に依存しないバイト単位で同一のイメージ・PDB が得られます。
  • 主な変更ファイル:
    • GrammarActions.BuildImage/Conversions/Debug/cs
    • EntityRegistry.cs
    • Options.cs
    • 新規 PathMap.cs、PdbDocumentTable.cs
    • CLI の IlasmRootCommand.cs、Program.cs
  • テスト:
    • 新規: PdbDocumentTests、CommandLinePdbDocumentTests、CommandLinePathMapTests、PathMapTests、PdbCaseGenerator/PdbGeneratedCaseTests(200 件のシード付き生成ケース)、PortablePdbTestReader。
    • MethodTests にエントリポイントの検証を追加し、SourceDirectiveTests などの既存テストも更新しています。

パフォーマンスへの影響

影響なし(実行時性能に関する記述はなく、ビルドツールの出力内容の変更が中心)。

関連Issue

  • #135212(背景の議論)
  • #135289(別 .pdb ファイル出力。マージ済み)
  • #135314(ネイティブとの残りの差異の追跡)

その他

  • 挙動変更:
    • /DEBUG または /PDB 指定時、.line がなくても入力ファイルが常にドキュメントとして含まれます。
    • CLI が各入力ファイルのフルパスをアセンブラに渡すため、エラーメッセージの入力パスもフルパス表記になります(ネイティブはコマンドラインで与えたパスのまま)。診断用パスを元の表記のまま保持し、ドキュメント名を別途渡す案も可能とのことです。
  • ネイティブとの意図的な差異: シーケンスポイントがない、または本体のないメソッドは、仕様どおり Document を nil のままにします(ネイティブは現在のドキュメントを指定)。
  • 別途対応予定(本 PR の対象外): LocalScope/LocalVariable 行、明示的なローカルスロットと字句スコープ、.il 自身の行に対する暗黙のシーケンスポイント、#include ファイルのドキュメント化、#line の自動インクリメント、.line の終了列の既定値、ディレクティブ適用時点で記録することに起因する 2 つのケース。
  • 測定結果(Linux x64、IlasmPortablePdbTester): ネイティブは 10/10 通過。managed 版は #135289 時点で 4/10、本 PR 適用で 6/10 になります。残る 4 件は TestPortablePdbLocalScope(TestLocalScopes1..4.il) で、ローカルスコープ対応

#135293 [wasm][JIT] Remove assertions assuming the SP arg of a fast tail call is a GT_PHYSREG

  • 作成者: @lewing
  • 作成日時: 2026年10月06日 17:01:07(UTC)
  • マージ日時: 2026年10月15日 21:24:33(UTC)
  • ラベル: area-CodeGen-coreclr

概要

WebAssembly(wasm)向けJITの fast tail call において、シャドウスタックポインタ(SP)引数が GT_PHYSREG であると仮定していたアサーションを削除する修正です。WasmRegAlloc::CollectReferencesForCall は SP 引数を ADD(SP, FRAME_SIZE) でラップしますが、オペランドが一時変数(temp)に評価される場合があり、その際にアサートが発火していました(regallocwasm.cpp:589)。

例として、長い sb.Append(..).Append(..)...ToString() のチェーンでは gtMayHaveStoreInterference が 8 個のストアで判定を諦めるため、arg morph が SP 引数を temp に退避し、アサートに抵触します。temp も同じ post-prolog の SP 値を保持しているため、temp をラップしても同様に正しい動作となります。

変更内容

  • src/coreclr/jit/regallocwasm.cpp: SP 引数が GT_PHYSREG であることを仮定したアサーションを削除(+0/-4。PR説明上は実質5行の削除)
  • ブランチ履歴には以前の morph 変更とそのリバートが含まれますが、最終的な差分は regallocwasm.cpp のみです。

検証結果:

  • #135291 の explicit-tail-call bail-out なしのチェック版 wasm crossgen2 で FSharp.Core 全体のコンパイルが成功(exit 0)。修正前は FSharpList<int>.ToString() でアサートし exit 133 でした。
  • 該当メソッドの生成コードを確認し、temp が SP から設定され、tail call が temp + 192 を渡していることを確認済みです。
  • wasm テストは実行されていません。

パフォーマンスへの影響

影響なし(アサーションの削除のみ)。

関連Issue

#135292(本PRで解決)

その他

  • 回帰テストは含まれていません。再現には明示的な tail. 呼び出しを含む IL が必要で、かつ crossgen2 の bail-out なしのチェック版 wasm JIT でのみ失敗するため、wasm R2R CI では検出されないとのことです。
  • PR説明は GitHub Copilot により生成されたものです。

#134664 Delete SUPPORT_LOCAL_DEBUGGING ifdef

概要

debug/di/cordb.cpp の SUPPORT_LOCAL_DEBUGGING ifdef を削除するクリーンアップです。このマクロは ARM 専用の DbiGetThreadContext / DbiSetThreadContext(アウトオブライン実装)でのみ使用されていました。ARM32 は Unix でのみサポートされ、Unix では当該マクロが 0 だったため、これらの関数は常に assert して FALSE を返すだけのスタブでした。この PR でスタブとマクロを削除し、ARM も他のプラットフォームと同じマクロを使うようにしています。

#define DbiGetThreadContext(hThread, lpContext) ::GetThreadContext(hThread, (CONTEXT*)(lpContext))
#define DbiSetThreadContext(hThread, lpContext) ::SetThreadContext(hThread, (CONTEXT*)(lpContext))

変更内容

  • src/coreclr/debug/di/cordb.cpp(+0/-83)
    • SUPPORT_LOCAL_DEBUGGING の define を削除
    • ARM 専用の DbiGetThreadContext / DbiSetThreadContext 実装を削除
  • src/coreclr/debug/di/stdafx.h(+0/-5)
    • TARGET_ARM による分岐を削除し、ARM も共通のマクロを使用

動作面では、ARM で呼び出し元が「assert して失敗するスタブ」ではなく PAL の GetThreadContext / SetThreadContext に到達するようになります(他の Unix アーキテクチャと同じ挙動)。呼び出し元の多くは Windows 専用の FEATURE_INTEROP_DEBUGGING パスにあります。対象はデバッガーインターフェイス(DI)の内部実装で、公開 API の変更はありません。

パフォーマンスへの影響

影響なし

関連Issue

なし

その他

  • 本 PR は GitHub Copilot により生成されたものです。
  • Copilot のレビューでは「変更推奨」とされ、High 重要度の指摘が 1 件(未解決)あります。内容は、ARM 固有のコンテキストのレイアウトおよびアライメントを保証するアダプターを維持するか、不要であることを示す必要がある、というものです。この指摘への対応状況は提供情報からは確認できません。

#134210 Enable building a stubbed NativeAOT WASM CoreLib

概要

NativeAOT の WASM 向け CoreLib をスタブ化してビルドできるようにする変更です。スタック巻き戻し・GC・例外処理(EH)の設計が未確定のため、必要なヘルパーをいったんスタブ化し、ilc が WASM モジュールをコンパイルできるようにすることが目的です。作成者によれば、リンクや実行はまだできず、ブロッカーの一つを解消する位置づけです。

変更内容

  • eng/Subsets.props、eng/common/native/NativeAotSupported.props:NativeAOT のサポート判定とサブセットの設定を変更(eng/common から2行を削除)
  • src/coreclr/nativeaot/Directory.Build.props:WASM 向けのプラットフォーム定義を追加
  • src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj:WASM 固有の実装を選択するようソース構成を変更
  • Runtime.Base/.../ExceptionHandling.wasm.cs(新規):プレースホルダの例外処理エクスポートを追加
  • Runtime.Base/.../InternalCalls.cs、RuntimeExports.cs:WASM で未対応の EH/スタック巻き戻し関連の import とネイティブのスタックトレース export を除外
  • System.Private.CoreLib/.../ThunkPool.NotSupported.cs(新規):動的サンクの操作をスタブ化
  • RuntimeAugments.cs、InteropHelpers.cs、RuntimeImports.cs、Thread.NativeAot.cs、StackTrace.NativeAot.cs、RuntimeInstance.cpp:WASM ビルドに合わせた条件分岐などの調整
  • レビュー指摘に関連して、Internal/Runtime/FrozenObjectHeapManager.Wasm.cs(仮想メモリ操作のスタブ)や StackTrace.NativeAot.Browser.cs(スタックトレース無効化)が言及されています

パフォーマンスへの影響

影響なし(スタブ化によるビルド可能化が目的で、パフォーマンスに関する記載はありません)

関連Issue

なし

その他

  • Copilot のレビューで、以下の点が指摘・未解決として残っています。
    • WASM ビルドで TARGET_UNIX が未定義のため、マネージド/ネイティブ間の ABI 不一致が生じ、モジュールパス検索やスレッド名設定に影響する(WASI ビルドでも同様)
    • eng/common は dotnet/arcade から自動管理されているため、NativeAOT サポートの変更は Arcade 管理側のソースで行うべき
  • 追加されたプレースホルダの EH ヘルパー(RhpThrowExact エクスポートなど)に関する ABI の不一致も指摘されました(最初のレビュー時点)
  • ブラウザ固有名のソースや、コメント・説明中の "browser-WASM" 表記を共有 WASM 向けに改める指摘(Low)もあります
  • 本 PR は暫定的なスタブ化であり、例外処理・GC・スタック巻き戻しの本格対応は今後の課題です

#133665 Reject bare CR in managed HttpListener request parsing

概要

マネージド実装の HttpListener がリクエスト解析時に、LF を伴わない単独の CR(bare CR)を黙って捨てて前後の文字列を連結してしまう問題を修正します。RFC 9112 §2.2 では、単独 CR を受け取った場合は要素を不正として扱うか CR を SP に置換することが求められており、現状はどちらにも該当しません。本変更では、LF が直後に続かない CR を拒否するようにし、http.sys(Windows)の挙動(400 を返す)に揃えます。

作成者の検証では、以下のようなリクエストがマネージド実装では受理され、http.sys では 400 になっていました。

  • Content-Le\rngth: 5 → Content-Length: 5 として扱われる
  • X-Test: ab\rcd → ヘッダー値が abcd になる
  • GET /c\rd HTTP/1.1 → RawUrl が /cd になる
  • Host: localhost\r\r\n → 受理される
  • チャンクサイズ行 1\r0\n → 0x10 バイトのチャンクとして読まれる

変更内容

  • ChunkStream.cs(+7/-4): GetChunkSize で、読み取りループの後ろにあり実質到達不能だった Missing \n チェックをループ内に移動し、bare CR を検出できるようにしました(break なしでループを抜けるのは offset == size のときのみで、offset < size が成立しないため)。
  • HttpConnection.cs(+7/-0): ReadLine で、CR の直後が LF でない場合に例外を投げます。ProcessInput が既にこの例外を 400 に変換します。
  • InvalidClientRequestTests.cs(+6/-0): bare CR を含む 4 件の不正リクエストを追加(実装非依存)。作成者は同じ 4 件が http.sys で 400 になることを確認しています。
  • HttpRequestStreamTests.cs(+46/-0): マネージド実装のみを対象とした Read_ChunkSizeWithBareCR_ThrowsHttpListenerException を追加。

互換性・挙動について:

  • 公開 API は変更なしです。
  • 新たに失敗するのは RFC 上不正で、http.sys が既に 400 で拒否しているリクエストのみです。
  • 単独 LF による行終端は引き続き許可され、CR と LF が複数回の読み取りに分割されるケースも従来どおり動作します。
  • 作成者の説明では、#132163 / #132747 で空白について対処した「中継装置との解釈不一致」と同種の問題を塞ぐものです。

パフォーマンスへの影響

影響なし(パフォーマンスに関する記載・計測はありません)。

関連Issue

その他

  • 作成者は、手元に .NET 11 SDK がなくリポジトリをビルドできなかったため、xunit テストは未実行で CI に依存しているとしています。代わりに、ChunkStream.cs と HttpConnection.ReadLine を取り出した net8.0 のハーネスで検証し、main では 7 件の bare-CR チェックが失敗、本変更後はすべて通過したとのことです。
  • 作成者は別の問題も指摘しています(本 PR では未対応): ChunkStream.ReadTrailer がトレーラー文字を _saved に追加しないためトレーラーフィールドが失われること、および 0\r\n\r\r\n でストリームが追加データを待ち続けること。必要なら Issue を起票するとしています。

#132637 Collapse VM contracts to STANDARD_VM_CONTRACT where equivalent

概要

VM内で展開されていた CONTRACTL ブロックを、意味的に等価な箇所で STANDARD_VM_CONTRACT / STANDARD_VM_CHECK に集約するリファクタリングです。あわせてデバッガ関連のコントラクトを簡素化し、不要になった遅延初期化の仕組みを削除しています。協調モード/プリエンプティブモードの両方から呼ばれ得るヘルパー(メタデータ取得、静的フィールドアドレス取得など)は、誤った MODE_PREEMPTIVE チェックを追加しないよう、モード非依存のまま維持しています。

変更内容

  • コントラクトの標準化: jitinterface.cpp、method.cpp、methodtable.cpp、virtualcallstub.cpp、threads.cpp、dllimport.cpp、comdelegate.cpp、comutilnative.cpp、callcounting.cpp、multicorejit*.cpp、perfmap.cpp などで、等価な展開済みコントラクトを標準マクロに置換
  • モード注釈の明示化: gchelpers.cpp、excep.cpp、encee.cpp、virtualcallstub.h などで協調モードを明示。binder.*、assembly.*、codeman.cpp、customattribute.cpp、eventtrace.cpp、eedbginterfaceimpl.cpp、funceval.cpp などではモード非依存(MODE_ANY)を明示
  • デバッガ関連の簡素化: debugger.cpp / debugger.h / dbginterface.h から遅延初期化用 API(宣言・実装)を削除(debugger.cpp は +10/-50)
  • その他: perfmap.h の無効化時スタブの標準化、sigbuilder.cpp のデストラクタに非スロー指定を追加、nibblestream.h のライタをコントラクトラッパーとして明示、debuginfostore.cpp のフォーマット整理など
  • 変更は src/coreclr/vm を中心に、debug/ee、inc、utilcode に及びます(約65ファイル)

パフォーマンスへの影響

影響なし(コントラクトは主にチェック/ドキュメント用途で、実行時挙動の変更は意図されていません。ベンチマーク結果の記載もありません)。

関連Issue

なし

その他

  • 検証(Windows x64、リベース後):
    • build.cmd clr+libs(Checked ランタイム): 警告・エラーなしで成功
    • Interop テスト(priority 1)のビルド: 成功
    • Interop テスト実行: 774件中 769件成功、失敗0、既存の ActiveIssue によるスキップ5件
    • ネイティブCOMクライアント6ディレクトリをプロセスローカルの PATH に追加する必要がありました(シェルの NoDefaultCurrentDirectoryInExePath=1 によるもの)。設定やソースコードは変更していません
  • Copilotレビューの指摘(未解決2件):
    • 【中】FEATURE_PERFMAP 無効時のスタブ(no-op ブランチ)のコントラクトが、実際の実装のGCコントラクトと不整合
    • 【低】モード非依存のコントラクトに更新した箇所で、古いコメントが残っている
  • 変更ファイル数が多いため、モード注釈の意味的な等価性が各箇所で保たれているかが主なレビューポイントです。

目次