Experiment: Mobius – eine .NET-Runtime auf .NET Core

Eine neue .NET-Runtime als Anwendung auf .NET Core: Mobius ist ein in der Praxis noch zu erprobendes Experiment, das die Grenzen von C# ausloten soll.

In Pocket speichern vorlesen Druckansicht
Experiment: Mobius – eine .NET-Runtime auf .NET Core

(Bild: motion.vidos/Shutterstock.com)

Lesezeit: 5 Min.
Von
  • Silke Hahn
Inhaltsverzeichnis

Eine .NET-Runtime als .NET-Anwendung schreiben: Beißt sich die Katze da nicht in den Schwanz, oder anders gesagt, müsste es da nicht zu endlosen Rekursivschleifen kommen wie bei einem Möbius-Band? Der polnische .NET-Entwickler Konrad Kokosa hat die Idee, die .NET-Runtime ohne C++ komplett in C# neu zu schreiben und sie dann als .NET-Anwendung auf .NET laufen zu lassen. Ob das geht, probiert er jetzt aus, und sein Projekt taufte er laut einem Blogeintrag (nicht ohne Selbstironie) "Mobius".

Dass der Ansatz für manche Kollegen komisch klingen könnte, sei ihm bewusst – auch, dass es eine ganze Menge Code bräuchte, um die gesamte .NET-Runtime neu zu schreiben. Ähnliche Ansätze habe es aber in anderen Ökosystemen schon gegeben, so zum Beispiel Jikes RVM (Research Virtual Machine), eine in Java geschriebene virtuelle Maschine. Diese sei – abgesehen von etwas auf C-basierendem Bootstrapping – bereits "self-hosted", was bedeutet, dass sie prinzipiell "auf sich selbst läuft" und keine weitere virtuelle Maschine benötigt.

Auch die polyglotte Virtuelle Maschine GraalVM geht in eine ähnliche Richtung wie die CoreRT, bei der der JIT-Compiler und die meisten Teile in Java geschrieben sind. Etwas Ähnliches schwebt Kokosa mit Mobius für .NET mit C# vor. Ziel sei, dass die .NET-Core-Runtime der Mobius-Runtime nur gelegentlich Services liefert, überwiegend durch das Aufrufen von "JITted Code" in der Anwendung – gemeint ist damit Code, der im Just-in-Time-Verfahren kompiliert wurde.

Schichtenmodell einer auf Mobius laufenden .NET-Anwendung mit zugrundeliegender .NET Core Runtime

(Bild: Konrad Kokosa)

Mobius soll für Forschung und Experimente dienen. Wäre der Runtime-Code in C# und .NET geschrieben, könnten Entwickler laut Kokosa einfacher Änderungen an JIT-Compiler und Garbage Collector (GC) vornehmen. Sogar ein experimentelles Schreiben der ganzen oder von Teilen der Runtime in einer Sprache wie F# sei denkbar, analog zum Konzept von Jikes RVM. Entwickler könnten daraus einiges lernen über die Struktur der Runtime und ihre Abhängigkeiten und zugleich sei es ein reizvolles Szenario, um die ganze Bandbreite von C#s Fähigkeiten auszuschöpfen mit niederschwelligen APIs (wie Span, stackallock, Unsafe class).

Unterwegs dürften Entwickler Issues in .NET Core finden. In Kokosas Vorstellung sollte die Performance deutlich zulegen, da der native Code, den der JIT-Compiler erzeugt, besser sei. Hier gehen die Meinungen auseinander: Erstmal ist es eine theoretische Annahme, dass die Managed Runtime, die auf einer anderen Managed Runtime läuft, robustere Entwicklung hervorbringt. Für den Garbage Collector gilt (theoretisch) dasselbe. Kokosas Motivation scheint vor allem Spaß am Experiment zu sein, bei ungewissem Ausgang. So beschreibt er Mobius als zwangloses Bastelprojekt.

Mobius soll weiterhin den Zwischencode (Intermediate Language / IL) der Anwendung mit dem JIT-Compiler zu nativem Code kompilieren. Auf diese Weise sollen Anwendungen auf Mobius mit ungefähr derselben Geschwindigkeit laufen wie ihr nativer Code erlaubt. Der Unterschied liege einzig in der Infrastruktur, deren Bestandteile wie GC, Typensystem und JIT-Compiler gelegentlich vom "ge-JIT-teten" Code aufgerufen würden, der Code läuft dann als Managed Code.

Beide Runtimes übereinander mit den gedoppelten Elementen, Veranschaulichung des Verhältnisses von nativem Code zu "JITted" Code und "JITted" App Code

(Bild: Konrad Kokosa)

Auf der Runtime laufen dann zwei Schichten, eine aus JIT-kompiliertem Code und eine aus nativem Code. Dadurch, dass Mobius frei von Allocations geschrieben sei, gebe es kaum Aufrufe des Garbage Collectors. Einmal warmgelaufen seien selbst JIT-Compiler-Aufrufe selten. In einer regulär funktionierenden Anwendung sollten dann die meisten Prozesse vom JIT-kompilierten Code ausgeführt werden, mit gelegentlichen Aufrufen des JIT-Compilers und sehr seltenen Aufrufen von nativem .NET Core. Da die zwei Codeschichten einige Managed Facilities doppelt haben, könnten Entwickler auch einige geteilte Managed Facilities für beide in Erwägung ziehen.

Geteilte Facilities beider Runtimes: Mobius könnte den Garbage Collector der .NET Core Runtime mitverwenden und deren Typensystem

(Bild: Konrad Kokosa)

Die größte Herausforderung ist und bleibt wohl das Neuschreiben des gesamten Typensystems, was Kokosa als "not such a big fun" beschreibt. Möglicherweise gibt es auch hier ein paar Abkürzungen, so könnte der bestehende Garbage Collector in Mobius recycelt werden. Allerdings wäre dann auch der Forschungscharakter des Projekts reduziert.

Bedeutungsperspektive: Mobius Runtime soll die Hauptlast der Prozesse tragen und benötigt nur gelegentliche Aufrufe von JIT und GC aus der .NET Core Runtime, der Code wird überwiegend als "JITted Code" zur Verfügung gestellt.

(Bild: Konrad Kokosa)

Für die Zukunft plant der .NET-Entwickler, den Code als Open Source zur Verfügung zu stellen. Derzeit arbeite er noch am vertikalen "Proof-of-Concept". Alle erforderlichen Mechanismen seien bereits unter Dach und Fach. Details zu Projekt Mobius stehen im Blogeintrag. Auf GitHub gibt es eine laufende Diskussion über die Portierbarkeit des JIT-Compilers und des Garbage Collector nach C#. (sih)