All calls in Jikes RVM are done as indirect calls (through JTOC/TIB slot) even when the exact target of the call is known at compile time. This simplifies code management (switching from one compiled version to another, for example due to AOS recompilation and/or invalidation) because it is sufficient to update the slot contents. However, it is suspected that this approach is having a significant performance impact.
There's a direct cost of doing the indirect call (although on IA32, this is somewhat mitigated by exploiting the fact that the JTOC starts at a known address) and there are indirect costs due to the different treatment of indirect and PC relative calls by hardware branch prediction.
We propose to use PC-relative call instructions for all statically resolvable call sites. These include invokestatic, invokespecial, and invokevirtual where the target is statically resolvable (but not inlined).
To maximize the indirect benefits (improve utilization/effectiveness of hardware structures for indirect branch prediction), it is not sufficient to only do this optimization in the opt compiler. We need to do it in the baseline compiler as well.
The interesting design decisions are:
(1) How to best support AOS and other subsystems that need to replace one compiled version of a method with another.
(2) How to best support eventual collection of dead compiled code.
(3) Bootimage time plumbing to allow intra-bootimage calls to be PC-relative by patching call instructions after the layout of code is determined.