In the time since this question was asked the following post has been made on the official Ethereum blog:
This helps to answer:
What optimizations does Geth's --jitvm do?
When the native byte-code is run for the first time, we also compile a JIT program in the background. (The JIT version is then run on subsequent executions.)
"By compiling the byte-code in to logical pieces the JIT has the ability to analyse the code more precisely and optimise where and whenever necessary."
The post goes on to mention two optimations:
Looking at the code in
jit_optimiser.go, these currently appear to be the only optimisations it can handle.
Fewer instructions means faster code execution.
What should users know about toggling --forcejit and --jitcache?
Earlier I mentioned that if
--jitvm is specified then the first time we execute the program we actually run the native byte-code, and compile a JIT program in the background for subsequent runs.
--forcejit we don't run the byte-code. Instead we compile and then run the JIT program. This means, at least the first time we compile, things are going to be slower than just running with
--jitvm. I suppose the advantage of using the forced version is that we can be sure our code is running with optimisations, even on the first run.
This can be used to set the size of the LRU (Least Recently Used) cache used for storing the JIT programs. It's not clear from the code if there's an upper limit on how much space these programs are allowed to take (neither in the Ethereum code or LRU package code), though there's an upper limit of 64 items (programs).