Skip to content

Integrate the Shenandoah/Generational-Shenandoah GC into Native ImageΒ #12237

@simonis

Description

@simonis

Shenandoah/Generational-Shenandoah support is already available for the GraalVM JIT (see PR Shenandoah support and commit [GR-65266] Add support for Shenandoah).

Now add support for using Shenandoah/Generational-Shenandoah as a supported GC in SubstrateVM/Native Image by leveraging the GC infrastructure which already exists in the Oracle GraalVM version. This will work by compiling a slightly adapted version of Shenandoah into a static library, and linking it into the final native image where it will be used through SubstrateVM's GC interface. The GraalVM team will add the required interfaces and glue code which is already used to integrate G1 into SubstrateVM (but not the G1 code itself) to GraalVM CE.

Using the existing G1 Native Image GC infrastructure for Shenandoah

  • Create a modified subset of the OpenJDK Shenandoah code that can be compiled into a static library
  • Create glue code on the Native Image side that
    • links against that static library
    • calls into that static library
  • This will make it a lot easier to use native GCs like Shenandoah with Native Image

Current Restrictions of the GC infrastructure

  • Linux/amd64 and linux/aarch64 only (macOS and Windows support would be rather easy to add, but the build system needs to be changed for that)
  • Only supports a single Native Image isolate (because the C++ code has global process-wide state)
  • Currently only contains what's needed for G1 (needs to be extended to cover the Shenandoah cases)

How does the selected GC influence the Native Image build

  • A specific GC is selected via a build-time option.
  • Register a GC implementation and all its components in a feature (Java heap allocation support, read/write barriers, etc.)
  • Static analysis: determines which code and data is needed
  • Code generation: emit code with read/write barriers for the selected GC
  • Image heap layouting: structures the image heap in a way that it can be memory mapped at run-time
  • Write image heap and code into executable file

How does the Native Image startup work with this GC infrastructure

  • Early argument parsing
  • Isolate creation
  • Call into the static library to do argument parsing (similar to what happens during HotSpot startup).
    This returns the requested Java heap address space size to Native Image.
  • Reserve the Java heap address space and map the image heap.
    After that, image heap data is accessible.
  • Call into the static library to startup and initialize the GC infrastructure (similar to the VM startup on HotSpot).
  • After that, Native Image is fully started and normal Java code can be executed.
| protected memory |      image heap      |     collected Java heap      |
|                  | read-only | writable | size determined by -Xms/-Xmx |
^
heapBase

Drafted implementation steps to integrate Shenandoah with Native Image

C++

  • Add Shenandoah code to the C++ files of the GC infrastructure
  • Add and modify Shenandoah code and its transitive dependencies until everything builds.

Java

Combining both parts

  • VM startup
  • Implement read/write barriers (see BarrierSetProvider)
  • Survive a simple garbage collection.
  • Implement object pinning (see PinnedObjectSupport)
  • Work on completeness and stability.
  • Work on performance (probably needs support for thread-local handshakes in Native Image).
  • Support JIT compilation if Truffle workloads are relevant (see RuntimeCodeInfoGCSupport)
  • Implement monitoring support (e.g., performance data that can be queried via jstat or MX beans, see GCRelatedMXBeans and AbstractMemoryMXBean).

Many thanks to @thomaswue and @wirthi for supporting this effort and to @christianhaeubl for drafting a first version of this proposal.

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions