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.
The input of generateDirectMethodHandleHolderClassBytes comes from the default_jli_trace.txt file that is generated in GenerateLinkOptData.gmk:
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.
Overally, we want to modify lookupPregenerated() to something like:
During CDS dump (static or dynamic), we will generate the CDSHolder1 and CDSHolder2 classes according to the program's execution profile.
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 LF_RESOLVE lines when parsing the classlist. At the end of the static dump, we invoke generateDirectMethodHandleHolderClassBytes to generate the DirectMethodHandle$CDSHolder1 class (as well as other holder classes that are currently generated by GenerateJLIClassesPlugin.java.)
Details TBD ....