[pypy-commit] extradoc extradoc: merge

fijal noreply at buildbot.pypy.org
Fri Aug 3 13:16:40 CEST 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: extradoc
Changeset: r4410:2129e8c0017e
Date: 2012-08-03 13:16 +0200
http://bitbucket.org/pypy/extradoc/changeset/2129e8c0017e/

Log:	merge

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -1,6 +1,8 @@
 syntax: glob
 *.py[co]
 *~
+*.swp
+*.orig
 talk/ep2012/stackless/slp-talk.aux
 talk/ep2012/stackless/slp-talk.latex
 talk/ep2012/stackless/slp-talk.log
@@ -8,4 +10,5 @@
 talk/ep2012/stackless/slp-talk.out
 talk/ep2012/stackless/slp-talk.snm
 talk/ep2012/stackless/slp-talk.toc
-talk/ep2012/stackless/slp-talk.vrb
\ No newline at end of file
+talk/ep2012/stackless/slp-talk.vrb
+talk/vmil2012/paper_env/
diff --git a/blog/draft/cffi-release-0.2.rst b/blog/draft/cffi-release-0.2.rst
new file mode 100644
--- /dev/null
+++ b/blog/draft/cffi-release-0.2.rst
@@ -0,0 +1,47 @@
+CFFI release 0.2
+================
+
+Hi everybody,
+
+We released `CFFI 0.2`_ (now as a full release candidate).  CFFI is a
+way to call C from Python.
+
+This release is only for CPython 2.6 or 2.7.  PyPy support is coming in
+the ``ffi-backend`` branch, but not finished yet.  CPython 3.x would be
+easy but requires the help of someone.
+
+The package is available `on bitbucket`_ as well as `documented`_. You
+can also install it straight from the python package index (pip).
+
+.. _`on bitbucket`: https://bitbucket.org/cffi/cffi
+.. _`CFFI 0.2`: http://cffi.readthedocs.org
+.. _`documented`: http://cffi.readthedocs.org
+
+* Contains numerous small changes and support for more C-isms.
+
+* The biggest news is the support for `installing packages`__ that use
+  ``ffi.verify()`` on machines without a C compiler.  Arguably, this
+  lifts the last serious restriction for people to use CFFI.
+
+* Partial list of smaller changes:
+  
+  - mappings between 'wchar_t' and Python unicodes
+  
+  - the introduction of ffi.NULL
+  
+  - a possibly clearer API for ``ffi.new()``: e.g. ``ffi.new("int *")``
+    instead of ``ffi.new("int")``
+    
+  - and of course a plethora of smaller bug fixes
+
+* CFFI uses ``pkg-config`` to install itself if available.  This helps
+  locate ``libffi`` on modern Linuxes.  Mac OS/X support is available too
+  (see the detailed `installation instructions`__).  Win32 should work out
+  of the box.  Win64 has not been really tested yet.
+
+.. __: http://cffi.readthedocs.org/en/latest/index.html#distributing-modules-using-cffi
+.. __: http://cffi.readthedocs.org/en/latest/index.html#macos-10-6
+
+
+Cheers,
+Armin Rigo and Maciej Fija&#322;kowski
diff --git a/blog/draft/py3k-status-update-5.rst b/blog/draft/py3k-status-update-5.rst
new file mode 100644
--- /dev/null
+++ b/blog/draft/py3k-status-update-5.rst
@@ -0,0 +1,46 @@
+Py3k status update #5
+---------------------
+
+This is the fifth status update about our work on the `py3k branch`_, which we
+can work on thanks to all of the people who donated_ to the `py3k proposal`_.
+
+Apart from the usual "fix shallow py3k-related bugs" part, most of my work in
+this iteration has been to fix the bootstrap logic of the interpreter, in
+particular to setup the initial ``sys.path``.
+
+Until few weeks ago, the logic to determine ``sys.path`` was written entirely
+at app-level in ``pypy/translator/goal/app_main.py``, which is automatically
+included inside the executable during translation.  The algorithm is more or
+less like this:
+
+  1. find the absolute path of the executable by looking at ``sys.argv[0]``
+     and cycling through all the directories in ``PATH``
+
+  2. starting from there, go up in the directory hierarchy until we find a
+     directory which contains ``lib-python`` and ``lib_pypy``
+
+This works fine for Python 2 where the paths and filenames are represented as
+8-bit strings, but it is a problem for Python 3 where we want to use unicode
+instead.  In particular, whenever we try to encode a 8-bit string into an
+unicode, PyPy asks the ``_codecs`` built-in module to find the suitable
+codec. Then, ``_codecs`` tries to import the ``encodings`` package, to list
+all the available encodings. ``encodings`` is a package of the standard
+library written in pure Python, so it is located inside
+``lib-python/3.2``. But at this point in time we yet have to add
+``lib-python/3.2`` to ``sys.path``, so the import fails.  Bootstrap problem!
+
+The hard part was to find the problem: since it is an error which happens so
+early, the interpreter is not even able to display a traceback, because it
+cannot yet import ``traceback.py``. The only way to debug it was through some
+carefully placed ``print`` statement and the help of ``gdb``. Once found the
+problem, the solution was as easy as moving part of the logic to RPython,
+where we don't have bootstrap problems.
+
+Once the problem was fixed, I was able to finally run all the CPython test
+against the compiled PyPy.  As expected there are lots of failures, and fixing
+them will be the topic of my next months.
+
+
+.. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html
+.. _`py3k proposal`: http://pypy.org/py3donate.html
+.. _`py3k branch`: https://bitbucket.org/pypy/pypy/src/py3k
diff --git a/blog/draft/stm-jul2012.rst b/blog/draft/stm-jul2012.rst
new file mode 100644
--- /dev/null
+++ b/blog/draft/stm-jul2012.rst
@@ -0,0 +1,194 @@
+Multicore programming in Python
+===============================
+
+Hi all,
+
+This is a short "position paper" kind of post about my view (Armin
+Rigo's) on the future of multicore programming.  It is a summary of the
+keynote presentation at EuroPython.  As I learned by talking with people
+afterwards, I am not a good enough speaker to manage to convey a deeper
+message in a 20-minutes talk.  I will try instead to convey it in a
+150-lines post...
+
+This is fundamentally about three points, which can be summarized as
+follow:
+
+1. We often hear about people wanting a version of Python running without
+   the Global Interpreter Lock (GIL): a "GIL-less Python".  But what we
+   programmers really need is not just a GIL-less Python --- we need a
+   higher-level way to write multithreaded programs than using directly
+   threads and locks.  One way is Automatic Mutual Exclusion (AME), which
+   would give us an "AME Python".
+
+2. A good enough Software Transactional Memory (STM) system can do that.
+   This is what we are building into PyPy: an "AME PyPy".
+
+3. The picture is darker for CPython, though there is a way too.  The
+   problem is that when we say STM, we think about either GCC 4.7's STM
+   support, or Hardware Transactional Memory (HTM).  However, both
+   solutions are enough for a "GIL-less CPython", but not
+   for "AME CPython", due to capacity limitations.  For the latter, we
+   need somehow to add some large-scale STM into the compiler.
+
+Let me explain these points in more details.
+
+
+GIL-less versus AME
+-------------------
+
+The first point is in favor of the so-called Automatic Mutual Exclusion
+approach.  The issue with using threads (in any language with or without
+a GIL) is that threads are fundamentally non-deterministic.  In other
+words, the programs' behaviors are not reproductible at all, and worse,
+we cannot even reason about it --- it becomes quickly messy.  We would
+have to consider all possible combinations of code paths and timings,
+and we cannot hope to write tests that cover all combinations.  This
+fact is often documented as one of the main blockers towards writing
+successful multithreaded applications.
+
+We need to solve this issue with a higher-level solution.  Such
+solutions exist theoretically, and Automatic Mutual Exclusion (AME) is
+one of them.  The idea of AME is that we divide the execution of each
+thread into a number of "blocks".  Each block is well-delimited and
+typically large.  Each block runs atomically, as if it acquired a GIL
+for its whole duration.  The trick is that internally we use
+Transactional Memory, which is a a technique that lets the interpreter
+run the blocks from each thread in parallel, while giving the programmer
+the illusion that the blocks have been run in some global serialized
+order.
+
+This doesn't magically solve all possible issues, but it helps a lot: it
+is far easier to reason in terms of a random ordering of large blocks
+than in terms of a random ordering of individual instructions.  For
+example, a program might contain a loop over all keys of a dictionary,
+performing some "mostly-independent" work on each value.  By using the
+technique described here, putting each piece of work in one "block"
+running in one thread of a pool, we get exactly the same effect: the
+pieces of work still appear to run in some global serialized order, in
+some random order (as it is anyway when iterating over the keys of a
+dictionary).  There are even techniques building on top of AME that can
+be used to force the order of the blocks, if needed.
+
+
+PyPy and STM
+------------
+
+Talking more precisely about PyPy: the current prototype ``pypy-stm`` is
+doing precisely this.  The length of the "blocks" above is selected in
+one of two ways: either we have blocks corresponding to some small
+number of bytecodes (in which case we have merely a GIL-less Python); or
+we have blocks that are specified explicitly by the programmer using
+``with thread.atomic:``.  The latter gives typically long-running
+blocks.  It allows us to build the higher-level solution sought after:
+it will run most of our Python code in multiple threads but always
+within a ``thread.atomic`` block, e.g. using a pool of threads.
+
+This gives the nice illusion of a global serialized order, and thus
+gives us a well-behaving model of our program's behavior.  The drawback
+is that we will usually have to detect and locate places that cause too
+many "conflicts" in the Transactional Memory sense.  A conflict causes
+the execution of one block of code to be aborted and restarted.
+Although the process is transparent, if it occurs more than
+occasionally, then it has a negative impact on performance.  We will
+need better tools to deal with them.
+
+The point here is that at any stage of this "improvement" process our
+program is *correct*, while it may not be yet as efficient as it could
+be.  This is the opposite of regular multithreading, where programs are
+efficient but not as correct as they could be.  In other words, as we
+all know, we only have resources to do the easy 80% of the work and not
+the remaining hard 20%.  So in this model you get a program that has 80%
+of the theoretical maximum of performance and it's fine.  In the regular
+multithreading model we would instead only manage to remove 80% of the
+bugs, and we are left with obscure rare crashes.
+
+
+CPython and HTM
+---------------
+
+Couldn't we do the same for CPython?  The problem here is that, at
+first, it seems we would need to change literally all places of the
+CPython C sources in order to implement STM.  Assuming that this is far
+too big for anyone to handle, we are left with three other options:
+
+- We could use GCC 4.7, which supports some form of STM.
+
+- We wait until Intel's next generation of CPUs comes out ("Haswell")
+  and use HTM.
+
+- We could write our own C code transformation (e.g. within a compiler
+  like LLVM).
+
+The issue with the first two solutions is the same one: they are meant
+to support small-scale transactions, but not long-running ones.  For
+example, I have no clue how to give GCC rules about performing I/O in a
+transaction --- this seems not supported at all; and moreover looking at
+the STM library that is available so far to be linked with the compiled
+program, it assumes short transactions only.
+
+Intel's HTM solution is both more flexible and more strictly limited.
+In one word, the transaction boundaries are given by a pair of special
+CPU instructions that make the CPU enter or leave "transactional" mode.
+If the transaction aborts, the CPU cancels any change, rolls back to the
+"enter" instruction and causes this instruction to return an error code
+instead of re-entering transactional mode (a bit like a ``fork()``).
+The software then detects the error code; typically, if only a few
+transactions end up being too long, it is fine to fall back to a
+GIL-like solution just to do these transactions.
+
+About the implementation: this is done by recording all the changes that
+a transaction wants to do to the main memory, and keeping them invisible
+to other CPUs.  This is "easily" achieved by keeping them inside this
+CPU's local cache; rolling back is then just a matter of discarding a
+part of this cache without committing it to memory.  From this point of
+view, there is a lot to bet that we are actually talking about the
+regular per-core Level 1 cache --- so any transaction that cannot fully
+store its read and written data in the 32-64KB of the L1 cache will
+abort.
+
+So what does it mean?  A Python interpreter overflows the L1 cache of
+the CPU very quickly: just creating new Python function frames takes a
+lot of memory (on the order of magnitude of 1/100 of the whole L1
+cache).  This means that as long as the HTM support is limited to L1
+caches, it is not going to be enough to run an "AME Python" with any
+sort of medium-to-long transaction (running for 0.01 second or longer).
+It can run a "GIL-less Python", though: just running a few dozen
+bytecodes at a time should fit in the L1 cache, for most bytecodes.
+
+
+Write your own STM for C
+------------------------
+
+Let's discuss now the third option: if neither GCC 4.7 nor HTM are
+sufficient for an "AME CPython", then this third choice would be to
+write our own C compiler patch (as either extra work on GCC 4.7, or an
+extra pass to LLVM, for example).
+
+We would have to deal with the fact that we get low-level information,
+and somehow need to preserve interesting high-level bits through the
+compiler up to the point at which our pass runs: for example, whether
+the field we read is immutable or not.  (This is important because some
+common objects are immutable, e.g. PyIntObject.  Immutable reads don't
+need to be recorded, whereas reads of mutable data must be protected
+against other threads modifying them.)  We can also have custom code to
+handle the reference counters: e.g. not consider it a conflict if
+multiple transactions have changed the same reference counter, but just
+resolve it automatically at commit time.  We are also free to handle I/O
+in the way we want.
+
+More generally, the advantage of this approach over the current GCC 4.7
+is that we control the whole process.  While this still looks like a lot
+of work, it looks doable.
+
+
+Conclusion?
+-----------
+
+I would assume that a programming model specific to PyPy and not
+applicable to CPython has little chances to catch on, as long as PyPy is
+not the main Python interpreter (which looks unlikely to change anytime
+soon).  Thus as long as only PyPy has STM, it looks like it will not
+become the main model of multicore usage in Python.  However, I can
+conclude with a more positive note than during EuroPython: there appears
+to be a more-or-less reasonable way forward to have an STM version of
+CPython too.
diff --git a/talk/dls2012/licm.pdf b/talk/dls2012/licm.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..dd7d2286dbdb2201e2f9e266c9279ce9a9ba2a0d
GIT binary patch

[cut]

diff --git a/talk/dls2012/paper.tex b/talk/dls2012/paper.tex
--- a/talk/dls2012/paper.tex
+++ b/talk/dls2012/paper.tex
@@ -124,6 +124,8 @@
 One of the nice properties of a tracing JIT is that many of its optimization
 are simple requiring one forward pass only. This is not true for loop-invariant code
 motion which is a very important optimization for code with tight kernels.
+Especially for dynamic languages that typically performs quite a lot of loop invariant
+type checking, boxed value unwrapping and virtual method lookups.
 In this paper we present a scheme for making simple optimizations loop-aware by
 using a simple pre-processing step on the trace and not changing the
 optimizations themselves. The scheme can give performance improvements of a
@@ -141,13 +143,15 @@
 
 \section{Introduction}
 
-A dynamically typed language needs to do a lot of type
-checking and unwrapping. For tight computationally intensive loops a
+A dynamic language typically needs to do quite a lot of type
+checking, wrapping/unwrapping of boxed values, and virtual method dispatching. 
+For tight computationally intensive loops a
 significant amount of the execution time might be spend on such tasks
-instead of the actual calculations. Moreover, the type checking and
-unwrapping is often loop invariant and performance could be increased
-by moving those operations out of the loop. We propose to design a
-loop-aware tracing JIT to perform such optimization at run time.
+instead of the actual computations. Moreover, the type checking,
+unwrapping and method lookups are often loop invariant and performance could be increased
+by moving those operations out of the loop. We propose a simple scheme
+to make a tracing JIT loop-aware by allowing it's existing optimizations to
+perform loop invariant code motion. 
 
 One of the advantages that tracing JIT compilers have above traditional
 method-based
@@ -533,7 +537,7 @@
 
 Each operation in the trace is copied in order.
 To copy an operation $v=\text{op}\left(A_1, A_2, \cdots, A_{|A|}\right)$
-a new variable, $\hat v$ is introduced. The copied operation will
+a new variable, $\hat v$, is introduced. The copied operation will
 return $\hat v$ using
 \begin{equation}
   \hat v = \text{op}\left(m\left(A_1\right), m\left(A_2\right), 
@@ -696,12 +700,12 @@
 By constructing a vector, $H$,  of such variables, the input and jump
 arguments can be updated using
 \begin{equation}
-  \hat J = \left(J_1, J_2, \cdots, J_{|J|}, H_1, H_2, \cdots, H_{|H}\right)
+  \hat J = \left(J_1, J_2, \cdots, J_{|J|}, H_1, H_2, \cdots, H_{|H|}\right)
   \label{eq:heap-inputargs}
 \end{equation}
 and
 \begin{equation}
-  \hat K = \left(K_1, K_2, \cdots, K_{|J|}, m(H_1), m(H_2), \cdots, m(H_{|H})\right)
+  \hat K = \left(K_1, K_2, \cdots, K_{|J|}, m(H_1), m(H_2), \cdots, m(H_{|H|})\right)
   .
   \label{eq:heap-jumpargs}
 \end{equation}
@@ -772,7 +776,7 @@
   .
 \end{equation}
 The arguments of the \lstinline{jump} operation of the peeled loop,
-$K$, is constructed by inlining $\hat J$,
+$K$, is constructed from $\hat J$ using the map $m$,
 \begin{equation}
   \hat K = \left(m\left(\hat J_1\right), m\left(\hat J_1\right), 
                  \cdots, m\left(\hat J_{|\hat J|}\right)\right)
diff --git a/talk/ep2012/jit/talk/Makefile b/talk/ep2012/jit/talk/Makefile
--- a/talk/ep2012/jit/talk/Makefile
+++ b/talk/ep2012/jit/talk/Makefile
@@ -3,7 +3,7 @@
 # http://bitbucket.org/antocuni/env/src/619f486c4fad/bin/inkscapeslide.py
 
 
-talk.pdf: talk.rst author.latex title.latex stylesheet.latex diagrams/tracing-phases-p0.pdf diagrams/trace-p0.pdf diagrams/tracetree-p0.pdf
+talk.pdf: talk.rst author.latex title.latex stylesheet.latex diagrams/tracing-phases-p0.pdf diagrams/trace-p0.pdf diagrams/tracetree-p0.pdf diagrams/architecture-p0.pdf diagrams/pypytrace-p0.pdf
 	rst2beamer.py --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit
 	sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit
 	#sed 's/\\maketitle/\\input{title.latex}/' -i talk.latex || exit
@@ -24,3 +24,9 @@
 
 diagrams/tracetree-p0.pdf: diagrams/tracetree.svg
 	cd diagrams && inkscapeslide.py tracetree.svg
+
+diagrams/architecture-p0.pdf: diagrams/architecture.svg
+	cd diagrams && inkscapeslide.py architecture.svg
+
+diagrams/pypytrace-p0.pdf: diagrams/pypytrace.svg
+	cd diagrams && inkscapeslide.py pypytrace.svg
diff --git a/talk/ep2012/jit/talk/author.latex b/talk/ep2012/jit/talk/author.latex
--- a/talk/ep2012/jit/talk/author.latex
+++ b/talk/ep2012/jit/talk/author.latex
@@ -2,7 +2,7 @@
 
 \title[PyPy JIT under the hood]{PyPy JIT under the hood}
 \author[antocuni, arigo]
-{Antonio Cuni \\ Arming Rigo}
+{Antonio Cuni \\ Armin Rigo (guest star)}
 
 \institute{EuroPython 2012}
 \date{July 4 2012}
diff --git a/talk/ep2012/jit/talk/diagrams/architecture.svg b/talk/ep2012/jit/talk/diagrams/architecture.svg
new file mode 100644
--- /dev/null
+++ b/talk/ep2012/jit/talk/diagrams/architecture.svg
@@ -0,0 +1,700 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1685.75"
+   height="949.56055"
+   id="svg3076"
+   version="1.1"
+   inkscape:version="0.48.2 r9819"
+   sodipodi:docname="architecture.svg">
+  <defs
+     id="defs3078">
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend"
+       style="overflow:visible">
+      <path
+         id="path4380"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lend"
+       style="overflow:visible">
+      <path
+         id="path4374"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend"
+       style="overflow:visible">
+      <path
+         id="path4356"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3"
+       style="overflow:visible">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4380-3"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-4"
+       style="overflow:visible">
+      <path
+         id="path4380-1"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         id="path4380-15"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-8"
+       style="overflow:visible">
+      <path
+         id="path4380-34"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-22"
+       style="overflow:visible">
+      <path
+         id="path4380-2"
+         style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.35355339"
+     inkscape:cx="1138.0708"
+     inkscape:cy="300.08853"
+     inkscape:document-units="px"
+     inkscape:current-layer="g4325"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="748"
+     inkscape:window-x="0"
+     inkscape:window-y="1"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata3081">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     id="layer4"
+     inkscape:label="content"
+     transform="translate(48.09375,-13.439453)">
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="1877.4071"
+       y="21.292315"
+       id="text5315"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan5317"
+         x="1877.4071"
+         y="21.292315">rpython</tspan><tspan
+         sodipodi:role="line"
+         x="1877.4071"
+         y="71.292313"
+         id="tspan5319">+codewriter</tspan><tspan
+         sodipodi:role="line"
+         x="1877.4071"
+         y="121.29231"
+         id="tspan5321">+jitcode</tspan><tspan
+         sodipodi:role="line"
+         x="1877.4071"
+         y="171.29231"
+         id="tspan5710">+timeline</tspan><tspan
+         sodipodi:role="line"
+         x="1877.4071"
+         y="221.29231"
+         id="tspan5712">+metatracer</tspan><tspan
+         sodipodi:role="line"
+         x="1877.4071"
+         y="271.29233"
+         id="tspan5714">+optimizer</tspan><tspan
+         sodipodi:role="line"
+         x="1877.4071"
+         y="321.29233"
+         id="tspan5716">+backend</tspan><tspan
+         sodipodi:role="line"
+         x="1877.4071"
+         y="371.29233"
+         id="tspan5720">+jitted</tspan></text>
+  </g>
+  <g
+     inkscape:label="rpython"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(584.875,133.32532)">
+    <g
+       id="g5340"
+       transform="translate(0,56.011525)">
+      <g
+         id="g5323">
+        <g
+           id="g3908"
+           transform="translate(-622,-168.57143)">
+          <text
+             sodipodi:linespacing="125%"
+             id="text3084"
+             y="246.54382"
+             x="106.92159"
+             style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+             xml:space="preserve"><tspan
+               y="246.54382"
+               x="106.92159"
+               id="tspan3086"
+               sodipodi:role="line">def LOAD_GLOBAL(self):</tspan><tspan
+               id="tspan3088"
+               y="276.54382"
+               x="106.92159"
+               sodipodi:role="line">    ...</tspan></text>
+          <rect
+             y="206.6479"
+             x="85.714287"
+             height="91.428574"
+             width="354.28571"
+             id="rect3138"
+             style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" />
+        </g>
+        <g
+           transform="translate(-622,-49.999979)"
+           id="g3908-1">
+          <text
+             sodipodi:linespacing="125%"
+             id="text3084-9"
+             y="246.54382"
+             x="106.92159"
+             style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+             xml:space="preserve"><tspan
+               y="246.54382"
+               x="106.92159"
+               id="tspan3086-3"
+               sodipodi:role="line">def STORE_FAST(self):</tspan><tspan
+               id="tspan3088-8"
+               y="276.54382"
+               x="106.92159"
+               sodipodi:role="line">    ...</tspan></text>
+          <rect
+             y="206.6479"
+             x="85.714287"
+             height="91.428574"
+             width="354.28571"
+             id="rect3138-0"
+             style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" />
+        </g>
+        <g
+           transform="translate(-622,68.571421)"
+           id="g3908-16">
+          <text
+             sodipodi:linespacing="125%"
+             id="text3084-3"
+             y="246.54382"
+             x="106.92159"
+             style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+             xml:space="preserve"><tspan
+               y="246.54382"
+               x="106.92159"
+               id="tspan3086-0"
+               sodipodi:role="line">def BINARY_ADD(self):</tspan><tspan
+               id="tspan3088-4"
+               y="276.54382"
+               x="106.92159"
+               sodipodi:role="line">    ...</tspan></text>
+          <rect
+             y="206.6479"
+             x="85.714287"
+             height="91.428574"
+             width="354.28571"
+             id="rect3138-8"
+             style="fill:none;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none" />
+        </g>
+      </g>
+    </g>
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="-454.88504"
+       y="-103.63782"
+       id="text5192"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan5194"
+         x="-454.88504"
+         y="-103.63782">RPYTHON</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="codewriter"
+     transform="translate(48.09375,-13.439453)">
+    <g
+       id="g4343"
+       transform="translate(550.78125,204.20488)">
+      <text
+         sodipodi:linespacing="125%"
+         id="text3084-92"
+         y="214.0381"
+         x="28.557568"
+         style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           id="tspan3088-3"
+           y="214.0381"
+           x="28.557568"
+           sodipodi:role="line">CODEWRITER</tspan></text>
+      <rect
+         y="155.21931"
+         x="8.5714369"
+         height="91.428574"
+         width="285.97812"
+         id="rect3138-7"
+         style="fill:none;stroke:#ff0000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:9, 3;stroke-dashoffset:0" />
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:12.49669838;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 381.19733,405.25855 130.48659,0"
+       id="path4348"
+       inkscape:connector-curvature="0" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="jitcode"
+     transform="translate(48.09375,-13.439453)">
+    <g
+       id="g5358"
+       transform="translate(7.9254937,0)">
+      <g
+         transform="translate(956.78125,-444.07872)"
+         id="g4105">
+        <g
+           transform="translate(2.8571441,301.42856)"
+           id="g3908-6">
+          <text
+             xml:space="preserve"
+             style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+             x="100.07337"
+             y="231.73483"
+             id="text3084-33"
+             sodipodi:linespacing="125%"><tspan
+               sodipodi:role="line"
+               x="100.07337"
+               y="231.73483"
+               id="tspan3088-9">...</tspan><tspan
+               id="tspan4077"
+               sodipodi:role="line"
+               x="100.07337"
+               y="261.73483">p0 = getfield_gc(p0, 'func_globals')</tspan><tspan
+               id="tspan4075"
+               sodipodi:role="line"
+               x="100.07337"
+               y="291.73483">p2 = getfield_gc(p1, 'strval')</tspan><tspan
+               id="tspan4057"
+               sodipodi:role="line"
+               x="100.07337"
+               y="321.73483">call(dict_lookup, p0, p2)</tspan><tspan
+               id="tspan4059"
+               sodipodi:role="line"
+               x="100.07337"
+               y="351.73483">....</tspan></text>
+          <rect
+             style="fill:none;stroke:#000000;stroke-width:1.67027557;stroke-miterlimit:4;stroke-dasharray:none"
+             id="rect3138-85"
+             width="544.94354"
+             height="165.82893"
+             x="86.099648"
+             y="207.03326" />
+          <flowRoot
+             style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+             id="flowRoot4061"
+             xml:space="preserve"><flowRegion
+               id="flowRegion4063"><rect
+                 y="353.79074"
+                 x="315.71429"
+                 height="77.14286"
+                 width="102.85714"
+                 id="rect4065" /></flowRegion><flowPara
+               id="flowPara4067"></flowPara></flowRoot>        </g>
+      </g>
+      <g
+         id="g4105-0"
+         transform="translate(958.20983,-261.44707)">
+        <g
+           transform="translate(2.8571441,301.42856)"
+           id="g3908-6-7">
+          <text
+             xml:space="preserve"
+             style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+             x="100.07337"
+             y="231.73483"
+             id="text3084-33-8"
+             sodipodi:linespacing="125%"><tspan
+               sodipodi:role="line"
+               x="100.07337"
+               y="231.73483"
+               id="tspan3088-9-8">...</tspan><tspan
+               id="tspan4077-6"
+               sodipodi:role="line"
+               x="100.07337"
+               y="261.73483">p0 = getfield_gc(p0, 'locals_w')</tspan><tspan
+               id="tspan4075-1"
+               sodipodi:role="line"
+               x="100.07337"
+               y="291.73483">setarrayitem_gc(p0, i0, p1)</tspan><tspan
+               id="tspan4059-8"
+               sodipodi:role="line"
+               x="100.07337"
+               y="321.73483">....</tspan></text>
+          <rect
+             style="fill:none;stroke:#000000;stroke-width:1.49203587;stroke-miterlimit:4;stroke-dasharray:none"
+             id="rect3138-85-9"
+             width="544.94354"
+             height="132.3252"
+             x="86.099648"
+             y="207.03326" />
+          <flowRoot
+             style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+             id="flowRoot4061-4"
+             xml:space="preserve"><flowRegion
+               id="flowRegion4063-2"><rect
+                 y="353.79074"
+                 x="315.71429"
+                 height="77.14286"
+                 width="102.85714"
+                 id="rect4065-2" /></flowRegion><flowPara
+               id="flowPara4067-6" /></flowRoot>        </g>
+      </g>
+      <g
+         transform="matrix(1.0073841,0,0,1,716.36172,92.764781)"
+         id="g4325">
+        <text
+           sodipodi:linespacing="125%"
+           id="text3084-33-1"
+           y="346.14929"
+           x="341.50195"
+           style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+           xml:space="preserve"><tspan
+             id="tspan3088-9-0"
+             y="346.14929"
+             x="341.50195"
+             sodipodi:role="line">...</tspan><tspan
+             y="376.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan6723">promote_class(p0)</tspan><tspan
+             y="406.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan4077-62">i0 = getfield_gc(p0, 'intval')</tspan><tspan
+             y="436.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan6727">promote_class(p1)</tspan><tspan
+             y="466.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan4075-3">i1 = getfield_gc(p1, 'intval')</tspan><tspan
+             y="496.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan4059-7">i2 = int_add(i0, i1)</tspan><tspan
+             y="526.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan4242">if (overflowed) goto ...</tspan><tspan
+             y="556.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan4246">p2 = new_with_vtable('W_IntObject')</tspan><tspan
+             y="586.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan4248">setfield_gc(p2, i2, 'intval')</tspan><tspan
+             y="616.14929"
+             x="341.50195"
+             sodipodi:role="line"
+             id="tspan4304">....</tspan></text>
+        <g
+           transform="matrix(1,0,0,1.1400311,480.57144,-267.23566)"
+           id="g4105-2">
+          <g
+             id="g3908-6-5"
+             transform="matrix(1,0,0,1.1954725,2.8571441,206.67858)">
+            <rect
+               y="257.17258"
+               x="-155.76105"
+               height="227.55032"
+               width="540.66492"
+               id="rect3138-85-5"
+               style="fill:none;stroke:#000000;stroke-width:1.94887984;stroke-miterlimit:4;stroke-dasharray:none" />
+            <flowRoot
+               xml:space="preserve"
+               id="flowRoot4061-0"
+               style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
+                 id="flowRegion4063-6"><rect
+                   id="rect4065-1"
+                   width="102.85714"
+                   height="77.14286"
+                   x="315.71429"
+                   y="353.79074" /></flowRegion><flowPara
+                 id="flowPara4067-1" /></flowRoot>          </g>
+        </g>
+      </g>
+    </g>
+    <path
+       style="fill:none;stroke:#000000;stroke-width:12.49669838;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 874.38698,405.25855 130.48662,0"
+       id="path4348-5"
+       inkscape:connector-curvature="0" />
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="1240.5885"
+       y="43.126953"
+       id="text5192-9"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan5194-4"
+         x="1240.5885"
+         y="43.126953">JITCODE</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer5"
+     inkscape:label="timeline"
+     transform="translate(48.09375,-13.439453)">
+    <path
+       style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       d="m -48.083261,738.03442 1685.742561,0"
+       id="path5619"
+       inkscape:connector-curvature="0" />
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="506.28845"
+       y="697.26794"
+       id="text5623"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan5625"
+         x="506.28845"
+         y="697.26794"
+         style="fill:#800000">compile-time</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="557.99744"
+       y="804.74817"
+       id="text5627"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan5629"
+         x="557.99744"
+         y="804.74817"
+         style="fill:#008000">runtime</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer6"
+     inkscape:label="metatracer"
+     transform="translate(48.09375,-13.439453)">
+    <text
+       xml:space="preserve"
+       style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="1331.2896"
+       y="928.88922"
+       id="text3084-92-9"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="1331.2896"
+         y="928.88922"
+         id="tspan3088-3-5">META-TRACER</tspan></text>
+    <rect
+       style="fill:none;stroke:#00ff00;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:9, 3;stroke-dashoffset:0"
+       id="rect3138-7-6"
+       width="285.97812"
+       height="91.428574"
+       x="1311.3035"
+       y="870.07043" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:10.14441872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 1446.1263,750.28419 -0.6836,86.05037"
+       id="path4348-5-9"
+       inkscape:connector-curvature="0" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer7"
+     inkscape:label="optimizer"
+     transform="translate(48.09375,-13.439453)">
+    <text
+       xml:space="preserve"
+       style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="918.10229"
+       y="928.88922"
+       id="text3084-92-9-5"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="918.10229"
+         y="928.88922"
+         id="tspan3088-3-5-2">OPTIMIZER</tspan></text>
+    <rect
+       style="fill:none;stroke:#00ff00;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:9, 3;stroke-dashoffset:0"
+       id="rect3138-7-6-7"
+       width="285.97812"
+       height="91.428574"
+       x="874.03418"
+       y="870.07043" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:10.88625526;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 1289.6562,915.68014 -99.0221,0"
+       id="path4348-5-94"
+       inkscape:connector-curvature="0" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer8"
+     inkscape:label="backend"
+     transform="translate(48.09375,-13.439453)">
+    <text
+       xml:space="preserve"
+       style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="491.6084"
+       y="928.88922"
+       id="text3084-92-9-5-0"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="491.6084"
+         y="928.88922"
+         id="tspan3088-3-5-2-7">BACKEND</tspan></text>
+    <rect
+       style="fill:none;stroke:#00ff00;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:9, 3;stroke-dashoffset:0"
+       id="rect3138-7-6-7-1"
+       width="285.97812"
+       height="91.428574"
+       x="436.76486"
+       y="870.07043" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:10.88625526;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 852.38686,915.68014 -99.02217,0"
+       id="path4348-5-94-1"
+       inkscape:connector-curvature="0" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer9"
+     inkscape:label="jitted"
+     transform="translate(48.09375,-13.439453)">
+    <text
+       xml:space="preserve"
+       style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
+       x="29.307829"
+       y="928.88922"
+       id="text3084-92-9-5-9"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="29.307829"
+         y="928.88922"
+         id="tspan3088-3-5-2-9">ASSEMBLER</tspan></text>
+    <rect
+       style="fill:none;stroke:#00ff00;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:9, 3;stroke-dashoffset:0"
+       id="rect3138-7-6-7-6"
+       width="285.97812"
+       height="91.428574"
+       x="-0.50445831"
+       y="870.07043" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:10.88625526;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 415.11751,915.68014 -99.02217,0"
+       id="path4348-5-94-2"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>
diff --git a/talk/ep2012/jit/talk/diagrams/pypytrace.svg b/talk/ep2012/jit/talk/diagrams/pypytrace.svg
new file mode 100644
--- /dev/null
+++ b/talk/ep2012/jit/talk/diagrams/pypytrace.svg
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="847.5791"
+   height="534.64679"
+   id="svg5724"
+   version="1.1"
+   inkscape:version="0.48.2 r9819"
+   sodipodi:docname="pypytrace.svg">
+  <defs
+     id="defs5726" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.7"
+     inkscape:cx="592.59034"
+     inkscape:cy="238.97744"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer13"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="748"
+     inkscape:window-x="0"
+     inkscape:window-y="1"
+     inkscape:window-maximized="1"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" />
+  <metadata
+     id="metadata5729">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     id="layer15"
+     inkscape:label="content"
+     transform="translate(37.14286,891.38847)">
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="-713.01819"
+       y="-786.45428"
+       id="text6436"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan6438"
+         x="-713.01819"
+         y="-786.45428">python</tspan><tspan
+         sodipodi:role="line"
+         x="-713.01819"
+         y="-736.45428"
+         id="tspan6440">+dis</tspan><tspan
+         sodipodi:role="line"
+         x="-713.01819"
+         y="-686.45428"
+         id="tspan6442">+trace0</tspan><tspan
+         sodipodi:role="line"
+         x="-713.01819"
+         y="-636.45428"
+         id="tspan6444">+trace1</tspan><tspan
+         sodipodi:role="line"
+         x="-713.01819"
+         y="-586.45428"
+         id="tspan6446">+trace2</tspan><tspan
+         sodipodi:role="line"
+         x="-713.01819"
+         y="-536.45428"
+         id="tspan6448">+trace3</tspan></text>
+  </g>
+  <g
+     inkscape:label="python"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(37.14286,891.38847)">
+    <flowRoot
+       transform="translate(-881.42853,413.45203)"
+       xml:space="preserve"
+       id="flowRoot4061-4-6"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
+         id="flowRegion4063-2-1"><rect
+           id="rect4065-2-4"
+           width="102.85714"
+           height="77.14286"
+           x="315.71429"
+           y="353.79074" /></flowRegion><flowPara
+         id="flowPara4067-6-1" /></flowRoot>    <flowRoot
+       transform="translate(-878.57142,-63.29983)"
+       xml:space="preserve"
+       id="flowRoot4061-9-6"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
+         id="flowRegion4063-9-2"><rect
+           id="rect4065-9-0"
+           width="102.85714"
+           height="77.14286"
+           x="315.71429"
+           y="353.79074" /></flowRegion><flowPara
+         id="flowPara4067-5-0" /></flowRoot>    <flowRoot
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       id="flowRoot6192"
+       xml:space="preserve"><flowRegion
+         id="flowRegion6194"><rect
+           y="-101.92353"
+           x="-842.85712"
+           height="940"
+           width="717.14288"
+           id="rect6196" /></flowRegion><flowPara
+         id="flowPara6198"></flowPara></flowRoot>    <text
+       xml:space="preserve"
+       style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       x="-37.14286"
+       y="-765.78998"
+       id="text5732"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan5734"
+         x="-37.14286"
+         y="-765.78998">def fn():</tspan><tspan
+         sodipodi:role="line"
+         x="-37.14286"
+         y="-725.78998"
+         id="tspan5736">    c = a+b</tspan><tspan
+         sodipodi:role="line"
+         x="-37.14286"
+         y="-685.78998"
+         id="tspan5770">    ...</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer10"
+     inkscape:label="dis"
+     transform="translate(37.14286,891.38847)">
+    <text
+       xml:space="preserve"
+       style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       x="-39.314735"
+       y="-619.57458"
+       id="text5732-8"
+       sodipodi:linespacing="125%"
+       inkscape:transform-center-x="-25.714286"
+       inkscape:transform-center-y="-97.142857"><tspan
+         sodipodi:role="line"
+         x="-39.314735"
+         y="-619.57458"
+         id="tspan5736-8">LOAD_GLOBAL A</tspan><tspan
+         sodipodi:role="line"
+         x="-39.314735"
+         y="-579.57458"
+         id="tspan5764">LOAD_GLOBAL B</tspan><tspan
+         sodipodi:role="line"
+         x="-39.314735"
+         y="-539.57458"
+         id="tspan5766">BINARY_ADD</tspan><tspan
+         sodipodi:role="line"
+         x="-39.314735"
+         y="-499.57458"
+         id="tspan5768">STORE_FAST  C</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer11"
+     inkscape:label="trace0"
+     transform="translate(37.14286,891.38847)">
+    <g
+       id="g4105-5"
+       transform="translate(321.42858,-1421.8712)">
+      <text
+         xml:space="preserve"
+         style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+         x="102.93052"
+         y="533.16339"
+         id="text3084-33-6"
+         sodipodi:linespacing="125%"><tspan
+           sodipodi:role="line"
+           x="102.93052"
+           y="533.16339"
+           id="tspan3088-9-84">...</tspan><tspan
+           id="tspan4077-7"
+           sodipodi:role="line"
+           x="102.93052"
+           y="555.66339">p0 = getfield_gc(p0, 'func_globals')</tspan><tspan
+           id="tspan4075-9"
+           sodipodi:role="line"
+           x="102.93052"
+           y="578.16339">p2 = getfield_gc(p1, 'strval')</tspan><tspan
+           id="tspan4057-8"
+           sodipodi:role="line"
+           x="102.93052"
+           y="600.66339">call(dict_lookup, p0, p2)</tspan><tspan
+           id="tspan4059-4"
+           sodipodi:role="line"
+           x="102.93052"
+           y="623.16339">...</tspan></text>
+      <flowRoot
+         transform="translate(2.8571441,301.42856)"
+         style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+         id="flowRoot4061-9"
+         xml:space="preserve"><flowRegion
+           id="flowRegion4063-9"><rect
+             y="353.79074"
+             x="315.71429"
+             height="77.14286"
+             width="102.85714"
+             id="rect4065-9" /></flowRegion><flowPara
+           id="flowPara4067-5" /></flowRoot>    </g>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer12"
+     inkscape:label="trace1"
+     transform="translate(37.14286,891.38847)">
+    <text
+       sodipodi:linespacing="125%"
+       id="text3084-33-6-5"
+       y="-772.99359"
+       x="424.3591"
+       style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       xml:space="preserve"><tspan
+         id="tspan3088-9-84-1"
+         y="-772.99359"
+         x="424.3591"
+         sodipodi:role="line">...</tspan><tspan
+         y="-750.49359"
+         x="424.3591"
+         sodipodi:role="line"
+         id="tspan4077-7-4">p0 = getfield_gc(p0, 'func_globals')</tspan><tspan
+         y="-727.99359"
+         x="424.3591"
+         sodipodi:role="line"
+         id="tspan4075-9-6">p2 = getfield_gc(p1, 'strval')</tspan><tspan
+         y="-705.49359"
+         x="424.3591"
+         sodipodi:role="line"
+         id="tspan4057-8-5">call(dict_lookup, p0, p2)</tspan><tspan
+         y="-682.99359"
+         x="424.3591"
+         sodipodi:role="line"
+         id="tspan4059-4-2">...</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer13"
+     inkscape:label="trace2"
+     transform="translate(37.14286,891.38847)">
+    <text
+       transform="scale(1.0036853,0.99632824)"
+       sodipodi:linespacing="125%"
+       id="text3084-33-1-3"
+       y="-652.034"
+       x="423.3837"
+       style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       xml:space="preserve"><tspan
+         id="tspan3088-9-0-4"
+         y="-652.034"
+         x="423.3837"
+         sodipodi:role="line">...</tspan><tspan
+         y="-629.534"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan4077-62-3"
+         style="font-weight:bold">guard_class(p0, W_IntObject)</tspan><tspan
+         y="-607.034"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan6717">i0 = getfield_gc(p0, 'intval')</tspan><tspan
+         y="-584.534"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan6719"
+         style="font-weight:bold">guard_class(p1, W_IntObject)</tspan><tspan
+         y="-562.034"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan4075-3-2">i1 = getfield_gc(p1, 'intval')</tspan><tspan
+         y="-539.534"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan4059-7-0">i2 = int_add(00, i1)</tspan><tspan
+         y="-517.034"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan4246-1"
+         style="font-weight:bold">guard_not_overflow()</tspan><tspan
+         id="tspan6279"
+         y="-494.534"
+         x="423.3837"
+         sodipodi:role="line">p2 = new_with_vtable('W_IntObject')</tspan><tspan
+         y="-472.034"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan4248-1">setfield_gc(p2, i2, 'intval')</tspan><tspan
+         y="-449.534"
+         x="423.3837"
+         sodipodi:role="line"
+         id="tspan4304-5">...</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer14"
+     inkscape:label="trace3"
+     transform="translate(37.14286,891.38847)">
+    <text
+       sodipodi:linespacing="125%"
+       id="text3084-33-8-9"
+       y="-424.24167"
+       x="424.3591"
+       style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace"
+       xml:space="preserve"><tspan
+         id="tspan3088-9-8-7"
+         y="-424.24167"
+         x="424.3591"
+         sodipodi:role="line">...</tspan><tspan
+         y="-401.74167"
+         x="424.3591"
+         sodipodi:role="line"
+         id="tspan4077-6-9">p0 = getfield_gc(p0, 'locals_w')</tspan><tspan
+         y="-379.24167"
+         x="424.3591"
+         sodipodi:role="line"
+         id="tspan4075-1-4">setarrayitem_gc(p0, i0, p1)</tspan><tspan
+         y="-356.74167"
+         x="424.3591"
+         sodipodi:role="line"
+         id="tspan4059-8-3">....</tspan></text>
+  </g>
+</svg>
diff --git a/talk/ep2012/jit/talk/diagrams/tracetree.svg b/talk/ep2012/jit/talk/diagrams/tracetree.svg
--- a/talk/ep2012/jit/talk/diagrams/tracetree.svg
+++ b/talk/ep2012/jit/talk/diagrams/tracetree.svg
@@ -87,6 +87,20 @@
          transform="matrix(-0.8,0,0,-0.8,-10,0)"
          inkscape:connector-curvature="0" />
     </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow1Lend-90"
+       style="overflow:visible">
+      <path
+         id="path9528-37"
+         d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+         transform="matrix(-0.8,0,0,-0.8,-10,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
   </defs>
   <sodipodi:namedview
      id="base"
@@ -96,7 +110,7 @@
      inkscape:pageopacity="0.0"
      inkscape:pageshadow="2"
      inkscape:zoom="0.49497475"
-     inkscape:cx="299.60564"
+     inkscape:cx="61.209641"
      inkscape:cy="309.93394"
      inkscape:document-units="px"
      inkscape:current-layer="layer12"
@@ -110,7 +124,11 @@
      fit-margin-top="0"
      fit-margin-left="0"
      fit-margin-right="0"
-     fit-margin-bottom="0" />
+     fit-margin-bottom="0"
+     inkscape:snap-global="true"
+     inkscape:snap-smooth-nodes="false"
+     inkscape:snap-bbox="true"
+     inkscape:snap-midpoints="true" />
   <metadata
      id="metadata8614">
     <rdf:RDF>
@@ -119,7 +137,7 @@
         <dc:format>image/svg+xml</dc:format>
         <dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title></dc:title>
+        <dc:title />
       </cc:Work>
     </rdf:RDF>
   </metadata>
@@ -146,7 +164,7 @@
          sodipodi:role="line"
          x="-575.78699"
          y="91.702011"
-         id="tspan10447">trace, guard_sign</tspan><tspan
+         id="tspan10447">+guard_sign</tspan><tspan
          sodipodi:role="line"
          x="-575.78699"
          y="141.70201"
@@ -162,14 +180,18 @@
          sodipodi:role="line"
          x="-575.78699"
          y="291.702"
-         id="tspan10706">trace, bridge</tspan><tspan
+         id="tspan3074">trace, loop</tspan><tspan
          sodipodi:role="line"
          x="-575.78699"
          y="341.702"
+         id="tspan10706">+bridge</tspan><tspan
+         sodipodi:role="line"
+         x="-575.78699"
+         y="391.702"
          id="tspan10708">+loop2</tspan><tspan
          sodipodi:role="line"
          x="-575.78699"
-         y="391.702"
+         y="441.702"
          id="tspan10710">+loop</tspan></text>
     <flowRoot
        xml:space="preserve"
@@ -181,7 +203,7 @@
            height="4268.9048"
            x="-1745.5436"
            y="-4295.3853" /></flowRegion><flowPara
-         id="flowPara10461"></flowPara></flowRoot>  </g>
+         id="flowPara10461" /></flowRoot>  </g>
   <g
      inkscape:label="trace"
      inkscape:groupmode="layer"
@@ -378,11 +400,12 @@
   <g
      inkscape:groupmode="layer"
      id="layer13"
-     inkscape:label="bridge">
+     inkscape:label="bridge"
+     style="display:inline">
     <text
        transform="translate(113.40737,86.55953)"
        xml:space="preserve"
-       style="display:inline;font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
        x="435.2373"
        y="498.73428"
        id="text8667-3"
@@ -402,9 +425,9 @@
          id="tspan8693-7" /></text>
     <path
        transform="translate(113.40737,86.55953)"
-       style="display:inline;fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend)"
-       d="m 320.95822,372.2853 105.05587,82.83251"
-       id="path10175-4-0"
+       style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Lend);display:inline"
+       d="M 323.24881,365.45845 438.4062,436.16913"
+       id="path10175-6"
        inkscape:connector-curvature="0"
        sodipodi:nodetypes="cc" />
   </g>
diff --git a/talk/ep2012/jit/talk/talk.rst b/talk/ep2012/jit/talk/talk.rst
--- a/talk/ep2012/jit/talk/talk.rst
+++ b/talk/ep2012/jit/talk/talk.rst
@@ -4,6 +4,20 @@
 PyPy JIT under the hood
 ================================
 
+About me
+---------
+
+- PyPy core dev
+
+- PyPy py3k tech leader
+
+- ``pdb++``, ``fancycompleter``, ...
+
+- Consultant, trainer
+
+- http://antocuni.eu
+
+
 About this talk
 ----------------
 
@@ -15,7 +29,9 @@
 
 * The PyPy JIT generator
 
-* JIT-friendly programs
+* Just In Time talk
+
+  last-modified: July, 4th, 12:06
 
 
 Part 0: What is PyPy?
@@ -256,3 +272,320 @@
 .. animage:: diagrams/tracetree-p*.pdf
    :align: center
    :scale: 34%
+
+
+Part 2
+------
+
+**The PyPy JIT generator**
+
+General architecture
+---------------------
+
+.. animage:: diagrams/architecture-p*.pdf
+   :align: center
+   :scale: 24%
+
+
+PyPy trace example
+-------------------
+
+.. animage:: diagrams/pypytrace-p*.pdf
+   :align: center
+   :scale: 40%
+
+
+PyPy optimizer
+---------------
+
+- intbounds
+
+- constant folding / pure operations
+
+- virtuals
+
+- string optimizations
+
+- heap (multiple get/setfield, etc)
+
+- ffi
+
+- unroll
+
+
+Intbound optimization (1)
+-------------------------
+
+|example<| |small| intbound.py |end_small| |>|
+
+.. sourcecode:: python
+
+    def fn():
+        i = 0
+        while i < 5000:
+            i += 2
+        return i
+
+|end_example|
+
+Intbound optimization (2)
+--------------------------
+
+|scriptsize|
+|column1|
+|example<| |small| unoptimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    i17 = int_lt(i15, 5000)
+    guard_true(i17)
+    i19 = int_add_ovf(i15, 2)
+    guard_no_overflow()
+    ...
+
+|end_example|
+
+|pause|
+
+|column2|
+|example<| |small| optimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    i17 = int_lt(i15, 5000)
+    guard_true(i17)
+    i19 = int_add(i15, 2)
+    ...
+
+|end_example|
+|end_columns|
+|end_scriptsize|
+
+|pause|
+
+* It works **often**
+
+* array bound checking
+
+* intbound info propagates all over the trace
+
+
+Virtuals (1)
+-------------
+
+|example<| |small| virtuals.py |end_small| |>|
+
+.. sourcecode:: python
+
+    def fn():
+        i = 0
+        while i < 5000:
+            i += 2
+        return i
+
+|end_example|
+
+
+Virtuals (2)
+------------
+
+|scriptsize|
+|column1|
+|example<| |small| unoptimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    guard_class(p0, W_IntObject)
+    i1 = getfield_pure(p0, 'intval')
+    i2 = int_add(i1, 2)
+    p3 = new(W_IntObject)
+    setfield_gc(p3, i2, 'intval')
+    ...
+
+|end_example|
+
+|pause|
+
+|column2|
+|example<| |small| optimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    i2 = int_add(i1, 2)
+    ...
+
+|end_example|
+|end_columns|
+|end_scriptsize|
+
+|pause|
+
+* The most important optimization (TM)
+
+* It works both inside the trace and across the loop
+
+* It works for tons of cases
+
+  - e.g. function frames
+
+
+Constant folding (1)
+---------------------
+
+|example<| |small| constfold.py |end_small| |>|
+
+.. sourcecode:: python
+
+    def fn():
+        i = 0
+        while i < 5000:
+            i += 2
+        return i
+
+|end_example|
+
+
+Constant folding (2)
+--------------------
+
+|scriptsize|
+|column1|
+|example<| |small| unoptimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    i1 = getfield_pure(p0, 'intval')
+    i2 = getfield_pure(<W_Int(2)>, 
+                       'intval')
+    i3 = int_add(i1, i2)
+    ...
+
+|end_example|
+
+|pause|
+
+|column2|
+|example<| |small| optimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    i1 = getfield_pure(p0, 'intval')
+    i3 = int_add(i1, 2)
+    ...
+
+|end_example|
+|end_columns|
+|end_scriptsize|
+
+|pause|
+
+* It "finishes the job"
+
+* Works well together with other optimizations (e.g. virtuals)
+
+* It also does "normal, boring, static" constant-folding
+
+
+Out of line guards (1)
+-----------------------
+
+|example<| |small| outoflineguards.py |end_small| |>|
+
+.. sourcecode:: python
+
+    N = 2
+    def fn():
+        i = 0
+        while i < 5000:
+            i += N
+        return i
+
+|end_example|
+
+
+Out of line guards (2)
+----------------------
+
+|scriptsize|
+|column1|
+|example<| |small| unoptimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    quasiimmut_field(<Cell>, 'val')
+    guard_not_invalidated()
+    p0 = getfield_gc(<Cell>, 'val')
+    ...
+    i2 = getfield_pure(p0, 'intval')
+    i3 = int_add(i1, i2)
+
+|end_example|
+
+|pause|
+
+|column2|
+|example<| |small| optimized |end_small| |>|
+
+.. sourcecode:: python
+
+    ...
+    guard_not_invalidated()
+    ...
+    i3 = int_add(i1, 2)
+    ...
+
+|end_example|
+|end_columns|
+|end_scriptsize|
+
+|pause|
+
+* Python is too dynamic, but we don't care :-)
+
+* No overhead in assembler code
+
+* Used a bit "everywhere"
+
+* Credits to Mark Shannon
+
+  - for the name :-)
+
+Guards
+-------
+
+- guard_true
+
+- guard_false
+
+- guard_class
+
+- guard_no_overflow
+
+- **guard_value**
+
+Promotion
+---------
+
+- guard_value
+
+- specialize code
+
+- make sure not to **overspecialize**
+
+- example: type of objects
+
+- example: function code objects, ...
+
+Conclusion
+-----------
+
+- PyPy is cool :-)
+
+- Any question?
diff --git a/talk/vmil2012/Makefile b/talk/vmil2012/Makefile
--- a/talk/vmil2012/Makefile
+++ b/talk/vmil2012/Makefile
@@ -1,13 +1,43 @@
 
