For people interested in JIT technology, there are two great posts this weekend from folks in my team.
JIT engines have some great properties, but unlike batch compilation they suffer from having to cope with code generated dynamically. Paolo talks about the memory reduction tricks that he has implemented in Mono.
The tricks are related to the temporary thunks that are generated during JITing ("trampolines"), and some future directions to reduce memory usage in the JIT even more.
Mark talks about his ongoing work to implement generic code sharing. Unlike Java generics that are a language feature, .NET generics are a virtual machine feature. Each approach has its pros and cons. In Java you only JIT the code once, and every generic instantitation reuses that implementation (because it is really a language feature); The .NET approach makes for simpler use or generics and better performance, but it comes with a price: new instantiations of the generics class need to be re-JITed.
Mark discusses his ongoing work to share generics JITed code (when two instantiations of a generic type would generate the same code, say when the sizes and semantics of the types are compatible).