The Source for Java Technology Collaboration


AOT Compilation in CVM

Overview

AOT stands for Ahead Of Time compilation, which means instead of compiling Java bytecode into native machine code at runtime, the bytecode are converted into native code beforehand, for example during VM build time or install time. In CVM, AOT compilation happens when the VM is being executed for the first time on the target platform. A list of Java methods is compiled during VM startup and the compiled code is saved into a file. During the subsequent executions of CVM the save AOT code is found and executed like dynamically JIT'ed code.

How to enable AOT in CVM

To enable AOT, build CVM with CVM_AOT=true. Currently AOT is only supported on linux-arm, linux-mips, and linux-powerpc.

Implementation Details

As mentioned in the overview, in CVM AOT compilation happens during the first time the VM is executed. When CVM is running the first time on the target platform, as part of the VM initialization process it opens and reads lib/methodsList.txt and compiles all the Java methods on the list. The methods in methodsList.txt are hot methods identified by profiling using various applications. The same JIT compiler used for dynamic compilation at runtime is used for the AOT compilation. After the last method in the list is compiled, all compiled code currently in the JIT code cache is save into a file named cvm.aot in the bin/ directory, along with the size of the compiled code. Also a SHA-1 hash value computed using CVM executable is embedded at the end of the compiled code. This hash value is used for binary compatibility check when the AOT code is reloaded druing the subsequent runs. After AOT code is saved, CVM can continue its normal execution until shutdown.

Following is the layout of the saved AOT code cache:

    ------------------------------------------------------
    |start address|size|                                 |
    |--------------------                                |
    |                 compiled code                      |
    .                                                    .
    .                                                    .
    |                                                    |
    ------------------------------------------------------
    | CVM SHA-1 checksum                                 |
    ------------------------------------------------------

When CVM is being relaunched after the first execution, during VM startup it first checks if there is saved AOT code. If AOT code exists, it checks binary compatibility by comparing the SHA1 hash value embedded in the AOT code with the one in the CVM. If the values are not compatible, AOT code is recompiled and the cvm.aot is replaced with a new one. If the hash values are compatible, the compiled code in the AOT file is mapped into the process address space using mmap. CVM does not require the AOT code always being mapped at the same location because the compiled code within the code cache are PC relative. However it does require that addresses outside of the code cache have to be constants. Dynamically loaded classes usually cannot guarantee fixed addresses, therefore ROMization is required for AOT. The mapped AOT code cache and JIT (dynamic compiled) code cache are not required to be consecutive. Currently the JIT code cache is separate from the AOT code cache.

Once the AOT code is mmapped, the VM iterates through the code cache to find each pre-compiled method and marks the method as being compiled. So when the method is invoked, the pre-compiled code will be executed and no compilation is needed for that method. From the VM point of view, there is no difference between dynamically compiled code and AOT code. The invocation process is the same.

If decompilation happens, only the dynamically compiled code is decompiled. AOT code is not decompiled.

How to modify methodsList.txt

Building the VM with CVM_TRACE_JIT=true and running it with -Xjit:trace=status shows all the methods being compiled when running a particular application. That is a good way to produce the method list. Note non-romized methods should not be included in the method list. Adding or removing methods in methodsList.txt does not cause AOT code being regenerated. To regenerate AOT code, delete the bin/cvm.aot file.

AOT related command line options

Following are AOT related -Xjit options.

  • aot={true | false}: Enable/disable AOT. By default AOT is enabled.
  • aotFile=AOT file: AOT file path.
  • recompileAOT={true | false}: Recompile AOT code. The exising AOT code will be replaced when this option is used.
  • aotCodeCacheSize=Size: Size for the code cache used for AOT compilation. The default size is 672K.
  • aotMethodList=filename: List of methods to be compiled and saved as AOT code.

Benefits

  • Memory sharing
In CVM, AOT code is mapped as read only. That allows different VM processes share the same memory location that AOT code encompasses.

  • Startup time saving
AOT can also help startup time by saving the time used for dynamic compilation.

Limitations

  • For sharing purpose, AOT code are mapped as read only and some of the optimizations in CVM JIT is disabled for AOT because they require writes to the code cache.

  • Requires ROMization for constant address outside of the code cache.

  • Only ROMized methods should be pre-compiled.

  • The CVM AOT implementation requires pc-relative code being generated so relocation is not required for AOT code. Currently AOT is only supported for ARM. For other platforms where compiled code are not pc-relative, a fixed address could be used for the AOT codecache.

-- Main.jiangli_zhou - 19 May 2008

Topic PhoneMEAdvancedCVMAOT . { Edit | Ref-By | Printable | Diffs r5 < r4 < r3 < r2 < r1 | More }
 XML java.net RSS

Revision r5 - 13 Jan 2009 - 17:15:43 - ChrisPlummer
Parents: WebHome > PhoneMEAdvanced