Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8086045

Improve the java.lang.invoke first initialization costs

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 9
    • Fix Version/s: 9
    • Component/s: core-libs

      Description

      It is known from Indify String Concat, Lambdas, and probably Jigsaw that initialization costs for java.lang.invoke infra take a significant time on first access to the infrastructure.

      See a simple experiment here:
        http://cr.openjdk.java.net/~shade/8086045/indy-startup.txt

      The goal for this task is to investigate if we can improve this, or should we conclude the first initialization overheads can be justifiably ignored.
      1. jdk9-dev-lambdatest-10deep.svg
        21 kB
        Staffan Friberg
      2. jdk9-dev-lambdatest-15deep.svg
        47 kB
        Staffan Friberg
      3. jdk9-dev-lambdatest-6deep.svg
        8 kB
        Staffan Friberg
      4. lambdatest_timeline.svg
        4.18 MB
        Staffan Friberg
      5. lambdatest.svg
        3.02 MB
        Staffan Friberg

        Issue Links

          Activity

          Hide
          redestad Claes Redestad added a comment -
          Startup applications can observe a hit of ~50-100ms from using indy compared to other alternatives, depending on the extent of the usage. Most is one-time setup costs that might be possible to optimize at link-time (as in with a jlink plugin) in the JDK 9 timeframe, but when comparing the cost of j.l.invoke infra initialization in isolation we're already in a better place than JDK 8, mostly due to allowing more of the infrastructure to be initialized lazily. New features such as ISC make the initialization happen earlier or at more inopportune times, though.

          Coincidentally I was looking at related things and noticed that desugaring the initializer in StringConcatFactory cuts back on some of the parts of indy initialized when doing string concatenation, see JDK-8152074. I'll assess how much this helps JDK-8151887 and update that bug.
          Show
          redestad Claes Redestad added a comment - Startup applications can observe a hit of ~50-100ms from using indy compared to other alternatives, depending on the extent of the usage. Most is one-time setup costs that might be possible to optimize at link-time (as in with a jlink plugin) in the JDK 9 timeframe, but when comparing the cost of j.l.invoke infra initialization in isolation we're already in a better place than JDK 8, mostly due to allowing more of the infrastructure to be initialized lazily. New features such as ISC make the initialization happen earlier or at more inopportune times, though. Coincidentally I was looking at related things and noticed that desugaring the initializer in StringConcatFactory cuts back on some of the parts of indy initialized when doing string concatenation, see JDK-8152074 . I'll assess how much this helps JDK-8151887 and update that bug.
          Hide
          redestad Claes Redestad added a comment -
          Experiment to generate BMH$Species classes with jlink plugin:

          http://cr.openjdk.java.net/~redestad/scratch/bmh_species_gen.txt
          Show
          redestad Claes Redestad added a comment - Experiment to generate BMH$Species classes with jlink plugin: http://cr.openjdk.java.net/~redestad/scratch/bmh_species_gen.txt
          Hide
          redestad Claes Redestad added a comment -
          Prototyped code to generate DirectMethodHandles ahead of time, getting further improvements on these tests:

          http://cr.openjdk.java.net/~redestad/scratch/dmh_gen.txt

          Together with previous improvements the total overhead of running Shipilev's HelloMH test compared to HelloVirtual is down to 12ms. Only 4 MethodHandles are still generated at runtime (getObjectField, indentity_L, zero_L and invokeExact_MT), which could possibly be dealt with separately.

          I intend to supply the patch to generate DMH's ahead-of-time in jlink with this RFE ID.
          Show
          redestad Claes Redestad added a comment - Prototyped code to generate DirectMethodHandles ahead of time, getting further improvements on these tests: http://cr.openjdk.java.net/~redestad/scratch/dmh_gen.txt Together with previous improvements the total overhead of running Shipilev's HelloMH test compared to HelloVirtual is down to 12ms. Only 4 MethodHandles are still generated at runtime (getObjectField, indentity_L, zero_L and invokeExact_MT), which could possibly be dealt with separately. I intend to supply the patch to generate DMH's ahead-of-time in jlink with this RFE ID.
          Hide
          redestad Claes Redestad added a comment -
          With the patches for JDK-8164483 and JDK-8164569 applied (currently undergoing testing) I've gotten down to having no class generation during bootstrap for the HelloMH test linked in the description of this bug. This brings the total runtime difference between HelloVirtual and HelloMH down to ~5ms, which can be explained by HelloMH loading an additional 35 classes and doing a fair amount of setup ceremony.

          I think after simplifying how to determine and configure the set of classes to generate (JDK-8163371) that the work here is done. JDK-8163372 could be moved to a separate RFE.
          Show
          redestad Claes Redestad added a comment - With the patches for JDK-8164483 and JDK-8164569 applied (currently undergoing testing) I've gotten down to having no class generation during bootstrap for the HelloMH test linked in the description of this bug. This brings the total runtime difference between HelloVirtual and HelloMH down to ~5ms, which can be explained by HelloMH loading an additional 35 classes and doing a fair amount of setup ceremony. I think after simplifying how to determine and configure the set of classes to generate ( JDK-8163371 ) that the work here is done. JDK-8163372 could be moved to a separate RFE.
          Hide
          redestad Claes Redestad added a comment -
          By adding capabilities to jlink to pre-generate common forms - tied together with minimal build-time profiling to ensure the default configuration evolves with common use - as well as a series of cleanup and micro-optimizations to the runtime internals, the cost of initializing java.lang.invoke using the attached test is down to less than 3 ms on my machine, executing a mere 64K bytecode (compared to 690K in 8u), and loading only 21 classes statically.

          There's more work to be done to improve on more advanced use cases, but I think we're done here.
          Show
          redestad Claes Redestad added a comment - By adding capabilities to jlink to pre-generate common forms - tied together with minimal build-time profiling to ensure the default configuration evolves with common use - as well as a series of cleanup and micro-optimizations to the runtime internals, the cost of initializing java.lang.invoke using the attached test is down to less than 3 ms on my machine, executing a mere 64K bytecode (compared to 690K in 8u), and loading only 21 classes statically. There's more work to be done to improve on more advanced use cases, but I think we're done here.

            People

            • Assignee:
              redestad Claes Redestad
              Reporter:
              shade Aleksey Shipilev
            • Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: