Some examples are divirtualization across dynamic libraries, or code inlining, which is quite basic stuff for those implementations.
Here is a 2015 paper for OpenJDK,
https://cr.openjdk.org/~vlivanov/talks/2015_JIT_Overview.pdf
Modern ART has a bit of everything, Assembly written interpreter for fast startup, followed by a JIT stage with PGO capabilities, followed by an AOT compiler that AOT compiles (with LTO) when the device is idle, and uploading PGO data into the Play Store, so that incrementally the same devices collaborate to the optimal PGO data set.
https://source.android.com/docs/core/runtime/jit-compiler
IBM and Azul JVMs have similar approaches with their cloud based JIT infrastructure.
https://developer.ibm.com/articles/jitserver-optimize-your-j...
https://www.azul.com/products/intelligence-cloud/cloud-nativ...