它指的是:在编译过程中遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。
方法内联不仅可以消除调用本身带来的性能开销,还可以进一步触发更多的优化。因此,它可以算是编译优化里最为重要的一环。
以getter/setter为例,如果没有方法内联,在调用getter/settter时,程序需要保存当前方法的执行位置,创建并压入用于getter/setter的栈桢、访问字段、弹出栈桢、最后恢复当前方法的执行。而当内联了对getter/setter的方法调用后,上述操作仅剩字段访问。
在C2中,方法内联是在解析字节码的过程中完成的。每当碰到方法调用字节码时,C2将决定是否需要内联该方法调用。如果需要内联,则开始解析目标方法的字节码。
即时编译器首先解析字节码,并生成IR图,然后在该IR图上进行优化。优化是由一个个独立的优化阶段(optimization phase)串联起来的。每个优化阶段都会对IR图进行转换。最后即时编译器根据IR图的节点以及调度顺序生成机器码。
同C2一样,Graal也会在解析字节码的过程中进行方法调用的内联。此外,Graal还拥有一个独立的优化阶段,来寻找指代方法调用的IR节点,并将之替换为目标方法的IR图。这个过程相对来说比较形象一些。
方法内联的过程
public static boolean flag = true;
public static int value0 = 0;
public static int value1 = 1;
public static int foo(int value) {
int result = bar(flag);
if (r