一個 .NET 應用僅僅只是一塊在 .NET 運行時上面運行的二進制代碼。而 .NET 運行時只是一個能執行這項任務的程序。當前的 .NET Framework 和 .NET Core 運行時採用 C++ 編寫,而 Mobius 是一個使用 C# 重寫的 .NET 運行時,重寫包括 JIT 編譯和 GC 等,這些邏輯都將和 C++ 無關git
原文:Mobius – .NET runtime running on .NET Core – TooSlowExceptiongithub
我看到這個有趣的項目的時候就想試試安利一下你們,這個項目特別適合用來了解 GC (Garbage Collector 垃圾收集)和 JIT (Just-In-Time Compiler 即時編譯器)的算法
讓 C# 編寫一個 .NET 運行時和編寫一個運行在這個運行時上的 .NET 應用是否有可能呢?換句話是不要 Native 的本機代碼或 C++ 代碼,全部的代碼都是經過 C# 編寫是否有可能?這看起來是一個無窮的遞歸,用 .NET 寫 .NET 的運行時運行在 .NET 的運行時上。這是否是就是將一個 .NET 運行時運行在另外一個 .NET 運行時上?算法
做者kkokosa決定開始試試水,這就是作 Mobius 運行時想法的緣由。這個想法聽起來很奇怪,連做者都不抱指望在一個世紀內將這個想法投入使用。不過做者的想法是想要了解若是寫出整個 .NET 運行時須要多少的代碼量。同時做者也發現了其實這個想法的做用其實很小,即便想象如今有一個 NuGet 包在安裝完成以後就能夠添加到咱的應用上,此時的這個包就包含了完整的運行時代碼,其實好像也不能作什麼框架
其實這個想法在其餘的領域也有人嘗試過,最著名的不過是 RVM —— 用 Java 編寫的 JVM 虛擬機。雖然他須要使用 C 的引導啓動,可是能作到本身託管本身,徹底由 Java 運行的虛擬機同時不須要其餘的虛擬機。這看起來很是和做者想象的 Mobius 很是接近性能
這個想法不止做者一我的在想,其實也有小夥伴在 Github 上發佈了一個 issus 說可否使用 C# 寫 JIT 和 GC 的邏輯學習
基於這些考慮,能夠看到開發 Mobius 的緣由以下:測試
如上面說的,其實都不是很強的理由,爲何要用 .NET 去寫 .NET 運行時。大多數狀況下,人們會認爲使用 C++ 開發和使用 C# 開發不是對立的,二者的差異不是很大。做者很是贊成這個觀點,這就是爲何做者實際上是將這個項目當成一個玩具和實驗的項目優化
先拋開是否有必要作這樣的事情,請讓咱想一想這個項目能夠如何作編碼
首先,要理解的最重要的事情是 Mobius 仍然會將咱的應用程序編譯爲本地 Native 代碼。以這種方式,最終應用程序將以(幾乎)本機代碼速度運行。不一樣之處在於託管的基礎設施,如 GC 和類型系統、JIT編譯器是做爲託管代碼運行的。這意味着這些代碼也被 JIT 編譯設計
如上圖,咱們有兩層JIT構建的代碼和底層實際運行時的本地 Native 代碼。從圖片看起來中間的這一層 .NET Core 基礎設施的 Mobius 層是多餘的。若是這一層是使用無分配對象的方式寫的,那麼不須要任何的 GC 方法。在預熱以後,對 JIT 的調用也將會不多。這就容許咱假設在一個正常運行的應用程序中,大部分在 Mobius 層的內容都是通過了 JIT 編譯優化完成以後運行的,這包括了經常使用的對 .NET Core 代碼的 JIT 構建的代碼,這將十分接近 .NET Core 的原生調用
從上面的圖看,其實 Mobius 的多餘仍是很明顯。一個能夠想的方法是在兩個運行時之間共享基礎設施
重寫整個類型系統並非一件頗有趣的事情。咱們甚至能夠考慮在 Mobius 中重用相同的 GC 垃圾回收,因此使用 Mobius 給 .NET 應用提供對象將看起來不錯。雖然上面的方法請看起來不錯,但依然存在兩個問題:
基於這個緣由,做者認爲 .NET Core 運行時應該只提供不多量的運行時服務給到 Mobius 框架,提供的服務主要只是調用 Jit 編譯代碼
當前做者仍是試驗可行性,正在作的是讓最簡單的 C# 應用能玩起來
private static int Main(string[] args) { int num = 1; int num2 = 2; return num + num2; }
經過一些可行性的測試,做者看到了曙光,應該是能作出來的。目前全部須要的機制都已就緒,包括:即便編譯的基礎支持,經過託管調用 JIT 代碼,經過 JIT 代碼調用 Mobius 框架。可是由於測試可行性的項目代碼寫的糟,還須要一點時間對代碼進行重構,完善並實現大量的元數據處理,去掉一些硬編碼值
如今這個可行性項目只是能作到運行當前這個簡單的應用而已,運行的時候經過徹底的 CIL 指令和沒有任何的異常處理,同時只有 GC 的存根
在下一篇系列文章中,做者將介紹Mobius實現最底層部分的更多細節和代碼片斷
逗比注:
若是本文看的不錯,想要參與開發,我以爲在這以前須要先讀一下農夫的書,請看 《.NET 底層入門》這本書
另外上面說的玩具什麼的只是原做者謙虛的說法,其實這個玩法是可行的,在 Github 有小夥伴在討論,請看 Port JIT and GC to C# 這個連接