Improve start-up time by storing pre-generated LambdaForm handlers in an application-specific CDS archive.
In JDK-8086045 (Improve the java.lang.invoke first initialization costs), the JDK can reduce the number of dynamically generated LambdaForm classes. Here's an example:
Here's the difference between the exploded build and the final image:
The JDK image's version of the java.lang.invoke.DirectMethodHandle$Holder class is generated here in GenerateJLIClassesPlugin.java. This plugin is executed when we generate the file images/jdk/lib/modules.
Here's how roughly the contents of default_jli_trace.txt correspond to the generated methods in DirectMethodHandle$Holder
The methods in DirectMethodHandle$Holder are used in InvokerBytecodeGenerator.java when compiling for LambdaForms:
The expected benefits will be application specific. Here's an experiment with Javac (I modified the JDK makefile to invoke com.sun.tools.javac.Main while generating default_jli_trace.txt).
Why do it in CDS
- We cannot store all possible LambdaForm handlers in the standard JDK image – we cannot enumerate all possible forms that may be used by all possible apps.
- We could also do this as part of jlink, when creating a custom JDK image. However, some users may not want to create a new JDK image.
- Also, there's currently no work-flow to include profiling data when building a custom JDK image (although this can be changed, probably as part of Project Leyden)
- CDS dynamic dump can be used without generating profiling data in a separate step, so the usability is better.
We regenerate the XXX$Holder classes to contain all necessary methods used by the application.
During the trial run (with -XX:DumpLoadedClassList=classlist), we can save the list of LambdaForm handlers using a special syntax like:
We collect all the @lambda-form-invoker lines when parsing the classlist. At the end of the static dump:
- We invoke generateDirectMethodHandleHolderClassBytes to generate a customized version of DirectMethodHandle$Holder (as well as other holder classes that are currently generated by GenerateJLIClassesPlugin.java.)
- This DirectMethodHandle$Holder class has all the methods needed for resolving the MethodHandle LambdaForms during the trial run.
- Store the InstanceKlass of the customized version of DirectMethodHandle$Holder into the CDS archive.
- The generation of the customized DirectMethodHandle$Holder is done in MetaspaceShared::regenerate_holder_classes().
- See JDK-8255493 (Support for pre-generated java.lang.invoke classes in CDS dynamic archive)
- Collect a @lambda-form-invoker list (in memory) when -XX:ArchiveClassesAtExit is specified.
- When the dynamic archive is dumped, use this list to create customized Holder classes.