You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During the 2019 Microsoft Hack Week I decided to marry my two favorite VMs: The Mono Runtime and the GraalVM.
Graal is a JIT for the JVM written in Java. This is awesome for itself, but on top of it a whole language framework called Truffle was built. It allows runtime hackers to bring their language to the JVM in a novel way and benefit from high performance. Check it out: https://www.graalvm.org/
The Mono Runtime has a long history on being flexible for all sort of use cases. The latest achievement is that it can run .NET code in the browser via WebAssembly.
Where is the opportunity for marriage here, you may ask?
The Sulong project implements a Truffle front-end for LLVM bitcode, so you can execute bitcode via Graal.
The Mono Runtime can emit LLVM bitcode with its AOT compiler.
Obviously someone has to try running Mono generated bitcode on Sulong!
Tl;dr: Sulong doesn't implement pthreads yet, but Mono heavily relies on it. I took a short-cut then and used Mono's interpreter, and got the simplest C# program running with that: return an exit code. And it only needs 8 seconds to do that 😄
As you have seen above, Sulong executes LLVM bitcode. In order to get a usable binary out of the Mono build system we can use wllvm, as explained here.
So what was done in this sulong-mods branch? Mainly two things:
Stub out all calls to pthreads, as it isn't supported by Sulong. That's quite a bummer, because Mono depends heavily on it. Among other things, it means that we won't have a GC for now and can't use thread local storage. The good news: I was told someone is working on pthread support at this very moment!
I sort of lie to autoconf and make it believe to target linux/amd64, and thus I hacked-up a lot of places that are target specific. Specifically, I removed all possible places that emit inline assembly, because Sulong trips over that. In hindsight I should have added another target to Mono, similar to what we did for WebAssembly which has similar constraints.
We can already run the binary generated via wllvm and extract-bc with Sulong:
Since the sulong-mods branch is messed up regarding building the base class library (BCL), I recommend to build it in a different checkout:
$ cd ..
$ # 2019-06 is the latest release branch
$ git clone [email protected]:mono/mono.git -b 2019-06
$ cd 2019-06
$ make -C sdks/builds package-desktop-bcl -j
$ # build result lives in ./sdks/out/desktop-bcl/net_4_x
$ cd ../sulong-mods # let's go back to the other repo checkout
Run stuff!
The lack of pthread is actually a showstopper. That's why I took a short-cut from now on and instead of using Mono's AOT compiler to generate LLVM bitcode for .NET methods as originally intended, I use Mono's interpreter instead.
Let's try the simplest C# program ever:
using System;publicclassHackweek{publicstaticintMain(string[]args){return22;}}
$ export MONO_PATH=../mono-2019-06/sdks/out/desktop-bcl/net_4_x
$ time lli ./mono/mini/mono-sgen.bc --interp exit22.exe;echo$?lli --interp 12.50s user 1.06s system 160% cpu 8.428 total22
It only takes whooping eight seconds! In all fairness, startup performance isn't exactly the strong suite of this whole setup.
Running the same program with --engine.TraceCompilation=true yields some interesting insights on what the dynamic compilation aspect of Sulong/Graal means: https://gist.github.com/lewurm/535ab580c3587aa62e3bc476d44b0728
A Mono Runtime hacker might spot one or other hot function in the runtime 😄
Anything more advanced crashes, I submitted two issues
But as I said, without pthread support it isn't worth pushing further.
Debugging hints
lli --inspect allows you to use the Chrome Inspector to debug your bitcode binary. For me this was really only useful in combination with --llvm.lazyParsing=false, so I can properly set breakpoints. Unfortunately that means the whole bitcode binary must contain valid bitcode; that was a bit annoying because I had to remove inline assembly all over the place first.
Another useful flag is --llvm.printStackTraceOnAbort. It does what it says, and I personally think it should be enabled by default.
I'm fascinated by how mature Sulong has become and knowing that an amazing set of people is working on it, I see a bright future for it. Maybe next year's Hack Week I can actually run a real C# programs 🙂
Thanks to Ahmed Shosha and Loïc Sharma to accompany me through the Hack Week! Kudos to the Graal team and specifically thanks to @zapster for answering all my questions about Sulong ❤️
The text was updated successfully, but these errors were encountered:
During the 2019 Microsoft Hack Week I decided to marry my two favorite VMs: The Mono Runtime and the GraalVM.
Graal is a JIT for the JVM written in Java. This is awesome for itself, but on top of it a whole language framework called Truffle was built. It allows runtime hackers to bring their language to the JVM in a novel way and benefit from high performance. Check it out: https://www.graalvm.org/
The Mono Runtime has a long history on being flexible for all sort of use cases. The latest achievement is that it can run .NET code in the browser via WebAssembly.
Where is the opportunity for marriage here, you may ask?
Obviously someone has to try running Mono generated bitcode on Sulong!
Tl;dr: Sulong doesn't implement
pthreads
yet, but Mono heavily relies on it. I took a short-cut then and used Mono's interpreter, and got the simplest C# program running with that: return an exit code. And it only needs 8 seconds to do that 😄Instructions tested on Ubuntu 18.04.
Download GraalVM
The Community Edition (CE) should be enough for our purposes: https://github.com/oracle/graal/releases/tag/vm-19.1.1
Nice.
Build a Mono Runtime that runs on Sulong
As you have seen above, Sulong executes LLVM bitcode. In order to get a usable binary out of the Mono build system we can use
wllvm
, as explained here.So what was done in this
sulong-mods
branch? Mainly two things:pthreads
, as it isn't supported by Sulong. That's quite a bummer, because Mono depends heavily on it. Among other things, it means that we won't have a GC for now and can't use thread local storage. The good news: I was told someone is working onpthread
support at this very moment!autoconf
and make it believe to targetlinux/amd64
, and thus I hacked-up a lot of places that are target specific. Specifically, I removed all possible places that emit inline assembly, because Sulong trips over that. In hindsight I should have added another target to Mono, similar to what we did for WebAssembly which has similar constraints.We can already run the binary generated via
wllvm
andextract-bc
with Sulong:Woot!
Build the BCL
Since the
sulong-mods
branch is messed up regarding building the base class library (BCL), I recommend to build it in a different checkout:Run stuff!
The lack of
pthread
is actually a showstopper. That's why I took a short-cut from now on and instead of using Mono's AOT compiler to generate LLVM bitcode for .NET methods as originally intended, I use Mono's interpreter instead.Let's try the simplest C# program ever:
It only takes whooping eight seconds! In all fairness, startup performance isn't exactly the strong suite of this whole setup.
Running the same program with
--engine.TraceCompilation=true
yields some interesting insights on what the dynamic compilation aspect of Sulong/Graal means: https://gist.github.com/lewurm/535ab580c3587aa62e3bc476d44b0728A Mono Runtime hacker might spot one or other hot function in the runtime 😄
Anything more advanced crashes, I submitted two issues
But as I said, without
pthread
support it isn't worth pushing further.Debugging hints
lli --inspect
allows you to use the Chrome Inspector to debug your bitcode binary. For me this was really only useful in combination with--llvm.lazyParsing=false
, so I can properly set breakpoints. Unfortunately that means the whole bitcode binary must contain valid bitcode; that was a bit annoying because I had to remove inline assembly all over the place first.Another useful flag is
--llvm.printStackTraceOnAbort
. It does what it says, and I personally think it should be enabled by default.More information here:
Conclusion
I'm fascinated by how mature Sulong has become and knowing that an amazing set of people is working on it, I see a bright future for it. Maybe next year's Hack Week I can actually run a real C# programs 🙂
Thanks to Ahmed Shosha and Loïc Sharma to accompany me through the Hack Week! Kudos to the Graal team and specifically thanks to @zapster for answering all my questions about Sulong ❤️
The text was updated successfully, but these errors were encountered: