.NET Framework デバッグ ~ JIT コンパイルの様子をみる
前の資料の続きで、JIT コンパイルの状態をみてみましょう。
button1_Click でブレークしたところで、button1_Click メソッドと button2_Click メソッドのメソッドディスクリプタを確認します。
さて、まずは Form1 の EEClass を確認します。この方法は他のページで説明済みです。
0:000> !sos.name2ee exceptiontest1.exe ExceptionTest1.Form1 Module: 00382c5c (ExceptionTest1.exe) Token: 0x02000005 MethodTable: 00385a40 EEClass: 00381574 Name: ExceptionTest1.Form1 0:000> !sos.dumpmt -md 00385a40 EEClass: 00381574 Module: 00382c5c Name: ExceptionTest1.Form1 mdToken: 02000005 (C:\Temp\Projects\bin\Release\ExceptionTest1.exe) BaseSize: 0x14c ComponentSize: 0x0 Number of IFaces in IFaceMap: 15 Slots in VTable: 377 -------------------------------------- MethodDesc Table Entry MethodDesc JIT Name 643e6350 64258338 PreJIT System.Windows.Forms.Form.ToString() 6ffc6a90 6fe4493c PreJIT System.Object.Equals(System.Object) 6ffc6b00 6fe4496c PreJIT System.Object.GetHashCode() 6f7a2ea0 6f6909dc PreJIT System.ComponentModel.Component.Finalize() 704cd930 6fe4d508 PreJIT System.MarshalByRefObject.GetLifetimeService() 6ffa9190 6fe4d510 PreJIT System.MarshalByRefObject.InitializeLifetimeService() 6ffda660 6fe4d518 PreJIT System.MarshalByRefObject.CreateObjRef(System.Type) 64436420 64258a64 PreJIT System.Windows.Forms.Control.get_CanRaiseEvents() ... 6499189c 642583d8 PreJIT System.Windows.Forms.Form.OnResizeBegin(System.EventArgs) 64991810 642583e0 PreJIT System.Windows.Forms.Form.OnResizeEnd(System.EventArgs) 0038c054 003859cc JIT ExceptionTest1.Form1..ctor() 0038c074 003859d8 JIT ExceptionTest1.Form1.button1_Click(System.Object, System.EventArgs) 0038c084 003859e4 NONE ExceptionTest1.Form1.button2_Click(System.Object, System.EventArgs) 0038c064 003859f8 JIT ExceptionTest1.Form1.InitializeComponent()
メソッドディスクリプタの情報を見るには !sos.dumpmd コマンドにメソッドディスクリプタのアドレスを渡します。
0:000> !sos.dumpmd 003859d8 *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v2.0.50727_32\Syst... Method Name: ExceptionTest1.Form1.button1_Click(System.Object, System.EventArgs) Class: 00381574 MethodTable: 00385a40 mdToken: 0600000a Module: 00382c5c IsJitted: yes CodeAddr: 00420328
この結果から JIT コンパイル済みであることがわかります。 最後の CodeAddr というのが JIT コンパイル後の button1_Click メソッドのアドレスです。
ちなみに、逆にこのアドレスから逆にメソッドディスクリプタを取得するには !sos.ip2md コマンドを使います。
0:000> !sos.ip2md 00420328
MethodDesc: 003859d8
Method Name: ExceptionTest1.Form1.button1_Click(System.Object, System.EventArgs)
Class: 00381574
MethodTable: 00385a40
mdToken: 0600000a
Module: 00382c5c
IsJitted: yes
CodeAddr: 00420328
またこの時点で、同じクラスの他のメソッド button2_Click のメソッド・ディスクリプタをみると、 以下のようにまだ JIT コンパイルされておらず、アドレスが割り当てられていないことがわかります。
0:000> !sos.dumpmd 003859e4 Method Name: ExceptionTest1.Form1.button2_Click(System.Object, System.EventArgs) Class: 00381574 MethodTable: 00385a40 mdToken: 0600000b Module: 00382c5c IsJitted: no CodeAddr: ffffffff