GraalVM for JDK 23

(2024-09-17)

Platform and Distributions

Availability of JDK 23 Features

Enable preview features by passing --enable-preview to use any of them.

Graal Compiler

  • Introduced a new compiler optimization to reduce code size on the x64 architecture, by emitting smaller jump instructions if the displacement fits in one byte. This optimization is enabled for Native Image by default and disabled elsewhere. Use -Djdk.graal.OptimizeLongJumps=true to enable.

Native Image

New Features

  • Added a new optimization level, -Os, to configure the optimizer to get the smallest code size and, thus, a reduced file size. It enables -O2 optimizations except those that can increase code or executable size significantly. Learn more in Native Image Optimization Levels.
  • Replaced typeReachable conditions with typeReached. typeReached conditions make the metadata entry available at run time when the type is considered reached. A type is reached at run time, right before the class-initialization routine starts for that type (class or interface), or any of the type’s subtypes are reached.
  • Streamlined Native Image reachability metadata configuration into a single file reachability-metadata.json. The formerly-used individual metadata files (reflection-config.json, resource-config.json, and so on) are now deprecated, but will still be accepted. See the documentation for more details.
  • Added support for glob patterns to specify file path to a resource in addition to Java regular expressions. The Tracing Agent now prints entries in the glob format. Learn more in Accessing Resources in Native Image.
  • Enabled the registration of java.lang.reflect.Proxy classes for reflection by adding proxy-type entries. This allows members of Proxy classes to be accessed reflectively at run time. The metadata file proxy-config.json is now deprecated, but will still be honored for backward compatibility. The Tracing Agent is modified to use the new approach. The new format to specify proxy classes in reachability-metadata.json is:
      {
        "reflection": [
          {
            "type": { "proxy": [ "IA", "IB" ] }
          }
        ]
      }
    
  • Added a stable name for the Proxy types in Native Image. The name $Proxy[id] is replaced by $Proxy.s[hashCode] where hashCode is computed using the names of the Proxy interfaces, the name of the class loader, and the name of the module if it is not a dynamic module.
  • Introduced a type field in reflection and JNI configuration files to support more than simple name types.
  • Improved the Foreign Function & Memory API (JEP 454) by adding experimental support for upcalls from foreign functions (part of “Project Panama”). Currently, foreign calls are supported on the x64 architecture. Enable with -H:+ForeignAPISupport. See Foreign Function and Memory API in Native Image for more details.
  • Fields that are accessed via a VarHandle or MethodHandle are no longer marked as “unsafely accessed” when VarHandle/MethodHandle can be fully intrinsified. This improves the run-time performance.
  • Introduced a new --static-nolibc API option to build mostly static native executables. It replaces the experimental -H:±StaticExecutableWithDynamicLibC option.
  • Implemented the compact garbage collection mode for the Serial GC old generation. Enable it with the -H:+CompactingOldGen option. The primary intention is to reduce the memory usage compared to the copying GC. Find more details at github.com/oracle/graal/pull/8870. This is an experimental feature.
  • Added the option -H:+GenerateEmbeddedResourcesFile to print information about embedded resources into embedded-resources.json.
  • Added support to catch OutOfMemoryError exceptions at build time if there is no memory left.
  • Changed the digest (used, for example, for symbol names) from SHA-1 encoded as a hex string (40 bytes) to 128-bit Murmur3 as a Base-62 string (22 bytes).

Deprecated Functionality

  • The old class initialization strategy, which was deprecated in GraalVM for JDK 22, is now removed. The option --StrictImageHeap no longer has any effect.
  • Reporting unsupported elements at run time is now enabled by default. The option --report-unsupported-elements-at-runtime is deprecated.

Improvements

  • Added a check to ensure that an explicitly set name (specified via -o name) is not accidentally overwritten by the -jar jarfile option.
  • Added a check that will cause the build process to fail and report an appropriate error if the --static option is not followed by --libc=musl. Static linking is currently only supported with musl.
  • In the strict reflection configuration mode (when ThrowMissingRegistrationErrors is enabled), Unsafe.allocateInstance is allowed only for types registered explicitly in the configuration.
  • Native Image now throws missing registration errors for JNI queries when the query was not included in the reachability metadata.

Debugging and Monitoring Improvements

  • Added a new API option --emit to generate build reports. It replaces the experimental host option -H:+BuildReport. Providing a path where to store a report is possible via --emit build-report=custom-build-report.html, instead of using the old option -H:BuildReportFile=custom-build-report.html. (Only available in Oracle GraalVM.)
  • Added initial support for the native memory tracking. Enable with --enable-monitoring=nmt. (Together with Red Hat.)
  • Improved the JFR monitoring experience by adding support for event throttling and the ObjectAllocationSample event. Also added the initial support for the OldObjectSample event. (Together with Red Hat.)
  • Now you can use vswhere to find Visual Studio Code installations more reliably and in non-standard installation locations.
  • The option -XX:MissingRegistrationReportingMode can now be used on the invocation instead of as a build option, to avoid rebuilding when debugging missing registration errors.

