Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
Background ========== In general, the java.lang.invoke framework would dynamically generate bytecodes according to the usage pattern of the current Java program (e.g., the actual types of parameters used in MethodHandle invocations). However, dynamic bytecode generation is expensive. For better start-up time, the framework tries to avoid dynamic generation and use pre-generated code instead. Examples are: [1] ClassSpecializer::Factory::loadSpecies() http://hg.openjdk.java.net/jdk/jdk/file/8ada048df69d/src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java [2] InvokerBytecodeGenerator::lookupPregenerated() http://hg.openjdk.java.net/jdk/jdk/file/8ada048df69d/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Since the run-time usage pattern is theoretically limitless, we cannot pre-generate all possible code. However, jlink uses profiling to look for commonly used patterns, pre-generates code for these patterns, and stores the pre-generated code into the JDK's lib/modules file. (See JDK-8086045). http://hg.openjdk.java.net/jdk/jdk/file/8ada048df69d/make/GenerateLinkOptData.gmk The pre-generated bytecodes for [1] are in these classes: $ jimage list lib/modules | grep Species_ java/lang/invoke/BoundMethodHandle$Species_LL java/lang/invoke/BoundMethodHandle$Species_LJ java/lang/invoke/BoundMethodHandle$Species_LLL ... For [2], the pre-generated bytecodes are in the methods of these classes java/lang/invoke/DirectMethodHandle$Holder java/lang/invoke/DelegatingMethodHandle$Holder java/lang/invoke/LambdaForm$Holder java.lang.invoke.Invokers$Holder Problem ======= The problem with the jlink pre-generated classes is that they may not match the usage pattern for all programs. E.g., a "fail" in the following log indicates that pregenerated code is not found and dynamic bytecodes must be generated: $ javac -J-Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true HelloWorld.java | grep fail [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeStatic L_L (fail) [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeSpecial L3_V (fail) [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeSpecial L4IIL_I (fail) [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder newInvokeSpecial L4II_L (fail) ... Solution ======== When dumping the classlist of a Java program using -XX:DumpLoadedClassList, we also collect information about the java.lang.invoke usage pattern. During the creation of the static CDS archive (-Xshare:dump), we use the collected information to re-generate the various $Species and $Holder classes so that they are customized for this application. Result ====== Preliminary testing shows that we can reduce the number of classes dynamically generated for java.lang.invoke by about 75% in the "javac HelloWorld.java" example, resulting in about 2.8% performance improvement. Design Doc ========= https://wiki.openjdk.java.net/display/HotSpot/Support+for+pre-generated+java.lang.invoke+classes+in+CDS+archive
|