- Getting Started
- Reference Manuals
- Native Image
- GraalVM Updater
- Embedding Reference
- Polyglot Programming
- JVM Languages Reference
- LLVM Languages Reference
- Python Reference
- R Reference Manual
- Ruby Reference
- WebAssembly Reference
- Debugging and Monitoring Tools
- GraalVM as a Platform
- Security Guide
- Release Notes
- Compiler Advantages
- Graph Compilation
- Ahead-of-time Compilation
- Compiler Operating Modes
- Diagnostic Data
The GraalVM compiler is a dynamic just-in-time (JIT) compiler, written in Java, that transforms bytecode into machine code. The GraalVM compiler integrates with Java HotSpot VM that supports a compatible version of the JVM Compiler Interface (JVMCI). JVMCI is a privileged low-level interface to the JVM, enabling a compiler written in Java to be used by the JVM as a dynamic compiler (see JEP 243. It can read metadata from the VM, such as method bytecode, and install machine code into the VM . GraalVM includes a version of the HotSpot JVM that supports JVMCI.
Compiler Advantages #
The GraalVM compiler provides optimized performance for programs running on the JVM through unique approaches to code analysis and optimization. It includes multiple optimization algorithms (called “Phases”) like aggressive inlining, polymorphic inlining, and others. For example, the GraalVM Enterprise compiler includes 62 optimization phases, of which 27 are patented.
The GraalVM compiler assures performance advantages for highly abstracted programs due to its ability to remove costly object allocations. Code using more abstraction and modern Java features like Streams or Lambdas will see greater speedups. Low level code or code that converge to things like I/O, memory allocation, or garbage collection will see less improvement. Consequently, an application running on GraalVM needs to spend less time doing memory management and garbage collection. For more information on performance tuning, refer to Compiler Configuration on JVM.
Graph Compilation #
The graph can represent similar statements of different languages, like “if” statements or loops, in the same way, which makes it possible to mix languages in the same program. The GraalVM compiler can perform then language-independent optimization and generate machine code on this grpah.
GraalVM also includes the Language Implementation Framework – a library, written in Java, to build interpreters for programming languages, which then run on GraalVM. These languages can consequently benefit from the optimization possibilities of the GraalVM compiler. The pipeline for such compilation is:
- The Language Implementation Framework code and data (Abstract Syntax Trees) is partially evaluated to produce a compilation graph. When such an Abstract Syntax Tree (AST) is hot (i.e., called many times), it is scheduled for compilation by the compiler.
- The compilation graph is optimized by the GraalVM compiler to produce machine code.
- JVMCI installs this machine code in the VM’s code cache.
- The AST will automatically redirect execution to the installed machine code once it is available.
Ahead-of-time Compilation #
Besides the Language Implementation Framework, GraalVM incorporates its optimizing compiler into an advanced ahead-of-time (AOT) compiation technology – Native Image, that translates Java and JVM-based code into a native platform executable. These native executables start nearly instantaneously, are smaller, and consume less resources of the same Java application, which makes them ideal for cloud deployments and microservices. For more information about AOT compilation, go to Native Image.
Compiler Operating Modes #
There are two operating modes of the GraalVM compiler when used as a HotSpot JIT compiler: as pre-compiled machine code (“libgraal”), or as dynamically executed Java bytecode (“jargraal”).
libgraal: the GraalVM compiler is compiled ahead-of-time into a native shared library. In this operating mode, the shared library is loaded by the HotSpot VM. The compiler uses memory separate from the HotSpot heap and it runs fast from the start since it does not need to warm-up. This is the default and recommended mode of operation.
jargraal: the GraalVM compiler goes through the same warm-up phase that the rest of Java
application does. That is, it is first interpreted before its hot methods are
compiled. This mode is selected with the
Diagnostic Data #
If an uncaught exception is thrown by the compiler, the compilation is simply
discarded and execution continues. However, the GraalVM compiler can instead produce
diagnostic data (such as compiler immediate representation graphs) that can be
submitted along with a bug report. This is enabled with
-Dgraal.CompilationFailureAction=Diagnose. The default location of the
diagnostics output is in
graal_dumps/ under the current working directory of
the process but can be changed with the
-Dgraal.DumpPath option. During the VM
shutdown, the location of the archive containing the diagnostic data is printed
to the console.
Furthermore, diagnostic data can be produced for any compilation performed by
the GraalVM compiler with the
-Dgraal.Dump option. This will produce
diagnostic data for every method compiled by the compiler. To refine the set of
methods for which diagnostic data is produced, use the
-Dgraal.MethodFilter=<class>.<method> option. For example,
-Dgraal.MethodFilter=java.lang.String.*,HashMap.get will produce diagnostic
data only for methods in the
java.lang.String class as well as methods named
get in a class whose non-qualified name is
Instead of being written to a file, diagnostic data can also be sent over the
network to Ideal Graph Visualizer.
This requires the
-Dgraal.PrintGraph=Network option, upon which the compiler
will try to send diagnostic data to 127.0.0.1:4445. This network endpoint can
be configured with the
options. Note: Ideal Graph Visualizer is available with Oracle GraalVM Enterprise Editon.