内容简介:.NET application is “just” a piece of CIL bytecode to be executed by the .NET runtime. And .NET runtime is “just” a program that is able to perform this task. It happens that currently .NET Framework/.NET Core runtimes are written in C++. I am also fully a
.NET application is “just” a piece of CIL bytecode to be executed by the .NET runtime. And .NET runtime is “just” a program that is able to perform this task. It happens that currently .NET Framework/.NET Core runtimes are written in C++. I am also fully aware of CoreRT that was .NET runtime with many parts rewritten to C# (like type system) but still, crucial parts (including JIT compiler and the GC) were left written in C++.
But what if we write .NET runtime as… .NET application? Is is possible at all? I mean, literally no native/C++ code, everything running as .NET Core application written in C#? Does this sound like kind of inception and infinite recursion? It would require running one .NET runtime on the top of another .NET runtime, right?
I decided to check it out and that’s how Mobius runtime idea has been coined ! Yeah, I know it sound strange and I do not expect it will be anything close to production ready thingy in the nearest century. I am fully aware of the amount of code needed to be written to make full .NET runtime. However, I found it interesting to validate such idea and I find it small usages as well. Imagine a NuGet package with the separate runtime that you can add to your application :wink:
Rationale
There were similar attempts in other environments, most notably Jikes RVM – JVM virtual machine written in Java. Although it still requires some C-based bootstraping , and is self-hosted (its Java code runs on itself without requiring a second virtual machine), it is very close to what I have in mind with Mobius. As the project website explains (emphasis mine):
Jikes RVM (Research Virtual Machine) provides a flexible open testbed to prototype virtual machine technologies and experiment with a large variety of design alternatives. (…) A Java implementation provides ease of portability, and a seamless integration of virtual machine and application resources such as objects, threads, and operating-system interfaces. (…) Many researchers have found that Jikes RVM provides a useful vehicle for research on the frontiers of virtual machine technologies (over 188 publications and 36 dissertations)
And obviously there is GraalVM with approach similar to CoreRT (JIT and most parts written in Java). Even in the .NET Core itself, more and more parts are being ported to the managed side. Ongoing discussions compare them within the .NET environment, please refer for example to Port JIT and GC to C# issue .
So in summary, Mobius is:
- for research and experiments – having runtime code in C#/.NET, we can easier and faster prototype various parts of it, like various JIT or GC implementation changes. We can even experiment with writing all or parts of the runtime in functional language like F#. That’s exactly the same rationale like in Jikes RVM.
- for learning – we can learn a lot about the structure of the runtime and its internal dependencies. It is also just so perfect scenario for utilizing modern C# capabilities, low-level APIs (Span, stackallock, Unsafe class). I’ve even already posted one .NET Core issue ( DynamicMethod calls without inlining #34500 ) that came out during work on Mobius.
- for performance – this is obviously the most controversial Running one managed runtime on the another managed runtime does not sound like anything related to performance. But, after applications warms up (most methods have been already JITted), in the end what matters is the quality of the native code generated by the JIT. Written in C# in this case, theoretically allows more robust optimizations development. And there is the GC, while written in C#, that theoretically can also benefit the same.
- for fun – for some, including me, it can be just pure fun to see its working! A perfect, not obliging pet project.
Note. I’m fully aware those reasons are not very strong. Mostly, one can argue that C++ development vs C# development is not so a big difference and it doesn’t explain rewriting the whole runtime. I fully agree and that’s why I treat the whole thing as a toy and experiment for learning!
Ok, putting aside the discussion whether it is worth doing, let’s think how to do it.
Design fundamentals
First of all, the most important thing to understand is that Mobius still JIT compiles IL of you application to the native code . In that manner, in the end, you application is running at (almost) the native code speed. The difference is that the managed infrastructure (like the GC, type system, JIT compiler), called from the JITted code occasionally (like allocations), is running as managed code. But it means it will be JITted either (by .NET Core).
In the end, we have two layers of JITted code and the native code of the underlying, real runtime. This additional layer of Mobius JITted code seems to be an overkill, but it really depends on how intensively Mobius uses .NET Core facilities. If it is mostly written in an alloc-free manner, there are almost no GC calls. In a warmed up state, JIT calls will be also rare. This allows to assume that in a regularly working application the most work will be done in the app JITted code, with some Mobius JITted calls and very occasional .NET Core native calls.
When looking at the above graph, duplication clearly stands out. One could think of sharing some managed facilities between both runtimes.
In the end, rewriting the whole type system is not such a big fun. We could even think of reusing the same GC in Mobius, so objects provided by Mobius to the .NET application would be living on the good, old .NET Core Managed Heap. Although it seems tempting as it reduces a lot of work, I see two main problems with this approach:
- it reduces “research and experiments” part of the Mobius purpose a lot – instead of inventing/experimenting on GC and JIT algorithms, we will be forced to think how to incorporate the already existing ones,
- JIT, GC and type system contracts are pretty coupled – it could reduce “research and experiments” part to minimum, leaving us with almost no other choice than reimplement the same mechanism in Mobius
In the end, how I would like to see it, is think as .NET Core runtime providing only occasional services to the Mobius runtime, mostly just calling application JITted code.
Current status
Although I definitely plan to open source all the work, currently I’m working on vertical proof-of-concept that will be able to run the simplest C# application:
private static int Main(string[] args) { int num = 1; int num2 = 2; return num + num2; }
I see the light at the end of the tunnel. Currently all required mechanisms are in place : JITting basics, calling JITTed code from managed code, calling Mobius from the JITted code. I need some more time to refactor, polish and implement a lot of metadata handling (to get rid of some boldly hard-coded values :)).
By vertical I mean, it will be able to literally run this and only this single application, with all CIL instructions required, with no exception handling, with only GC-stubs.
In the next series of articles I will present more details and code snippets of the most low-level part of the Mobius implementation.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
区块链技术驱动金融
阿尔文德·纳拉亚南、约什·贝努、爱德华·费尔顿、安德鲁·米勒、史蒂文·戈德费德 / 林华、王勇 / 中信出版社,中信出版集团 / 2016-8-25 / CNY 79.00
从数字货币及智能合约技术层面,解读了区块链技术在金融领域的运用。“如果你正在寻找一本在技术层面解释比特币是如何运作的,并且你有一定计算机科学和编程的基本知识,这本书应该很适合你。” 《区块链:技术驱动金融》回答了一系列关于比特币如何运用区块链技术运作的问题,并且着重讲述了各种技术功能,以及未来会形成的网络。比特币是如何运作的?它因何而与众不同?你的比特币安全吗?比特币用户如何匿名?区块链如何......一起来看看 《区块链技术驱动金融》 这本书的介绍吧!