原文鏈接:http://www.mono-project.com/news/2017/11/13/mono-interpreter/ Mono即將通過它的JIT編譯器和靜態編譯器以及一個.net解釋器以帶來一些新的方式來運行你的代碼. 在2001年Mono項目誕生之時,我們為.net指令集實現了一個 ...
原文鏈接:http://www.mono-project.com/news/2017/11/13/mono-interpreter/
Mono即將通過它的JIT編譯器和靜態編譯器以及一個.net解釋器以帶來一些新的方式來運行你的代碼.
在2001年Mono項目誕生之時,我們為.net指令集實現了一個解釋器用基於它實現了一個在Linux上的自托管的.net開發環境.
當時我們把解釋器定義為一個用來構建JIT編譯器的臨時工具. 那個解釋器(mint)和JIT引擎(mono)並行存在至我們將JIT引擎移植到我們支持的所有平臺上
當有了泛型之後,同時維護解釋器和JIT引擎帶來巨大工程量,同時我們看不到太多它存在的價值以及為它做很多額外工作的意義,所以我們刪除瞭解釋器
我們後來為.net代碼引入了全靜態編譯. 這是一項用來支持不允許動態代碼生成的平臺的技術, iOS是它誕生的主要原因,但是這項技術同時為Mono打來了通向PlayStation和Xbox等游戲主機的大門
全靜態編譯的最大缺點是可執行輸出需要在每一次更新代碼里重新生成,這是一個漫長的過程同時不適用於一些互動式開發
例如, 一些游戲開發者希望能在不觸發全靜態編譯的情況下調整他們的游戲代碼. 全靜態編譯使得這個場景無法實現, 所以他們不得不通過在他們游戲代碼中嵌入一種腳本語言來實現快速迭代和調整他們項目的目的
.NET 動態能力的缺乏使得很多想將.net作為教學或者原型工具的人喪失了興趣. 很多像Xamarin Workbooks的東西, 或者簡單的腳本無法使用.net語言而不得不從其他平臺尋找解決方案.
當Frank Krueger構建他的Continuous IDE的時候就非常需要在iOS上有類似的環境以致於他使用F#實現了自己的.net解釋器最終給iPad帶來了完整的.net開發環境
為瞭解決這些問題同時支持MS內部的一些產品,我們決定重啟Mono解釋器項目, 它將伴隨著一個twist歸來.
新的Mono解釋器
我們複活了Mono解釋器並升級了它對.net的支持, 添加了對泛型的支持並將它升級到最新版的.net, 下一步準備為它添加混合模擬執行的支持
這是Mono在現在可以支持WebAssembly的方式之一 (另外一種就是通過LLVM靜態編譯)
這個解釋器目前已經是Mono主線的一部分而且已經通過了我們大部分測試,你可以通過從源代碼編譯Mono而現在就可以開始通過以下方式使用它:
$ mono --interpreter yourassembly.exe
混合執行模式
目前解釋器本身已經成形,我們正在努力的實現通過配置使得我們可以將解釋代碼和靜態編譯代碼或者JIT後的代碼混合,我們稱之為混合模式執行
對於iOS, PalyStatition以及Xbox之類的平臺來說,這意味著你可以預編譯你的核心庫或者核心程式, 同時又可以支持動態載入和執行代碼. 得到你所有的核心庫通過LLVM優化的好處的同時仍然具備靈活的運行動態代碼的能力.
這將允許游戲開發者們在他們的系統中使用.net語言來實現原型,測試以及調整他們的游戲而不需要重新編譯程式.
它還將為使用. NET 語言的設備上運行可腳本化應用程式打開大門
將來的工作
我們正在通過擴展解釋器的能力以滿足很多有意思的場景,下麵是一些擺在我們面前的項目:
靜態編譯Mono的提升
在全AOT編譯的Mono版本(iOS, 游戲主機)上我們無法發佈任何System.Reflection.Emit的實現,因為平臺無法支持,但是現在我們有瞭解釋器,我們可以支持了.
下麵是幾個相關的應用.
System.Linq.Expressions API被廣泛用於像Entity Framework或者使用C#編譯器將表達式轉化為表達式樹等高級場景下,你也許見過類似以下場景的代碼:
Expression sum = a + b;
var adder = sum.Compile ();
adder ();
在全AOT場景下, 我們支持Entity Framework和上面邏輯的方式是為Expression類製作一個解釋器. 這個表達式解釋器有很多限制,而且影響很大.
通過啟用解釋器支持下的System.Reflection.Emit我們可以刪除很多代碼.
這也會允許為.net構建的腳本語言可以在靜態編譯環境下運行, 比如IronPython, IronRuby and IronScheme.
為了達到這些目的, 我們正在努力的為混合模式執行工作. 這意味著解釋代碼可以與已有的靜態編譯代碼協同工作
更好的隔離
在上面我提到了我們之前沒做好的一個場景就是通過熱載入代碼使開發人員可以實時部署和調整他們的游戲代碼
我們即將通過完成對AppDomains的支持來滿足這個需求
正在研究的混合模式選項
這個解釋器是運行一些代碼的輕量選擇. 我們發現一些特殊程式在被解釋時的速度超過了被JIT引擎執行的速度
我們計划去探索一種混合執行方式,有時被稱為分層編譯
我們可以讓解釋器執行已知的性能不敏感代碼 - 比如, 靜態構造器或者其他只執行一次的初始化代碼以助於減少記憶體占用以及代碼生成和執行時間.
另外一個考慮是先在解釋模式下運行代碼, 當我們超過了某些門檻時切換到JIT引擎來執行,或者使用Attribute來標記哪些方法值得去優化.