- Dynamic method calls that get de-virtualized, because there is only one visible implementation, including across shared libraries
- Inlining across shared libraries
- Adaptation of new CPU opcodes, for example a Java application written in 2000 could in theory make use of AVX, without being recompiled.
- In the same vein, that is how shading languages work
In certain cases [1] JIT can beat AOT by a decent margin because it has access to live information that isn't available at compile time. In theory you could AOT compile, profile, and recompile but in practice my understanding is that nothing beats doing it live.
Consider that if the workload suddenly changes in production and your heuristic violates an invariant as a result, you can deoptimize, reprofile, and recompile everything on the fly.
But wait, you say! Can't an AOT compiler do that? But no, the state space is almost certainly going to be too large by many orders of magnitude. So unless your AOT compiler effectively inserts a JIT compiler ...
[1] Sorry, no examples to hand. Nobody knows but I'm actually a dog. Don't trust me!