-jit-guards.pdf: paper.tex paper.bib
+jit-guards.pdf: paper.tex paper.bib figures/log.tex figures/example.tex figures/benchmarks_table.tex figures/backend_table.tex figures/ops_count_table.tex figures/loop_bridge.pdf figures/guard_table.tex
 	pdflatex paper
 	bibtex paper
 	pdflatex paper
 	pdflatex paper
 	mv paper.pdf jit-guards.pdf
 
+UNAME := $(shell "uname")
 view: jit-guards.pdf
+ifeq ($(UNAME), Linux)
 	evince jit-guards.pdf &
+endif
+ifeq ($(UNAME), Darwin)
+	open jit-guards.pdf &
+endif
 
 %.tex: %.py
 	pygmentize -l python -o $@ $<
+
+figures/%_table.tex: tool/build_tables.py logs/backend_summary.csv logs/summary.csv tool/table_template.tex logs/bridge_summary.csv
+	tool/setup.sh
+	paper_env/bin/python tool/build_tables.py $@
+
+logs/logbench*:;
+
+logs/summary.csv: logs/logbench* tool/difflogs.py
+	@if ls logs/logbench* &> /dev/null; then python tool/difflogs.py --diffall logs; fi
+
+logs/backend_summary.csv: logs/logbench* tool/backenddata.py
+	@if ls logs/logbench* &> /dev/null; then python tool/backenddata.py logs; fi
+
+logs/bridge_summary.csv: logs/logbench* tool/bridgedata.py
+	@if ls logs/logbench* &> /dev/null; then python tool/bridgedata.py logs; fi
+
+
+logs::
+	tool/run_benchmarks.sh
+
+clean:
+	rm -f *.aux *.bbl *.blg *.log *.tdo
+	rm -f *.pdf
+	rm -f figures/*table.tex figures/*table.aux
diff --git a/talk/vmil2012/example/example.py b/talk/vmil2012/example/example.py
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/example/example.py
@@ -0,0 +1,53 @@
+from pypy.rlib import jit
+from pypy.jit.codewriter.policy import JitPolicy
+
+class Base(object):
+    def __init__(self, n):
+        self.value = n
+
+    @staticmethod
+    def build(n):
+        if n & 1 == 0:
+            return Even(n)
+        else:
+            return Odd(n)
+
+class Odd(Base):
+    def f(self):
+        return Even(self.value * 3 + 1)
+
+class Even(Base):
+    def f(self):
+        n = self.value >> 2
+        if n == 1:
+            return None
+        return self.build(n)
+
+def main(args):
+    i = 2
+    if len(args) == 17:
+        return -1
+    while True:
+        a = Base.build(i)
+        j = 0
+        while j < 100:
+            j += 1
+            myjitdriver.jit_merge_point(i=i, j=j, a=a)
+            if a is None:
+                break
+            a = a.f()
+        else:
+            print i
+        i += 1
+
+def target(*args):
+    return main, None
+
+def jitpolicy(driver):
+    """Returns the JIT policy to use when translating."""
+    return JitPolicy()
+myjitdriver = jit.JitDriver(greens=[], reds=['i', 'j', 'a'])
+
+if __name__ == '__main__':
+    import sys
+    main(sys.argv)
diff --git a/talk/vmil2012/example/log.txt b/talk/vmil2012/example/log.txt
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/example/log.txt
@@ -0,0 +1,279 @@
+[1c697e4e251e] {jit-log-noopt-loop
+[i0, i1, p2]
+label(i0, i1, p2, descr=TargetToken(4417159200))
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+guard_nonnull(p2, descr=<ResumeGuardDescr object at 0x106f6e220>)
+guard_class(p2, 4405741656, descr=<ResumeGuardDescr object at 0x106f6e320>)
+i4 = getfield_gc(p2, descr=<FieldS example.Base.inst_value 8>)
+i6 = int_rshift(i4, 2)
+i8 = int_eq(i6, 1)
+guard_false(i8, descr=<ResumeGuardDescr object at 0x106f6e5c8>)
+i10 = int_and(i6, 1)
+i11 = int_is_zero(i10)
+guard_true(i11, descr=<ResumeGuardDescr object at 0x106f6e7c8>)
+p13 = new_with_vtable(4405741656)
+setfield_gc(p13, i6, descr=<FieldS example.Base.inst_value 8>)
+i15 = int_lt(i1, 100)
+guard_true(i15, descr=<ResumeGuardDescr object at 0x106f6ea60>)
+i17 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+label(i0, i17, p13, descr=<Loop-1>)
+[1c697e522d8e] jit-log-noopt-loop}
+[1c697e603dfe] {jit-log-noopt-loop
+[i0, i1, p2]
+label(i0, i3, i4, descr=TargetToken(4417159280))
+    p6 = new_with_vtable(4405741656)
+    setfield_gc(p6, i4, descr=<FieldS example.Base.inst_value 8>)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+guard_nonnull(p6, descr=<ResumeGuardDescr object at 0x106f7b060>) []
+guard_class(p6, 4405741656, descr=<ResumeGuardDescr object at 0x106f7b240>) []
+i8 = getfield_gc(p6, descr=<FieldS example.Base.inst_value 8>)
+i10 = int_rshift(i8, 2)
+i12 = int_eq(i10, 1)
+guard_false(i12, descr=<ResumeGuardDescr object at 0x106f7ba58>) []
+i14 = int_and(i10, 1)
+i15 = int_is_zero(i14)
+guard_true(i15, descr=<ResumeGuardDescr object at 0x106f7c138>) []
+p16 = new_with_vtable(4405741656)
+setfield_gc(p16, i10, descr=<FieldS example.Base.inst_value 8>)
+i18 = int_lt(i3, 100)
+guard_true(i18, descr=<ResumeGuardDescr object at 0x106f7c610>) []
+i20 = int_add(i3, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+jump(i0, i20, p16, descr=<Loop-1>)
+[1c697e622cb2] jit-log-noopt-loop}
+[1c697e6e123c] {jit-log-opt-loop
+# Loop 0 ((no jitdriver.get_printable_location!)) : loop with 27 ops
+[i0, i1, p2]
++97: label(i0, i1, p2, descr=TargetToken(4417159200))
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++104: guard_nonnull_class(p2, 4405741656, descr=<Guard2>) [i1, i0, p2]
++122: i4 = getfield_gc(p2, descr=<FieldS example.Base.inst_value 8>)
++126: i6 = int_rshift(i4, 2)
++130: i8 = int_eq(i6, 1)
+guard_false(i8, descr=<Guard3>) [i6, i1, i0]
++140: i10 = int_and(i6, 1)
++147: i11 = int_is_zero(i10)
+guard_true(i11, descr=<Guard4>) [i6, i1, i0]
++157: i13 = int_lt(i1, 100)
+guard_true(i13, descr=<Guard5>) [i1, i0, i6]
++167: i15 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++171: label(i0, i15, i6, descr=TargetToken(4417159280))
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++171: i16 = int_rshift(i6, 2)
++175: i17 = int_eq(i16, 1)
+guard_false(i17, descr=<Guard6>) [i16, i15, i0]
++185: i18 = int_and(i16, 1)
++192: i19 = int_is_zero(i18)
+guard_true(i19, descr=<Guard7>) [i16, i15, i0]
++202: i20 = int_lt(i15, 100)
+guard_true(i20, descr=<Guard8>) [i15, i0, i16]
++212: i21 = int_add(i15, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++216: jump(i0, i21, i16, descr=TargetToken(4417159280))
++224: --end of the loop--
+[1c697e6fe748] jit-log-opt-loop}
+[1c697e8094f8] {jit-log-noopt-loop
+[i0, i1, p2]
+guard_nonnull(p2, descr=<ResumeGuardDescr object at 0x106fb3e88>)
+guard_class(p2, 4405741512, descr=<ResumeGuardDescr object at 0x106fb3f88>)
+i4 = getfield_gc(p2, descr=<FieldS example.Base.inst_value 8>)
+i6 = int_mul(i4, 3)
+i8 = int_add(i6, 1)
+p10 = new_with_vtable(4405741656)
+setfield_gc(p10, i8, descr=<FieldS example.Base.inst_value 8>)
+i12 = int_lt(i0, 100)
+guard_true(i12, descr=<ResumeGuardDescr object at 0x106fb43d0>)
+i14 = int_add(i0, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+jump(i1, i14, p10, descr=<Loop0>)
+[1c697e817ed0] jit-log-noopt-loop}
+[1c697e8622e8] {jit-log-noopt-loop
+[i0, i1, p2]
+label(i0, i1, i3, descr=TargetToken(4417159920))
+    p2 = new_with_vtable(4405741656)
+    setfield_gc(p2, i3, descr=<FieldS example.Base.inst_value 8>)
+guard_nonnull(p2, descr=<ResumeGuardDescr object at 0x106fc1570>)
+guard_class(p2, 4405741656, descr=<ResumeGuardDescr object at 0x106fc1670>)
+i6 = getfield_gc(p2, descr=<FieldS example.Base.inst_value 8>)
+i8 = int_rshift(i6, 2)
+i10 = int_eq(i8, 1)
+guard_false(i10, descr=<ResumeGuardDescr object at 0x106fc1918>)
+i12 = int_and(i8, 1)
+i13 = int_is_zero(i12)
+guard_true(i13, descr=<ResumeGuardDescr object at 0x106fc1b18>)
+p15 = new_with_vtable(4405741656)
+setfield_gc(p15, i8, descr=<FieldS example.Base.inst_value 8>)
+i17 = int_lt(i1, 100)
+guard_true(i17, descr=<ResumeGuardDescr object at 0x106fc1db0>)
+i19 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+jump(i0, i19, p15, descr=<Loop0>)
+[1c697e88b3e8] jit-log-noopt-loop}
+[1c697e8e996c] {jit-log-opt-bridge
+# bridge out of Guard 2 with 20 ops
+[i0, i1, p2]
++7: guard_nonnull_class(p2, 4405741512, descr=<Guard9>) [i0, i1, p2]
++25: i4 = getfield_gc(p2, descr=<FieldS example.Base.inst_value 8>)
++29: i6 = int_mul(i4, 3)
++33: i8 = int_add(i6, 1)
++37: i10 = int_lt(i0, 100)
+guard_true(i10, descr=<Guard10>) [i0, i1, i8]
++47: i12 = int_add(i0, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++51: label(i1, i12, i8, descr=TargetToken(4417159920))
++51: i14 = int_rshift(i8, 2)
++55: i16 = int_eq(i14, 1)
+guard_false(i16, descr=<Guard11>) [i14, i12, i1]
++65: i18 = int_and(i14, 1)
++72: i19 = int_is_zero(i18)
+guard_true(i19, descr=<Guard12>) [i14, i12, i1]
++82: i21 = int_lt(i12, 100)
+guard_true(i21, descr=<Guard13>) [i12, i1, i14]
++92: i23 = int_add(i12, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++96: jump(i1, i23, i14, descr=TargetToken(4417159280))
++112: --end of the loop--
+[1c697e9012f0] jit-log-opt-bridge}
+[1c697ea674bc] {jit-log-noopt-loop
+[i0, i1, i2]
+p4 = new_with_vtable(4405741512)
+setfield_gc(p4, i0, descr=<FieldS example.Base.inst_value 8>)
+i6 = int_lt(i1, 100)
+guard_true(i6, descr=<ResumeGuardDescr object at 0x107005300>)
+i8 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+jump(i2, i8, p4, descr=<Loop0>)
+[1c697ea70e54] jit-log-noopt-loop}
+[1c697ea9ffa4] {jit-log-noopt-loop
+[i0, i1, p2]
+label(i0, i1, i3, descr=TargetToken(4417160720))
+    p2 = new_with_vtable(4405741512)
+    setfield_gc(p2, i3, descr=<FieldS example.Base.inst_value 8>)
+guard_nonnull(p2, descr=<ResumeGuardDescr object at 0x107010580>)
+guard_class(p2, 4405741512, descr=<ResumeGuardDescr object at 0x107010680>)
+i6 = getfield_gc(p2, descr=<FieldS example.Base.inst_value 8>)
+i8 = int_mul(i6, 3)
+i10 = int_add(i8, 1)
+p12 = new_with_vtable(4405741656)
+setfield_gc(p12, i10, descr=<FieldS example.Base.inst_value 8>)
+i14 = int_lt(i1, 100)
+guard_true(i14, descr=<ResumeGuardDescr object at 0x107010ac8>)
+i16 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+jump(i0, i16, p12, descr=<Loop0>)
+[1c697eab1220] jit-log-noopt-loop}
+[1c697eaffe10] {jit-log-opt-bridge
+# bridge out of Guard 12 with 12 ops
+[i0, i1, i2]
++7: i4 = int_lt(i1, 100)
+guard_true(i4, descr=<Guard14>) [i1, i2, i0]
++17: i6 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++21: label(i2, i6, i0, descr=TargetToken(4417160720))
++21: i8 = int_mul(i0, 3)
++25: i10 = int_add(i8, 1)
++29: i12 = int_lt(i6, 100)
+guard_true(i12, descr=<Guard15>) [i6, i2, i10]
++39: i14 = int_add(i6, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++43: jump(i2, i14, i10, descr=TargetToken(4417159920))
++59: --end of the loop--
+[1c697eb0deb0] jit-log-opt-bridge}
+[1c697eb6cc08] {jit-log-noopt-loop
+[i0, i1, i2]
+p4 = new_with_vtable(4405741512)
+setfield_gc(p4, i0, descr=<FieldS example.Base.inst_value 8>)
+i6 = int_lt(i1, 100)
+guard_true(i6, descr=<ResumeGuardDescr object at 0x10702cf20>)
+i8 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+jump(i2, i8, p4, descr=<Loop0>)
+[1c697eb754fc] jit-log-noopt-loop}
+[1c697eba0930] {jit-log-opt-bridge
+# bridge out of Guard 7 with 5 ops
+[i0, i1, i2]
++7: i4 = int_lt(i1, 100)
+guard_true(i4, descr=<Guard16>) [i1, i2, i0]
++17: i6 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++21: jump(i2, i6, i0, descr=TargetToken(4417160720))
++37: --end of the loop--
+[1c697ebb936c] jit-log-opt-bridge}
+[1c697ec16c6a] {jit-log-noopt-loop
+[i0, i1, i2]
+p4 = new_with_vtable(4405741656)
+setfield_gc(p4, i2, descr=<FieldS example.Base.inst_value 8>)
+p6 = call_pure(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i1, descr=<Callr 8 i EF=3>)
+guard_no_exception(, descr=<ResumeGuardDescr object at 0x107049600>)
+call(ConstClass(rpython_print_item), p6, descr=<Callv 0 r EF=4>)
+guard_no_exception(, descr=<ResumeGuardDescr object at 0x107049728>)
+i9 = getfield_gc(ConstPtr(ptr8), descr=<FieldS list.length 8>)
+i10 = int_is_true(i9)
+guard_true(i10, descr=<ResumeGuardDescr object at 0x107049908>)
+i12 = getfield_gc(ConstPtr(ptr11), descr=<FieldS list.length 8>)
+i14 = int_add(i12, -1)
+p16 = getfield_gc(ConstPtr(ptr15), descr=<FieldP list.items 16>)
+setarrayitem_gc(p16, i14, 10, descr=<ArrayU 1>)
+i19 = getfield_gc(ConstPtr(ptr18), descr=<FieldS list.length 8>)
+p21 = getfield_gc(ConstPtr(ptr20), descr=<FieldP list.items 16>)
+p23 = call(ConstClass(ll_join_chars_trampoline__v11___simple_call__function_ll), i19, p21, descr=<Callr 8 ir EF=4>)
+guard_no_exception(, descr=<ResumeGuardDescr object at 0x107049d88>)
+call(ConstClass(ll_listdelslice_startonly_trampoline__v20___simple_call__function_ll), ConstPtr(ptr25), 0, descr=<Callv 0 ri EF=4>)
+guard_no_exception(, descr=<ResumeGuardDescr object at 0x107049eb8>)
+i29 = call_may_force(ConstClass(ll_os.ll_os_write), 1, p23, descr=<Calli 8 ir EF=6>)
+guard_not_forced(, descr=<ResumeGuardForcedDescr object at 0x107049fe8>)
+guard_no_exception(, descr=<ResumeGuardDescr object at 0x10704a0b8>)
+i31 = int_add(i1, 1)
+i33 = int_and(i31, 1)
+i34 = int_is_zero(i33)
+guard_true(i34, descr=<ResumeGuardDescr object at 0x10704a338>)
+p36 = new_with_vtable(4405741656)
+setfield_gc(p36, i31, descr=<FieldS example.Base.inst_value 8>)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+i38 = same_as(1)
+jump(i31, i38, p36, descr=<Loop0>)
+[1c697ec3287c] jit-log-noopt-loop}
+[1c697ec91ba8] {jit-log-opt-bridge
+# bridge out of Guard 8 with 23 ops
+[i0, i1, i2]
++7: p4 = call(ConstClass(ll_int_str__IntegerR_SignedConst_Signed), i1, descr=<Callr 8 i EF=3>)
++38: guard_no_exception(, descr=<Guard22>) [i1, p4]
++58: call(ConstClass(rpython_print_item), p4, descr=<Callv 0 r EF=4>)
++85: guard_no_exception(, descr=<Guard23>) [i1]
++105: i7 = getfield_gc(ConstPtr(ptr6), descr=<FieldS list.length 8>)
++118: i8 = int_is_true(i7)
+guard_true(i8, descr=<Guard24>) [i1]
++128: i10 = int_add(i7, -1)
++135: p12 = getfield_gc(ConstPtr(ptr11), descr=<FieldP list.items 16>)
++148: setarrayitem_gc(p12, i10, 10, descr=<ArrayU 1>)
++154: p15 = call(ConstClass(ll_join_chars_trampoline__v11___simple_call__function_ll), i7, p12, descr=<Callr 8 ir EF=4>)
++181: guard_no_exception(, descr=<Guard25>) [i1, p15]
++201: call(ConstClass(ll_listdelslice_startonly_trampoline__v20___simple_call__function_ll), ConstPtr(ptr17), 0, descr=<Callv 0 ri EF=4>)
++250: guard_no_exception(, descr=<Guard26>) [i1, p15]
++270: i21 = call_may_force(ConstClass(ll_os.ll_os_write), 1, p15, descr=<Calli 8 ir EF=6>)
+guard_not_forced(, descr=<Guard21>) [i1]
++320: guard_no_exception(, descr=<Guard27>) [i1]
++340: i23 = int_add(i1, 1)
++351: i25 = int_and(i23, 1)
++358: i26 = int_is_zero(i25)
+guard_true(i26, descr=<Guard28>) [i23]
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
++368: jump(i23, 1, i23, descr=TargetToken(4417159920))
++396: --end of the loop--
+[1c697eca70c2] jit-log-opt-bridge}
+[1c697ecf5a40] {jit-log-noopt-loop
+[i0, i1, i2]
+i4 = int_lt(i1, 100)
+guard_true(i4, descr=<ResumeGuardDescr object at 0x107078038>)
+i6 = int_add(i1, 1)
+debug_merge_point(0, 0, '(no jitdriver.get_printable_location!)')
+p8 = same_as(ConstPtr(ptr7))
+jump(i2, i6, p8, descr=<Loop0>)
+[1c697ecfb8a4] jit-log-noopt-loop}
+[1c697ed186d0] {jit-log-noopt-loop
+[i0, i1, p2]
+label(i0, i1, descr=TargetToken(4417161920))
+    p2 = same_as(ConstPtr(ptr3))
+guard_is
\ No newline at end of file
diff --git a/talk/vmil2012/figures/example.tex b/talk/vmil2012/figures/example.tex
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/figures/example.tex
@@ -0,0 +1,31 @@
+\begin{lstlisting}[language=Python, numbers=right]
+class Base(object):
+    def __init__(self, n):
+        self.value = n
+    @staticmethod
+    def build(n):
+        if n & 1 == 0:
+            return Even(n)
+        else:
+            return Odd(n)
+
+class Odd(Base):
+    def f(self):
+        return Even(self.value * 3 + 1)
+
+class Even(Base):
+    def f(self):
+        n = self.value >> 2
+        if n == 1:
+            return None
+        return self.build(n)
+
+def check_reduces(a):
+    j = 1
+    while j < 100:
+        j += 1
+        if a is None:
+            return True
+        a = a.f()
+    return False
+\end{lstlisting}
diff --git a/talk/vmil2012/figures/frames_example.svg b/talk/vmil2012/figures/frames_example.svg
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/figures/frames_example.svg
@@ -0,0 +1,315 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="frames_example.svg">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.7"
+     inkscape:cx="615.8897"
+     inkscape:cy="576.45334"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1920"
+     inkscape:window-height="1176"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       style="fill:none;stroke:#969696;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 104.04571,299.29346 c -1.30959,1.88953 19.16856,11.55339 22.67726,22.73502 4.08908,13.03121 2.47104,18.65244 2.57656,27.77261 0.10552,9.12017 4.44942,30.07965 1.01015,50.00255 -3.43927,19.9229 -24.94253,55.71887 -25.25382,66.67007 -0.31129,10.9512 -0.56558,14.56277 0,23.2335 0.56558,8.67073 0.4193,35.01843 0.50508,53.03301 0.0858,18.01458 -2.66368,43.52981 0,55.05332 2.66368,11.52351 42.19247,17.40231 48.48732,28.28427 6.29485,10.88196 -51.08915,104.6838 -45.97589,111.3233 5.11326,6.6395 74.60109,-47.87775 84.11971,-83.05629 9.51861,-35.17853 -5.44013,-175.74928 -4.80878,-190.90157 0.63135,-15.15229 -11.65816,-134.47725 -38.3858,-153.03811 -26.72763,-18.56086 -43.6422,-13.00121 -44.95179,-11.11168 z"
+       id="path3987"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="zszzzzzzzzzzzz" />
+    <path
+       sodipodi:type="star"
+       style="color:#000000;fill:none;stroke:#c8c8c8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path4036"
+       sodipodi:sides="5"
+       sodipodi:cx="371.23105"
+       sodipodi:cy="328.58789"
+       sodipodi:r1="8.1441097"
+       sodipodi:r2="4.0720549"
+       sodipodi:arg1="-1.5707963"
+       sodipodi:arg2="-0.9424778"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 371.23105,320.44378 2.39349,4.84975 5.35202,0.77769 -3.87276,3.775 0.91424,5.33039 -4.78699,-2.51666 -4.78699,2.51666 0.91423,-5.33039 -3.87275,-3.775 5.35201,-0.77769 z"
+       inkscape:transform-center-y="-0.77769332"
+       transform="translate(-261.62951,-28.789348)" />
+    <path
+       sodipodi:type="star"
+       style="color:#000000;fill:none;stroke:#c8c8c8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path4036-7"
+       sodipodi:sides="5"
+       sodipodi:cx="371.23105"
+       sodipodi:cy="328.58789"
+       sodipodi:r1="8.1441097"
+       sodipodi:r2="4.0720549"
+       sodipodi:arg1="-1.5707963"
+       sodipodi:arg2="-0.9424778"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 371.23105,320.44378 2.39349,4.84975 5.35202,0.77769 -3.87276,3.775 0.91424,5.33039 -4.78699,-2.51666 -4.78699,2.51666 0.91423,-5.33039 -3.87275,-3.775 5.35201,-0.77769 z"
+       inkscape:transform-center-y="-0.77769332"
+       transform="translate(-241.42645,20.980737)" />
+    <path
+       sodipodi:type="star"
+       style="color:#000000;fill:none;stroke:#c8c8c8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path4036-9"
+       sodipodi:sides="5"
+       sodipodi:cx="371.23105"
+       sodipodi:cy="328.58789"
+       sodipodi:r1="8.1441097"
+       sodipodi:r2="4.0720549"
+       sodipodi:arg1="-1.5707963"
+       sodipodi:arg2="-0.9424778"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 371.23105,320.44378 2.39349,4.84975 5.35202,0.77769 -3.87276,3.775 0.91424,5.33039 -4.78699,-2.51666 -4.78699,2.51666 0.91423,-5.33039 -3.87275,-3.775 5.35201,-0.77769 z"
+       inkscape:transform-center-y="-0.77769332"
+       transform="translate(-241.42645,71.003593)" />
+    <g
+       id="g3989">
+      <rect
+         y="231.04726"
+         x="91.923882"
+         height="199.46342"
+         width="410.12195"
+         id="rect2985"
+         style="color:#000000;fill:none;stroke:#000000;stroke-width:1.0622313;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text3755"
+         y="256.30106"
+         x="115.03556"
+         style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+         xml:space="preserve"><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           y="256.30106"
+           x="115.03556"
+           id="tspan3757"
+           sodipodi:role="line">a = Base.build(i)</tspan><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           id="tspan3759"
+           y="281.30106"
+           x="115.03556"
+           sodipodi:role="line">j = 0</tspan><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           id="tspan3761"
+           y="306.30106"
+           x="115.03556"
+           sodipodi:role="line">while j &lt; 100:</tspan><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           id="tspan3763"
+           y="331.30106"
+           x="115.03556"
+           sodipodi:role="line">    j += 1</tspan><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           id="tspan3767"
+           y="356.30106"
+           x="115.03556"
+           sodipodi:role="line">    if a is None:</tspan><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           id="tspan3769"
+           y="381.30106"
+           x="115.03556"
+           sodipodi:role="line">        break</tspan><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           id="tspan3771"
+           y="406.30106"
+           x="115.03556"
+           sodipodi:role="line">    a = a.f()</tspan><tspan
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.0622313;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+           id="tspan3773"
+           y="431.30106"
+           x="115.03556"
+           sodipodi:role="line" /></text>
+    </g>
+    <path
+       sodipodi:type="star"
+       style="color:#000000;fill:none;stroke:#c8c8c8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path4036-95"
+       sodipodi:sides="5"
+       sodipodi:cx="371.23105"
+       sodipodi:cy="328.58789"
+       sodipodi:r1="8.1441097"
+       sodipodi:r2="4.0720549"
+       sodipodi:arg1="-1.5707963"
+       sodipodi:arg2="-0.9424778"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 371.23105,320.44378 2.39349,4.84975 5.35202,0.77769 -3.87276,3.775 0.91424,5.33039 -4.78699,-2.51666 -4.78699,2.51666 0.91423,-5.33039 -3.87275,-3.775 5.35201,-0.77769 z"
+       inkscape:transform-center-y="-0.77769332"
+       transform="translate(-262.1346,161.89703)" />
+    <g
+       id="g4001">
+      <rect
+         y="447.04724"
+         x="91.923882"
+         height="121.15703"
+         width="410.12195"
+         id="rect2985-4"
+         style="fill:none;stroke:#000000;stroke-width:0.8278693;stroke-opacity:1" />
+      <text
+         sodipodi:linespacing="125%"
+         id="text3755-0"
+         y="472.30106"
+         x="115.03556"
+         style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+         xml:space="preserve"><tspan
+           id="tspan3898"
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+           y="472.30106"
+           x="115.03556"
+           sodipodi:role="line">n = self.value &gt;&gt; 2</tspan><tspan
+           id="tspan3900"
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+           y="497.30106"
+           x="115.03556"
+           sodipodi:role="line">if n == 1:</tspan><tspan
+           id="tspan3902"
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+           y="522.30103"
+           x="115.03556"
+           sodipodi:role="line">    return None</tspan><tspan
+           id="tspan3904"
+           style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+           y="547.30103"
+           x="115.03556"
+           sodipodi:role="line">return self.build(n)</tspan></text>
+    </g>
+    <path
+       sodipodi:type="star"
+       style="color:#000000;fill:none;stroke:#c8c8c8;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+       id="path4036-70"
+       sodipodi:sides="5"
+       sodipodi:cx="371.23105"
+       sodipodi:cy="328.58789"
+       sodipodi:r1="8.1441097"
+       sodipodi:r2="4.0720549"
+       sodipodi:arg1="-1.5707963"
+       sodipodi:arg2="-0.9424778"
+       inkscape:flatsided="false"
+       inkscape:rounded="0"
+       inkscape:randomized="0"
+       d="m 371.23105,320.44378 2.39349,4.84975 5.35202,0.77769 -3.87276,3.775 0.91424,5.33039 -4.78699,-2.51666 -4.78699,2.51666 0.91423,-5.33039 -3.87275,-3.775 5.35201,-0.77769 z"
+       inkscape:transform-center-y="-0.77769332"
+       transform="translate(-262.13457,270.50872)" />
+    <g
+       id="g4009">
+      <rect
+         y="581.04724"
+         x="91.923882"
+         height="121.15703"
+         width="410.12195"
+         id="rect2985-4-1"
+         style="fill:none;stroke:#000000;stroke-width:0.8278693;stroke-opacity:1" />
+      <g
+         id="g4095">
+        <text
+           xml:space="preserve"
+           style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+           x="115.03556"
+           y="606.30103"
+           id="text3755-0-4"
+           sodipodi:linespacing="125%"><tspan
+             sodipodi:role="line"
+             x="115.03556"
+             y="606.30103"
+             style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+             id="tspan3975">if n &amp; 1 == 0:</tspan><tspan
+             sodipodi:role="line"
+             x="115.03556"
+             y="631.30103"
+             style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+             id="tspan3977">    return Even(n)</tspan><tspan
+             sodipodi:role="line"
+             x="115.03556"
+             y="656.30103"
+             style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+             id="tspan3979">else:</tspan><tspan
+             sodipodi:role="line"
+             x="115.03556"
+             y="681.30103"
+             style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+             id="tspan3981">    return Odd(n)</tspan></text>
+        <rect
+           style="fill:none;stroke:#000000;stroke-width:0.8278693;stroke-opacity:1"
+           id="rect2985-4-1-2"
+           width="410.12195"
+           height="121.15703"
+           x="91.923882"
+           y="581.04724" />
+      </g>
+      <g
+         transform="translate(1.1727523e-7,136)"
+         id="g4095-7">
+        <text
+           xml:space="preserve"
+           style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+           x="115.03556"
+           y="606.30103"
+           id="text3755-0-4-3"
+           sodipodi:linespacing="125%"><tspan
+             sodipodi:role="line"
+             x="115.03556"
+             y="606.30103"
+             style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+             id="tspan3981-5">self.value = n</tspan><tspan
+             sodipodi:role="line"
+             x="115.03556"
+             y="631.30103"
+             style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace;-inkscape-font-specification:Monospace"
+             id="tspan4176" /></text>
+        <rect
+           style="fill:none;stroke:#000000;stroke-width:0.8278693;stroke-opacity:1"
+           id="rect2985-4-1-2-8"
+           width="410.12195"
+           height="42.870205"
+           x="91.923882"
+           y="581.04724" />
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/talk/vmil2012/figures/log.tex b/talk/vmil2012/figures/log.tex
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/figures/log.tex
@@ -0,0 +1,27 @@
+\begin{lstlisting}[mathescape, numbers=right]
+[$j_1$, $a_1$]
+label($j_1$, $a_1$, descr=label0))
+$j_2$ = int_add($j_1$, 1)
+guard_nonnull_class($a_1$, Even)
+$i_1$ = getfield_gc($a_1$, descr='value')
+$i_2$ = int_rshift($i_1$, 2)
+$b_1$ = int_eq($i_2$, 1)
+guard_false($b_1$)
+$i_3$ = int_and($i_2$, 1)
+$i_4$= int_is_zero($i_3$)
+guard_true($i_4$)
+$b_2$ = int_lt($j_2$, 100)
+guard_true($b_2$)
+
+label($j_2$, $i_2$, descr=label1)
+$j_3$ = int_add($j_2$, 1)
+$i_5$ = int_rshift($i_2$, 2)
+$b_3$ = int_eq($i_5$, 1)
+guard_false($b_3$)
+$i_6$ = int_and($i_5$, 1)
+$b_4$ = int_is_zero($i_6$)
+guard_true($b_4$)
+$b_5$ = int_lt($j_3$, 100)
+guard_true($b_5$)
+jump($j_3$, $i_5$, descr=label1)
+\end{lstlisting}
diff --git a/talk/vmil2012/figures/loop_bridge.graffle b/talk/vmil2012/figures/loop_bridge.graffle
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/figures/loop_bridge.graffle
@@ -0,0 +1,1407 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActiveLayerIndex</key>
+	<integer>0</integer>
+	<key>ApplicationVersion</key>
+	<array>
+		<string>com.omnigroup.OmniGrafflePro</string>
+		<string>139.7.0.167456</string>
+	</array>
+	<key>AutoAdjust</key>
+	<true/>
+	<key>BackgroundGraphic</key>
+	<dict>
+		<key>Bounds</key>
+		<string>{{0, 0}, {559, 783}}</string>
+		<key>Class</key>
+		<string>SolidGraphic</string>
+		<key>ID</key>
+		<integer>2</integer>
+		<key>Style</key>
+		<dict>
+			<key>shadow</key>
+			<dict>
+				<key>Draws</key>
+				<string>NO</string>
+			</dict>
+			<key>stroke</key>
+			<dict>
+				<key>Draws</key>
+				<string>NO</string>
+			</dict>
+		</dict>
+	</dict>
+	<key>BaseZoom</key>
+	<integer>0</integer>
+	<key>CanvasOrigin</key>
+	<string>{0, 0}</string>
+	<key>ColumnAlign</key>
+	<integer>1</integer>
+	<key>ColumnSpacing</key>
+	<real>36</real>
+	<key>CreationDate</key>
+	<string>2012-07-24 10:50:56 +0000</string>
+	<key>Creator</key>
+	<string>David Schneider</string>
+	<key>DisplayScale</key>
+	<string>1.000 cm = 1.000 cm</string>
+	<key>GraphDocumentVersion</key>
+	<integer>8</integer>
+	<key>GraphicsList</key>
+	<array>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+			<key>ID</key>
+			<integer>61</integer>
+			<key>Points</key>
+			<array>
+				<string>{83, 205}</string>
+				<string>{42, 264.875}</string>
+				<string>{83, 334.75}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>2</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>24</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>Group</string>
+			<key>Graphics</key>
+			<array>
+				<dict>
+					<key>Bounds</key>
+					<string>{{151.00001525878906, 447.5}, {166.99998474121094, 93.5}}</string>
+					<key>Class</key>
+					<string>ShapedGraphic</string>
+					<key>ID</key>
+					<integer>59</integer>
+					<key>Magnets</key>
+					<array>
+						<string>{1, 0}</string>
+						<string>{-1, 0}</string>
+					</array>
+					<key>Shape</key>
+					<string>Rectangle</string>
+					<key>Text</key>
+					<dict>
+						<key>Text</key>
+						<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fnil\fcharset0 Monaco;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs20 \cf0 read ll resume data\
+decode resume data\
+retrieve stack and register values\
+...}</string>
+					</dict>
+				</dict>
+				<dict>
+					<key>Bounds</key>
+					<string>{{151, 414}, {167, 33.5}}</string>
+					<key>Class</key>
+					<string>ShapedGraphic</string>
+					<key>ID</key>
+					<integer>60</integer>
+					<key>Magnets</key>
+					<array>
+						<string>{0, 1}</string>
+						<string>{0, -1}</string>
+					</array>
+					<key>Shape</key>
+					<string>Rectangle</string>
+					<key>Text</key>
+					<dict>
+						<key>Text</key>
+						<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 compensation code}</string>
+					</dict>
+				</dict>
+			</array>
+			<key>ID</key>
+			<integer>58</integer>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>40</integer>
+			</dict>
+			<key>ID</key>
+			<integer>56</integer>
+			<key>Points</key>
+			<array>
+				<string>{323.5, 350.5}</string>
+				<string>{338, 414}</string>
+				<string>{346.8410005147403, 506.4534215178565}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>44</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>41</integer>
+			</dict>
+			<key>ID</key>
+			<integer>55</integer>
+			<key>Points</key>
+			<array>
+				<string>{375, 301.25}</string>
+				<string>{418, 369}</string>
+				<string>{421.99397498596954, 444.99998514226786}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>43</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>39</integer>
+			</dict>
+			<key>ID</key>
+			<integer>54</integer>
+			<key>Points</key>
+			<array>
+				<string>{92.51008491617111, 351.93749427457396}</string>
+				<string>{131, 421.49998514226786}</string>
+				<string>{121.99397498596946, 517.5}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+				<key>Info</key>
+				<integer>2</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>38</integer>
+			</dict>
+			<key>ID</key>
+			<integer>53</integer>
+			<key>Points</key>
+			<array>
+				<string>{83, 301.25}</string>
+				<string>{42, 373}</string>
+				<string>{46.9741099939598, 433.72820859342926}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>37</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>44</integer>
+			</dict>
+			<key>ID</key>
+			<integer>52</integer>
+			<key>Points</key>
+			<array>
+				<string>{376, 205}</string>
+				<string>{414, 274}</string>
+				<string>{375, 333.75}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>34</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>43</integer>
+			</dict>
+			<key>ID</key>
+			<integer>51</integer>
+			<key>Points</key>
+			<array>
+				<string>{376, 159}</string>
+				<string>{413, 215.5}</string>
+				<string>{375, 301.25}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>32</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>60</integer>
+			</dict>
+			<key>ID</key>
+			<integer>50</integer>
+			<key>Points</key>
+			<array>
+				<string>{272, 301.25}</string>
+				<string>{248, 330}</string>
+				<string>{234.5, 414}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>43</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>60</integer>
+			</dict>
+			<key>ID</key>
+			<integer>49</integer>
+			<key>Points</key>
+			<array>
+				<string>{323.5, 350.5}</string>
+				<string>{257, 386}</string>
+				<string>{234.5, 414}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>44</integer>
+				<key>Info</key>
+				<integer>1</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>60</integer>
+			</dict>
+			<key>ID</key>
+			<integer>48</integer>
+			<key>Points</key>
+			<array>
+				<string>{186, 334.75}</string>
+				<string>{211, 366}</string>
+				<string>{234.5, 414}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>Pattern</key>
+					<integer>2</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>42</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>60</integer>
+			</dict>
+			<key>ID</key>
+			<integer>47</integer>
+			<key>Points</key>
+			<array>
+				<string>{186, 301.25}</string>
+				<string>{211, 328}</string>
+				<string>{234.5, 414}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>37</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>30</integer>
+			</dict>
+			<key>ID</key>
+			<integer>46</integer>
+			<key>Points</key>
+			<array>
+				<string>{188, 205}</string>
+				<string>{231, 158}</string>
+				<string>{271, 113}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>24</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Class</key>
+			<string>LineGraphic</string>
+			<key>Head</key>
+			<dict>
+				<key>ID</key>
+				<integer>37</integer>
+			</dict>
+			<key>ID</key>
+			<integer>45</integer>
+			<key>Points</key>
+			<array>
+				<string>{83, 159}</string>
+				<string>{42, 222}</string>
+				<string>{83, 301.25}</string>
+			</array>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>HeadArrow</key>
+					<string>FilledArrow</string>
+					<key>Legacy</key>
+					<true/>
+					<key>LineType</key>
+					<integer>1</integer>
+					<key>TailArrow</key>
+					<string>0</string>
+				</dict>
+			</dict>
+			<key>Tail</key>
+			<dict>
+				<key>ID</key>
+				<integer>18</integer>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{272, 317}, {103, 33.5}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>44</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{0, 1}</string>
+				<string>{0, -1}</string>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 Trampoline #4}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{272, 284.5}, {103, 33.5}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>43</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 Trampoline #3}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 318}, {103, 33.5}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>42</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>stroke</key>
+				<dict>
+					<key>Pattern</key>
+					<integer>2</integer>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 Trampoline #2}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{342, 421.49998514226786}, {85, 47}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>41</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Cloud</string>
+			<key>Style</key>
+			<dict/>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 ll resume data #3}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{341.99998930037054, 493.99999618530273}, {85, 47}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>40</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Cloud</string>
+			<key>Style</key>
+			<dict/>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 ll resume data #4}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{42, 494}, {85, 47}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>39</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Cloud</string>
+			<key>Style</key>
+			<dict/>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 ll resume data #2}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{42, 421.5}, {85, 47}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>38</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Cloud</string>
+			<key>Style</key>
+			<dict/>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 ll resume data #1}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 284.5}, {103, 33.5}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>37</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 Trampoline #1}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{271, 238.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>36</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 jump}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{271, 215.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>35</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{271, 193.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>34</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 guard 4}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{271, 170.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>33</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{271, 147.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>32</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 guard 3}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{271, 124.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>31</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{271, 101.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>30</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{248, 59}, {151, 24}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>ID</key>
+			<integer>29</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict/>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 Bridge from guard #2}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{248, 83}, {151, 286}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>28</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 238.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>27</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 jump}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 215.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>26</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 193.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>24</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 patched guard #2}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 170.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>19</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 147.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>18</integer>
+			<key>Magnets</key>
+			<array>
+				<string>{1, 0}</string>
+				<string>{-1, 0}</string>
+			</array>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict>
+				<key>fill</key>
+				<dict>
+					<key>Color</key>
+					<dict>
+						<key>b</key>
+						<string>0.4</string>
+						<key>g</key>
+						<string>0.8</string>
+						<key>r</key>
+						<string>1</string>
+					</dict>
+				</dict>
+			</dict>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 guard #1}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 124.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>17</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{83, 101.5}, {105, 23}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>16</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 operation}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{60, 59}, {151, 24}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>FitText</key>
+			<string>Vertical</string>
+			<key>Flow</key>
+			<string>Resize</string>
+			<key>ID</key>
+			<integer>20</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+			<key>Style</key>
+			<dict/>
+			<key>Text</key>
+			<dict>
+				<key>Text</key>
+				<string>{\rtf1\ansi\ansicpg1252\cocoartf1187
+\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
+
+\f0\fs24 \cf0 Trace}</string>
+			</dict>
+		</dict>
+		<dict>
+			<key>Bounds</key>
+			<string>{{60, 83}, {151, 286}}</string>
+			<key>Class</key>
+			<string>ShapedGraphic</string>
+			<key>ID</key>
+			<integer>23</integer>
+			<key>Shape</key>
+			<string>Rectangle</string>
+		</dict>
+	</array>
+	<key>GridInfo</key>
+	<dict/>
+	<key>GuidesLocked</key>
+	<string>NO</string>
+	<key>GuidesVisible</key>
+	<string>YES</string>
+	<key>HPages</key>
+	<integer>1</integer>
+	<key>ImageCounter</key>
+	<integer>1</integer>
+	<key>KeepToScale</key>
+	<false/>
+	<key>Layers</key>
+	<array>
+		<dict>
+			<key>Lock</key>
+			<string>NO</string>
+			<key>Name</key>
+			<string>Layer 1</string>
+			<key>Print</key>
+			<string>YES</string>
+			<key>View</key>
+			<string>YES</string>
+		</dict>
+	</array>
+	<key>LayoutInfo</key>
+	<dict>
+		<key>Animate</key>
+		<string>NO</string>
+		<key>circoMinDist</key>
+		<real>18</real>
+		<key>circoSeparation</key>
+		<real>0.0</real>
+		<key>layoutEngine</key>
+		<string>dot</string>
+		<key>neatoSeparation</key>
+		<real>0.0</real>
+		<key>twopiSeparation</key>
+		<real>0.0</real>
+	</dict>
+	<key>LinksVisible</key>
+	<string>NO</string>
+	<key>MagnetsVisible</key>
+	<string>NO</string>
+	<key>MasterSheets</key>
+	<array/>
+	<key>ModificationDate</key>
+	<string>2012-08-02 13:05:21 +0000</string>
+	<key>Modifier</key>
+	<string>David Schneider</string>
+	<key>NotesVisible</key>
+	<string>NO</string>
+	<key>Orientation</key>
+	<integer>2</integer>
+	<key>OriginVisible</key>
+	<string>NO</string>
+	<key>PageBreaks</key>
+	<string>YES</string>
+	<key>PrintInfo</key>
+	<dict>
+		<key>NSBottomMargin</key>
+		<array>
+			<string>float</string>
+			<string>41</string>
+		</array>
+		<key>NSHorizonalPagination</key>
+		<array>
+			<string>coded</string>
+			<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
+		</array>
+		<key>NSLeftMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+		<key>NSPaperSize</key>
+		<array>
+			<string>size</string>
+			<string>{595, 842}</string>
+		</array>
+		<key>NSPrintReverseOrientation</key>
+		<array>
+			<string>int</string>
+			<string>0</string>
+		</array>
+		<key>NSRightMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+		<key>NSTopMargin</key>
+		<array>
+			<string>float</string>
+			<string>18</string>
+		</array>
+	</dict>
+	<key>PrintOnePage</key>
+	<false/>
+	<key>ReadOnly</key>
+	<string>NO</string>
+	<key>RowAlign</key>
+	<integer>1</integer>
+	<key>RowSpacing</key>
+	<real>36</real>
+	<key>SheetTitle</key>
+	<string>Canvas 1</string>
+	<key>SmartAlignmentGuidesActive</key>
+	<string>YES</string>
+	<key>SmartDistanceGuidesActive</key>
+	<string>YES</string>
+	<key>UniqueID</key>
+	<integer>1</integer>
+	<key>UseEntirePage</key>
+	<false/>
+	<key>VPages</key>
+	<integer>1</integer>
+	<key>WindowInfo</key>
+	<dict>
+		<key>CurrentSheet</key>
+		<integer>0</integer>
+		<key>ExpandedCanvases</key>
+		<array>
+			<dict>
+				<key>name</key>
+				<string>Canvas 1</string>
+			</dict>
+		</array>
+		<key>ListView</key>
+		<true/>
+		<key>OutlineWidth</key>
+		<integer>142</integer>
+		<key>RightSidebar</key>
+		<false/>
+		<key>ShowRuler</key>
+		<true/>
+		<key>Sidebar</key>
+		<true/>
+		<key>SidebarWidth</key>
+		<integer>120</integer>
+		<key>Zoom</key>
+		<real>1</real>
+		<key>ZoomValues</key>
+		<array>
+			<array>
+				<string>Canvas 1</string>
+				<real>1</real>
+				<real>1</real>
+			</array>
+		</array>
+	</dict>
+</dict>
+</plist>
diff --git a/talk/vmil2012/figures/loop_bridge.pdf b/talk/vmil2012/figures/loop_bridge.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..a73e62a7afeb03fb031f00c14de9543754ade016
GIT binary patch

[cut]

diff --git a/talk/vmil2012/logs/backend_summary.csv b/talk/vmil2012/logs/backend_summary.csv
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/logs/backend_summary.csv
@@ -0,0 +1,12 @@
+exe,bench,asm size,guard map size
+pypy-c,chaos,157.141601562,24.4013671875
+pypy-c,crypto_pyaes,170.418945312,24.1279296875
+pypy-c,django,233.50390625,51.03125
+pypy-c,go,4871.02246094,888.092773438
+pypy-c,pyflate-fast,729.340820312,150.737304688
+pypy-c,raytrace-simple,491.594726562,74.0048828125
+pypy-c,richards,157.1171875,17.638671875
+pypy-c,spambayes,2499.93554688,331.73828125
+pypy-c,sympy_expand,929.21484375,214.017578125
+pypy-c,telco,516.486328125,77.59765625
+pypy-c,twisted_names,1694.91308594,228.374023438
diff --git a/talk/vmil2012/logs/benchs.txt b/talk/vmil2012/logs/benchs.txt
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/logs/benchs.txt
@@ -0,0 +1,11 @@
+chaos
+crypto_pyaes
+django
+go
+pyflate-fast
+raytrace-simple
+richards
+spambayes
+sympy_expand
+telco
+twisted_names
diff --git a/talk/vmil2012/logs/bridge_summary.csv b/talk/vmil2012/logs/bridge_summary.csv
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/logs/bridge_summary.csv
@@ -0,0 +1,12 @@
+exe,bench,guards,bridges
+pypy-c,chaos,1142,13
+pypy-c,crypto_pyaes,1131,16
+pypy-c,django,1471,21
+pypy-c,go,43005,805
+pypy-c,pyflate-fast,4985,104
+pypy-c,raytrace-simple,3500,85
+pypy-c,richards,1362,38
+pypy-c,spambayes,15434,321
+pypy-c,sympy_expand,5712,113
+pypy-c,telco,3554,64
+pypy-c,twisted_names,12812,114
diff --git a/talk/vmil2012/logs/resume_summary.csv b/talk/vmil2012/logs/resume_summary.csv
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/logs/resume_summary.csv
@@ -0,0 +1,12 @@
+exe,bench,number of guards,total resume data size,naive resume data size
+pypy-c,chaos,888,389.4765625,1307.61328125
+pypy-c,crypto_pyaes,956,491.69140625,1684.98046875
+pypy-c,django,1137,611.619140625,2558.9921875
+pypy-c,go,29989,23216.4765625,91648.1972656
+pypy-c,pyflate-fast,4019,2029.67578125,7426.25
+pypy-c,raytrace-simple,2661,1422.10351562,4567.625
+pypy-c,richards,1044,685.36328125,2580.06054688
+pypy-c,spambayes,12693,6418.13476562,35645.0546875
+pypy-c,sympy_expand,4532,2232.78515625,10008.6386719
+pypy-c,telco,2804,1524.15429688,6385.03515625
+pypy-c,twisted_names,9561,5434.06835938,29272.2089844
diff --git a/talk/vmil2012/logs/summary.csv b/talk/vmil2012/logs/summary.csv
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/logs/summary.csv
@@ -0,0 +1,12 @@
+exe,bench,number of loops,new before,new after,get before,get after,set before,set after,guard before,guard after,numeric before,numeric after,rest before,rest after
+pypy-c,chaos,32,1810,186,1832,945,8996,684,3954,888,1091,459,4104,2006
+pypy-c,crypto_pyaes,35,1385,234,1263,897,9779,992,2795,956,1339,737,3114,2212
+pypy-c,django,40,1350,188,2855,1186,8714,834,5111,1137,733,285,3977,2031
+pypy-c,go,870,59577,4874,94261,33539,373765,22356,130499,29989,22291,8590,105354,53618
+pypy-c,pyflate-fast,147,5797,781,7789,3492,38540,2394,13826,4019,4081,2165,15853,8788
+pypy-c,raytrace-simple,115,6997,629,6307,2715,43811,2812,14174,2661,2461,1506,15664,7203
+pypy-c,richards,51,1933,84,2656,1051,15947,569,5503,1044,725,217,5697,2587
+pypy-c,spambayes,471,15784,2773,27912,13135,108448,16484,42053,12693,13001,5517,35225,20360
+pypy-c,sympy_expand,174,6393,1069,10293,4265,36188,3877,20333,4532,2712,1330,16319,7344
+pypy-c,telco,93,7334,466,9849,2306,40558,2565,20356,2804,2831,1014,16893,6639
+pypy-c,twisted_names,250,14670,1918,26892,9814,90695,9127,47490,9561,8797,2981,33991,16546
diff --git a/talk/vmil2012/paper.bib b/talk/vmil2012/paper.bib
--- a/talk/vmil2012/paper.bib
+++ b/talk/vmil2012/paper.bib
@@ -0,0 +1,30 @@
+ at inproceedings{Gal:2006,
+        author = {Gal, Andread and Probst, Christian W. and Franz, Michael},
+        title = {{HotpathVM: An Effective JIT Compiler for Resource-constrained Devices}},
+        location = {Ottawa, {Ontario}, {Canada}},
+        series = {{VEE} '06},
+        isbn = {1-59593-332-6}, 
+        booktitle = {Proceedings of the 2nd International Conference on Virtual Execution Environments}, 
+        publisher = {{ACM}},
+        year = {2006},
+        pages = {144-153}
+}
+ at inproceedings{Gal:2009ux,
+        author = {Gal, Andreas and Franz, Michael and Eich, B and Shaver, M and Anderson, David},
+        title = {{Trace-based Just-in-Time Type Specialization for Dynamic Languages}},
+        booktitle = {PLDI '09: Proceedings of the ACM SIGPLAN 2009 conference on Programming language design and implementation},
+        url = {http://portal.acm.org/citation.cfm?id=1542528},
+}
+ at inproceedings{Bala:2000wv,
+        author = {Bala, Vasanth and Duesterwald, Evelyn and Banerjia, Sanjeev},
+        title = {{Dynamo: A Transparent Dynamic Optimization System}},
+        booktitle = {PLDI '00: Proceedings of the ACM SIGPLAN 2000 conference on Programming language design and implementation},
+}
+ at misc{Pall:2009,
+    author = {Pall, Mike},
+    title = {LuaJIT 2.0 intellectual property disclosure and research opportunities},
+    month = jun,
+    year = {2009},
+    url = {http://lua-users.org/lists/lua-l/2009-11/msg00089.html}
+}
+
diff --git a/talk/vmil2012/paper.tex b/talk/vmil2012/paper.tex
--- a/talk/vmil2012/paper.tex
+++ b/talk/vmil2012/paper.tex
@@ -1,4 +1,4 @@
-\documentclass{sigplanconf}
+\documentclass[10pt,preprint]{sigplanconf}
 
 \usepackage{ifthen}
 \usepackage{fancyvrb}
@@ -13,6 +13,7 @@
 \usepackage{amsfonts}
 \usepackage[utf8]{inputenc}
 \usepackage{setspace}
+\usepackage[colorinlistoftodos]{todonotes}
 
 \usepackage{listings}
 
@@ -36,7 +37,7 @@
 }
 
 \newboolean{showcomments}
-\setboolean{showcomments}{false}
+\setboolean{showcomments}{true}
 \ifthenelse{\boolean{showcomments}}
   {\newcommand{\nb}[2]{
     \fbox{\bfseries\sffamily\scriptsize#1}
@@ -54,6 +55,7 @@
 \newcommand\arigo[1]{\nb{AR}{#1}}
 \newcommand\fijal[1]{\nb{FIJAL}{#1}}
 \newcommand\pedronis[1]{\nb{PEDRONIS}{#1}}
+\newcommand\bivab[1]{\nb{DAVID}{#1}}
 \newcommand{\commentout}[1]{}
 
 \newcommand{\noop}{}
@@ -72,14 +74,14 @@
 
 \begin{document}
 
-\title{Efficiently Handling Guards in the low level design of RPython's tracing JIT}
+\title{Efficiently Handling Guards in the Low Level Design of RPython's tracing JIT}
 
-\authorinfo{Carl Friedrich Bolz$^a$ \and David Schneider$^{a}$}
+\authorinfo{David Schneider$^{a}$ \and Carl Friedrich Bolz$^a$}
            {$^a$Heinrich-Heine-Universit&#228;t D&#252;sseldorf, STUPS Group, Germany
            }
-           {XXX emails}
+           {david.schneider at uni-duesseldorf.de \and cfbolz at gmx.de}
 
-\conferenceinfo{VMIL'11}{}
+\conferenceinfo{VMIL'12}{}
 \CopyrightYear{2012}
 \crdata{}
 
@@ -94,20 +96,92 @@
 \keywords{XXX}
 
 \begin{abstract}
-
+In pellentesque faucibus vestibulum. Nulla at nulla justo, eget luctus tortor.
+Nulla facilisi. Duis aliquet egestas purus in blandit. Curabitur vulputate,
+ligula lacinia scelerisque tempor, lacus lacus ornare ante, ac egestas est urna
+sit amet arcu. Class aptent taciti sociosqu ad litora torquent per conubia
+nostra, per inceptos himenaeos. Sed molestie augue sit amet leo consequat
+posuere. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices
+posuere cubilia Curae; Proin vel ante a orci tempus eleifend ut et magna. Lorem
+ipsum dolor sit amet, consectetur adipiscing elit. Vivamus luctus urna sed urna
+ultricies ac tempor dui sagittis. In.
 \end{abstract}
 
 
 %___________________________________________________________________________
 \section{Introduction}
 
+In this paper we describe and analyze how deoptimization works in the context
+of tracing just-in-time compilers. What instructions are used in the
+intermediate and low-level representation of the JIT instructions and how these
+are implemented.
 
-The contributions of this paper are:
+Although there are several publications about tracing just-in-time compilers,
+to our knowledge, there are none that describe deoptimization and the use and
+implementation of guards in this context.
+
+Based on the informal observation that guards are among the most common
+operations in the traces produced by PyPy's tracing JIT and that guards are
+operations that are associated with an overhead to maintain information about
+state to be able to rebuild the execution state in case of deoptimization, our
+goal is to present concrete numbers for the frequency and the overhead produced
+by guards, explain how they are implemented in the different levels of PyPy's
+tracing JIT and explain the rationale behind the design decisions based on the
+numbers.
+
+The operations executed by an interpreter are recorded by the tracing JIT in
+case they are frequently executed, this process is described in more detail in
+Section~\ref{sec:Resume Data}, during the recording phase special operations,
+\texttt{guards}, are inserted into the recorded trace at all points where
+control flow could diverge. As can be seen on Figure~\ref{fig:guard_percent}
+guards account for 14.42\% to 22.32\% of the operations before and for 15.2\%
+to 20.12\% of the operations after the optimization pass over the traced and
+compiled parts of the benchmarks, making guards one of the most common
+operations. Many of these guards fail rarely on not all during execution. Given
+that associated with each guard information is stored, that is required to
+rebuild the execution state in case control flow diverges from the recorded
+path at a guard it is important to store the information associated with the
+guards in a manner that tries to keep the overhead for storing the information
+low while avoiding to put a burden on the execution of the recorded trace,
+making the optimization of guards an important aspect of
+the low-level design of a tracing just-in-time compiler.
+
+%Section~\ref{sec:Evaluation} presents Figures about the absolute number of
+%operations for each benchmark, and the overhead produced by the information
+%stored at the different levels for the guards
+In this paper we want to substantiate the aforementioned observations and
+describe based on them the reasoning behind and the implementation of guards in
+PyPy's tracing just-in-time compiler, the contributions of this paper are:
 \begin{itemize}
- \item
+  \item An analysis of guards in the context of PyPy's tracing JIT to
+  substantiate the aforementioned observation, based on a set of benchmarks.
+  \item We provide a detailed measurements about the frequency and the
+  overhead associated with guards.
+  \item We provide a description about how guards are implemented in the high\-
+  and low-level parts of the JIT and describe the rationale behind the design.
 \end{itemize}
+\begin{figure}
+    \include{figures/guard_table}
+    \caption{Percentage of guards before and after optimization for different benchmarks}
+    \label{fig:guard_percent}
+\end{figure}
 
-The paper is structured as follows:
+The set of central concepts upon which this work is based is described in
+Section~\ref{sec:Background}, such as the PyPy project, the RPython language
+and its meta-tracing JIT. Based on these concepts in Section~\ref{sec:Resume
+Data} we proceed to describe for PyPy's tracing JIT the details of guards in
+the frontend\bivab{better term for this?} related to recording and storing the
+information required to restore the interpreter state in case of a guard
+failure, once the frontend has traced and optimized a loop it invokes the
+backend to compile the operations to machine code, Section \ref{sec:Guards in
+the Backend} describes the low-level aspects of how guards are implemented in
+the JIT-backend. The frequency of guards and the overhead associated with the
+implementation described in this paper is discussed in
+Section~\ref{sec:evaluation}. Section~\ref{sec:Related Work} presents an
+overview about how guards are treated in the context of other just-in-time
+compilers. Finally Section~\ref{sec:Conclusion} summarizes our conclusions and
+gives an outlook on further research topics.
+
 
 \section{Background}
 \label{sec:Background}
@@ -117,16 +191,16 @@
 
 
 The RPython language and the PyPy Project were started in 2002 with the goal of
-creating a python interpreter written in a High level language, allowing easy
+creating a Python interpreter written in a high level language, allowing easy
 language experimentation and extension. PyPy is now a fully compatible
-alternative implementation of the Python language, xxx mention speed. The
-Implementation takes advantage of the language features provided by RPython
+alternative implementation of the Python language\bivab{mention speed}. The
+implementation takes advantage of the language features provided by RPython
 such as the provided tracing just-in-time compiler described below.
 
 RPython, the language and the toolset originally developed to implement the
 Python interpreter have developed into a general environment for experimenting
-and developing fast and maintainable dynamic language implementations. xxx Mention
-the different language impls.
+and developing fast and maintainable dynamic language implementations.
+\bivab{Mention the different language impls}
 
 RPython is built of two components, the language and the translation toolchain
 used to transform RPython programs to executable units.  The RPython language
@@ -148,6 +222,7 @@
 \label{sub:tracing}
 
  * Tracing JITs
+ * Mention SSA
  * JIT Compiler
    * describe the tracing jit stuff in pypy
    * reference tracing the meta level paper for a high level description of what the JIT does
@@ -156,30 +231,305 @@
 
 %___________________________________________________________________________
 
+\begin{figure}
+    \input{figures/example.tex}
+    \caption{Example Program}
+    \label{fig:trace-log}
+\end{figure}
 
-\section{Resume Data}
+\section{Guards in the Frontend} %{Resume Data}
 \label{sec:Resume Data}
 
-* High level handling of resumedata
-   * trade-off fast tracing v/s memory usage
-   * creation in the frontend&#194;
-   * optimization
-   * compression
-   * interaction with optimization
+Since tracing linearizes control flow by following one concrete execution,
+not the full control flow of a program is observed.
+The possible points of deviation from the trace are guard operations
+that check whether the same assumptions observed during tracing still hold during execution.
+In later executions of the trace the guards can fail.
+If that happens, execution needs to continue in the interpreter.
+This means it is necessary to attach enough information to a guard
+to reconstruct the interpreter state when that guard fails.
+This information is called the \emph{resume data}.
+
+To do this reconstruction, it is necessary to take the values of the SSA
+variables of the trace and build interpreter stack frames.  Tracing
+aggressively inlines functions, therefore the reconstructed state of the
+interpreter can consist of several interpreter frames.
+
+If a guard fails often enough, a trace is started from it
+to create a trace tree.
+When that happens another use case of resume data
+is to construct the tracer state.
+
+There are several forces guiding the design of resume data handling.
+Guards are a very common operations in the traces.
+However, a large percentage of all operations
+are optimized away before code generation.
+Since there are a lot of guards
+the resume data needs to be stored in a very compact way.
+On the other hand, tracing should be as fast as possible,
+so the construction of resume data must not take too much time.
+
+\subsection{Capturing of Resume Data During Tracing}
+\label{sub:capturing}
+
+Every time a guard is recorded during tracing
+the tracer attaches preliminary resume data to it.
+The data is preliminary in that it is not particularly compact yet.
+The preliminary resume data takes the form of a stack of symbolic frames.
+The stack contains only those interpreter frames seen by the tracer.
+The frames are symbolic in that the local variables in the frames
+do not contain values.
+Instead, every local variables contains the SSA variable of the trace
+where the value would later come from, or a constant.
+
+\subsection{Compression of Resume Data}
+\label{sub:compression}
+
+The core idea of storing resume data as compactly as possible
+is to share parts of the data structure between subsequent guards.
+This is often useful because the density of guards in traces is so high,
+that quite often not much changes between them.
+Since resume data is a linked list of symbolic frames
+often only the information in the top frame changes from one guard to the next.
+The other frames can often be just reused.
+The reason for this is that during tracing only the variables
+of the currently executing frames can change.
+Therefore if two guards are generated from code in the same function
+the resume data of the rest of the stack can be reused.
+
+In addition to sharing as much as possible between subsequent guards
+a compact representation of the local variables of symbolic frames is used.
+Every variable in the symbolic frame is encoded using two bytes.
+Two bits are used as a tag to denote where the value of the variable
+comes from.
+The remaining 14 bits are a payload that depends on the tag bits.
+
+The possible source of information are:
+
+\begin{itemize}
+    \item For small integer constants
+        the payload contains the value of the constant.
+    \item For other constants
+        the payload contains an index into a per-loop list of constants.
+    \item For SSA variables,
+        the payload is the number of the variable.
+    \item For virtuals,
+        the payload is an index into a list of virtuals, see next section.
+\end{itemize}
+\todo{figure showing linked resume-data}
+
+\subsection{Interaction With Optimization}
+\label{sub:optimization}
+
+Guards interact with optimizations in various ways.
+Most importantly optimizations try to remove as many operations
+and therefore guards as possible.
+This is done with many classical compiler optimizations.
+In particular guards can be removed by subexpression elimination.
+If the same guard is encountered a second time in the trace,
+the second one can be removed.
+This also works if a later guard is weaker implied by a earlier guard.
+
+One of the techniques in the optimizer specific to tracing for removing guards
+is guard strengthening~\cite{bebenita_spur:_2010}.
+The idea of guard strengthening is that if a later guard is stronger
+than an earlier guard it makes sense to move the stronger guard
+to the point of the earlier, weaker guard and to remove the weaker guard.
+Moving a guard to an earlier point is always valid,
+it just means that the guard fails earlier during the trace execution
+(the other direction is clearly not valid).
+
+The other important point of interaction between resume data and the optimizer
+is RPython's allocation removal optimization~\cite{bolz_allocation_2011}.
+This optimization discovers allocations in the trace that create objects
+that do not survive long.
+An example is the instance of \lstinline{Even} in the example\cfbolz{reference figure}.
+Allocation removal makes resume data more complex.
+Since allocations are removed from the trace it becomes necessary
+to reconstruct the objects that were not allocated so far when a guard fails.
+Therefore the resume data needs to store enough information
+to make this reconstruction possible.
+
+Adding this additional information is done as follows.
+So far, every variable in the symbolic frames
+contains a constant or an SSA variable.
+After allocation removal the variables in the symbolic frames can also contain
+``virtual'' objects.
+These are objects that were not allocated so far,
+because the optimizer removed their allocation.
+The virtual objects in the symbolic frames describe exactly
+how the heap objects that have to be allocated on guard failure look like.
+To this end, the content of every field of the virtual object is described
+in the same way that the local variables of symbolic frames are described.
+The fields of the virtual objects can therefore be SSA variables, constants
+or other virtual objects.
+They are encoded using the same compact two-byte representation
+as local variables.
+
+During the storing of resume data virtual objects are also shared
+between subsequent guards as much as possible.
+The same observation as about frames applies:
+Quite often a virtual object does not change from one guard to the next.
+Then the data structure is shared.
+
+Similarly, stores into the heap are delayed as long as possible.
+This can make it necessary to perform these delayed stores
+when leaving the trace via a guard.
+Therefore the resume data needs to contain a description
+of the delayed stores to be able to perform them when the guard fails.
+So far no special compression is done with this information.
+
+% subsection Interaction With Optimization (end)
+\subsection{Compiling Side-Exits and Trace Stitching} % (fold)
+\label{sub:Compiling side-exits and trace stitching}
    * tracing and attaching bridges and throwing away resume data
+   * restoring the state of the tracer
+     * keeping virtuals
    * compiling bridges
+\todo{maybe mention that the failargs also go into the bridge}
 
+% subsection Compiling side-exits and trace stitching (end)
 % section Resume Data (end)
 
+\todo{set line numbers to the line numbers of the rpython example}
+\begin{figure}
+    \input{figures/log.tex}
+    \caption{Optimized trace}
+    \label{fig:trace-log}
+\end{figure}
+% section Resume Data (end)
 \section{Guards in the Backend}
 \label{sec:Guards in the Backend}
 
-* Low level handling of guards
-   * Fast guard checks v/s memory usage
-   * memory efficient encoding of low level resume data
-   * fast checks for guard conditions
-   * slow bail out
+After optimization the resulting trace is handed to the over platform specific
+backend to be compiled to machine code. The compilation phase consists of two
+passes over the lists of instructions, a backwards pass to calculate live
+ranges of IR-level variables and a forward one to emit the instructions. During
+the forward pass IR-level variables are assigned to registers and stack
+locations by the register allocator according to the requirements of the to be
+emitted instructions.  Eviction/spilling is performed based on the live range
+information collected in the first pass. Each IR instruction is transformed
+into one or more machine level instructions that implement the required
+semantics, operations withouth side effects whose result is not used are not
+emitted. Guards instructions are transformed into fast checks at the machine
+code level that verify the corresponding condition.  In cases the value being
+checked by the guard is not used anywhere else the guard and the operation
+producing the value can merged, reducing even more the overhead of the guard.
+Figure \ref{fig:trace-compiled} shows how an \texttt{int\_eq} operation
+followed by a guard that checks the result of the operation are compiled to
+pseudo-assembler if the operation and the guard are compiled separated or if
+they are merged.
 
+\bivab{Figure needs better formatting}
+\begin{figure}[ht]
+  \noindent
+  \centering
+  \begin{minipage}{1\columnwidth}
+    \begin{lstlisting}[mathescape]
+$b_1$ = int_eq($i_2$, 1)
+guard_false($b_1$)
+    \end{lstlisting}
+  \end{minipage}
+  \begin{minipage}{.40\columnwidth}
+    \begin{lstlisting}
+CMP r6, #1
+MOVEQ r8, #1
+MOVNE r8, #0
+CMP r8, #0
+BEQ <bailout>
+    \end{lstlisting}
+  \end{minipage}
+  \hfill
+  \begin{minipage}{.40\columnwidth}
+    \begin{lstlisting}
+CMP r6, #1
+BNE <bailout>
+...
+...
+...
+    \end{lstlisting}
+  \end{minipage}
+  \caption{Separated and merged compilation of operations and guards}
+  \label{fig:trace-compiled}
+\end{figure}
+
+Each guard in the IR has attached to it a list of the IR-variables required to
+rebuild the execution state in case the trace is left through the side-exit
+corresponding to the guard. When a guard is compiled, additionally to the
+condition check two things are generated/compiled. First a special data
+structure called \emph{low-level resume data} is created that encodes the
+information provided by the register allocator about where the values
+corresponding to each IR-variable required by the guard will be stored when
+execution reaches the code emitted for the corresponding guard. \bivab{go into
+more detail here?!} This encoding needs to be as compact as possible to
+maintain an acceptable memory profile.
+
+\todo{example for low-level resume data showing how the current encoding works?}
+
+Second a piece of code is generated for each guard that acts as a trampoline.
+Guards are implemented as a conditional jump to this trampoline. In case the
+condition checked in the guard fails execution and a side-exit should be taken
+execution jumps to the trampoline. In the trampoline the pointer to the
+\emph{low-level resume data} is loaded and jumps to generic bail-out handler
+that is used to leave the compiled trace in case of a guard failure.
+
+Using the encoded location information the bail-out handler reads from the
+saved execution state the values that the IR-variables had  at the time of the
+guard failure and stores them in a location that can be read by the fronted.
+After saving the information the control is passed to the frontend signaling
+which guard failed so the frontend can read the information passed and restore
+the state corresponding to the point in the program.
+
+As in previous sections the underlying idea for the design of guards is to have
+a fast on-trace profile and a potentially slow one in the bail-out case where
+the execution takes one of the side exits due to a guard failure. At the same
+time the data stored in the backend needed to rebuild the state needs to be as
+compact as possible to reduce the memory overhead produced by the large number
+of guards, the numbers in Figure~\ref{fig:backend_data} illustrate that the
+compressed encoding currently has about 15\% to 25\% of the size of of the
+generated instructions on x86.
+
+As explained in previous sections, when a specific guard has failed often enough
+a new trace, referred to as a \emph{bridge}, starting from this guard is recorded and
+compiled. When compiling bridges the goal is that future failures of the guards
+that led to the compilation of the bridge should execute the bridge without
+additional overhead, in particular the failure of the guard should not lead
+to leaving the compiled code prior to execution the code of the bridge.
+
+The process of compiling a bridge is very similar to compiling a loop.
+Instructions and guards are processed in the same way as described above. The
+main difference is the setup phase. When compiling a trace we start with a clean
+slate. The compilation of a bridge is started from a state (register and stack
+bindings) that corresponds to the state during the compilation of the original
+guard. To restore the state needed to compile the bridge we use the encoded
+representation created for the guard to rebuild the bindings from IR-variables
+to stack locations and registers used in the register allocator.  With this
+reconstruction all bindings are restored to the state as they were in the
+original loop up to the guard.
+
+Once the bridge has been compiled the guard that led to compiling the birdge is
+patched to redirect control flow to the bridge in case the check fails. In
+future if the guard fails again it jumps to the code compiled for the bridge
+instead of bailing out. Once the guard has been compiled and attached to the
+loop the guard becomes just a point where control-flow can split. The loop
+after the guard and the bridge are just conditional paths.
+Figure~\ref{fig:trampoline} shows a digram of a compiled loop with two guards,
+Guard \#1 jumps to the trampoline, loads the \texttt{low level resume data} and
+then calls the compensation code, whereas Guard \#2 has already been patched
+and directly jumps to the corresponding bridge. The bridge also contains two
+guards that work based on the same principles.
+\begin{figure}
+\centering
+\includegraphics[width=0.5\textwidth]{figures/loop_bridge.pdf}
+\caption{Trace control flow in case of guard failures with and without bridges}
+\label{fig:trampoline}
+\end{figure}
+%* Low level handling of guards
+%   * Fast guard checks v/s memory usage
+%   * memory efficient encoding of low level resume data
+%   * fast checks for guard conditions
+%   * slow bail out
+%
 % section Guards in the Backend (end)
 
 %___________________________________________________________________________
@@ -188,6 +538,87 @@
 \section{Evaluation}
 \label{sec:evaluation}
 
+The results presented in this section are based on numbers gathered by running
+a subset of the standard PyPy benchmarks. The PyPy benchmarks are used to
+measure the performance of PyPy and are composed of a series of
+micro-benchmarks and larger programs.\footnote{http://speed.pypy.org/} The
+benchmarks were taken from the PyPy benchmarks repository using revision
+\texttt{ff7b35837d0f}.\footnote{https://bitbucket.org/pypy/benchmarks/src/ff7b35837d0f}
+The benchmarks were run on a version of PyPy based on the
+tag~\texttt{0b77afaafdd0} and patched to collect additional data about the
+guards in the machine code
+backends.\footnote{https://bitbucket.org/pypy/pypy/src/0b77afaafdd0} All
+benchmark data was collected on a MacBook Pro 64 bit running Max OS 10.8 with
+the loop unrolling optimization disabled.\footnote{Since loop unrolling
+duplicates the body of loops it would no longer be possible to meaningfully
+compare the number of operations before and after optimization. Loop unrolling
+is most effective for numeric kernels, so the benchmarks presented here are not
+affected much by its absence.}
+
+Figure~\ref{fig:benchmarks} shows the total number of operations that are
+recorded during tracing for each of the benchmarks and what percentage of these
+are guards. Figure~\ref{fig:benchmarks} also shows the number of operations
+left after performing the different trace optimizations done by the trace
+optimizer, such as xxx. The last columns show the overall optimization rate and
+the optimization rate specific for guard operations, showing what percentage of
+the operations were removed during the optimizations phase.
+Figure~\ref{fig:benchmarks} shows that as can also be seen on
+Figure~\ref{fig:guard_percent} the optimization rate for guards is on par with
+the average optimization rate for all operations in a trace. After optimization
+the amount of guards left in the trace still represents about 15.18\% to
+20.22\% of the operation, a bit less than before the optimization where guards
+represented between 15.85\% and 22.48\% of the operations. After performing the
+optimizations the most common operations are those that are difficult or
+impossible to optimize, such as JIT internal operations and different types of
+calls. These account for 14.53\% to 18.84\% of the operations before and for
+28.69\% to 46.60\% of the operations after optimization. These numbers show
+that about one fifth of the operations, making guards one of the most common
+operations, that are compiled are guards and have associated with them the
+high- and low-level datastructes that are reconstruct the state.
+
+\begin{figure*}
+    \include{figures/benchmarks_table}
+    \caption{Benchmark Results}
+    \label{fig:benchmarks}
+\end{figure*}
+
+\todo{figure about failure counts of guards (histogram?)}
+\todo{add resume data sizes without sharing}
+\todo{add a footnote about why guards have a threshold of 100}
+
+The overhead that is incurred by the JIT to manage the \texttt{resume data},
+the \texttt{low-level resume data} and the generated machine code is shown in
+Figure~\ref{fig:backend_data}. It shows the total memory consumption of the
+code and of the data generated by the machine code backend for the different
+benchmarks mentioned above. The size of the machine code is composed of the
+size of the compiled operations, the trampolines generated for the guards and a
+set of support functions that are generated when the JIT starts and are shared
+by all compiled traces. The size of the \texttt{low-level resume data} is the
+size of the registers and stack to IR-level variable mappings and finally the
+size of the \texttt{resume data} is an approximation of the size of the
+compressed high-level resume data. While the \texttt{low-level resume data} has
+a size of about 15\% to 20\% of the generated instructions the \texttt{resume
+data} is even in the compressed form larger than the generated machine code.
+
+Tracing JITs compilers only compile a subset of the executed program so the
+amount of generated machine code will be smaller than for function based JITs.
+At the same time there is a several times larger overhead for keeping the
+resume information for the guards. The generated machine code accounts for
+20.21\% to 37.97\% of the size required for storing the different kinds of
+resume data.
+
+\begin{figure*}
+    \include{figures/backend_table}
+    \caption{Total size of generated machine code and guard data}
+    \label{fig:backend_data}
+\end{figure*}
+
+Both figures do not take into account garbage collection. Pieces of machine
+code can be globally invalidated or just become cold again. In both cases the
+generated machine code and the related data is garbage collected. The figures
+show the total amount of operations that are evaluated by the JIT and the
+total amount of code and data that is generated from the optimized traces.
+
 * Evaluation
    * Measure guard memory consumption and machine code size
    * Extrapolate memory consumption for guard other guard encodings
@@ -196,14 +627,116 @@
    * Measure the of guards and how many of these ever fail
 
 \section{Related Work}
+\label{sec:Related Work}
+
+\subsection{Guards in Other Tracing JITs}
+\label{sub:Guards in Other Tracing JITs}
+
+Guards as described are a concept associated with tracing just-in-time
+compilers to represent possible divergent control flow paths.
+
+SPUR~\cite{bebenita_spur:_2010} is a tracing JIT compiler
+for a C\# virtual machine.
+It handles guards by always generating code for every one of them
+that transfers control back to the unoptimized code.
+Since the transfer code needs to reconstruct the stack frames
+of the unoptimized code,
+the transfer code is quite large.
+
+Mike Pall, the author of LuaJIT describes in a post to the lua-users mailing
+list different technologies and techniques used in the implementation of
+LuaJIT~\cite{Pall:2009}.\todo{decide if LuaJIT is a footnote or a reference and
+fix website citation} Pall explains that guards in LuaJIT use a datastucture
+called snapshots, similar to PyPy's resume data, to store the information about
+how to rebuild the state from a side-exit using the information in the snapshot
+and the machine execution state. Pall also acknowledges that snapshot for
+guards are associated with a large memory footprint. The solution used in
+LuaJIT is to store sparse snapshots, avoiding the creation of snapshots for
+every guard to reduce memory pressure. Snapshots are only created for guards
+after updates to the global state, after control flow points from the original
+program and for guards that are likely to fail. As an outlook Pall mentions the
+plans to switch to compressed snapshots to further reduce redundancy.
+
+Linking side exits to pieces of later compiled machine code was described first
+in the context of Dynamo~\cite{Bala:2000wv} under the name of Fragment Linking.
+Once a new hot trace is emitted into the fragment cache it is linked to side
+exit that led to the compilation. Fragment Linking avoids the performance
+penalty involved in leaving the compiled and it to remove the compensation
+code used when restoring the machine state on a side exit.
+
+In~\cite{Gal:2006} Gal et. al describe that in the HotpathVM they experimented
+with having one generic compensation code block, like the RPython JIT, that
+uses a register variable mapping to restore the interpreter state. Later this
+was replaced by generating compensation code for each guard which produced a
+lower overhead in their benchmarks. HotpathVM also records secondary traces
+starting from failing guards that are connected directly to the original trace.
+Secondary traces are compiled by first restoring the register allocator state to
+the state at the side exit. The information is retrieved from a mapping stored
+in the guard that maps machine level registers and stack to Java level stack
+and variables.
+
+Gal et. al~\cite{Gal:2009ux} write about how TraceMonkey uses trace stitching
+to avoid th overhead of returning to the trace monitor and calling another
+trace when taking a side exit. In their approach it is required to write live
+values to an activation record before entering the new trace.
+
+% subsection Guards in Other Tracing JITs (end)
+
+\subsection{Deoptimization in Method-Based JITs}
+\label{sub:Deoptimization in Method-Based JITs}
+
+Deoptimization in method-based JITs is used if one of the assumptions
+of the code generated by a JIT-compiler changes.
+This is often the case when new code is added to the system,
+or when the programmer tries to debug the program.
+
+Deutsch et. al.~\cite{deutsch_efficient_1984} describe the use of stack descriptions
+to make it possible to do source-level debugging of JIT-compiled code.
+Self uses deoptimization to reach the same goal~\cite{XXX}.
+When a function is to be debugged, the optimized code version is left
+and one compiled without inlining and other optimizations is entered.
+Self uses scope descriptors to describe the frames
+that need to be re-created when leaving the optimized code.
+The scope descriptors are between 0.45 and 0.76 times
+the size of the generated machine code.
+
+Java Hotspot~\cite{paleczny_java_2001} contains a deoptimization framework that is used
+for debugging and when an uncommon trap is triggered.
+To be able to do this, Hotspot stores a mapping from optimized states
+back to the interpreter state at various deoptimization points.
+There is no discussion of the memory use of this information.
+
+The deoptimization information of Hotspot is extended
+to support correct behaviour
+when scalar replacement of fields is done for non-escaping objects~\cite{kotzmann_escape_2005}.
+The approach is extremely similar to how RPython's JIT handles virtual objects.
+For every object that is not allocated in the code,
+the deoptimization information contains a description
+of the content of the fields.
+When deoptimizing code, these objects are reallocated
+and their fields filled with the values
+described by the deoptimization information.
+The paper does not describe any attempts to store this information compactly.
+
+
+% subsection Deoptimization in Method-Based JITs (end)
+% section Related Work (end)
 
 
 \section{Conclusion}
+\label{sec:Conclusion}
 
+\todo{conclusion}
 
 \section*{Acknowledgements}
-
+\section*{Appendix}
+\begin{figure*}
+    \include{figures/ops_count_table}
+    \caption{Relative numbers of operations in the traces generated for
+    different benchmarks}
+    \label{fig:ops_count}
+\end{figure*}
 \bibliographystyle{abbrv}
-\bibliography{paper}
-
+\bibliography{zotero,paper}
+\listoftodos
 \end{document}
diff --git a/talk/vmil2012/tool/backenddata.py b/talk/vmil2012/tool/backenddata.py
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/tool/backenddata.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+from __future__ import division
+"""
+Parse and summarize the traces produced by pypy-c-jit when PYPYLOG is set.
+only works for logs when unrolling is disabled
+"""
+
+import csv
+import optparse
+import os
+import re
+import sys
+from pypy.jit.metainterp.history import ConstInt
+from pypy.jit.tool.oparser import parse
+from pypy.rpython.lltypesystem import llmemory, lltype
+from pypy.tool import logparser
+
+
+def collect_logfiles(path):
+    if not os.path.isdir(path):
+        logs = [os.path.basename(path)]
+    else:
+        logs = os.listdir(path)
+    all = []
+    for log in logs:
+        parts = log.split(".")
+        if len(parts) != 3:
+            continue
+        l, exe, bench = parts
+        if l != "logbench":
+            continue
+        all.append((exe, bench, log))
+    all.sort()
+    return all
+
+
+def collect_guard_data(log):
+    """Calculate the total size in bytes of the locations maps for all guards
+    in a logfile"""
+    guards = logparser.extract_category(log, 'jit-backend-guard-size')
+    return sum(int(x[6:]) for x in guards if x.startswith('chars'))
+
+
+def collect_asm_size(log, guard_size=0):
+    """Calculate the size of the machine code pieces of a logfile. If
+    guard_size is passed it is substracted from result under the assumption
+    that the guard location maps are encoded in the instruction stream"""
+    asm = logparser.extract_category(log, 'jit-backend-dump')
+    asmlen = 0
+    for block in asm:
+        expr = re.compile("CODE_DUMP @\w+ \+\d+\s+(.*$)")
+        match = expr.search(block)
+        assert match is not None  # no match found
+        code = match.group(1)
+        asmlen += len(code)
+    return asmlen - guard_size
+
+
+def collect_data(dirname, logs):
+    for exe, name, log in logs:
+        path = os.path.join(dirname, log)
+        logfile = logparser.parse_log_file(path)
+        guard_size = collect_guard_data(logfile)
+        asm_size = collect_asm_size(logfile, guard_size)
+        yield (exe, name, log, asm_size, guard_size)
+
+
+def main(path):
+    logs = collect_logfiles(path)
+    if os.path.isdir(path):
+        dirname = path
+    else:
+        dirname = os.path.dirname(path)
+    results = collect_data(dirname, logs)
+
+    with file("logs/backend_summary.csv", "w") as f:
+        csv_writer = csv.writer(f)
+        row = ["exe", "bench", "asm size", "guard map size"]
+        csv_writer.writerow(row)
+        print row
+        for exe, bench, log, asm_size, guard_size in results:
+            row = [exe, bench, asm_size / 1024, guard_size / 1024]
+            csv_writer.writerow(row)
+            print row
+
+if __name__ == '__main__':
+    parser = optparse.OptionParser(usage="%prog logdir_or_file")
+
+    options, args = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        sys.exit(2)
+    else:
+        main(args[0])
diff --git a/talk/vmil2012/tool/bridgedata.py b/talk/vmil2012/tool/bridgedata.py
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/tool/bridgedata.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+"""
+Parse and summarize the jit-summary data """
+
+import csv
+import optparse
+import os
+import re
+import sys
+from pypy.jit.metainterp.history import ConstInt
+from pypy.jit.tool.oparser import parse
+from pypy.rpython.lltypesystem import llmemory, lltype
+from pypy.tool import logparser
+
+
+def collect_logfiles(path):
+    if not os.path.isdir(path):
+        logs = [os.path.basename(path)]
+    else:
+        logs = os.listdir(path)
+    all = []
+    for log in logs:
+        parts = log.split(".")
+        if len(parts) != 3:
+            continue
+        l, exe, bench = parts
+        if l != "logbench":
+            continue
+        all.append((exe, bench, log))
+    all.sort()
+    return all
+
+
+def collect_data(dirname, logs):
+    for exe, name, log in logs:
+        path = os.path.join(dirname, log)
+        logfile = logparser.parse_log_file(path)
+        summary = logparser.extract_category(logfile, 'jit-summary')
+        if len(summary) == 0:
+            yield (exe, name, log, 'n/a', 'n/a')
+        summary = summary[0].splitlines()
+        for line in summary:
+            if line.startswith('Total # of bridges'):
+                bridges = line.split()[-1]
+            elif line.startswith('opt guards'):
+                guards = line.split()[-1]
+        yield (exe, name, log, guards, bridges)
+
+
+def main(path):
+    logs = collect_logfiles(path)
+    if os.path.isdir(path):
+        dirname = path
+    else:
+        dirname = os.path.dirname(path)
+    results = collect_data(dirname, logs)
+
+    with file("logs/bridge_summary.csv", "w") as f:
+        csv_writer = csv.writer(f)
+        row = ["exe", "bench", "guards", "bridges"]
+        csv_writer.writerow(row)
+        print row
+        for exe, bench, log, guards, bridges in results:
+            row = [exe, bench, guards, bridges]
+            csv_writer.writerow(row)
+            print row
+
+if __name__ == '__main__':
+    parser = optparse.OptionParser(usage="%prog logdir_or_file")
+
+    options, args = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        sys.exit(2)
+    else:
+        main(args[0])
diff --git a/talk/vmil2012/tool/build_tables.py b/talk/vmil2012/tool/build_tables.py
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/tool/build_tables.py
@@ -0,0 +1,180 @@
+from __future__ import division
+import csv
+import django
+from django.template import Template, Context
+import os
+import sys
+
+# This line is required for Django configuration
+django.conf.settings.configure()
+
+
+def getlines(csvfile):
+    with open(csvfile, 'rb') as f:
+        reader = csv.DictReader(f, delimiter=',')
+        return [l for l in reader]
+
+
+def build_ops_count_table(csvfiles, texfile, template):
+    assert len(csvfiles) == 1
+    lines = getlines(csvfiles[0])
+    keys = 'numeric set get rest new guard '.split()
+    table = []
+    head = ['Benchmark']
+    head += ['%s b' % k for k in keys]
+    head += ['%s a' % k for k in keys]
+
+    for bench in lines:
+        ops = {'before': sum(int(bench['%s before' % s]) for s in keys),
+                'after': sum(int(bench['%s after' % s]) for s in keys)}
+
+        res = [bench['bench'].replace('_', '\\_'),]
+        for t in ('before', 'after'):
+            values = []
+            for key in keys:
+                o = int(bench['%s %s' % (key, t)])
+                values.append(o / ops[t] * 100)
+
+            assert 100.0 - sum(values) < 0.0001
+            res.extend(['%.2f ' % v for v in values])
+        table.append(res)
+    output = render_table(template, head, sorted(table))
+    write_table(output, texfile)
+
+def build_guard_table(csvfiles, texfile, template):
+    assert len(csvfiles) == 1
+    lines = getlines(csvfiles[0])
+    table = []
+    head = ['Benchmark', 'guards b/o in \%', 'guards a/o in \%']
+
+    keys = 'numeric set get rest new guard '.split()
+    for bench in lines:
+        ops = {'before': sum(int(bench['%s before' % s]) for s in keys),
+                'after': sum(int(bench['%s after' % s]) for s in keys)}
+
+        res = [bench['bench'].replace('_', '\\_'),]
+        for t in ('before', 'after'):
+            o = int(bench['guard %s' % t])
+            res.append('%.2f ' % (o / ops[t] * 100))
+        table.append(res)
+    output = render_table(template, head, sorted(table))
+    write_table(output, texfile)
+
+
+
+def build_benchmarks_table(csvfiles, texfile, template):
+    assert len(csvfiles) == 2
+    lines = getlines(csvfiles[0])
+    bridge_lines = getlines(csvfiles[1])
+    bridgedata = {}
+    for l in bridge_lines:
+        bridgedata[l['bench']] = l
+
+    head = ['Benchmark',
+            'ops b/o',
+            '\\% guards b/o',
+            'ops a/o',
+            '\\% guards a/o',
+            'opt. rate in \\%',
+            'guard opt. rate in \\%',
+            'bridges']
+
+    table = []
+    # collect data
+    keys = 'numeric guard set get rest new'.split()
+    for bench in lines:
+        ops_bo = sum(int(bench['%s before' % s]) for s in keys)
+        ops_ao = sum(int(bench['%s after' % s]) for s in keys)
+        guards_bo = int(bench['guard before'])
+        guards_ao = int(bench['guard after'])
+        # the guard count collected from jit-summary counts more guards than
+        # actually emitted, so the number collected from parsing the logfiles
+        # will probably be lower
+        assert guards_ao <= bridgedata[bench['bench']]['guards']
+        res = [
+                bench['bench'].replace('_', '\\_'),
+                ops_bo,
+                "%.2f" % (guards_bo / ops_bo * 100,),
+                ops_ao,
+                "%.2f" % (guards_ao / ops_ao * 100,),
+                "%.2f" % ((1 - ops_ao / ops_bo) * 100,),
+                "%.2f" % ((1 - guards_ao / guards_bo) * 100,),
+                bridgedata[bench['bench']]['bridges'],
+              ]
+        table.append(res)
+    output = render_table(template, head, sorted(table))
+    write_table(output, texfile)
+
+
+def build_backend_count_table(csvfiles, texfile, template):
+    lines = getlines(csvfiles[0])
+    resume_lines = getlines(csvfiles[1])
+    resumedata = {}
+    for l in resume_lines:
+        resumedata[l['bench']] = l
+
+    head = ['Benchmark',
+            'Machine code size (kB)',
+            'hl resume data (kB)',
+            'll resume data (kB)',
+            'machine code resume data relation in \\%']
+
+    table = []
+    # collect data
+    for bench in lines:
+        name = bench['bench']
+        bench['bench'] = bench['bench'].replace('_', '\\_')
+        gmsize = float(bench['guard map size'])
+        asmsize = float(bench['asm size'])
+        rdsize = float(resumedata[name]['total resume data size'])
+        rel = "%.2f" % (asmsize / (gmsize + rdsize) * 100,)
+        table.append([
+            bench['bench'],
+            "%.2f" % (asmsize,),
+            "%.2f" % (rdsize,),
+            "%.2f" % (gmsize,),
+            rel])
+    output = render_table(template, head, sorted(table))
+    write_table(output, texfile)
+
+
+def write_table(output, texfile):
+    # Write the output to a file
+    with open(texfile, 'w') as out_f:
+        out_f.write(output)
+
+
+def render_table(ttempl, head, table):
+    # open and read template
+    with open(ttempl) as f:
+        t = Template(f.read())
+    c = Context({"head": head, "table": table})
+    return t.render(c)
+
+
+tables = {
+        'benchmarks_table.tex':
+            (['summary.csv', 'bridge_summary.csv'], build_benchmarks_table),
+        'backend_table.tex':
+            (['backend_summary.csv', 'resume_summary.csv'], build_backend_count_table),
+        'ops_count_table.tex':
+            (['summary.csv'], build_ops_count_table),
+        'guard_table.tex':
+            (['summary.csv'], build_guard_table),
+        }
+
+
+def main(table):
+    tablename = os.path.basename(table)
+    if tablename not in tables:
+        raise AssertionError('unsupported table')
+    data, builder = tables[tablename]
+    csvfiles = [os.path.join('logs', d) for d in data]
+    texfile = os.path.join('figures', tablename)
+    template = os.path.join('tool', 'table_template.tex')
+    builder(csvfiles, texfile, template)
+
+
+if __name__ == '__main__':
+    assert len(sys.argv) > 1
+    main(sys.argv[1])
diff --git a/talk/vmil2012/tool/difflogs.py b/talk/vmil2012/tool/difflogs.py
new file mode 100755
--- /dev/null
+++ b/talk/vmil2012/tool/difflogs.py
@@ -0,0 +1,198 @@
+#!/usr/bin/env python
+"""
+Parse and summarize the traces produced by pypy-c-jit when PYPYLOG is set.
+only works for logs when unrolling is disabled
+"""
+
+import py
+import os
+import sys
+import csv
+import optparse
+from pprint import pprint
+from pypy.tool import logparser
+from pypy.jit.tool.oparser import parse
+from pypy.jit.metainterp.history import ConstInt
+from pypy.rpython.lltypesystem import llmemory, lltype
+
+categories = {
+    'getarrayitem_gc': 'get',
+    'getarrayitem_gc_pure': 'get',
+    'getarrayitem_raw': 'get',
+    'getfield_gc': 'get',
+    'getfield_gc_pure': 'get',
+    'getfield_raw': 'get',
+    'getinteriorfield_gc': 'get',
+    'new': 'new',
+    'new_array': 'new',
+    'new_with_vtable': 'new',
+    'newstr': 'new',
+    'newunicode': 'new',
+    'setarrayitem_gc': 'set',
+    'setarrayitem_raw': 'set',
+    'setfield_gc': 'set',
+    'setfield_raw': 'set',
+    'setinteriorfield_gc': 'set',
+    'strgetitem': 'get',
+    'strsetitem': 'set',
+}
+rest_op_bucket = set()
+
+all_categories = 'new get set guard numeric rest'.split()
+
+def extract_opnames(loop):
+    loop = loop.splitlines()
+    for line in loop:
+        if line.startswith('#') or line.startswith("[") or "end of the loop" in line:
+            continue
+        frontpart, paren, _ = line.partition("(")
+        assert paren
+        if " = " in frontpart:
+            yield frontpart.split(" = ", 1)[1]
+        elif ": " in frontpart:
+            yield frontpart.split(": ", 1)[1]
+        else:
+            yield frontpart
+
+def summarize(loop, adding_insns={}):    # for debugging
+    insns = adding_insns.copy()
+    seen_label = True
+    if "label" in loop:
+        seen_label = False
+    for opname in extract_opnames(loop):
+        if not seen_label:
+            if opname == 'label':
+                seen_label = True
+            else:
+                assert categories.get(opname, "rest") == "get"
+                continue
+        if(opname.startswith("int_")
+                or opname.startswith("float_")
+                or opname.startswith('uint_')):
+            opname = "numeric"
+        elif opname.startswith("guard_"):
+            opname = "guard"
+        else:
+            _opname = categories.get(opname, 'rest')
+            if _opname == 'rest':
+                rest_op_bucket.add(opname)
+            opname = _opname
+        insns[opname] = insns.get(opname, 0) + 1
+    assert seen_label
+    return insns
+
+def compute_summary_diff(loopfile, options):
+    print loopfile
+    log = logparser.parse_log_file(loopfile)
+    loops, summary = consider_category(log, options, "jit-log-opt-")
+
+    # non-optimized loops and summary
+    nloops, nsummary = consider_category(log, options, "jit-log-noopt-")
+    diff = {}
+    keys = set(summary.keys()).union(set(nsummary))
+    for key in keys:
+        before = nsummary[key]
+        after = summary[key]
+        diff[key] = (before-after, before, after)
+    return len(loops), summary, diff
+
+def main(loopfile, options):
+    _, summary, diff = compute_summary_diff(loopfile, options)
+
+    print
+    print 'Summary:'
+    print_summary(summary)
+
+    if options.diff:
+        print_diff(diff)
+
+def consider_category(log, options, category):
+    loops = logparser.extract_category(log, category)
+    if options.loopnum is None:
+        input_loops = loops
+    else:
+        input_loops = [loops[options.loopnum]]
+    summary = dict.fromkeys(all_categories, 0)
+    for loop in loops:
+        summary = summarize(loop, summary)
+    return loops, summary
+
+
+def print_summary(summary):
+    ops = [(summary[key], key) for key in summary]
+    ops.sort(reverse=True)
+    for n, key in ops:
+        print '%5d' % n, key
+
+def print_diff(diff):
+    ops = [(key, before, after, d) for key, (d, before, after) in diff.iteritems()]
+    ops.sort(reverse=True)
+    tot_before = 0
+    tot_after = 0
+    print ",",
+    for key, before, after, d in ops:
+        print key, ", ,",
+    print "total"
+    print args[0], ",",
+    for key, before, after, d in ops:
+        tot_before += before
+        tot_after += after
+        print before, ",", after, ",",
+    print tot_before, ",", tot_after
+
+def mainall(options):
+    logs = os.listdir("logs")
+    all = []
+    for log in logs:
+        parts = log.split(".")
+        if len(parts) != 3:
+            continue
+        l, exe, bench = parts
+        if l != "logbench":
+            continue
+        all.append((exe, bench, log))
+    all.sort()
+    with file("logs/summary.csv", "w") as f:
+        csv_writer = csv.writer(f)
+        row = ["exe", "bench", "number of loops"]
+        for cat in all_categories:
+            row.append(cat + " before")
+            row.append(cat + " after")
+        csv_writer.writerow(row)
+        print row
+        for exe, bench, log in all:
+            num_loops, summary, diff = compute_summary_diff("logs/" + log, options)
+            print diff
+            print exe, bench, summary
+            row = [exe, bench, num_loops]
+            for cat in all_categories:
+                difference, before, after = diff[cat]
+                row.append(before)
+                row.append(after)
+            csv_writer.writerow(row)
+            print row
+
+if __name__ == '__main__':
+    parser = optparse.OptionParser(usage="%prog loopfile [options]")
+    parser.add_option('-n', '--loopnum', dest='loopnum', default=None, metavar='N', type=int,
+                      help='show the loop number N [default: last]')
+    parser.add_option('-a', '--all', dest='loopnum', action='store_const', const=None,
+                      help='show all loops in the file')
+    parser.add_option('-d', '--diff', dest='diff', action='store_true', default=False,
+                      help='print the difference between non-optimized and optimized operations in the loop(s)')
+    parser.add_option('--diffall', dest='diffall', action='store_true', default=False,
+                      help='diff all the log files around')
+
+    options, args = parser.parse_args()
+    if options.diffall:
+        mainall(options)
+    elif len(args) != 1:
+        parser.print_help()
+        sys.exit(2)
+    else:
+        main(args[0], options)
+    if len(rest_op_bucket):
+        print "=" * 80
+        print "Elements considered as rest"
+        for x in sorted(rest_op_bucket):
+            print x
diff --git a/talk/vmil2012/tool/env.patch b/talk/vmil2012/tool/env.patch
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/tool/env.patch
@@ -0,0 +1,12 @@
+diff -r ff7b35837d0f runner.py
+--- a/runner.py	Sat Jul 21 13:35:54 2012 +0200
++++ b/runner.py	Mon Jul 23 16:22:08 2012 +0200
+@@ -28,7 +28,7 @@
+     funcs = perf.BENCH_FUNCS.copy()
+     funcs.update(perf._FindAllBenchmarks(benchmarks.__dict__))
+     opts = ['-b', ','.join(benchmark_set),
+-            '--inherit_env=PATH',
++            '--inherit_env=PATH,PYPYLOG',
+             '--no_charts']
+     if fast:
+         opts += ['--fast']
diff --git a/talk/vmil2012/tool/ll_resume_data_count.patch b/talk/vmil2012/tool/ll_resume_data_count.patch
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/tool/ll_resume_data_count.patch
@@ -0,0 +1,37 @@
+diff -r eec77c3e87d6 pypy/jit/backend/x86/assembler.py
+--- a/pypy/jit/backend/x86/assembler.py	Tue Jul 24 11:06:31 2012 +0200
++++ b/pypy/jit/backend/x86/assembler.py	Tue Jul 24 14:29:36 2012 +0200
+@@ -1849,6 +1849,7 @@
+     CODE_INPUTARG   = 8 | DESCR_SPECIAL
+ 
+     def write_failure_recovery_description(self, mc, failargs, locs):
++        char_count = 0
+         for i in range(len(failargs)):
+             arg = failargs[i]
+             if arg is not None:
+@@ -1865,6 +1866,7 @@
+                     pos = loc.position
+                     if pos < 0:
+                         mc.writechar(chr(self.CODE_INPUTARG))
++                        char_count += 1
+                         pos = ~pos
+                     n = self.CODE_FROMSTACK//4 + pos
+                 else:
+@@ -1873,11 +1875,17 @@
+                 n = kind + 4*n
+                 while n > 0x7F:
+                     mc.writechar(chr((n & 0x7F) | 0x80))
++                    char_count += 1
+                     n >>= 7
+             else:
+                 n = self.CODE_HOLE
+             mc.writechar(chr(n))
++            char_count += 1
+         mc.writechar(chr(self.CODE_STOP))
++        char_count += 1
++        debug_start('jit-backend-guard-size')
++        debug_print("chars %s" % char_count)
++        debug_stop('jit-backend-guard-size')
+         # assert that the fail_boxes lists are big enough
+         assert len(failargs) <= self.fail_boxes_int.SIZE
+ 
diff --git a/talk/vmil2012/tool/rdatasize.py b/talk/vmil2012/tool/rdatasize.py
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/tool/rdatasize.py
@@ -0,0 +1,138 @@
+import csv
+import os
+import sys
+from collections import defaultdict
+
+from backenddata import collect_logfiles
+from pypy.tool import logparser
+
+word_to_kib = 1024 / 8. # 64 bit
+numberings_per_word = 2/8. # two bytes
+
+
+def cond_incr(d, key, obj, seen, incr=1):
+    if obj not in seen:
+        seen.add(obj)
+        d[key] += incr
+    d["naive_" + key] += incr
+
+def compute_numbers(infile):
+    seen = set()
+    seen_numbering = set()
+    # all in words
+    results = defaultdict(float)
+    log = logparser.parse_log_file(infile)
+    rdata = logparser.extract_category(log, 'jit-resume')
+    results["num_guards"] = len(rdata)
+    for log in rdata:
+        for line in log.splitlines():
+            if line.startswith("Log storage"):
+                results['num_storages'] += 1
+                continue
+            if not line.startswith("\t"):
+                continue
+            line = line[1:]
+            if line.startswith("jitcode/pc"):
+                _, address = line.split(" at ")
+                cond_incr(results, "num_snapshots", address, seen)
+            elif line.startswith("numb"):
+                content, address = line.split(" at ")
+                size =  line.count("(") * numberings_per_word + 3 # gc, len, prev
+                cond_incr(results, "optimal_numbering", content, seen_numbering, size)
+                cond_incr(results, "size_estimate_numbering", address, seen, size)
+            elif line.startswith("const "):
+                address, _ = line[len("const "):].split("/")
+                cond_incr(results, "num_consts", address, seen)
+            elif "info" in line:
+                _, address = line.split(" at  ")
+                if line.startswith("varrayinfo"):
+                    factor = numberings_per_word
+                elif line.startswith("virtualinfo") or line.startswith("vstructinfo") or line.startswith("varraystructinfo"):
+                    factor = 1 + numberings_per_word # one descr reference per entry
+                naive_factor = factor
+                if address in seen:
+                    factor = 0
+                else:
+                    results['num_virtuals'] += 1
+                    results['size_virtuals'] += 1 # an entry in the list of virtuals
+                results['naive_num_virtuals'] += 1
+                results['naive_size_virtuals'] += 1 # an entry in the list of virtuals
+                target = "size_virtuals"
+                naive_target = "naive_size_virtuals"
+
+                cond_incr(results, "size_virtuals", address, seen, 4) # bit of a guess
+            elif "pending setfields" == line.strip():
+                results['size_setfields'] += 3 # reference to object, gc, len
+                factor = 3 # descr, index, numbering from, numbering to (plus alignment)
+                naive_factor = 0
+                target = "size_setfields"
+                naive_target = "naive_size_setfields" # dummy
+            elif line[0] == "\t":
+                results[target] += factor
+                results[naive_target] += naive_factor
+
+    results["kib_snapshots"] = results['num_snapshots'] * 4. / word_to_kib # gc, jitcode, pc, prev
+    results["naive_kib_snapshots"] = results['naive_num_snapshots'] * 4. / word_to_kib
+    results["kib_numbering"] = results['size_estimate_numbering'] / word_to_kib
+    results["naive_kib_numbering"] = results['naive_size_estimate_numbering'] / word_to_kib
+    results["kib_consts"] = results['num_consts'] * 4 / word_to_kib
+    results["naive_kib_consts"] = results['naive_num_consts'] * 4 / word_to_kib
+    results["kib_virtuals"] = results['size_virtuals'] / word_to_kib
+    results["naive_kib_virtuals"] = results['naive_size_virtuals'] / word_to_kib
+    results["kib_setfields"] = results['size_setfields'] / word_to_kib
+    results["total"] = (
+        results[      "kib_snapshots"] +
+        results[      "kib_numbering"] +
+        results[      "kib_consts"] +
+        results[      "kib_virtuals"] +
+        results[      "kib_setfields"])
+    results["naive_total"] = (
+        results["naive_kib_snapshots"] +
+        results["naive_kib_numbering"] +
+        results["naive_kib_consts"] +
+        results["naive_kib_virtuals"] +
+        results["naive_kib_setfields"])
+    return results
+
+
+def main(argv):
+    import optparse
+    parser = optparse.OptionParser(usage="%prog logdir_or_file")
+
+    options, args = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        sys.exit(2)
+        return
+    path = args[0]
+    if os.path.isdir(path):
+        dirname = path
+    else:
+        dirname = os.path.dirname(path)
+    files = collect_logfiles(path)
+    with file("logs/resume_summary.csv", "w") as f:
+        csv_writer = csv.writer(f)
+        row = ["exe", "bench", "number of guards", "total resume data size", "naive resume data size"]
+        csv_writer.writerow(row)
+
+        for exe, bench, infile in files:
+            results = compute_numbers(os.path.join(dirname, infile))
+            row = [exe, bench, results["num_guards"], results['total'], results['naive_total']]
+            csv_writer.writerow(row)
+
+            print "=============================="
+            print bench
+            print "storages:", results['num_storages']
+            print "snapshots: %sKiB vs %sKiB" % (results["kib_snapshots"], results["naive_kib_snapshots"])
+            print "numberings: %sKiB vs %sKiB" % (results["kib_numbering"], results["naive_kib_numbering"])
+            print "optimal: %s" % (results['optimal_numbering'] / word_to_kib)
+            print "consts:  %sKiB vs %sKiB" % (results["kib_consts"], results["naive_kib_consts"])
+            print "virtuals:  %sKiB vs %sKiB" % (results["kib_virtuals"], results["naive_kib_virtuals"])
+            print "number virtuals: %i vs %i" % (results['num_virtuals'], results['naive_num_virtuals'])
+            print "setfields: %sKiB" % (results["kib_setfields"], )
+            print "--"
+            print "total:  %sKiB vs %sKiB" % (results["total"], results["naive_total"])
+
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/talk/vmil2012/tool/run_benchmarks.sh b/talk/vmil2012/tool/run_benchmarks.sh
new file mode 100755
--- /dev/null
+++ b/talk/vmil2012/tool/run_benchmarks.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+base="$(dirname "${DIR}")"
+bench_list="${base}/logs/benchs.txt"
+benchmarks="${base}/pypy-benchmarks"
+REV="ff7b35837d0f"
+pypy_co="${base}/pypy"
+PYPYREV='0b77afaafdd0'
+pypy="${pypy_co}/pypy-c"
+pypy_opts=",--jit enable_opts=intbounds:rewrite:virtualize:string:pure:heap:ffi"
+baseline=$(which true)
+logopts='jit'
+# checkout and build a pypy-c version
+if [ ! -d "${pypy_co}" ]; then
+  echo "Cloning pypy repository to ${pypy_co}"
+  hg clone https://bivab@bitbucket.org/pypy/pypy "${pypy_co}"
+fi
+#
+cd "${pypy_co}"
+echo "updating pypy to fixed revision ${PYPYREV}"
+hg revert --all
+hg pull -u
+hg update "${PYPYREV}"
+echo "Patching pypy"
+patch -p1 -N < "$base/tool/ll_resume_data_count.patch"
+#
+echo "Checking for an existing pypy-c"
+if [ ! -x "${pypy-c}" ]
+then
+  pypy/bin/rpython -Ojit pypy/translator/goal/targetpypystandalone.py
+else
+    echo "found!"
+fi
+
+# setup a checkout of the pypy benchmarks and update to a fixed revision
+if [ ! -d "${benchmarks}" ]; then
+  echo "Cloning pypy/benchmarks repository to ${benchmarks}"
+  hg clone https://bitbucket.org/pypy/benchmarks "${benchmarks}"
+  cd "${benchmarks}"
+  echo "updating benchmarks to fixed revision ${REV}"
+  hg update "${REV}"
+  echo "Patching benchmarks to pass PYPYLOG to benchmarks"
+  patch -p1 < "$base/tool/env.patch"
+else
+  cd "${benchmarks}"
+  echo "Clone of pypy/benchmarks already present, reverting changes in the checkout"
+  hg revert --all
+  echo "updating benchmarks to fixed revision ${REV}"
+  hg update "${REV}"
+  echo "Patching benchmarks to pass PYPYLOG to benchmarks"
+  patch -p1 < "$base/tool/env.patch"
+fi
+
+# run each benchmark defined on $bench_list
+while read line
+do
+    logname="${base}/logs/logbench.$(basename "${pypy}").${line}"
+    export PYPYLOG="${logopts}:$logname"
+    bash -c "./runner.py --changed=\"${pypy}\" --args=\"${pypy_opts}\" --benchmarks=${line}"
+done < $bench_list
diff --git a/talk/vmil2012/tool/setup.sh b/talk/vmil2012/tool/setup.sh
new file mode 100755
--- /dev/null
+++ b/talk/vmil2012/tool/setup.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+VENV=paper_env
+if [ ! -d "$VENV" ]; then
+    virtualenv "${VENV}"
+    source "${VENV}/bin/activate"
+    pip install django
+    echo "virtualenv created in ${VENV}"
+else
+    echo "virtualenv already present in ${VENV}"
+fi
+
diff --git a/talk/vmil2012/tool/table_template.tex b/talk/vmil2012/tool/table_template.tex
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/tool/table_template.tex
@@ -0,0 +1,25 @@
+\begin{center}
+{\smaller
+    \begin{tabular}{ {%for c in head %} |l| {% endfor %} }
+    \hline
+    {% for col in head %}
+        \textbf{ {{col}} }
+        {% if not forloop.last %}
+           &
+        {% endif %}
+    {% endfor %}
+    \\
+    \hline
+    {% for row in table %}
+        {% for cell in row %}
+            {{cell}}
+            {% if not forloop.last %}
+               &
+            {% endif %}
+        {% endfor %}
+        \\
+    {% endfor %}
+    \hline
+    \end{tabular}
+}
+\end{center}
diff --git a/talk/vmil2012/zotero.bib b/talk/vmil2012/zotero.bib
new file mode 100644
--- /dev/null
+++ b/talk/vmil2012/zotero.bib
@@ -0,0 +1,159 @@
+
+ at inproceedings{deutsch_efficient_1984,
+	address = {Salt Lake City, Utah},
+	title = {Efficient implementation of the Smalltalk-80 system},
+	isbn = {0-89791-125-3},
+	url = {http://portal.acm.org/citation.cfm?id=800017.800542},
+	doi = {10.1145/800017.800542},
+	abstract = {The Smalltalk-80* programming language includes dynamic storage allocation, full upward funargs, and universally polymorphic procedures; the Smalltalk-80 programming system features interactive execution with incremental compilation, and implementation portability. These features of modern programming systems are among the most difficult to implement efficiently, even individually. A new implementation of the Smalltalk-80 system, hosted on a small microprocessor-based computer, achieves high performance while retaining complete (object code) compatibility with existing implementations. This paper discusses the most significant optimization techniques developed over the course of the project, many of which are applicable to other languages. The key idea is to represent certain runtime state (both code and data) in more than one form, and to convert between forms when needed.},
+	booktitle = {{POPL}},
+	publisher = {{ACM}},
+	author = {Deutsch, L. Peter and Schiffman, Allan M.},
+	year = {1984}
+},
+
+ at inproceedings{titzer_improving_2010,
+	address = {Pittsburgh, Pennsylvania, {USA}},
+	title = {Improving compiler-runtime separation with {XIR}},
+	isbn = {978-1-60558-910-7},
+	url = {http://portal.acm.org/citation.cfm?id=1735997.1736005&coll=&dl=GUIDE&type=series&idx=SERIES11259&part=series&WantType=Proceedings&title=VEE&CFID=82768812&CFTOKEN=13856884},
+	doi = {10.1145/1735997.1736005},
+	abstract = {Intense research on virtual machines has highlighted the need for flexible software architectures that allow quick evaluation of new design and implementation techniques. The interface between the compiler and runtime system is a principal factor in the flexibility of both components and is critical to enabling rapid pursuit of new optimizations and features. Although many virtual machines have demonstrated modularity for many components, significant dependencies often remain between the compiler and the runtime system components such as the object model and memory management system. This paper addresses this challenge with a carefully designed strict compiler-runtime interface and the {XIR} language. Instead of the compiler backend lowering object operations to machine operations using hard-wired runtime-specific logic, {XIR} allows the runtime system to implement this logic, simultaneously simplifying and separating the backend from runtime-system details. In this paper we describe the design and implementation of this compiler-runtime interface and the {XIR} language in the {C1X} dynamic compiler, a port of the {HotSpotTM} Client compiler. Our results show a significant reduction in backend complexity with {XIR} and an overall reduction in the compiler-runtime interface complexity while still generating comparable quality code with only minor impact on compilation time.},
+	booktitle = {Proceedings of the 6th {ACM} {SIGPLAN/SIGOPS} international conference on Virtual execution environments},
+	publisher = {{ACM}},
+	author = {Titzer, Ben L. and W&#252;rthinger, Thomas and Simon, Doug and Cintra, Marcelo},
+	year = {2010},
+	keywords = {compilers, intermediate representations, Java, jit, lowering, object model, register allocation, runtime interface, software architecture, virtual machines},
+	pages = {39--50}
+},
+
+ at inproceedings{bebenita_spur:_2010,
+	address = {{Reno/Tahoe}, Nevada, {USA}},
+	title = {{SPUR:} a trace-based {JIT} compiler for {CIL}},
+	isbn = {978-1-4503-0203-6},
+	shorttitle = {{SPUR}},
+	url = {http://portal.acm.org/citation.cfm?id=1869459.1869517&coll=GUIDE&dl=GUIDE&type=series&idx=SERIES318&part=series&WantType=Proceedings&title=OOPSLA%2FSPLASH&CFID=106280261&CFTOKEN=29377718},
+	doi = {10.1145/1869459.1869517},
+	abstract = {Tracing just-in-time compilers {(TJITs)} determine frequently executed traces (hot paths and loops) in running programs and focus their optimization effort by emitting optimized machine code specialized to these traces. Prior work has established this strategy to be especially beneficial for dynamic languages such as {JavaScript}, where the {TJIT} interfaces with the interpreter and produces machine code from the {JavaScript} trace.},
+	booktitle = {{OOPSLA}},
+	publisher = {{ACM}},
+	author = {Bebenita, Michael and Brandner, Florian and Fahndrich, Manuel and Logozzo, Francesco and Schulte, Wolfram and Tillmann, Nikolai and Venter, Herman},
+	year = {2010},
+	keywords = {cil, dynamic compilation, javascript, just-in-time, tracing}
+},
+
+ at inproceedings{kotzmann_escape_2005,
+	address = {New York, {NY}, {USA}},
+	series = {{VEE} '05},
+	title = {Escape analysis in the context of dynamic compilation and deoptimization},
+	isbn = {1-59593-047-7},
+	location = {Chicago, {IL}, {USA}},
+	doi = {10.1145/1064979.1064996},
+	abstract = {In object-oriented programming languages, an object is said to escape the method or thread in which it was created if it can also be accessed by other methods or threads. Knowing which objects do not escape allows a compiler to perform aggressive {optimizations.This} paper presents a new intraprocedural and interprocedural algorithm for escape analysis in the context of dynamic compilation where the compiler has to cope with dynamic class loading and deoptimization. It was implemented for Sun Microsystems' Java {HotSpot&#8482;} client compiler and operates on an intermediate representation in {SSA} form. We introduce equi-escape sets for the efficient propagation of escape information between related objects. The analysis is used for scalar replacement of fields and synchronization removal, as well as for stack allocation of objects and fixed-sized arrays. The results of the interprocedural analysis support the compiler in inlining decisions and allow actual parameters to be allocated on the caller {stack.Under} certain circumstances, the Java {HotSpot&#8482;} {VM} is forced to stop executing a method's machine code and transfer control to the interpreter. This is called deoptimization. Since the interpreter does not know about the scalar replacement and synchronization removal performed by the compiler, the deoptimization framework was extended to reallocate and relock objects on demand.},
+	booktitle = {Proceedings of the 1st {ACM/USENIX} international conference on Virtual execution environments},
+	publisher = {{ACM}},
+	author = {Kotzmann, Thomas and M&#246;ssenb&#246;ck, Hanspeter},
+	year = {2005},
+	note = {{ACM} {ID:} 1064996},
+	keywords = {algorithms, allocation/deallocation strategies, deoptimization},
+	pages = {111&#8211;120}
+},
+
+ at inproceedings{bolz_allocation_2011,
+	address = {Austin, Texas, {USA}},
+	title = {Allocation removal by partial evaluation in a tracing {JIT}},
+	abstract = {The performance of many dynamic language implementations suffers from high allocation rates and runtime type checks. This makes dynamic languages less applicable to purely algorithmic problems, despite their growing popularity. In this paper we present a simple compiler optimization based on online partial evaluation to remove object allocations and runtime type checks in the context of a tracing {JIT.} We evaluate the optimization using a Python {VM} and find that it gives good results for all our (real-life) benchmarks.},
+	booktitle = {{PEPM}},
+	author = {Bolz, Carl Friedrich and Cuni, Antonio and Fija&#322;kowski, Maciej and Leuschel, Michael and Pedroni, Samuele and Rigo, Armin},
+	year = {2011},
+	keywords = {code generation, experimentation, interpreters, languages, optimization, partial evaluation, performance, run-time environments, tracing jit}
+},
+
+ at inproceedings{bolz_runtime_2011,
+	address = {New York, {NY}, {USA}},
+	series = {{ICOOOLPS} '11},
+	title = {Runtime feedback in a meta-tracing {JIT} for efficient dynamic languages},
+	isbn = {978-1-4503-0894-6},
+	url = {http://doi.acm.org/10.1145/2069172.2069181},
+	doi = {10.1145/2069172.2069181},
+	abstract = {Meta-tracing {JIT} compilers can be applied to a variety of different languages without explicitly encoding language semantics into the compiler. So far, they lacked a way to give the language implementor control over runtime feedback. This restricted their performance. In this paper we describe the mechanisms in {PyPy&#8217;s} meta-tracing {JIT} that can be used to control runtime feedback in language-specific ways. These mechanisms are flexible enough to express classical {VM} techniques such as maps and runtime type feedback.},
+	booktitle = {Proceedings of the 6th Workshop on Implementation, Compilation, Optimization of Object-Oriented Languages, Programs and Systems},
+	publisher = {{ACM}},
+	author = {Bolz, Carl Friedrich and Cuni, Antonio and Fija&#322;kowski, Maciej and Leuschel, Michael and Pedroni, Samuele and Rigo, Armin},
+	year = {2011},
+	keywords = {code generation, interpreter, meta-programming, runtime feedback, tracing jit},
+	pages = {9:1&#8211;9:8}
+},
+
+ at article{wurthinger_array_2009,
+	title = {Array bounds check elimination in the context of deoptimization},
+	volume = {74},
+	issn = {0167-6423},
+	url = {http://dx.doi.org/10.1016/j.scico.2009.01.002},
+	doi = {10.1016/j.scico.2009.01.002},
+	abstract = {Whenever an array element is accessed, Java virtual machines execute a compare instruction to ensure that the index value is within the valid bounds. This reduces the execution speed of Java programs. Array bounds check elimination identifies situations in which such checks are redundant and can be removed. We present an array bounds check elimination algorithm for the Java {HotSpot(TM)} {VM} based on static analysis in the just-in-time compiler. The algorithm works on an intermediate representation in static single assignment form and maintains conditions for index expressions. It fully removes bounds checks if it can be proven that they never fail. Whenever possible, it moves bounds checks out of loops. The static number of checks remains the same, but a check inside a loop is likely to be executed more often. If such a check fails, the executing program falls back to interpreted mode, avoiding the problem that an exception is thrown at the wrong place. The evaluation shows a speedup near to the theoretical maximum for the scientific {SciMark} benchmark suite and also significant improvements for some Java Grande benchmarks. The algorithm slightly increases the execution speed for the {SPECjvm98} benchmark suite. The evaluation of the {DaCapo} benchmarks shows that array bounds checks do not have a significant impact on the performance of object-oriented applications.},
+	number = {5-6},
+	journal = {Sci. Comput. Program.},
+	author = {W&#252;rthinger, Thomas and Wimmer, Christian and M&#246;ssenb&#246;ck, Hanspeter},
+	month = mar,
+	year = {2009},
+	keywords = {Array bounds check elimination, Java, just-in-time compilation, optimization, performance},
+	pages = {279&#8211;295}
+},
+
+ at inproceedings{holzle_debugging_1992,
+	address = {New York, {NY}, {USA}},
+	series = {{PLDI} '92},
+	title = {Debugging optimized code with dynamic deoptimization},
+	isbn = {0-89791-475-9},
+	url = {http://doi.acm.org/10.1145/143095.143114},
+	doi = {10.1145/143095.143114},
+	abstract = {{SELF's} debugging system provides complete source-level debugging (expected behavior) with globally optimized code. It shields the debugger from optimizations performed by the compiler by dynamically deoptimizing code on demand. Deoptimization only affects the procedure activations that are actively being debugged; all other code runs at full speed. Deoptimization requires the compiler to supply debugging information at discrete interrupt points; the compiler can still perform extensive optimizations between interrupt points without affecting debuggability. At the same time, the inability to interrupt between interrupt points is invisible to the user. Our debugging system also handles programming changes during debugging. Again, the system provides expected behavior: it is possible to change a running program and immediately observe the effects of the change. Dynamic deoptimization transforms old compiled code (which may contain inlined copies of the old version of the changed procedure) into new versions reflecting the current source-level state. To the best of our knowledge, {SELF} is the first practical system providing full expected behavior with globally optimized code.},
+	booktitle = {Proceedings of the {ACM} {SIGPLAN} 1992 conference on Programming language design and implementation},
+	publisher = {{ACM}},
+	author = {H&#246;lzle, Urs and Chambers, Craig and Ungar, David},
+	year = {1992},
+	pages = {32&#8211;43}
+},
+
+ at inproceedings{bolz_tracing_2009,
+	address = {Genova, Italy},
+	title = {Tracing the meta-level: {PyPy's} tracing {JIT} compiler},
+	isbn = {978-1-60558-541-3},
+	shorttitle = {Tracing the meta-level},
+	url = {http://portal.acm.org/citation.cfm?id=1565827},
+	doi = {10.1145/1565824.1565827},
+	abstract = {We attempt to apply the technique of Tracing {JIT} Compilers in the context of the {PyPy} project, i.e., to programs that are interpreters for some dynamic languages, including Python. Tracing {JIT} compilers can greatly speed up programs that spend most of their time in loops in which they take similar code paths. However, applying an unmodified tracing {JIT} to a program that is itself a bytecode interpreter results in very limited or no speedup. In this paper we show how to guide tracing {JIT} compilers to greatly improve the speed of bytecode interpreters. One crucial point is to unroll the bytecode dispatch loop, based on two kinds of hints provided by the implementer of the bytecode interpreter. We evaluate our technique by applying it to two {PyPy} interpreters: one is a small example, and the other one is the full Python interpreter.},
+	booktitle = {{ICOOOLPS}},
+	publisher = {{ACM}},
+	author = {Bolz, Carl Friedrich and Cuni, Antonio and Fija&#322;kowski, Maciej and Rigo, Armin},
+	year = {2009},
+	pages = {18--25}
+},
+
+ at inproceedings{paleczny_java_2001,
+	address = {Monterey, California},
+	title = {The Java {HotSpot} server compiler},
+	url = {http://portal.acm.org/citation.cfm?id=1267848},
+	abstract = {The Java {HotSpotTM} Server Compiler achieves improved asymptotic performance through a combination of object-oriented and classical-compiler optimizations. Aggressive inlining using class-hierarchy analysis reduces function call overhead and provides opportunities for many compiler optimizations.},
+	booktitle = {Proceedings of the Java Virtual Machine Research and Technology Symposium on Java Virtual Machine Research and Technology Symposium - Volume 1},
+	publisher = {{USENIX} Association},
+	author = {Paleczny, Michael and Vick, Christopher and Click, Cliff},
+	year = {2001},
+	keywords = {toread}
+},
+
+ at article{holzle_third-generation_1994,
+	title = {A third-generation {SELF} implementation: reconciling responsiveness with performance},
+	volume = {29},
+	shorttitle = {A third-generation {SELF} implementation},
+	url = {http://portal.acm.org/citation.cfm?id=191081.191116},
+	doi = {10.1145/191081.191116},
+	abstract = {Programming systems should be both responsive (to support rapid development) and efficient (to complete computations quickly). Pure object-oriented languages are harder to implement efficiently since they need optimization to achieve good performance. Unfortunately, optimization conflicts with interactive responsiveness because it tends to produce long compilation pauses, leading to unresponsive programming environments. Therefore, to achieve good responsiveness, existing exploratory programming environments such as the Smalltalk-80 environment rely on interpretation or non-optimizing dynamic compilation. But such systems pay a price for their interactiveness, since they may execute programs several times slower than an optimizing {system.SELF-93} reconciles high performance with responsiveness by combining a fast, non-optimizing compiler with a slower, optimizing compiler. The resulting system achieves both excellent performance (two or three times faster than existing Smalltalk systems) and good responsiveness. Except for situations requiring large applications to be (re)compiled from scratch, the system allows for pleasant interactive use with few perceptible compilation pauses. To our knowledge, {SELF-93} is the first implementation of a pure object-oriented language achieving both good performance and good {responsiveness.When} measuring interactive pauses, it is imperative to treat multiple short pauses as one longer pause if the pauses occur in short succession, since they are perceived as one pause by the user. We propose a definition of pause clustering and show that clustering can make an order-of-magnitude difference in the pause time distribution.},
+	number = {10},
+	journal = {{SIGPLAN} Not.},
+	author = {H&#246;lzle, Urs and Ungar, David},
+	year = {1994},
+	keywords = {interactivity, recompilation, self},
+	pages = {229--243}
+}
\ No newline at end of file


More information about the pypy-commit mailing list