HotSpot JIT inlining strategy: top-down or down-top
Asked Answered
B

2

15

Suppose we have 3 methods: method 2 is called from method 1, method 3 is called from method 2. Methods 2 and 3 are of size 30 bytecodes each. Also, suppose for definiteness method 2 is always called from method 1 exactly once, and method 3 is always called from method 2 exaclty once.

If method 2 is inlined first, method 3 will be called from the body of method 1 directly, and could be inlined in its turn. If method 3 is inlined into method 2 first, the size of the latter will become about 60 bytecodes, and it couldn't be inlined, because default MaxInlineSize threshold is 35 bytecodes.

In which order HotSpot JIT inlines methods: top-down or down-top?

Begun answered 11/9, 2013 at 9:43 Comment(0)
L
19

The MaxInlineSize affects compilations of methods executed at least one time but less than MinInliningThreshold times only. For methods executed more than MinInliningThreshold there is a different setting -XX:FreqInlineSize=… having a far bigger (platform dependent) default value. Hotspots are still inlined regardless of the MaxInlineSize. You may test it by running an application with -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -XX:MaxInlineSize=0. It will still report inlining of hot spots (these with the comment “(hot)”). Only methods formerly reported as inlined with the comment “executed < MinInliningThreshold times” might then get the comment to “too big”. If you set down the FreqInlineSize you might receive comments like “hot method too big”. I never saw them with the default setting.

Leman answered 11/9, 2013 at 12:23 Comment(1)
FreqInlineSize is 325 on modern 64bit Linux.Begun
G
3

Running the below code with the parameters reveals that both methods m3 is inlined first. i used the following parameters for jvm: -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining. Apparenly the method who's first execution count reaches the inlining threshold is inlined first. In our case m3. So for the hotspot i used for testing is down-top as m3 is first executed and the m2 execution ends.

Code was run with jdk7_u40 with TieredCompilation disabled, server mode on windows 8 box. Output of the command was:

            @ 66   java.lang.String::indexOfSupplementary (71 bytes)   too big
            @ 21   methodTest::m3 (31 bytes)   inline (hot)
            @ 11   methodTest::m2 (35 bytes)   inline (hot)
              @ 21   methodTest::m3 (31 bytes)   inline (hot)
            @ 14   methodTest::m1 (25 bytes)   inline (hot)
              @ 11   methodTest::m2 (35 bytes)   inline (hot)
                @ 21   methodTest::m3 (31 bytes)   inline (hot)

m1 is 25 bytes in size, m2 is 35 bytes and m3 has 31 bytes.

public class methodTest {

    public static void main(String[] args) {
        doTest();
    }

    int i = 0;
    int j = 0;
    int k = 0;

    private static void doTest() {
        methodTest m = new methodTest();

        for (int i = 0; i < 1000000000; i++) {
            m.m1();
        }
        System.out.println(m.i);
        System.out.println(m.j);
        System.out.println(m.k);
    }

    private void m1() {
        i++;
        m2();
        j++;
    }

    private void m2() {
        i++;
        i++;
        m3();
        j++;
    }

    private void m3() {
        i++;
        j++;
        k++;
    }
}
Glaring answered 11/9, 2013 at 11:51 Comment(3)
It turns out that only initial method size is taken into account? Because m2 is still inlined after m3. So, inlining order doesn't matter?Begun
Apparently it doesn't. It seem to take into account the size of the bytecode for that method. I just double checked the .class file and those indeed are the sizes of the bytecode for the methods.Glaring
@Begun if you look at oracle.com/technetwork/java/javase/tech/… you can see the explanation for MaxInlineSize parameter.Glaring

© 2022 - 2024 — McMap. All rights reserved.