2014-10-10 56 views
2

例如,在这种情况下Hotspot JVM是否会执行强制消除casts,unboxing和divisions?

int x; 
for (...) { 
    ... some work, y and z not changed 
    x = y/z; 
    ... some code using x 
} 

是JVM(实际上JIT编译器)允许for环和“一些工作”(有副作用,可能或抛出不同的异常)之前计算x = y/z一次,如果它couldn 't证明z非零,在“正确的”时刻抛出ArithmeticException

大约铸件同样的问题(这可能导致对ClassCastException)和取消装箱(它可能引起NullPointerException),在某些情况下,JVM/JIT编译器仍然假设不能证明该对象具有适当的类或装箱值为非空。

Upd。 morgano表示此问题专用于JVM实现。在这种情况下,我的问题是关于热点JVM/JIT编译器的实现。

+0

使用[-XX:+ PrintAssembly](https://wikis.oracle.com/display/HotSpotInternals/PrintAssembly)并亲自查看HotSpot的功能。 – 2014-10-10 01:36:33

回答

2

是的,HotSpot JVM通常可以做到这一点。

C2 JIT编译器的一个关键特性是推测优化。这意味着JIT可以在不抛出运行时异常的情况下进行编译。在这种情况下,它可以容易地应用通用子表达式消除,循环不变吊装和其他相关优化。

如果在某些时候发生推测性假设失败,JIT将优化该方法并在解释模式下继续执行,以便将运行时异常引发到正确的位置。

顺便说一句,我已经检查了生成的程序集,HotSpot的确在您的示例中计算x = y/z一次。

+0

谢谢。优化/去优化点非常容易,但却没有引起我的注意。 – leventov 2014-10-10 09:30:42