JEP: Ahead-of-Time Compilation. JDK-8166089
AOT (Ahead-Of-Time) compilation feature review.
----------------------------------------------
Compile Java classes to native code prior to launching Java application to achieve next goals:
• Provide faster startup for applications since compiled code for java hot methods will be readily available.
• Provide quicker time to peak performance. Statically generated code could be 1st pass in a multi-tiered compilation system instead of Interpreter.
• Sharing AOT'd code by applications running on the same system.
• Support platforms where executing dynamically generated code is prohibited e.g. iOS
AOT initial release in JDK 9 is only supported on 64-bit Linux systems running 64-bit Java with G1 and Parallel GCs. The system should have installed libelf to allow generation of AOT shared libraries (.so) as result of AOT compilation. Also AOT compilation should be done on the machine which will be used to run an application. Or on a machine with the same hardware and software configuration. These limitations will be addressed in future releases.
AOT compilation of any other JDK module, or of user code, is experimental and not supported in JDK 9.
For this release to use AOTed `java.base` user have to compile the module and copy resulting AOT library into java installation directory or specify it on java command line.
AOT compilation should be executed on the same system or a system with the same configuration on which AOT code will be used by Java application.
Use jaotc tool to execute AOT compilation. The tool is part of java installation - same as javac.
jaotc --output libHelloWorld.so HelloWorld.class
Then specify generated AOT library during application execution:
java -XX:AOTLibrary=./libHelloWorld.so HelloWorld
For this release the same java runtime configuration should be used during AOT compilation and execution. For example, jaotc should be run with Parallel GC if application will use it:
jaotc -J-XX:+UseParallelGC --output libHelloWorld.so HelloWorld.class
java -XX:+UseParallelGC -XX:AOTLibrary=./libHelloWorld.so HelloWorld
The runtime configuration is recorded in AOT library and verified when library is loaded during execution.
The set of AOT libraries could be generated for different execution environment. For example, to use different GCs or compressed oops.
AOT libraries can be compiled in two modes controlled by --compile-for-tiered flag:
1. Non-tiered AOT compiled code behaves similarly to statically compiled C++ code in that no profiling information is collected and no JIT recompilation will happen.
2. Tiered AOT compiled code does collect profiling information. The profiling done is the same as the simple profiling done by C1 methods compiled at Tier 2. If AOT methods hit the AOT invocation thresholds these methods are being recompiled by C1 at Tier 3 first in order to gather full profiling information. This is required for C2 JIT recompilation to be able to produce optimal code and reach peak application performance.
During JVM startup the AOT initialization code looks for well-known shared libraries in a well-known location or libraries specified by -XX:AOTLibrary option. If shared libraries are found, these are picked up and used. If no shared libraries can be found, AOT will be turned off for this JVM instance going forward or exit VM if flag -XX:+ UseAOTStrictLoading is specified.
JVM knows next `well-known` names for java.base AOT libraries generated for specific runtime configuration:
libjava.base.so -XX:-UseCompressedOops -XX:+UseG1GC
libjava.base-coop.so -XX:+UseCompressedOops -XX:+UseG1GC
libjava.base-nong1.so -XX:-UseCompressedOops -XX:+UseParallelGC
libjava.base-coop-nong1.so -XX:+UseCompressedOops -XX:+UseParallelGC
JVM also knows AOT libraries names for next java modules but they usage is experimental:
jdk.compiler
jdk.scripting.nashorn
jdk.vm.ci
jdk.vm.compiler
To generate and use AOT library for java.base module follow next steps.
------------------------------------------------------------------
Compile java.base module. It requires significant java heap to keep all compiled methods:
jaotc -J-XX:+UseCompressedOops -J-XX:+UseG1GC -J-Xmx4g --compile-for-tiered --output libjava.base-coop.so --module java.base
Specify generated AOT library during execution:
java -XX:AOTLibrary=./libjava.base-coop.so,./libHelloWorld.so HelloWorld
Or copy generated AOT library to java installation directory (may need to adjust directory's permissions):
cp libjava.base-coop.so $JAVA_HOME/lib/
In such case it will be loaded automatically without need to specify on command line:
java -XX:AOTLibrary=./libHelloWorld.so HelloWorld
Consider stripping unused symbols from AOT library to reduce library's size.
===============================================================================
New java AOT flags.
------------------
-XX:+/-UseAOT
Use AOT-compiled files. By default it is ON.
-XX:AOTLibrary=<file>
Specify a list of AOT library files. Separate libraries entries with colons (:) or comma (,).
-XX:+/-PrintAOT
Print used AOT klasses and methods.
Additional diagnostic flag is available (requires to specify -XX:+UnlockDiagnosticVMOptions flag):
-XX:+/-UseAOTStrictLoading
Exit the JVM if any of the AOT libraries has invalid runtime config.
-XX:+/-PrintAOTStatistics
Print AOT statistics.
The logging of AOT runtime events is integrated with JEP 271: Unified GC Logging. The following Unified Logging tags are supported:
aotclassfingerprint
aotclassload
aotclassresolve
===============================================================================================================
jaotc - Java Ahead-Of-Time compiler.
-----------------------------------
Java static compiler which produce native code for compiled java methods. It uses Graal as the code-generating backend and libelf for generating .so AOT library.
The tool is part of java installation and can be used the same way as javac.
jaotc <options> <--module name>
or
jaotc <options> <list of classes or jar files>
The following jaotc flags are available:
--module <name> - Module to compile.
--module-path <path> - Specify where to find application modules. Looking in java installation directory if not specified.
--output <file> - Output file name. Default name is "unnamed.so".
--compile-commands <file> - Name of file with compile commands
--compile-for-tiered - Generated profiling code for tiered compilation. By default profiling code is not generated.
--classpath <path> - Specify where to find user class files
--threads <number> - Number of compilation threads to be used. Default value is min(16, available_cpus).
--ignore-errors - Ignores all exceptions thrown during class loading. By default exit compilation if class loading throws exception.
--exit-on-error - Exit on compilation errors. By default failed compilation is skipped and compilation of other methods continues.
--info - Print information during compilation
--verbose - Print verbose information
--debug - Print debug information
--help - Print this usage message
-J<flag> - Pass <flag> directly to the runtime system
--info
print information about compilation phases
--verbose
print more details about compilation phases, switch on --info flag
--debug
print even more details, switch on --info and --verbose flag
--compile-commands <file>
file format:
<command> <java methods>
<command>:
exclude - exclude compilation of specified methods
compileOnly - compile only specified methods
<java methods> - regular expressions which specifies classes and methods. For example:
exclude sun.util.resources..*.TimeZoneNames_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.security.ssl.*
compileOnly java.lang.String.*
AOT (Ahead-Of-Time) compilation feature review.
----------------------------------------------
Compile Java classes to native code prior to launching Java application to achieve next goals:
• Provide faster startup for applications since compiled code for java hot methods will be readily available.
• Provide quicker time to peak performance. Statically generated code could be 1st pass in a multi-tiered compilation system instead of Interpreter.
• Sharing AOT'd code by applications running on the same system.
• Support platforms where executing dynamically generated code is prohibited e.g. iOS
AOT initial release in JDK 9 is only supported on 64-bit Linux systems running 64-bit Java with G1 and Parallel GCs. The system should have installed libelf to allow generation of AOT shared libraries (.so) as result of AOT compilation. Also AOT compilation should be done on the machine which will be used to run an application. Or on a machine with the same hardware and software configuration. These limitations will be addressed in future releases.
AOT compilation of any other JDK module, or of user code, is experimental and not supported in JDK 9.
For this release to use AOTed `java.base` user have to compile the module and copy resulting AOT library into java installation directory or specify it on java command line.
AOT compilation should be executed on the same system or a system with the same configuration on which AOT code will be used by Java application.
Use jaotc tool to execute AOT compilation. The tool is part of java installation - same as javac.
jaotc --output libHelloWorld.so HelloWorld.class
Then specify generated AOT library during application execution:
java -XX:AOTLibrary=./libHelloWorld.so HelloWorld
For this release the same java runtime configuration should be used during AOT compilation and execution. For example, jaotc should be run with Parallel GC if application will use it:
jaotc -J-XX:+UseParallelGC --output libHelloWorld.so HelloWorld.class
java -XX:+UseParallelGC -XX:AOTLibrary=./libHelloWorld.so HelloWorld
The runtime configuration is recorded in AOT library and verified when library is loaded during execution.
The set of AOT libraries could be generated for different execution environment. For example, to use different GCs or compressed oops.
AOT libraries can be compiled in two modes controlled by --compile-for-tiered flag:
1. Non-tiered AOT compiled code behaves similarly to statically compiled C++ code in that no profiling information is collected and no JIT recompilation will happen.
2. Tiered AOT compiled code does collect profiling information. The profiling done is the same as the simple profiling done by C1 methods compiled at Tier 2. If AOT methods hit the AOT invocation thresholds these methods are being recompiled by C1 at Tier 3 first in order to gather full profiling information. This is required for C2 JIT recompilation to be able to produce optimal code and reach peak application performance.
During JVM startup the AOT initialization code looks for well-known shared libraries in a well-known location or libraries specified by -XX:AOTLibrary option. If shared libraries are found, these are picked up and used. If no shared libraries can be found, AOT will be turned off for this JVM instance going forward or exit VM if flag -XX:+ UseAOTStrictLoading is specified.
JVM knows next `well-known` names for java.base AOT libraries generated for specific runtime configuration:
libjava.base.so -XX:-UseCompressedOops -XX:+UseG1GC
libjava.base-coop.so -XX:+UseCompressedOops -XX:+UseG1GC
libjava.base-nong1.so -XX:-UseCompressedOops -XX:+UseParallelGC
libjava.base-coop-nong1.so -XX:+UseCompressedOops -XX:+UseParallelGC
JVM also knows AOT libraries names for next java modules but they usage is experimental:
jdk.compiler
jdk.scripting.nashorn
jdk.vm.ci
jdk.vm.compiler
To generate and use AOT library for java.base module follow next steps.
------------------------------------------------------------------
Compile java.base module. It requires significant java heap to keep all compiled methods:
jaotc -J-XX:+UseCompressedOops -J-XX:+UseG1GC -J-Xmx4g --compile-for-tiered --output libjava.base-coop.so --module java.base
Specify generated AOT library during execution:
java -XX:AOTLibrary=./libjava.base-coop.so,./libHelloWorld.so HelloWorld
Or copy generated AOT library to java installation directory (may need to adjust directory's permissions):
cp libjava.base-coop.so $JAVA_HOME/lib/
In such case it will be loaded automatically without need to specify on command line:
java -XX:AOTLibrary=./libHelloWorld.so HelloWorld
Consider stripping unused symbols from AOT library to reduce library's size.
===============================================================================
New java AOT flags.
------------------
-XX:+/-UseAOT
Use AOT-compiled files. By default it is ON.
-XX:AOTLibrary=<file>
Specify a list of AOT library files. Separate libraries entries with colons (:) or comma (,).
-XX:+/-PrintAOT
Print used AOT klasses and methods.
Additional diagnostic flag is available (requires to specify -XX:+UnlockDiagnosticVMOptions flag):
-XX:+/-UseAOTStrictLoading
Exit the JVM if any of the AOT libraries has invalid runtime config.
-XX:+/-PrintAOTStatistics
Print AOT statistics.
The logging of AOT runtime events is integrated with JEP 271: Unified GC Logging. The following Unified Logging tags are supported:
aotclassfingerprint
aotclassload
aotclassresolve
===============================================================================================================
jaotc - Java Ahead-Of-Time compiler.
-----------------------------------
Java static compiler which produce native code for compiled java methods. It uses Graal as the code-generating backend and libelf for generating .so AOT library.
The tool is part of java installation and can be used the same way as javac.
jaotc <options> <--module name>
or
jaotc <options> <list of classes or jar files>
The following jaotc flags are available:
--module <name> - Module to compile.
--module-path <path> - Specify where to find application modules. Looking in java installation directory if not specified.
--output <file> - Output file name. Default name is "unnamed.so".
--compile-commands <file> - Name of file with compile commands
--compile-for-tiered - Generated profiling code for tiered compilation. By default profiling code is not generated.
--classpath <path> - Specify where to find user class files
--threads <number> - Number of compilation threads to be used. Default value is min(16, available_cpus).
--ignore-errors - Ignores all exceptions thrown during class loading. By default exit compilation if class loading throws exception.
--exit-on-error - Exit on compilation errors. By default failed compilation is skipped and compilation of other methods continues.
--info - Print information during compilation
--verbose - Print verbose information
--debug - Print debug information
--help - Print this usage message
-J<flag> - Pass <flag> directly to the runtime system
--info
print information about compilation phases
--verbose
print more details about compilation phases, switch on --info flag
--debug
print even more details, switch on --info and --verbose flag
--compile-commands <file>
file format:
<command> <java methods>
<command>:
exclude - exclude compilation of specified methods
compileOnly - compile only specified methods
<java methods> - regular expressions which specifies classes and methods. For example:
exclude sun.util.resources..*.TimeZoneNames_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.security.ssl.*
compileOnly java.lang.String.*