Getting started with GraalVM

Do you know GraalVM? It’s polygot runtime for JVM. I’m very interested in GraalVM. So today I set up it and run examples.

Officially Graal is explained as below:

GraalVM - New JIT Compiler and Polyglot Runtime for the JVM

Graal is a new just-in-time compiler for the JVM focused on peak performance and multi-language support. Graal offers performance advantages not only to Java code, but also to scripting languages such as JavaScript, Ruby, and R. Additionally, it enables the execution of native code on the JVM via an LLVM-based front end (project Sulong). Languages are executed by Graal via the Truffle framework, which comes with seamless interoperability and polyglot debugging and profiling functionality. Oracle Labs GraalVM: Programming Languages and Runtimes Overview

It’s a little confusing, Graal is not same as GraalVM. Simply stated, GraalVM consists of Graal and Truffle.

Set up

You can download GraalVM from the following URL. Oracle Labs GraalVM: Download

Then you uncompress the file in a directory of your choice and add “[GraalVM]/bin” to PATH. Finally try to run the following command.

$ graalvm -version
Option -version is deprecated use --version

GraalVM version: 0.23
Graal languages:
  JS: 0.9
  R: 0.1
  Ruby: 2.3.3
Java version:
  java version "1.8.0_121"
  Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
  Java HotSpot(TM) 64-Bit Server VM (build 25.71-b01-internal-jvmci-0.26, mixed mode)

Shell

GraalVM has a shell mode and we can switch language in it.

$ graalvm --shell
GraalVM MultiLanguage Shell 0.23
Copyright (c) 2013-7, Oracle and/or its affiliates
  JS version 0.9
  R version 0.1
  Ruby version 2.3.3
Usage: 
  Use Ctrl+L to switch language and Ctrl+D to exit.
  Enter -usage to get a list of available commands.
Ruby> 1 + 2
3

Run examples

GraalVM provides many examples in “[GraalVM]/bin” directory. So I try to run some of them.

Run multiple language code in Java code

import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;

public class HelloPolyglotWorld {

    public static void main(String[] args) throws Exception {
        System.out.println("Hello polyglot world Java!");
        PolyglotEngine engine = PolyglotEngine.newBuilder().build();
        engine.eval(Source.newBuilder("print('Hello polyglot world JavaScript!');").mimeType("application/javascript").name("").build()).get();
        engine.eval(Source.newBuilder("puts 'Hello polyglot world Ruby!'").mimeType("application/x-ruby").name("").build()).get();
        engine.eval(Source.newBuilder("print('Hello polyglot world R!');").mimeType("application/x-r").name("").build()).get();
    }

}

We can use PolyglotEngine and Source class to run multiple language code in Java code. In this code I wrote Ruby, JavaScript and R code. The result is below.

$ javac -cp [path]/graalvm-0.23/lib/truffle/truffle-api.jar HelloPolyglotWorld.java

$ graalvm HelloPolyglotWorld
Hello polyglot world Java!
Hello polyglot world JavaScript!
Hello polyglot world Ruby!
[1] "Hello polyglot world R!"

Ahead-of-Time Compilation with GraalVM

What ahead-of-Time Compilation means is following:

ahead-of-time (AOT) compilation is the act of compiling a higher-level programming language such as C or C++, or an intermediate representation such as Java bytecode or .NET Framework Common Intermediate Language (CIL) code, into a native (system-dependent) machine code so that the resulting binary file can execute natively.

https://en.wikipedia.org/wiki/Ahead-of-time_compilation

GraalVM ahead-of-time (AOT) compilation supports most of the Java code. Features that are not supported are: complex reflection, JNI calls, and dynamic class loading.

public class HelloAOTWorld {

    public static void main(String[] args) {
        System.out.println("Hello AOT world!");
    }
}

This is typical hello world example. We compile it with ordinal javac.

$ javac HelloAOTWorld.java
$ ls
HelloAOTWorld.class HelloAOTWorld.java  README.md

To build a Image we run aop-image command. This command requires the name of the executable and the path to the main class.

$ aot-image -cp . -H:Name=hello-aot-world -H:Class=HelloAOTWorld
Building image ...
   classlist:   3,480.44 ms
       (cap):   2,136.63 ms
       setup:   3,101.83 ms
  (typeflow):   4,000.54 ms
   (objects):     956.22 ms
  (features):       2.89 ms
    analysis:   5,136.17 ms
    universe:     394.75 ms
     (parse):   1,071.17 ms
    (inline):   1,543.93 ms
   (compile):  12,391.45 ms
     compile:  15,248.24 ms
       image:   1,065.07 ms
   debuginfo:     845.91 ms
       write:   1,397.95 ms
     [total]:  30,748.55 ms

$ ls -lath
total 10496
drwxr-xr-x@  6 jyukutyo  staff   204B  5 26 13:45 .
-rwxr-xr-x   1 jyukutyo  staff   5.1M  5 26 13:45 hello-aot-world
-rw-r--r--   1 jyukutyo  staff   436B  5 26 13:42 HelloAOTWorld.class
drwxr-xr-x@ 10 jyukutyo  staff   340B  5 24 17:13 ..
-rw-r--r--@  1 jyukutyo  staff   133B  5 20 03:33 HelloAOTWorld.java
-rw-r--r--@  1 jyukutyo  staff   2.1K  5 20 03:33 README.md

File hello-aot-world was created and its size is 5.1M(!). You can invoke the executable as follows:

$ ./hello-aot-world
Hello AOT world!

Did it!