20.2.0 #


Java #

  • GraalVM Community Edition is based on OpenJDK version 1.8.0_262 and OpenJDK version 11.0.8.
  • [GraalVM Enterprise] Oracle GraalVM Enterprise Edition is based on Oracle JDK version 1.8.0_261 and Oracle JDK version You can find Oracle JDK release notes for these versions at the Oracle Technology Network website.
  • Added the ability to release the memory used by libgraal to the OS when an application enters a stable phase and compilation goes idle. This is achieved by attaching each compiler thread to a libgraal isolate. The number of compiler threads that can be attached to an isolate is controlled by the jvmci.ThreadsPerNativeLibraryRuntime system property. The default is all threads attached to a single isolate. Isolates are initialized on demand to handle extra compiler threads. When a compiler thread becomes idle (idleness delay is configurable by jvmci.CompilerIdleDelay), it detaches itself from its isolate. As the last thread detaches from an isolate, it is shutdown and its memory (i.e., the libgraal heap) is released to the OS. This feature has the following of advantages:
    • It can reduce the RSS memory footprint of a GraalVM process. If the compiler is not being used, it uses no resources.
    • [GraalVM Enterprise] If multiple isolates are used, it mitigates interference between complier threads. For example, there is less contention on shared objects and a garbage collection in one isolate will not pause threads in other isolates.
  • [GraalVM Enterprise] Improved the optimization responsible for removing redundant read/write, array clone() and accesses to the cloned arrays operations. Workloads that heavily use array read/write operations, especially inside loops, in combination with allocations may benefit from this optimization. As a result of the enhanced read/write optimization, the speedups of up to 2.5x on the JetStream benchmarks were seen with GraalVM JavaScript engine.
  • [GraalVM Enterprise] Added an experimental partial loop unrolling optimization. Partial loop unrolling is an extended form of traditional loop unrolling optimization that works for arbitrary counted loops with an unknown upper bound of loop iterations i. The optimization is not enabled by default, you can experiment with the optimization by enabling it with -Dgraal.EnterprisePartialUnroll=true. Note, the optimization is still experimental and thus may lead to unknown errors.
  • Fixed an error in code generation which was leading to incorrect behaviour of programs using the Apache commons-compress BZip2 implementation (see #2534).
  • Improved excessive compile time of certain programs (see #2548).
  • Improved error reporting with libgraal. Fatal errors in libgraal now produce a hs-err crash log that can substantially improve triaging and debugging such errors. Likewise, low level libgraal output, such as libgraal GC messages produced by -Dlibgraal.PrintGC=true are routed to HotSpot’s log stream. That is, libgraal error handling and logging is unified with HotSpot support for these features and thus configurable by options such as -XX:LogFile and -XX:OnError.
  • Renamed the MitigateSpeculativeExecutionAttacks compiler option to SpectrePHTBarriers (e.g., use -Dgraal.SpectrePHTBarriers=AllTargets for java or --vm.Dgraal.SpectrePHTBarriers=AllTargets for js).

Native Image #

  • [GraalVM Enterprise] Improved the G1GC-like garbage collection for workloads where Native Image requires smaller GC pauses. More details are in the documentation on how to enable and configure it documentation on how to enable and configure it.
  • Added an option to create “mostly static” native images which link statically everything except libc. Native images built this way are convenient to use in small docker images, for example, based on distroless/static. Enable nearly static native image generation with the following option: -H:+StaticExecutableWithDynamicLibC.
  • Improved generation of native images statically linked against muslc. If you have musl-gcc on the path, you can now generate a native image statically linked against muslc with the following options: --static --libc=musl. More information about this is available in the documentation.
  • Enabled -H:+RemoveSaturatedTypeFlows by default, which should result in faster native image generation and use less memory for the generation.
  • Changed the class initialization strategy to initialize at build time only a small part of the JDK library. To get the previous behaviour back, use --initialize-at-build-time option for necessary packages.
  • Many other improvements and bug fixes can be found in the repository.

JavaScript #

  • Updated Node.js to version 12.18.0. Notable changes in this release are available from the Node.JS project website.
  • Updated ICU4J library to version 67.1.
  • Implemented the Intl.NumberFormat Unified API proposal.
  • Implemented the Logical Assignment Operators proposal.
  • Implemented the Top-level Await proposal.
  • Implemented the Promise.any proposal. It is available in ECMAScript 2021 mode (--js.ecmascript-version=2021).
  • Implemented support for async stack traces.
  • Fixed Date.toLocaleString and Intl.DateTimeFormat to use the context’s default time zone rather than the system default if no explicit time zone is requested.
  • Improved js.timezone option to validate the time zone ID and support zone offsets like “-07:00”.

Updates for Language and Tool Implementers #

  • Enabled by default the new inlining heuristic in which inlining budgets are based on Graal IR node counts and not on Truffle Node counts. More information can be found in the Inlining guide.
  • Added support for subclassing DynamicObject so that guest languages can directly base their object class hierarchy on it, add fields and use @ExportLibrary on subclasses.
  • Added new DynamicObjectLibrary API for accessing and mutating properties and the shape of DynamicObject instances. More information can be found in the Dynamic Object Model guide.
  • Added new identity APIs to InteropLibrary:
    • hasIdentity(Object receiver) to find out whether an object specifies identity
    • isIdentical(Object receiver, Object other, InteropLibrary otherLib) to compare the identity of two object
    • isIdenticalOrUndefined(Object receiver, Object other) to specify the identity of an object
    • identityHashCode(Object receiver) to implement maps that depend on identity
  • Added Truffle DSL @Bind annotation to common out expression for use in guards and specialization methods.
  • Added the ability to disable adoption for DSL cached expressions with type node using @Cached(value ="...", weak = true).
  • Added an option not to adopt the parameter annotated by @Cached, using @Cached(value ="...", adopt = false).
  • Added CompilerDirectives.shouldNotReachHere() as a short-cut for languages to indicate that a path should not be reachable neither in compiled nor interpreted code paths.

More details are available from the changelog.

Updates for Polyglot Embedders #

  • Added Context.parse(Source) to parse but not evaluate a source. Parsing the source allows to trigger e.g., syntax validation prior to executing the code.
  • Added PolyglotException.isResourceExhausted() to determine if an error was caused by a resource limit (e.g., OutOfMemoryError) that was exceeded.
  • Added a factory method creating a FileSystem based on the host Java NIO. The obtained instance can be used as a delegate in a decorating filesystem.
  • Added optional FileSystem.isSameFile method testing if the given paths refer to the same physical file. The method can be overridden by the FileSystem implementer with a more efficient test.

More details are available from the changelog.

Tooling #

VS Code
  • Updated Language Server Protocol (LSP) implementation to support the latest protocol version 3.15.
  • Updated VSCode extension by merging into one. More details about Visual Studio Code Extension.
  • Added showing code coverage from GraalVM LSP in VS Code.
  • Updated VisualVM to use NetBeans platform 11.3.
  • Added GoToSource from VisualVM to your preferred IDE.
Ideal Graph Visualizer

[GraalVM Enterprise]

  • Implemented usability improvements for graphs identification in IGV (IGV graph now displays a dump ID and a user label with Graph name).
  • Added Go To Type and Attach Debugger actions.
  • IGV updated to NetBeans platform to 11.3.

LLVM Runtime #

  • Added support for InteropLibrary.isIdentical and related messages.
  • Added the --print-toolchain-api-identifier, --print-toolchain-api-tool <tool-name> and --print-toolchain-api-paths <path-name> arguments to the lli launcher. These can be used to query the Toolchain API from the command line.
  • Added support for requesting locations via the #getPaths() method to the Java API of the Toolchain. For example, the location of the toolchain executables or libraries.
  • Added llvm/api/toolchain.h header for accessing the Toolchain from C code.
  • Added ability to read and write bigger values to a polyglot i8 array. For example, when reading an i64 from a foreign value that is typed as i8 array, the LLVM runtime will read 8 i8 values and combine them to an i64 result.
  • Removed the --llvm.sourcePath option (deprecated since 19.0). Use --inspect.SourcePath instead.
  • Removed support for the application/x-llvm-ir-bitcode-base64 mime-type (deprecated since 19.0).

Python #

  • Improved reference counting for native extensions to prevent memory leaks.
  • Added code serialization to .pyc files (.pyc files persistently store the Python bytecode compiled from the source .py files).
  • Fixed warning in pandas about size of the datetime objects.
  • Improved compatibility (more CPython unittests pass for core types).
  • Added support for parsing requests with arguments for embedding Python.
  • Added support for the basic usage of tox – a Python testing wrapper.
  • Removed support for iterables as arrays in polyglot applications.
  • [GraalVM Enterprise] Added a faster implementation of _struct.

R #

  • Improved SVG support activated with the --R.UseInternalGridGraphics=false flag.
  • Improved FastR user experience: FastR should have no requirements on both Linux and macOS i.e., installing GCC or GFortran should not be necessary to run FastR, but it may be necessary to install some third party R packages.

Ruby #

New features:

  • Updated to Ruby 2.6.6.
  • Configured Ruby to always show core library files in backtraces.
  • The Java stacktrace is now shown when sending SIGQUIT to the process, also on TruffleRuby Native, see Debugging for details.
  • Use InteropLibrary#toDisplayString() to better display objects from other languages.
  • foreign_object.to_s now uses InteropLibrary#toDisplayString() (and still asString() if isString()).
  • foreign_object.inspect has been improved to be more useful (include the language and meta object).
  • foreign_object.name = value will now call Interoplibrary#writeMember("name", value) instead of invokeMember("name=", value).
  • Calls to foreign objects with a block argument will now pass the block as the last argument.
  • foreign.name will now use invokeMember if invocable and if not use readMember. See doc/contrib/interop_implicit_api.md for details.

Bug fixes:

  • Fix #class_exec, #module_exec, #instance_eval, and instance_exec to use activated refinements (@ssnickolay).
  • Use upgraded default gems when installed.
  • The output for --engine.TraceCompilation is now significantly easier to read, by having shorter method names and source names.
  • Fixed indentation for squiggly heredoc syntax with single quotes.
  • Fixed missing flushing when printing an exception at top-level with a custom backtrace, which caused no output to be shown.


  • Implemented Ripper by using the C extension.
  • Implemented ObjectSpace::WeakMap.
  • Supported #refine for Module (@ssnickolay).
  • Fixed refine + super compatibility (@ssnickolay)
  • Implemented UnboundMethod#bind_call.
  • RUBY_REVISION is now the full commit hash used to build TruffleRuby, similar to MRI 2.7+.
  • Changed the lookup methods to achieve Refinements specification (@ssnickolay)


  • Enabled lazy translation from the parser AST to the Truffle AST for user code by default. This should improve application startup time.
  • instance variable ... not initialized and similar warnings are now optimized to have no peak performance impact if they are not printed (depends on $VERBOSE).
  • Implemented integer modular exponentiation using BigInteger#mod_pow ( @skateman).
  • Fixed a performance issue when computing many substrings of a given non-leaf String with non-US-ASCII characters.
  • Speedup native handle to Ruby object lookup for C extensions.


  • RubyGems gem commands updated to use the --no-document option by default.

Connect with us