Calls of Java methods have stubs to the interpreter for the cases when an invoked Java method is not compiled. Calls of static Java methods and final Java methods have statically bound information about a callee during compilation. C1 and C2 always generate a new stub for each call. As the generated stubs for calls of the same method are the same, they can be shared.
The following Test.java reproduces the issue: two stubs to the interpreter for calls of the static `error`.
class Test {
private static void error(int i, String msg) {
if (i > 900000)
throw new RuntimeException(msg);
}
public static void test(int i, String[] args) {
if (i % args.length == 0) {
error(i, "args[0] == " + args[0]);
} else {
error(i, "No args");
}
}
public static void main(String[] args) {
for (int i = 1; i < 1000000; ++i) {
test(i, args);
}
}
}
A command to run:
$ java -XX:+PrintAssembly -XX:+PrintRelocations -XX:+PrintStubCode -XX:+PrintInterpreter -XX:CompileCommand="compileonly,Test::test" -XX:CompileCommand=dontinline,Test::error -XX:CompileCommand=dontinline,Test::test Test q b c> run.log
C1-compiled nmethod, Test::test, stub code section:
0x0000ffff79bd2530: isb ; {static_stub}
0x0000ffff79bd2534: mov x12, #0x388 // #904
; {metadata({method} {0x0000ffff18400388} 'error' '(ILjava/lang/String;)V' in 'Test')}
0x0000ffff79bd2538: movk x12, #0x1840, lsl #16
0x0000ffff79bd253c: movk x12, #0xffff, lsl #32
0x0000ffff79bd2540: mov x8, #0xe58c // #58764
0x0000ffff79bd2544: movk x8, #0x793b, lsl #16
0x0000ffff79bd2548: movk x8, #0xffff, lsl #32
0x0000ffff79bd254c: br x8
...
0x0000ffff79bd2560: isb ; {static_stub}
0x0000ffff79bd2564: mov x12, #0x388 // #904
; {metadata({method} {0x0000ffff18400388} 'error' '(ILjava/lang/String;)V' in 'Test')}
0x0000ffff79bd2568: movk x12, #0x1840, lsl #16
0x0000ffff79bd256c: movk x12, #0xffff, lsl #32
0x0000ffff79bd2570: mov x8, #0xe58c // #58764
0x0000ffff79bd2574: movk x8, #0x793b, lsl #16
0x0000ffff79bd2578: movk x8, #0xffff, lsl #32
0x0000ffff79bd257c: br x8
C2-compiled nmethod, Test::test, stub code section:
0x0000ffff80fa39d0: isb ; {static_stub}
0x0000ffff80fa39d4: mov x12, #0x388 // #904
; {metadata({method} {0x0000ffff18400388} 'error' '(ILjava/lang/String;)V' in 'Test')}
0x0000ffff80fa39d8: movk x12, #0x1840, lsl #16
0x0000ffff80fa39dc: movk x12, #0xffff, lsl #32
0x0000ffff80fa39e0: mov x8, #0xe58c // #58764
0x0000ffff80fa39e4: movk x8, #0x793b, lsl #16
0x0000ffff80fa39e8: movk x8, #0xffff, lsl #32
0x0000ffff80fa39ec: br x8
0x0000ffff80fa3a00: isb ; {static_stub}
0x0000ffff80fa3a04: mov x12, #0x388 // #904
; {metadata({method} {0x0000ffff18400388} 'error' '(ILjava/lang/String;)V' in 'Test')}
0x0000ffff80fa3a08: movk x12, #0x1840, lsl #16
0x0000ffff80fa3a0c: movk x12, #0xffff, lsl #32
0x0000ffff80fa3a10: mov x8, #0xe58c // #58764
0x0000ffff80fa3a14: movk x8, #0x793b, lsl #16
0x0000ffff80fa3a18: movk x8, #0xffff, lsl #32
0x0000ffff80fa3a1c: br x8