Mobius – .NET runtime running on .NET Core

栏目: IT技术 · 发布时间: 4年前

内容简介:.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).

Mobius – .NET runtime running on .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.

Mobius – .NET runtime running on .NET Core

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.

Mobius – .NET runtime running on .NET Core

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.


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高性能Python

高性能Python

(美)戈雷利克、(英)欧日沃尔德 / 东南大学出版社 / 2015-2

你的Python代码也许运行正确,但是你需要运行得更快速。通过探讨隐藏在设计备选方案中的基础理论,戈雷利克和欧日沃尔德编著的《高性能Python》将帮助你更深入地理解Python的实现。你将了解如何定位性能瓶颈,从而显著提升高数据流量程序中的代码执行效率。 你该如何利用多核架构和集群?或者你该如何搭建一个可以自由伸缩而不会影响可靠性的系统?有经验的Python程序员将会学习到这类问题的具体解......一起来看看 《高性能Python》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换