Hotspot's JIT compiled code tends to be pretty specialized based on runtime profiling information, which may not necessarily be similar between different runs even the class itself hasn't changed, or (in an extreme case) even if none of the code has.
Some other JVMs (at least Azul's Zing) try to solve this by cache profiling information to speed up code generation.
I believe the ReadyNow technology used by Zing records what methods are compiled at which level, then trigger a compilation of those methods at start up. So you effectively use profiling information from the previous run to inform the next run of what the final target state is, allowing the warm up times to be dramatically reduced.
Some other JVMs (at least Azul's Zing) try to solve this by cache profiling information to speed up code generation.