When does JIT inline methods

The Hotspot JIT only inlines methods that are less than a certain (configurable) size. So using smaller methods allows more inlining, which is good.

When running this code with the following JVM flags: -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:FreqInlineSize=50 -XX:MaxInlineSize=50 -XX:+PrintInlining (yes I have used values that prove my case: m is too big but both the refactored m and m2 are below the threshold – with other values you might get a different output).

package Performance;
 
public class MethodInlining {
	private int count = 0;
 
	public static void main(String[] args) throws Exception {
		MethodInlining t = new MethodInlining();
		int sum = 0;
		for (int i = 0; i < 1000000; i++) {
			sum += t.m();
		}
		System.out.println(sum);
	}
 
	public int m() {
		int i = count;
		if (i % 10 == 0) {
			i += 1;
		} else if (i % 10 == 1) {
			i += 2;
		} else if (i % 10 == 2) {
			i += 3;
		}
		i += count;
		i *= count;
		i++;
		return i;
	}
}

Here is the part of the output. We can clearly see that method ‘m’ was not inlined inside ‘main’ method because it is too large

155 38 3 Performance.MethodInlining::main (39 bytes)
@ 4 Performance.MethodInlining:: (10 bytes)
@ 1 java.lang.Object:: (1 bytes)
@ 35 java/io/PrintStream::println (not loaded) not inlineable
@ 17 Performance.MethodInlining::m (62 bytes) callee is too large

Now lets break the method ‘m’ into 2 parts

package Performance;
 
public class MethodInlining {
	private int count = 0;
 
	public static void main(String[] args) throws Exception {
		MethodInlining t = new MethodInlining();
		int sum = 0;
		for (int i = 0; i < 1000000; i++) {
			sum += t.m();
		}
		System.out.println(sum);
	}
 
	public int m() {
	    int i = count;
	    i = m2(i);
	    i += count;
	    i *= count;
	    i++;
	    return i;
	}
 
	public int m2(int i) {
	    if (i % 10 == 0) {
	        i += 1;
	    } else if (i % 10 == 1) {
	        i += 2;
	    } else if (i % 10 == 2) {
	        i += 3;
	    }
	    return i;
	}
}

Now we can see inside ‘main’ method ‘m’ got inlined and inside ‘m’ method ‘m2’ method got inlined
174 40 % 4 Performance.MethodInlining::main @ 15 (39 bytes)
@ 17 Performance.MethodInlining::m (30 bytes) inline (hot)
@ 7 Performance.MethodInlining::m2 (40 bytes) inline (hot)

Uday Ogra

Connect with me at http://facebook.com/tendulkarogra and lets have some healthy discussion :)

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *