Could a Java compiler reorder function calls?

时间:2018-04-20 21:21:08

标签: java compiler-optimization

I know that java compiler can actually reorder code instructions. But can java reorder function calls?

For example:

...
//these lines may be reordered
a=7;
b=5;
...
//but what about this?
callOne();
callTwo();

2 个答案:

答案 0 :(得分:8)

如果可以确定这样做对结果没有影响,那么是的。由于它不能,编译器不会。

但是,JIT可以内联调用,因为它知道方法是否被覆盖,然后它可以重新排列代码,如果它认为合适的话。既然它只能保证结果保持不变,那么你为什么要关心?无论如何你都看不出差异。

答案 1 :(得分:2)

对于单线程程序,只有在证明重新排序不会影响计算结果的情况下,才允许重新排序指令(包括方法调用)。这在JLS中没有明确说明 1 ,但它是隐含的:

  • JLS(作为整个文档)指定了一个结构良好的单线程程序将做什么。

  • 如果编译器对程序中的指令重新排序,使其行为与规范所说的不同,则编译器将不符合JLS。

对于多线程程序,Chapter 17.4 Memory Model 允许重新排序,这可能会影响未正确同步的程序的行为。

JLS声明:

  

在给定程序和该程序的执行跟踪的情况下,存储器模型描述执行跟踪是否是程序的合法执行。 Java编程语言内存模型的工作原理是检查执行跟踪中的每个读取,并根据某些规则检查该读取所观察到的写入是否有效。

     

内存模型描述了程序的可能行为。只要程序的所有结果执行产生可由内存模型预测的结果,实现就可以自由地生成它喜欢的任何代码。

     

这为实现者提供了大量的自由来执行无数的代码转换,包括重新排序操作和删除不必要的同步。

     

Java编程语言的语义允许编译器和微处理器执行优化,这些优化可以与错误同步的代码交互,从而产生看似矛盾的行为。

在深入研究Java内存模型的技术细节之前,它提供了这种行为的示例......接下来的20页左右。

对于您的示例,如果可以证明它没有区别 2 ,则允许对这些方法调用进行重新排序。这是否可以证明将取决于方法的作用。

1 - 实际上,JLS 17.4.7,案例3可以解释为明确禁止在单线程情况下改变行为的重新排序。 JMM很难理解......而且我并没有声称自己足够专业,无法明确说明这件事的意义。

2 - ...对于JLS 17.4.7意义上的任何格式良好的执行。