JDK-8280481 : Duplicated stubs to interpreter for static calls
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 19
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • CPU: x86_64,aarch64
  • Submitted: 2022-01-21
  • Updated: 2023-11-10
  • Resolved: 2022-07-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 20
20 b05Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
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

Comments
[17u] This is a large backport of a quite recent change, where I think the risk is bigger than the win. It might be an option to readdress this once it was delivered and has proven its benefit.
07-11-2022

Fix Request (17u) A backport of shared stubs to the interpreter for statically bound Java methods calls. The backport contains implementations for the aarch64, x86 and x86_64 backends. Other backends are guarded with Unimplemented() calls and constexpr supports_shared_stubs() returning false. A risk is between low and moderate. Performance regressions are unlikely because stubs are used to go to the interpreter which will be the main contributor to the execution time. Crashes are unlikely because we either successfully generate a shared stub during compilation or fail. If generation fails, there will be no compiled method with missing stubs. Tested with fastdebug and release builds on aarch64, x86 and x86_64: gtest: Passed tier1, tier2: Passed The backport can be considered clean. Git backport conflicts were caused by changes positioning issues.
18-10-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/780 Date: 2022-10-11 18:53:21 +0000
11-10-2022

Changeset: 35156041 Author: Evgeny Astigeevich <eastig@amazon.com> Committer: Paul Hohensee <phh@openjdk.org> Date: 2022-07-05 20:50:02 +0000 URL: https://git.openjdk.org/jdk/commit/351560414d7ddc0694126ab184bdb78be604e51f
05-07-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk/pull/8816 Date: 2022-05-20 16:27:51 +0000
20-05-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk/pull/8024 Date: 2022-03-29 22:09:34 +0000
20-04-2022

x86_64 C1 Test::test: 0x00007f3195af38b5: movabs $0x80043ed58,%rbx ; {static_stub} 0x00007f3195af38bf: jmp 0x00007f3195440244 ; {runtime_call I2C/C2I adapters} 0x00007f3195af38c4: nop 0x00007f3195af38c5: movabs $0x80043ed58,%rbx ; {static_stub} 0x00007f3195af38cf: jmp 0x00007f3195440244 ; {runtime_call I2C/C2I adapters} 0x00007f3195af38d4: nop 0x00007f3195af38d5: movabs $0x80044d900,%rbx ; {static_stub} 0x00007f3195af38df: jmp 0x00007f31954a9ca1 ; {runtime_call I2C/C2I adapters} 0x00007f3195af38e4: nop 0x00007f3195af38e5: movabs $0x80043ea80,%rbx ; {static_stub} 0x00007f3195af38ef: jmp 0x00007f31954405c8 ; {runtime_call I2C/C2I adapters} 0x00007f3195af38f4: nop 0x00007f3195af38f5: movabs $0x80043ea80,%rbx ; {static_stub} 0x00007f3195af38ff: jmp 0x00007f31954405c8 ; {runtime_call I2C/C2I adapters} 0x00007f3195af3904: nop 0x00007f3195af3905: movabs $0x80043ef60,%rbx ; {static_stub} 0x00007f3195af390f: jmp 0x00007f319544b344 ; {runtime_call I2C/C2I adapters} 0x00007f3195af3914: nop 0x00007f3195af3915: movabs $0x7f3154000388,%rbx ; {static_stub} 0x00007f3195af391f: jmp 0x00007f319545a5c3 ; {runtime_call I2C/C2I adapters} 0x00007f3195af3924: nop 0x00007f3195af3925: movabs $0x7f3154000388,%rbx ; {static_stub} 0x00007f3195af392f: jmp 0x00007f319545a5c3 ; {runtime_call I2C/C2I adapters}
21-01-2022

x86_64 C2 Test::test: 0x00007f319cf53b80: movabs $0x7f3154000388,%rbx ; {no_reloc} 0x00007f319cf53b8a: jmp 0x00007f319545a5c3 ; {runtime_call I2C/C2I adapters} 0x00007f319cf53b8f: movabs $0x7f3154000388,%rbx ; {static_stub} 0x00007f319cf53b99: jmp 0x00007f319545a5c3 ; {runtime_call I2C/C2I adapters}
21-01-2022