Eug*_*ene 8 java jvm virtual-machine jvm-arguments java-9
假设我有这个代码(我认为这无关紧要,但以防万一):
public class AtomicJDK9 {
static AtomicInteger ai = new AtomicInteger(0);
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i < 30_000; ++i) {
sum += atomicIncrement();
}
System.out.println(sum);
}
public static int atomicIncrement() {
ai.getAndAdd(12);
return ai.get();
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我如何调用它(使用java-9):
java -XX:+UnlockDiagnosticVMOptions
-XX:-TieredCompilation
-XX:+PrintIntrinsics
AtomicJDK9
Run Code Online (Sandbox Code Playgroud)
我想要找出的是什么方法被内在代码所取代.第一个被击中(在不安全的内部):
@HotSpotIntrinsicCandidate
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
v = getIntVolatile(o, offset);
} while (!weakCompareAndSwapIntVolatile(o, offset, v, v + delta));
return v;
}
Run Code Online (Sandbox Code Playgroud)
并且这个方法确实存在于上面调用的输出中:
@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic)
Run Code Online (Sandbox Code Playgroud)
但是,整个输出很奇怪(对我而言):
@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic)
@ 3 jdk.internal.misc.Unsafe::getIntVolatile (0 bytes) (intrinsic)
@ 18 jdk.internal.misc.Unsafe::weakCompareAndSwapIntVolatile (11 bytes) (intrinsic)
@ 7 jdk.internal.misc.Unsafe::compareAndSwapInt (0 bytes) (intrinsic)
@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic)
Run Code Online (Sandbox Code Playgroud)
为什么getAndAddInt在输出中出现两次?
此外,如果getAndAddInt确实被内部调用替换,为什么需要在调用堆栈中替换所有其他内部方法 l它们将不再被使用.我认为它就像从底部遍历方法调用的堆栈一样简单.
为了说明编译器逻辑,我使用以下参数运行JVM.
-XX:-TieredCompilation -XX:CICompilerCount=1
-XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:+PrintInlining
Run Code Online (Sandbox Code Playgroud)
这就是它打印的内容.
337 29 java.util.concurrent.atomic.AtomicInteger::getAndAdd (12 bytes)
@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic)
337 30 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes)
@ 3 jdk.internal.misc.Unsafe::getIntVolatile (0 bytes) (intrinsic)
@ 18 jdk.internal.misc.Unsafe::weakCompareAndSwapIntVolatile (11 bytes) (intrinsic)
338 32 jdk.internal.misc.Unsafe::weakCompareAndSwapIntVolatile (11 bytes)
@ 7 jdk.internal.misc.Unsafe::compareAndSwapInt (0 bytes) (intrinsic)
339 33 AtomicJDK9::atomicIncrement (16 bytes)
@ 5 java.util.concurrent.atomic.AtomicInteger::getAndAdd (12 bytes) inline (hot)
@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic)
@ 12 java.util.concurrent.atomic.AtomicInteger::get (5 bytes) accessor
Run Code Online (Sandbox Code Playgroud)
AtomicInteger.getAndAdd 不仅从您的代码调用,而且从常见的JDK代码调用.AtomicInteger.getAndAdd达到调用阈值比你的早一点AtomicJDK9.atomicIncrement.然后getAndAdd提交到编译队列,这是第一个内在打印输出的来源.AtomicInteger.getAndAdd被解释,Unsafe.getAndAddInt和Unsafe.weakCompareAndSwapIntVolatile方法也达到调用门槛,并开始编制.在编译这些Unsafe方法时会打印下3个内在函数.AtomicJDK9.atomicIncrement也到达调用threashold并开始编译.最后一个内在打印输出对应于您的方法.