This morning Google Reader brought up this
blog post about a technique used internally by the MS CLR
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.