21.1.0 #


Java Updates #

The OpenJDK release that GraalVM Community Edition is built on was updated to:

  • 8u292 for Java 8 based GraalVM Community
  • 11.0.11 for Java 11 based GraalVM Community
  • 16.0.1 for Java 16 based GraalVM Community

The Oracle JDK release that GraalVM Enterprise Edition is built on was updated to:

Platform Updates #

  • Java 16 (experimental) support: The GraalVM distributions based on Oracle Java 16 and OpenJDK 16 are available for download with several known limitations.
  • MacOS platform support: Builds of GraalVM Community Edition for macOS based on OpenJDK 8 are no longer being produced. GraalVM Enterprise Edition for macOS based on Oracle JDK 8 continue to be available.
  • Linux AArch64 platform compatibility: The GraalVM distributions for Linux AArch64 architecture remain experimental in this release. Supported features include the GraalVM compiler, the gu tool, the Node.js JavaScript runtime, Native Image, some developer tools.
  • Windows platform compatibility: To run GraalVM Community Edition based on OpenJDK 8u292 on a Windows platform, the MSVCR100.dll redistributable package needs to be installed (for more details, see the issue #3187).

Compiler #

  • [GraalVM Enterprise] Added support to detect inverted (tail counted) loops as counted loops. GraalVM Enterprise now detects such loops as counted, enabling them to be analyzed and optimized like all other counted loops. These loops are subject to full unrolling, partial unrolling, guard optimization and vectorization. This new capability can be disabled with -Dgraal.DetectInvertedLoopsAsCounted=false.
  • [GraalVM Enterprise] Added a novel loop inversion optimization in GraalVM Enterprise. This adds compiler support to generate inverted loops from regular ones. Inverted loops have superior characteristics for instruction level parallelism and optimization capabilities compared to regular, head counted loops. We have seem performance improvements of up to 30% for micro benchmarks exercising the inverted loop shape. Loop inversion is on by default and can be disabled with -Dgraal.LoopInversion=false.
  • [GraalVM Enterprise] Added a new optimization that analyzes code guarded by a conditional of the form x == y and replace all uses of x with y (or vice versa) if the replacement results in potential for further optimization.
  • [GraalVM Enterprise] Enhanced SIMD vectorization, to support vector byte reversal (e.g., Integer.reverseBytes). SIMD vectorization is still experimental and not enabled by default. Enable it with -Dgraal.VectorizeSIMD=true.
  • [GraalVM Enterprise] Added support for vectorizing hashCode-like loops using the hash = c * hash + array[i]. Disable with -Dgraal.VectorizeHashes=false.
  • Eliminated the cast of the loaded array element to Node, to prevent the situation when volatile fields are loading from arrays, losing type information about the element, and resulting in unneeded casts. This method in ConcurrentHashMap can be an example: 
    static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
          return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
  • Eliminate unneeded memory barriers on sequential volatile writes on x86. There are patterns in classes such as ConcurrentHashMap where numerous volatile writes can occur in a sequence (after inlining). The GraalVM compiler now omits the memory barrier for all but the last write in the sequence, speeding up methods such as ConcurrentHashMap.transfer.

Native Image #

  • Improved support for localization. Now you can specify which locales should be included in the native executable, and which should be the default. For example, to switch the default locale to German and also include French and English, use -H:DefaultLocale=de -H:IncludeLocales=fr,en. All locales can be included via -H:+IncludeAllLocales.
  • Deprecated the --enable-all-security-services option as it is no longer necessary. Security services are now registered automatically when found in use by static analysis.
  • Improved support on Windows: applications now do file globbing on parameters.
  • Added reporting on the native image build to produce multiple artifacts. Results of the build are written to the imagename.build_artifacts.txt file.
  • Fixed a bug on Linux and macOS that resulted in local symbols about all methods being included in the native image, when -g is passed for debug information generation. Method symbols are not necessary for debugging because the Dwarf debugging information also contains this information. When local symbols are desired, e.g., for certain profilers, they can be included in the image using -H:-DeleteLocalSymbols (independently of the -g option).
  • Allowed multiple different native images in the same process, e.g., an application and a shared library. This was required for Linux platforms.
  • Automatically mark more classes for build-time initializaiton. This reduces the overhead of class initialization at run time.

Polyglot Runtime #

  • Enabled multi-tier compilation by default. This feature was first introduced in 20.3 as an experimental option. Truffle now uses two tiers of compilation. The first tier is optimized for compilation speed and reuses the GraalVM compiler economy configuration to perform speedy compilations with method inlining of trivial methods only. The second tier compiles with all GraalVM’s compiler optimizations enabled and is performed after the first tier compilation is completed. Our benchmark results show that this improves warmup for most languages significantly.
  • Added new capabilities for language implementations that require an optional dependency to the newest JVMCI version 21.1-b02 (issue JDK-8263776). In the next release, 21.2 we plan to use some of these capabilities for core runtime functionality, and therefore JVMCI 21.1-b02 will become a required dependency. This will make runtime compilation for JDK releases that do not support JVMCI 21.1-b02 unsupported. Note that all Truffle languages can still be executed on any JDK but without support for runtime compilation. 
  • Introduced new experimental flags to set the compilation thresholds for multi-tier compilation: --engine.FirstTierCompilationThreshold sets the threshold for the first, and --engine.LastTierCompilationThreshold for the second tier. If multi-tier compilation is disabled, --engine.SingleTierCompilationThreshold=x may be used. The original option, --engine.CompilationThreshold, is now deprecated and will be removed in a future release.
  • Added a new experimental compilation queue implementation inspired by HotSpot. The implementation is not yet enabled by default, but can be tried out using the --engine.TraversingCompilationQueue option. The flag is expected to reduce warmup time. More changes and enhancements are planned for the next release, where it is expected to become the default implementation.
  • Deprecated the --engine.CompilationThreshold option. Use --engine.FirstTierCompilationThreshold and --engine.LastTierCompilationThreshold instead.

Java on Truffle #

  • Introduced many fixes and improvements to the Java Debug Wire Protocol (JDWP) support. Many edge cases have been fixed which increased the performance of Java on Truffle while debugging is enabled (up to 200x!).
  • Provided fixes for method redefinition: reflective access and MethodHandles now follow method changes.
  • Added support for signal handlers (sun.misc.Signal / jdk.internal.misc.Signal). This means shutdown hooks are now run when closing a program with Ctrl-C.
  • Removed the dependency on deprecated Scope API and implement newly introduced NodeLibrary instead.
  • Fixed guest stack traces as reported by the GraalVM embedder API (PolyglotException).
  • Improved support for restricting thread creation.

JavaScript #

  • Updated Node.js to version 14.16.1.
  • Node.js support is not enabled by default and must be installed explicitly with GraalVM Updater if needed: gu install nodejs. The JavaScript runtime continue to be included in the base GraalVM installation.
  • Added Iterator interoperability support. It allows JavaScript iterators to be used via the Value API (hasIterator(), getIterator(), hasIteratorNextElement(), getIteratorNextElement()), as well as iterable objects from other languages to be iterated in GraalVM’s JavaScript runtime (e.g., via for-of loops), and vice versa.
  • Enabled buffer interoperability support. It allows host ByteBuffers and buffers from other languages to be used with JavaScript typed arrays (e.g., new Uint8Array(foreignBuffer)) and DataView, without copying. It also enables access to ArrayBuffers via the Value API (readBuffer*, writeBuffer*).
  • Implemented the experimental version of the WebAssembly JavaScript Interface, which allows invoking WebAssembly programs from within JavaScript programs (available behind the --js.webassembly option).

The changelog is available in the project repository.

LLVM Runtime (Sulong) #

  • [GraalVM Enterprise] The ability to build GraalVM or a native image with “native mode” completely removed (so only --llvm.managed mode works).
  • Made pointers to foreign “buffer-like” objects (e.g., JS ArrayBuffer) be transparently accessed like native buffers.
  • Added support for loading bitcode modules with regular dlopen in addition to the Polyglot API
  • Added experimental support for the Linux AArch64 platform.
  • Implemented a sanity check to verify that loaded bitcode files are compiled correctly for the GraalVM LLVM Runtime. In particular, this will fail when loading bitcode that is built for managed mode and used in native mode, or vice versa. This can be turned into a non-fatal warning with the --llvm.verifyBitcode=false option.

The project changelog is available on GitHub.

Ruby #

  • Implemented more complete support of Ruby 2.7 (see #2004 for more details).
  • Multi-tier compilation is now enabled by default, which improves warmup significantly.
  • C extensions which link to a static library now generally work by prepending the GraalVM LLVM toolchain to PATH when installing gems.
  • Improved the performance of checks for recursion (#2189).
  • Improved random number generation performance by avoiding synchronization (#2190).
  • Implemented the ability to create a single call target per block by default instead of two.
  • Optimized some uses of class variables (#2259).
  • Speeded up the interpreter and reduced footprint by making several methods that need the caller frame  always inlined in their caller.
  • Added support for accessing local variables of the interactive Binding via language bindings: context.getBindings("ruby").putMember("my_var", 42);. See #2030.
  • Made signal handlers run without triggering multi-threading.
  • Implemented the Debug Inspector C API.
  • Switched to the io-console C extension for better performance and compatibility in irb.
  • Updated to irb 1.3.3 and reline 0.2.3 which allow pasting code in IRB reasonably fast (#2233).
  • Standalone builds of TruffleRuby are now based on JDK11 (they used JDK8 previously).

More details are available from the TruffleRuby changelog.

Python #

  • Improved support for Java subclassing and  new Interoperability APIs for better Jython migration path. The features often requested and available with Jython, like convenient iteration over Python types from Java, implementing Java abstract classes and interfaces from Python, catching and re-throwing Java exceptions in Python code, are now provided with GraalVM’s Python runtime as well, making the migration easier.
  • Added the SSL support. This allows out-of-the-box installation of Python packages. Now users can run the Python pip installer to download Python packages, and their dependencies, just as they would on CPython.
  • Added a completely native backend for posix API. This provides better performance and more compatibility for filesystem access.
  • Added support for multi-threading with GIL. Multi-threading is supported in GraalVM’s Python runtime to the same extent as CPython. That is, there is only concurrency, not parallelism for most workloads.
  • Added support for the current HPy Python C API to run C extensions at better performance. This is an ongoing research project together with members of the PyPy project and the University of Cape Town to provide a faster API for NumPy and other popular Python C extensions.

More details are available in the project changelog.

R #

  • Upgraded GraalVM’s R runtime to R 4.0.3:
    • Made the GraalVM R runtime mostly compatible with R 4.0.3;
    • Migrated to new versions of the base and recommended packages;
    • Implemented some of the new features of R 4.0.3 (see the changelog for a complete list).
  • Upgraded the CRAN snapshot, used by default by install.packages, to 2021-02-01:
    • Support of the new versions of some of the most popular packages on GraalVM’s R runtime is a work in progress;
    • Packages with known issues remain: dplyr 1.0.3, ggplot 3.3.3, knitr 1.31.

More details are available in the project changelog.

WebAssembly (GraalWasm) #

  • Substantially improved the speedup and the overall peak performance of the GraalWasm interpreter by over 10x.
  • Provided the basic WASI functions that allow manipulating the files and accessing the file system through the Truffle filesystem layer. 
  • GraalWasm is now passing most of the tests in the official WebAssembly test suite.
  • Improved the speed of the standalone GraalWasm launcher, and the peak performance overall.
  • Implemented the WebAssembly-JavaScript Interface specification, which allows invoking WebAssembly programs from within JavaScript programs running on GraalVM’s JavaScript runtime.
  • Implemented parsing custom name sections in the .wasm files to make stack-traces more user-friendly.
  • Made the GraalWasm interpreter  respect the binary-validation rules.
  • Introduced checks for memory/table/function count limits when parsing and linking binaries, as defined in the specification.
  • Added checks to not get exponential compilation slowdown on some pathological code examples.

Tools #

Visual Studio Code Extensions

  • Added results visualization for unit tests: VS Code results visualization for unit test
  • Improved Micronaut support by adding YAML <> Java code editing features: Micronaut extension added YAML support
  • Added a number of refactorings.
  • Included Micronaut projects Docker build commands.
  • Improved support for Maven and Gradle multi-project builds.


  • Added support for upcoming JDK 16 (#260).
  • Added support for the new Apple M1 processor (aarch64) (#262).
  • Added support for the importation of plugins from the previous release (#270).
  • Added a display list of enabled modules in heap dumps feature, taken from JDK 9+ created by jlink (#275). VisualVM dispay list of enabled modules in heap dumps

Polyglot Embedding #

  • [GraalVM Enterprise] Added a new experimental sandbox option --sandbox.MaxHeapMemory=<size> that specifies the maximum heap memory that a guest application can retain during its run. This feature is currently only supported on HotSpot. More information on how to use heap memory limits can be found in the sandbox documentation. Note that this feature is still experimental.
  • Added support for byte buffer-like data structures. This release adds new methods to access buffer values like Value.hasBufferElements(). Java host interoperability was improved to handle java.nio.ByteBuffer implementations to make them work like native guest language buffers. This feature can be enabled and disabled using HostAccess.Builder.allowBufferAccess(boolean). Support for polyglot buffers in languages may vary. See the individual language changelog for more details.
  • Added support for iterable and iterator-like data structures. This includes new methods to detect if a polyglot value is an iterator or iterable with Value.isIterator() and Value.hasIterator(). New proxy interfaces ProxyIterator and ProxyIterable were added to mimic iterators and iterables. Java host interoperability was improved to handle java.util.Iterator and java.util.Iterable implementations to make them work like guest language values. This feature can be enabled and disabled with HostAccess.Builder.allowIteratorAccess(boolean) and HostAccess.Builder.allowIterableAccess(boolean). Guest language iterators can now also be mapped to Java iterators using Value.as(Iterator.class). The support for this feature in individual languages may vary. See the language changelog for more details.
  • Added support for map-like data structures (issue #143). This includes new methods for polyglot values like Value.hasHashEntries() to query if a polyglot value represents a hash map like data structure. A new interface ProxyHashMap was added to mimic such values. Java host interoperability was improved to handle java.util.Map implementations to make them look like guest language hash maps. This feature can be enabled and disabled with HostAccess.Builder.allowMapAccess(boolean). Guest language maps can now also be mapped to Java Maps using Value.as(Map.class). The support for this feature in individual languages may vary. See the language changelog for more details.
  • Added Context.safepoint() to cooperatively poll thread local actions of a polyglot context while a host method is executed. For example, this allows the context to check for interruption or cancellation.

A detailed list of all the changes can be found in the changelog.

Truffle Language and Tool Implementations #

  • Added support for submitting thread local actions to run at guest language safepoints for language implementations (issue JDK-8263776). Please see the tutorial on how to adapt and use this feature in a language or tool implementation.
  • Added a new interoperability trait for buffer elements in InteropLibrary that allows better integration with native buffers.
  • Added a new interoperability type iterator and a new trait for iterable in InteropLibrary to improve traversal of collections between languages.
  • Added a new interoperability trait for hash entries in InteropLibrary to improve interoperability between guest language hash maps (issue #143).
  • Added TruffleInstrument.Env.calculateContextHeapSize(TruffleContext, long, AtomicBoolean) to calculate the heap size retained by a context.
  • Added @GenerateAOT to support preparation for AOT specializing nodes. Read the AOT tutorial to get started with Truffle and AOT compilation. We also added the --engine.CompileAOTOnCreate option to trigger AOT compilation on call target create. More changes and enhancements are planned for the next release.
  • Added ExactMath.truncate(float) and ExactMath.truncate(double) methods to remove the decimal part (round toward zero) of a float or of a double respectively. These methods are intrinsified.
  • Added several new events to ContextsListener when language context initialization was completed or failed.
  • Added CompilerDirectives.isExact(Object, Class) to check whether a value is of an exact type. This method should be used instead of the value != null && value.getClass() == exactClass pattern.
  • Added Frame.clear(FrameSlot). This allows the compiler to reason about the liveness of local variables. Languages are recommended to use this method when applicable.
  • Added TruffleLanguage.Env.getLogger(String) and TruffleLanguage.Env.getLogger(Class<?>) creating a context-bound logger. The returned TruffleLogger always uses a logging handler and options from Env’s context and does not depend on being entered on any thread.
  • Added TruffleContext.leaveAndEnter(Node, Supplier) to wait for another thread without triggering multithreading.
  • The native image build now fails for the Truffle languages if a method that is known to be not suitable for partial evaluation is reachable for runtime compilation. The check can be disabled by the -H:-TruffleCheckBlackListedMethods option for the native-image builder. Removed the deprecated TruffleLanguage.Env.getTruffleFile(String)TruffleLanguage.Env.getTruffleFile(URI) methods.
  • Added TruffleContext.isCancelling() to check whether a Truffle context is being cancelled.
  • Added new features to the specializing DSL @NodeChild annotation: Added implicit and implicitCreate attributes to allow implicit creation of child nodes by the parent factory method.
  • Added allowUncached and uncached attributes to allow using @NodeChild with @GenerateUncached.
  • Profiles now can be disabled using Profile.disable() and reset using Profile.reset().
  • Added support for two-phase attach in the Truffle instrumentation with the new EventBinding.attach() method.

A detailed list of all the changes can be found in the Truffle framework changelog.