Skip to content

Instantly share code, notes, and snippets.

@cotto
Created June 13, 2011 05:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cotto/1022340 to your computer and use it in GitHub Desktop.
Save cotto/1022340 to your computer and use it in GitHub Desktop.
m0 glossy
M0 Glossy Brochure
M0 is being presented as a significant component of Parrot's future, but
because it's still under active development it can be hard to find an
authoritative source of information about what it is and why it's relevant.
The purpose of this document is to provide anyone who has a basic background
with Parrot a quick and concise idea of what M0 is without needing to read the
full specification.
What is M0?
M0 is an aggressively minimalist process virtual machine. The "M" in "M0"
stands alternately for "magic" and "microcode". This means that it's a
low-level microcode-like instruction set and that it's at magic level 0, i.e.
as simple and straightforward as possible. M0 has three primary design
objectives. The first is that it provide primitives that can be used to
provide the same capabilities as C and PIR. The second objective is that it be
straightforward to analyze and manipulate. The third objective is that is that
it be capable of interacting with existing C code and C libraries. We're
designing M0 to allow a variety of implementations in both high-level languages
like Perl or JavaScript and low-level languages like C or Java. It is being
written simultaneously as a detailed specification [LINK] and as an
interpreter, assembler and test suite [LINK] in Perl 5.
Like Parrot, M0 is a register machine and uses continuation-passing style (CPS)
for contol flow. This means that there is no M0 stack and that we perform
complex control flow by saving and restoring the state of a call frame. M0 is
based on chunks and call frames. M0's chunks are roughly analogous to
subroutines and call frames encapsulate the state of a single thread of
execution. M0 call frames are used as the continuation for CPS. All global
program state such as op functions, the chunk registry and a list of running
call frames, is stored in a global interpreter structure. The precise layout
of these data structures is specified in detail in the M0 design document
[LINK].
Is there an M1, M2, etc?
M0 refers to a specific VM because it's at the lowest level. "M1" refers to
any tool built diretly on M0, e.g. PIR, and as such refers to a family of tools
rather than a specific technology. "M2", "M3", etc refer to tools that are
increasingly abstracted away from M0 and increasingly magical. Rakudo sits at
M4 or so. M7 is Skynet.
Why are we building M0?
As we've profiled Parrot looking for performance improvements, we've found that
some significant bottlenecks are due to deep design issues that can't easily be
coded around. For example, we incur a penalty every time we do significant
work while moving between C and PIR code. One of our developers has documented
[http://whiteknight.github.com/2011/05/10/timings_vtable_overrides.html] an
example of this, but there are many. We are designing M0 so that it can
replace the C components of Parrot and so that PIR can be translated directly
into M0 ops. The result is removing the impedance mismatch between PIR and C,
allowing Parrot to be much more efficient.
Isn't this just another example of NIH? Why not use an existing VM?
During the exploratory phase, we decided on a set of criteria for M0 and looked
for existing, mature projects that met those criteria. (TODO: list some
criteria here, add a link to the rest). We looked at any projects we could
find, but none of them did what we needed. Although it would be preferable to
use a well-tested existing solution, lacking such a solution, we set out to
build our own.
Does moving to M0 mean that effort to improve Parrot's C code is wasted?
Effort that goes into improving our existing C code is well spent.
Improvements to C code have an immediate result for today's Parrot. It is
likely to be several months before M0 is integrated into Parrot and the
transition of existing C code to M0 will take a long time after that. We won't
be throwing out our C code and reimplementing subsystems in M0 from scratch.
We'll use our current C code as a template and will be careful to preserve the
semantics and optimizations of the C code as much as possible during the
transition. M0 will present us with new optimization possibilities, but we
will not be throwing out the work that's gone into our current code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment