Search code examples
javajmhdead-code

Understanding avoiding Dead-code eliminations consequnces


I'm reading JMH samples and now I'm at the section about safe-looping. Here is an example:

@Benchmark
public void measureRight_2() {
    for (int x : xs) {
        sink(work(x));
    }
}

@CompilerControl(CompilerControl.Mode.DONT_INLINE)
public static void sink(int v) {
    // IT IS VERY IMPORTANT TO MATCH THE SIGNATURE TO AVOID AUTOBOXING.
    // The method intentionally does nothing.
}

But they made one caveat about this technique (emphasize mine).

Sometimes, the cost of sinking the value into a Blackhole is dominating the nano-benchmark score. In these cases, one may try to do a make-shift "sinker" with non-inlineable method. This trick is very VM-specific, and can only be used if you are verifying the generated code (that's a good strategy when dealing with nano-benchmarks anyway).

I do not quite understand what actuall a VM specific here. We use a method which is not supposed to be inlined. So the computation cannot be optimized away. What detail did I miss?


Solution

  • There is no guarantee that:

    1. The no-inlining hint is communicated to JVM correctly;
    2. The no-inlining hint is not deliberately ignored by JVM;
    3. The no-inlining hint is not accidentally ignored by JVM;
    4. The no-inlining hint is working, but JVM employs a cross-method optimization that avoids preparing arguments for known empty methods;
    5. The no-inlining hint is working, but JVM employs some other magic optimization you cannot come up with in 15 minutes of thinking;

    This may change from JVM family to JVM family, or even within the minor/patch releases of a given JVM family. This is why it is said to be very VM-specific, and to be used only if you actually control what happens exactly.