Strictly speaking, PyPy doesn't have a JIT; it has a JIT generator. I will describe how the JIT is generated during the translation of the interpreter as well as the advantages of the meta-JIT method.
Next, we'll explore tracing, in which the JIT records operations in a hot loop. I'll introduce the meta interpreter and the JIT IR (intermediate representation).
Optimizations are the next step of JITing. The focus will be on the most important optimizations for dynamic languages: virtuals and virtualizables. However, PyPy also includes the standard set of compiler peephole optimizations, like strength reduction, and well as some more complicated loop optimizations, like constant hoisting.
The final topic will be assembly generation. We'll see register allocation and how specific high-level Python operations are compiled down to tight x86 instructions.
Time permitting, additional topics may include how the garbage collector is integrated with the JIT and how the JIT bails back to the interpreter when a guard fails.
Along the way, I will demonstrate how each phase of JITing acts on an example Python loop. This will also allow me to introduce the jitviewer, a program to view how PyPy is compiling your loops.