首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

認識元數據與 IL(下):JIT 編譯時的角色與運作機制

     編輯:關於.NET

承接[上集](第二十四回)與[中集](第二十五回),本文深入 JIT 編譯階段,揭示元數據與 IL 如何協同驅動程式執行。核心流程:類別載入 → 方法表建立 → 首次呼叫觸發 JIT → IL 轉換原生碼 → 後續直接執行。

範例程式碼

public class Base {
    public void M() { Console.WriteLine("M in Base"); }
    public virtual void N() { Console.WriteLine("N in Base"); }
}
public class Three : Base {
    private static int ID { get; set; }
    public override void N() { Console.WriteLine("N in Three"); }
    public void M() { Console.WriteLine("M in Three"); M1(); }
    public void M1() { Console.WriteLine("M1 in Three"); }
}
static void Main() {
    Base three = new Three();
    three.M(); three.N();
}

類別載入與方法表(Method Table)建立

Class Loader 從元數據表 (TypeDef, MethodDef 等) 讀取類型資訊,建立 CORINFO_CLASS_STRUCT 結構,包含:

  • 非虛方法表
  • 虛方法表(VTable):依繼承順序排列——父類虛方法 → 子類覆寫/新增虛方法 → 實例方法 → 靜態方法

Three 的方法表結構示意:

方法表結構

透過 SOS 擴充指令驗證:

!dumpheap -type Three
!dumpmt -md 

輸出顯示 MethodDesc Table,每個方法對應一個 MethodDesc 結構,初始指向 IL 代碼與 PreJitStub(JIT 觸發器)。

MethodDesc 與 JIT 編譯觸發機制

MethodDesc 結構

每個 MethodDesc 初始包含:

  • IL 代碼位址
  • 指向 PreJitStub 的呼叫指令

首次呼叫流程:

  1. 呼叫指令跳轉到 PreJitStub
  2. JIT 編譯器將 IL 轉換為 x86/x64 原生碼
  3. 原生碼位址回寫覆蓋 MethodDesc 中的 JIT 指令(插入 jmp)
JIT 後 MethodDesc 更新

後續呼叫:直接跳轉至原生碼,零 JIT 開銷。

虛方法分派:N() 呼叫實例

three.N() 透過 VTable 分派:

  1. 從物件標頭取得 Method Table 指標
  2. 根據 VTable Slot 索引定位 Three.N 的 MethodDesc
  3. 執行上述 JIT/直呼邏輯

非虛方法 M() 則直接透過 MethodDesc 靜態繫結。

元數據 Token:IL 與元數據的橋樑

IL 指令透過 4 位元組 Metadata Token 參考元數據表:

  • 高 1 位元組:表索引(如 0x06 = MethodDef)
  • 低 3 位元組:記錄索引(RID)
.method private hidebysig static void Main() cil managed
{
    IL_0003: newobj instance void .../One::.ctor() /* 06000007 */
    IL_000b: callvirt instance void .../One::set_ID(int32) /* 06000006 */
}

運行時可透過 Type.MetadataToken 取得 Token 值。

總結與系列展望

元數據描述靜態結構,IL 闡釋動態執行,兩者在 JIT 編譯階段緊密協作:

  • Class Loader 消費元數據建立方法表
  • MethodDesc 綁定 IL 與 JIT 入口
  • JIT 將 IL 編譯為原生碼並熱插拔

後續主題將延伸至:組件與模組、應用程式域、CLR 載入流程、JIT 深度解析、方法呼叫慣例、反射機制等,構建完整 CLR 運行時知識圖譜。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved