22.3.0 #


Platform Updates #

The 22.3.0 release is the final Feature release in the annual release train and will be supported for the next 12 months with bug and vulnerability fixes. GraalVM Community releases from the 21.x branch are end-of-life. See the Version Roadmap for the release schedule and the new GraalVM Community Roadmap for upcoming features.

  • Released experimental JDK 19 GraalVM builds including the Graal compiler, Native Image, and all GraalVM languages and tools except Espresso (Java on Truffle). These builds enable users to take advantage of the latest JDK 18 and JDK 19 features such as Virtual Threads, the Simple Web Server, Structured Concurrency, and more. Support for JDK 19 will be available in a future release. See #4957 and #5063.
  • Reduced the GraalVM Native Image installable file size by around 80MB: the LLVM backend is now shipped as a separate native-image-llvm-backend component (no longer shipped by default with native-image).
  • Released the LLVM runtime for GraalVM Community Edition for Windows under experimental support.

  • Updated the OpenJDK release on which GraalVM Community Edition is built to:
  • Updated the Oracle JDK release on which GraalVM Enterprise Edition is built to:

Java and Compiler Updates #

  • Added support for JDK 18 and JDK 19 features such as Virtual Threads, the Simple Web Server, Structured Concurrency, and more in the GraalVM based on JDK 19 builds.
  • Improved JIT compilation isolation by using one isolate per the libgraal compiler thread. This avoids all GC interference between the compiler threads which reduces GC pauses during compilation. This translates to improved compilation speed in general. On the DaCapo benchmarks, compilation as measured in bytecodes-per-second at least doubled, with individual benchmarks such as fop and pmd showing a 3x speed up. To enable the old mode, add -XX:JVMCINativeLibraryThreadFraction=0.66 -XX:JVMCIThreadsPerNativeLibraryRuntime=0 to the command line.
  • Added a dedicated Native Image GC policy for libgraal that will adjust the Eden space aggressively to minimize RSS memory usage.
  • Improved jlink behavior so that it produces images which use the Graal compiler (libgraal) as the top-tier compiler. A jlink-ed image produced from GraalVM uses JVMCI by default, and java -version output is GraalVM-branded.
  • Enabled StripMineCountedLoops and EarlyGVN compiler optimizations by default. These were first introduced in the 22.2 release with the -Dgraal.StripMineCountedLoops=true and -Dgraal.EarlyGVN=true options.
  • Implemented loop vectorization for integer min/max operations. This implementation handles all integer sizes, hand-written min/max patterns (for example, x > y ? x : y, not just Math.min/Math.max), unsigned min/max, and fold-shaped loops (for example, computing the minimum or maximum element of an array).
  • Removed the deprecated JMX HotSpotGraalRuntime management bean from both libgraal and jargraal.

Native Image #

  • Added support for JDK 19 and OpenJDK Project Loom Virtual Threads (JEP 425): virtual threads for high-throughput lightweight concurrency are supported with both the Serial GC and the G1 GC. Since virtual threads are a preview feature in JDK 19, they are also a preview feature for GraalVM Native Image. They can be enabled with the new option --enable-preview. Virtual threads are not available on GraalVM based on JDK 11 and JDK 17, and they are not available yet for native executables that contain a Truffle language (JavaScript, Python, etc.). See #4920 for more details.
  • Identified and added missing parts in the Native Image API: functionality where applications and frameworks reached into internals of the native-image generator. It includes a new public API for programmatic registration of JNI, Resource, Proxy, and Serialization classes from Feature interface classes, and moving annotations for method substitutions to the Graal SDK. Even though these annotations are not supported APIs, for practical reasons they can now be used without depending on the native-image generator. For this release, the native-image internals are still published to Maven Central, but this will be stopped in a future release. We therefore encourage all users to only rely on the Graal SDK starting with this release, and if this is not possible, report further missing API on GitHub.
  • Update the G1 GC version that is available in Native Image to JDK 19. This G1 version is also used for native executables based on JDK 11 and JDK 17. In addition, the G1 GC can now be used with native executables that are statically linked with the musl C library.
  • Added RuntimeResourceAccess#addResource(Module module, String resourcePath, byte[] resource) API method that enables resources to be injected into native executables.

