1. 程式人生 > 其它 >轉載 CoreCLR原始碼探索(七) JIT的工作原理(入門篇)

轉載 CoreCLR原始碼探索(七) JIT的工作原理(入門篇)

轉載自:https://www.cnblogs.com/zkweb/p/7687737.html

很多C#的初學者都會有這麼一個疑問, .Net程式程式碼是如何被機器載入執行的?
最簡單的解答是, C#會通過編譯器(CodeDom, Roslyn)編譯成IL程式碼,
然後CLR(.Net Framework, .Net Core, Mono)會把這些IL程式碼編譯成目標機器的機器程式碼並執行.
相信大多數的C#的書籍都是這樣一筆帶過的.
這篇和下篇文章會深入講解JIT的具體工作流程,
和前面的GC篇一樣, 實現中的很多細節都是無標準文件的, 用搜索引擎不會找到它們相關的資料.

因為內容相當多, 講解JIT的文章將會分為兩篇.
第一篇是入門篇, 看過這個系列之前的文章和CLR via C#, 瞭解一些編譯原理的都可以看的明白.
第二篇是詳解篇, 會分析JIT的具體實現流程, 演算法和資料結構.

這篇的內容是基於CoreCLR 1.1.0分析的, 其他CLR中的實現不一定和這篇分析的實現完全一樣.
微軟最近提供了一篇JIT入門文件,
儘管裡面寫的相當潦草但是仍有很大的參考價值, 推薦同時參考這個文件.

JIT的作用介紹

相信很多C#程式設計師都知道, 我們編寫的C#程式碼在經過編譯後得出的exe或dll裡面包含的並不是機器程式碼,
而是一種中間程式碼, 也稱為MSIL(簡稱IL).
MSIL可以在不同的系統或者平臺上執行, CLR中執行它們的模組就是這篇要講的JIT.

如圖所示

CoreCLR中的JIT代號是RyuJIT, RyuJIT可以把MSIL翻譯為X86, X64或者ARM的機器程式碼.

使用JIT的好處有

  • 同一個程式集可以在不同平臺上執行
  • 減少編譯時間(編譯到MSIL的時間比編譯到機器程式碼的時間要短很多)
  • 可以根據目標平臺選擇最優的程式碼(例如只在支援AVX指令的CPU使用AVX指令)

使用JIT的壞處有

  • 增加執行負擔
  • 不能執行過多的優化(否則將會增加更多的執行負擔)
  • 部分平臺上無法使用(例如iOS)

為了解決這些壞處而出現的技術有NGEN, AOT, CoreRT等, 但是使用它們以後同時也就失去了使用JIT的好處.

JIT的流程總覽

以下的圖片來源於微軟提供的JIT入門文件:

總體上來說RyuJIT可以分為兩個部分.
前端: 也就是圖上的第一行, 負責把MSIL轉換為JIT中的內部表現(IR)並且執行優化.
後端: 也就是圖上的第二行, 負責準備生產機器程式碼, 分配暫存器等與平臺相關的處理.

程式設計是個人愛好