Polyglot Runtime

  • Enabled random offsets of runtime compiled functions entry points for the UNTRUSTED polyglot sandbox policy. GraalVM additionally pads the starting offset of functions with a random number of trap instructions which helps prevent a potential JIT spray attack.
  • Added TruffleLanguage.Env.getScopePublic(LanguageInfo) and TruffleLanguage.Env.getScopeInternal(LanguageInfo) to enable languages direct access to other language scopes to implement new polyglot builtins.
  • Added PolyglotException.StackFrame.getBytecodeIndex() which enables to access the internal bytecode index that the language uses to identify an execution location.

Polyglot Embedding

  • Added the system property polyglot.engine.userResourceCache which enables embedders to override the default location of the resources cache directory for a Java application running on HotSpot. By default, the resources cache directory is located in the org.graalvm.polyglot directory within the OS-specific cache directory in the user’s home directory. The main rationale behind this override is to accommodate applications running in containers where the user’s home directory may not be writable.
  • Added the option engine.InterpreterCallStackHeadRoom to protect against stack overflow in the middle of a guest method execution in the interpreter. For the UNTRUSTED polyglot sandbox policy, the value for the option is computed automatically based on the value of the mandatory option sandbox.MaxASTDepth, the option sandbox.MaxStackFrames is no longer mandatory. The new option is available only in the AOT mode.
  • Added experimental support for virtual threads on HotSpot. Not all languages are currently supported for use with virtual threads. Check the language changelog for further information. Truffle debugging, CPU time limits, and some memory limits are currently not supported on virtual threads. The number of threads is currently limited to 65535 threads entered per context.
  • The RuntimeOptions.listDescriptors and getDescriptor methods also return the Graal compiler options (if any) that could already be accessed through RuntimeOptions.get and set.
  • Java host interop no longer exposes bridge methods.

Find a complete list of updates in the changelog.

Espresso

  • Espresso can now use TRegex to execute java.util.regex patterns. TRegex offers better performance than the standard implementation. Use java.UseTRegex to enable this engine.
  • The interop ReadBuffer method can now be used from the guest Interop API and guest ByteBuffer objects implement this interop message.
  • Fixed several JDWP compatibility issues improving the user experience when debugging Espresso with a Java IDE.
  • Added the org.graalvm.continuations package, along with support for continuations. See the Espresso Continuations documentation for more details.
  • Added java.RuntimeResourceId to enable customizing the resource used to locate the Java standard library used by Espresso. The resource called espresso-runtime- will be used. By default, jdk21, and then openjdk21 are attempted.

GraalJS

GraalPy

  • GraalPy is now considered stable.
  • Updated to Python 3.11.7.
  • Added the intrinsified _pickle module implementation to GraalPy built on top of GraalVM Community Edition.
  • The Polyglot API eval method now throws more meaningful exceptions when evaluating code from other languages in Python. Exceptions from a language are raised directly as interop objects (typed as polyglot.ForeignException). The shortcut for executing Python code without specifying a language was removed. Use the regular eval method.

GraalWasm

  • GraalWasm is now considered stable.
  • Implemented the SIMD proposal. This feature is enabled by default and can be disabled with the option --wasm.SIMD=false.
  • Added support for the clock_res_get, fd_advise, fd_datasync, fd_fdstat_set_rights, fd_filestat_set_size, fd_pread, fd_pwrite, fd_readdir, fd_renumber, fd_sync, and fd_tell functions.

Truffle Language and Tool Implementations

  • Deprecated Node.getCost() and the associated NodeCost class without replacement. A Truffle DSL no longer generates implementations of this method automatically and will therefore always return NodeCost.MONOMORPHIC by default. This is intended to reduce the binary footprint.
  • Improved the debugging experience:
    • DebuggerSession.suspend(Thread thread) now preserves ongoing stepping strategies.
    • Added SuspendedEvent.isStep(), SuspendedEvent.isUnwind(), and SuspendedEvent.isBreakpointHit() to enable debugger backends or languages to query reasons for the suspension.
  • Added the MathUtils API providing additional mathematical functions useful for language implementations such as asinh, acosh, and atanh.
  • Added the UnadoptableNode interface. This interface should be preferred to overriding Node.isAdoptable() if the result is statically known.

Find a complete list of updates in the Truffle changelog.

Deprecated and Removed Functionality

  • The Node.js feature was deprecated in Oracle GraalVM for JDK 21 and has been removed in Oracle GraalVM for JDK 23.
  • The LLVM runtime and LLVM toolchain were deprecated in Oracle GraalVM for JDK 21 and have been removed in Oracle GraalVM for JDK 23.

Connect with us