This morning Google Reader brought up this
blog post about a technique used internally by the MS CLR
version 4.0.
It is basically a way to share complex code between
different architectures, thus reducing the maintenance
burden and allowing better compatibility in the tricky area
of marshalling (when the runtime goes from managed code to
unmanaged code it needs to perform many operations,
including massaging the data exchanged between the two
worlds).
At the beginning Mono had specialized x86 chunks of code to
do the work, but we soon realized the problems with that.
At the time I proposed to use a small, specialized bytecode
set (after all the operations involved are very few), which
would have been great for the interpreter I was working on.
Dietmar instead pushed for the use of IL bytecode: this
would have been a slower solution for the interpreter, but
it would allow access to a wider set of operations and it
would reduce the burden on the JIT backend, which, after
all, already had an IL frontend.
We went for the IL solution (the time frame was the
beginning of 2002) and we're glad to see that MS choose to
adopt the same technique a few years later.
There are two important considerations about this story in
the context of Mono development
- we started to always choose techniques that would favour the JIT against the interpreter, both in the case of speed and maintenance burden. This was a path that eventually lead to the discontinuation of the interpreter.
- we built a codebase that is easily portable across architectures, to the point that we consider a JIT port only slightly more complicated than an interpreter port (because of the many features of Mono/CLR even an interpreter needs quite a bit of very low-level knowledge about how an architecture works)
As an extension, we later used the same IL-based technique
to implement many other runtime helper methods that would
otherwise have been to be written in low-level
architecture-specific code: remoting helpers, garbage
collection fast paths, delegate runtime methods etc.
For the curious, most of this code is in
metadata/marshal.c
in the Mono source code.
