Here is the summary in their own words: (http://codespeak.net/pypy/dist/pypy/doc/jit/index.html)
---
When PyPy is translated into an executable like pypy-c, the executable contains a full virtual machine that can optionally include a Just-In-Time compiler. This JIT compiler is generated automatically from the interpreter that we wrote in RPython.
This JIT Compiler Generator can be applied on interpreters for any language, as long as the interpreter itself is written in RPython and contains a few hints to guide the JIT Compiler Generator.
---
Indeed it is. Compiling took 9000s on a 2GHz Dual Core Athlon with 2GB RAM. Don't even try to compile it on a machine with 1GB RAM, your system will start trashing heavily and finish sometimes between next week and never. </rant>
But after downloading the binaries, I have to say: Wow! One of my naive project euler solution is about 3-4 times faster than it was using Psyco. Absolutely impressive. (Numbers: ~66s Python 2.6, ~8.6s Psyco, ~2.8s PyPy)
My highly scientific benchmarks (time python -c "pass") give no noticeable difference, with pypy starting in between 0.015s and 0.020s and Python 2.6 starting in 0.022s to 0.028s.
All of this is on a 1.6GHz C2D, 1GB RAM, Arch Linux 32 bit.
http://en.wikipedia.org/wiki/Abstract_interpretation
Basically, RPython fills the role of a concrete semantics of Python, and then they write functions that can convert that concrete semantics to other forms - for example, a JIT compiler that when run generates x86 machine code with the same semantics as the interpreter.
It's a very powerful technique that can generate all sorts of information about the program, much of which can then feed back into the compiler to direct further optimization. For example, you can model typechecking as an abstract interpretation that maps values to their types. You can model type inference as typechecking plus a substitution that maps type variables to concrete (or generalized) types. You can model Haskell-style typeclasses as type inference plus a list of predicates on every expression labeling the possible typeclasses that the type may belong to.
When you don't have to babysit C, you get to spend your time improving the actual application you are trying to write. This makes for a better application.