Debugging and monitoring experience improvements:

  • Improved the debugging experience to identify memory usage and memory leaks (contributed by Red Hat). For example, perf report is able to associate code addresses sampled during a perf record session with Java methods and print the DWARF-derived method name for the method in its output histogram. Read more about special considerations for using perf and valgrind in the documentation.
  • Added the --enable-monitoring=<all,heapdump,jfr,jvmstat> option to enable fine-grained control over monitoring features included in native executables. The old option -H:±AllowVMInspection should no longer be used. The new option is part of the supported API.
  • Added initial support for jvmstat to GraalVM Community Edition. Previously, this was available in GraalVM Enterprise Edition only.
  • Added support for the JFR events JavaMonitorEnter, JavaMonitorWait, and ThreadSleep (contributed by Red Hat).
  • Add the option --enable-sbom to the supported API. The old non-API option -H:IncludeSBOM should no longer be used.

Build output enhancements:

  • Introduced the experimental -H:BuildOutputJSONFile=<file.json> option to export build output information in JSON format. In addition, the old build output style and the -H:±BuildOutputUseNewStyle option are removed.
  • Added the --silent option to silence the build output.

GraalVM Native Image ecosystem updates:

Known Issues with JDK 19 Support

Note that the java.io.Console API does not work properly on JDK 19: The information whether or not a Console is available is wrongly computed at build time. This means that, for example, when building a native executable on a CI system without a terminal, the executable will not have a Console available even when running inside a terminal. This also affects the Truffle language launchers that are shipped with GraalVM.

The project changelog is available on GitHub.

Polyglot Runtime #

  • Introduced the SnippetRun#getException() method that provides an IllegalArgumentException thrown during snippet execution. IllegalArgumentException is converted to a PolyglotException before it is returned.

A full list of updates can be found in the changelog.

JavaScript and Node.js #

The project changelog is available on GitHub.

Python #

  • Renamed the entire project from GraalPython to GraalPy, and the launcher from graalpython to graalpy. This change also updates GraalVM’s launchers to include symlinks from python and python3 to graalpy for better integration with other tools.

Performance improvements:

  • Switched to the new bytecode interpreter by default. This change brings better startup performance and memory footprint while retaining good JIT-compiled performance. For example, the development time actions such as pip install <package> or running import <package> in the REPL are now 20-25% faster and use around 25% less memory on average.

Compatibility improvements:

  • Switched to a new parser generated from CPython’s new PEG grammar definition. It brings better compatibility and enables us to implement the ast module.
  • Added support for Tracing API (sys.settrace), which makes pdb and related tools work on GraalPy.
  • Added support for Profiling API (sys.setprofile), which makes the profile package work.
  • Updated pip to automatically choose the best version for known packages. You can use pip install pandas, and pip will select the versions of pandas and numpy that is tested in the GraalPy continuous integration.
  • Added support for Flask.
  • Implemented PEP 405 for full support of virtual environments. This fixes issues with the virtualenv package and tox that are used in PyCharm or in many projects’ continuous integration (CI) jobs.

A full list of updates can be found in the changelog.

Ruby #

New features:

  • Foreign strings now have all methods of Ruby String. They are treated as #frozen? UTF-8 Ruby Strings.
  • Added the Java.add_to_classpath method to add JAR paths at runtime. It enables users to modify the JVM classpath when running in the JVM mode (--jvm). For example, a Ruby gem, managed via Bundler, loads a Java library can update the classpath itself. See #2693 for more details.
  • Added support for Ruby 3.1’s Hash shorthand and punning syntax, and anonymous block forwarding syntax.
  • Added the following keyword arguments to Polyglot::InnerContext.new: languages, language_options, inherit_all_access, code_sharing.

