HotSpot 能否在不内联它们的情况下优化掉对纯方法的冗余调用?

Can HotSpot optimize away redundant calls to pure methods without inlining them?

Pure methods 是那些没有副作用的:它们的唯一作用是 return 一个值,该值是它们参数的函数。

两次调用具有相同参数的同一个纯方法将 return 得到相同的值。那么,假设两次调用具有相同参数的纯方法,HotSpot 是否可以优化第二次调用,简单地重新使用第一次调用的值?

例如:

int add(int x, int y) {
  return x + y;
}

int addTwice(int x, int y) {
  return add(x, y) + add(x, y);
}

如果 HotSpot 没有在 addTwice 中内联 add,它是否理解 addpure 并因此调用 add 仅一次并使 return 值加倍?

当然,这种微不足道的 [mcve] 不太可能引起直接兴趣,但由于内联、发散控制流、自动生成代码等原因,在实践中可能会出现类似情况。

HotSpot 到目前为止无法做到这一点。

如果没有内联,方法调用对于 JIT 编译器来说通常是不透明的。很难进行跨方法优化。原因之一是方法入口点是易变的,即由于 JIT 编译、重新编译、反优化、JVMTI 调用等,它可以在 运行 时间同时更改。当 HotSpot 进行显式方法调用时,它不知道目标方法是否被解释或编译,是否收集 JIT 统计信息,是否正在调试,内部是否有断点,是否启用了 JVMTI 方法事件。

另一方面,即使存在这样的优化,也不会太有用。纯方法的功能非常有限,因此它们通常短小精悍,并且有很多机会被内联。内联后,JIT 更容易在同一编译范围内进行优化。