UnityでC#のアセンブラを見る
Unityは独自に拡張したMonoを使っていたり、そもそもC#のバージョンが違っていたりで.NETとは異なる動作をします。ビルドされた結果が見られれば最終的にどう動いているのか調査できます。
unity-asm-explorer-packageに含まれるAsmExplorerを使うと実際に動作しているアセンブラを見られます。この使い方を説明します。
Unityバージョンに注意
以下はUnity2020.3.17で試しています。Unity2021.2ではMonoのバージョンが変わったために今のところ動かないようです。
セットアップ
まずunity-asm-explorer-package全体をgitでcloneするかDownload ZIPでダウンロードします。そしてPackages\com.s-schoener.asmexplorerフォルダを、使いたいUnityプロジェクトのPackagesフォルダにコピーします。
これでUnityエディタ上でエラーが出なければ使えるようになります。問題なく導入できていればメニューにWindow/Asm Explorerが追加されています。
私の環境では「Multiple precompiled assemblies with the same name System.Runtime.CompilerServices.Unsafe.dll included on the current platform. Only one assembly with the same name is allowed per platform.」というエラーがでてすぐには使えませんでした。 これはSystem.Runtime.CompilerServices.Unsafe.dllが他と重複しているエラーなのでcom.s-schoener.asmexplorer/Plugins/Tracing/netstandard2.0/にあるSystem.Runtime.CompilerServices.Unsafe.dllを消して解決しました。他にも多くのdllが入っているので環境によって他にも調整が必要かもしれません。
エディタ上でアセンブラを表示する
メニューのWindow/Asm Explorer/Inspectを選択すると、ブラウザが起動して次のような画面が表示されます。
Unityで読み込まれているC#のアセンブリ一覧が表示されているので、見たいクラスが入っているものを選択していくとJITアセンブラが見れます。アセンブリはAssemblyDefinitionを使っていなければAssembly-CSharpになります。
ただし、この状態だとデバッグ用のコードが混ざっていて最適化もされてません。そうではなくリリースビルドのアセンブラを表示したいです。
ビルドしてアセンブラを表示する
シーンに新しいGameObjectを作成してAsmExplorerHelperというコンポーネントを追加しておきます。これでビルドすれば動きます。
ただしビルド時にProfilerSessionInstance.csでコンパイルエラーが出るのでファイルの先頭に「using UnityEngine;」を追加してください。(直ったので不要です)
ビルドを起動してWindow/Asm Explorer/Inspectで開かれたURL(http://localhost:8080/explorer/)にアクセスするとエディタ上で動かしたときと同じ画面が表示されます。
下のような感じでアセンブラを確認できるようになります。
ポートを変える
アセンブラを表示するURLに8080ポートを使っていますが、エディタ上とビルドでポートが競合して動かなかったりします。なのでポートを変更しておくのをお勧めします。
ExplorerInstance.csでPortとして定義されているので適当に変えます。とりあえずエディタ上では53128、ビルドしたら63128としておきます。
#if UNITY_EDITOR
public const int Port = 53128;
#else
public const int Port = 63128;
#endif
まとめ
とりあえずUnityでもJIT Asmが見れるようになりました。色々と荒削りなライブラリのようなので自分で使いやすいように変更して使うのがよさそうです。