Performance-related improvements:

  • Improved interpreter performance by optimizing for better host inlining.
  • Used poll instead of select for simple IO waiting to reduce overheads (#1584).
  • Improved interoperability with Java: no more conversion between Java Strings and Ruby Strings at the interop boundary.

Compatibility updates:

  • Added support for #dup and #clone on foreign strings.
  • Implemented rb_ivar_foreach to iterate over instance and class variables like in CRuby. See #2701 for more details.


  • Removed Truffle::Interop.{import_without_conversion,export_without_conversion}. Use Polyglot.{import,export} instead.
  • Removed Truffle::Interop.members_without_conversion. Use Truffle::Interop.members instead.

A full list of changes is available in the changelog.

R #

  • Implemented the global native variable API to improve R graphics isolation when using multiple R contexts. Users can now use a native package from two R contexts at the same time. The API consists of several upcalls, named with the FASTR_GlobalVar prefix, for example, FASTR_GlobalVarAlloc. Currently, only grid and graphics built-in packages are refactored to use the global native variable API.
  • Added partial support for dplyr 1.0.3 to enable users to work with data frames such as objects, both in memory and out of memory. The SET_PRCODE, SET_PRENV, and SET_PRVALUE upcalls are now implemented.

The project changelog is available on GitHub.

LLVM Runtime #

  • Updated LLVM toolchain to version 14.0.6.
  • Released the LLVM runtime for GraalVM Community Edition for Windows under experimental support.
  • Improved support for the x86 extended precision for floating-point numbers. It is now possible to call native functions (for example, libc) with long double arguments on the x86 architecture. The long double variants of math.h functions now use full precision. Previously they were implemented using double arithmetic.

Java on Truffle (Espresso) #

  • Added the polyglot automatic interface type mapping for 1:1 mappings between a host and an embedded guest context.
  • Improved interoperability: when an Espresso-to-Espresso conversion was seen, then an Espresso-to-primitive conversion happens. The latter would fail.
  • Methods from Espresso objects can now be read to obtain a new interop executable object, isExecutable.
  • Fixed exit status on uncaught exceptions in the main thread.
  • Added the addPath invokable member to Espresso bindings (polyglot.getBindings("espresso"), the entry point where class loading happens) if java.UseBindingsLoader=true. It enables adding a new path to the classloader associated with the bindings. It was a necessary addition to better control the behavior of Espresso when going through the Truffle TCK.

The project changelog is available on GitHub.

WebAssembly #

  • Implemented the Multi-Value proposal. It can be disabled with the option --wasm.MultiValue=false.
  • Enabled the Sign-Extension-Ops and Saturating-Float-To-Int conversions by default.

The project changelog is available on GitHub.

Polyglot Embedding #

  • Implemented the FieldValueTransformer API as a more generic mechanism to intercept and constant fold field values (replaces the existing RecomputeFieldValue for the kind Custom). It allows modifying the value of a particular field if it is marked as a transformer with BeforeAnalysisAccess#registerFieldValueTransformer. A transformer must be registered before the field is seen reachable by the static analysis, and only one transformer per field. At build time, the field value transformer provides the value of the field for the image heap. Without a transformer, the value of the field in the image heap is the same as the hosted. This API is necessary for compatibility with Spring.
  • Added Context.Builder.allowInnerContextOptions(boolean) which enables the context to spawn inner contexts and modify and override language options. Inner contexts no longer share code with the initial context. The default value for this privilege is determined according to whether Context.Builder.allowAllPrivilages(boolean) is set or not. Do not enable this privilege in security-sensitive scenarios.
  • Moved Native Image strictly-internal annotation classes from com.oracle.svm.core.annotate to (@Alias, @TargetClass, @Substitute, etc.) to org.graalvm.sdk module.

A full list of changes is available in the changelog.

Truffle Language and Tool Implementations #

  • Tuned the host inlining heuristic for reduced code size. A new host inlining tuning guide is available in the documentation.
  • Added new capabilities to TruffleContext, for example, TruffleContext.Builder.forceSharing(Boolean) to force or deny code sharing for inner contexts, and many others. Check the Truffle project changelog to see a full list.
  • Removed several deprecated core APIs, for example, FrameSlot, CompilerOptions, etc. Check the Truffle project changelog to see a full list.
  • Added TruffleInstrument.Env#createSystemThread and TruffleLanguage.Env#createSystemThread to create a new thread designed to process instrument tasks in the background.
  • Added copyStatic, clearStatic and swap...Static additional methods to the Static Frame API.
  • Added a check if the static frame access is validated when assertions are enabled. Reading a slot with a different type than written to leads to an AssertionError.
  • Deprecated the TruffleLanguage.Env.newContextBuilder() method and replaced it with a new method TruffleLanguage.Env.newInnerContextBuilder(String...). The new method no longer inherits all privileges from the parent context and no longer initializes the creator context by default. The new method also allows setting the permitted languages for the inner context similarly to the Polyglot Embedding API.
  • Changed the behavior of setting application arguments: inner contexts no longer inherit application arguments from their outer context. Now you can set application arguments explicitly for inner contexts using TruffleContext.Builder.arguments(String, String[]).
  • Modified behavior of inner contexts: an inner context no longer uses system exit on exit, even if the polyglot embedder specified it with Context.Builder.useSystemExit(boolean) for an outer context.
  • Introduced the RootNode.getParentFrameDescriptor method to support identifying lexical scope parents of hot methods and compiling them earlier.

A full list of updates can be found in the changelog.

Connect with us