To expand on Eliot's answers, in Jikes RVM all calls (both static and virtual) are indirect. For static calls we load the code address from the JTOC. For calls to instance methods we load the code address from a TIB. When the system starts out, all of these code addresses are initialized with stubs that when execute invoke a compiler (typically the baseline compiler) to generate code, replace the stub with the real code, and then re-execute the call (which invokes the newly generated code).
We do lose some performance by making static calls indirect instead of pc-relative. We think the performance loss is modest (since frequently executed code gets opt compiled, and we apply fairly aggressive inlining at O1 and O2 in the opt compiler and because most hardware has at least some hardware resources for indirect branch prediction). The benefit is a simpler re-compilation architecture, since we don't have to patch pc-relative calls to old versions of compiled code when we recompile.