Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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++;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top