I have a confession to make. It’s not the easiest one and it took me more than a month to get myself together for it.
I am madly in love with an oyster!
No wait, that’s not it.
I am madly in love with nonsense.
Yeah, that’s what I wanted to say. If you ever met me in person then you probably know that I have an unhealthy tendency to say random things that pop into my head. Interestingly enough I like to do the same when I talk to the Machine: I like to wildly crank out random nonsensical code as if I were a quantum superposition of infinitely many monkeys equipped with keyboards and tasked with producing Shakespeare’s sonnets hidden in C++ metaprograms.
Why am I saying all this? Well… “What was your talk about?” This probably is the most common question I am getting about my JSConf EU 2012 talk. And the truth is…
I ain’t got no freaking idea!
No, seriously. What was this all about?
I really do believe that self hosting big portions of the VM improves its maintainability, extensibility, portability and even performance characteristics.
During my time on the V8 team I had to investigate quite a number of performance issues in the real world code and my inability to interactively observe what V8 is doing under the hood was always causing certain pain and frustration. And this is given my knowledge of V8’s implementation and all kinds of tracing flags that cause V8 to dump a lot of information about its decisions.
Those flags, while very helpful, exist in separation. There is no unifying “dashboard”. Debugging output requires manual cross-referencing, which is kinda 1699-ish. This output is all about the past (it states what happened) but it does not tell you what is the state of things here and now. It is not interactive.
I wanted everybody to feel that vacuum and antiquity of existing tools and that’s about it for the first part of my talk.
I have this crazy idea that if you need to understand something you need to do it yourself.
Want understand how JIT compiler works? Don’t just read stuff on the net. Not even sources are enough! Take your laptop, cup of chamomile tea and implement one. Or at least take some and hack its socks off.
The idea here is to have some fun and learn at the same time. Playing is the only way of learning when we are kids. I don’t see why we should abandon it when we are becoming older… Just replace colorful alphabet cubes with assembly instructions. Those are equally fun.
All these ideas combined lead to a couple of small projects that I’ve decided to open source.
mö.js — source code
That is why I choose to implement largely LuaJIT2 inspired tracing compiler instead of a classical method based JIT like V8. Because I have never done a tracing compiler before I just wanted to have some fun implementing one.
On the other side you can also see that mö.js also contains IC code that I have written for an older blog post of mine. I hope that mö.js will continue to grow as I am traveling in through the world of VMs and play with different approaches.
node-llvm — source code
Quite some time ago I played a bit with an idea of hosting a statically typed language with a LLVM based compiler inside node.js.
I never actually finished implementing the language but I produced somewhat working LLVM bindings for node.js. These bindings came in handy when I decided to generate a bit of native code by mö.js’s tracing compiler.
All gory details I decided to hide in a small module called Meldo that actually does the evil job of messing with V8 heap directly and not through the standard V8 API. My hope was that it can eventually become a well documented module that other people can employ when they are either curious or just trying to win some milliseconds through the use of the Dark Side of the Force. This hope did not materialize yet, because I never got enough time to clean things up and thoroughly document it. So I am releasing it as is like a proof of concept.
Another issue here is that I can’t publish
node-llvm in the
npm yet because it depends on a custom binding generator kharon which in turn depends on libclang bindings that are API incompatible with
libclang package available on
npm. Basically it is Issue 1 that I discovered during open sourcing today :-)
Thus unfortunately for now the only way to try
node-llvm is to clone git repository and install it piece by piece manually.
git clone https://code.google.com/p/node-llvm/ npm install $node-llvm-dir/kharon/node-libclang npm install $node-llvm-dir/ npm install $node-llvm-dir/examples/meldo
[Obviously one also needs to checkout and build LLVM and Clang as described in their wiki]