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?

Raedwald
  • 46,613
  • 43
  • 151
  • 237
leventov
  • 14,760
  • 11
  • 69
  • 98

2 Answers2

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.

Holger
  • 285,553
  • 42
  • 434
  • 765
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++;
    }
}
Claudiu
  • 1,469
  • 13
  • 21
  • 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? – leventov Sep 11 '13 at 11:59
  • 1
    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. – Claudiu Sep 11 '13 at 12:07
  • @leventov if you look at http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html you can see the explanation for MaxInlineSize parameter. – Claudiu Sep 11 '13 at 12:08