|
| 1 | +# Overview |
| 2 | + |
| 3 | +This branch is based on the tag `25+37-jvmci-b04` of this repository and contains infrastructure that simplifies the integration of HotSpot garbage collectors into Native Image. |
| 4 | + |
| 5 | +## Limitations |
| 6 | + |
| 7 | +The current implementation has a few limitations: |
| 8 | + |
| 9 | +- Only `linux/amd64` and `linux/aarch64` are supported at the moment. |
| 10 | + macOS and Windows support should be easy to add but the build system needs to be changed for that. |
| 11 | +- Only a **single** Native Image isolate is supported at the moment because the C++ code has process-wide global state. |
| 12 | + |
| 13 | +## Structure |
| 14 | + |
| 15 | +The directory structure is modeled closely after the OpenJDK, with a few notable differences: |
| 16 | + |
| 17 | +``` |
| 18 | +src/ |
| 19 | +└── hotspot/ |
| 20 | + ├── cpu/ |
| 21 | + ├── os/ |
| 22 | + ├── os_cpu/ |
| 23 | + ├── share/ |
| 24 | + ├── jfrfiles/ # JFR-related files (autogenerated) |
| 25 | + ├── jvmtifiles/ # JVMTI-related files |
| 26 | + ├── mocks/ # Autogenerated mocks for C/C++ header (see below) |
| 27 | + └── svm/ # SVM-specific files (see below) |
| 28 | +``` |
| 29 | + |
| 30 | +- **mocks/**: Contains autogenerated mocks for all deleted C/C++ headers. |
| 31 | + This ensures that `#include` directives remain valid, which reduces the need for conditional compilation (`#ifdefs`) around header inclusion. |
| 32 | +- **svm/**: Contains files that either entirely new or significantly different from their OpenJDK counterparts. |
| 33 | + The structure of the subdirectories mirrors the OpenJDK's `hotspot` directory. |
| 34 | + - *Example*: `src/hotspot/svm/share/oops/oop.hpp` corresponds to `src/hotspot/share/oops/oop.hpp` in OpenJDK. |
| 35 | + |
| 36 | +## Differences to OpenJDK |
| 37 | + |
| 38 | +All files that were not strictly required were removed from the code base. |
| 39 | +This includes major components such as class loading, metaspace handling, JIT compilation, code generation, garbage collection, and other VM-internal infrastructure. |
| 40 | + |
| 41 | +Outside the `svm/` directory, SVM-specific changes are typically guarded with directives such as `#ifdef SVM`. |
| 42 | +In general, we try to keep the diff against OpenJDK minimal so that updating to new OpenJDK versions is reasonably easy. |
| 43 | + |
| 44 | +In addition, there are several large conceptual differences between Native Image and HotSpot, such as: |
| 45 | + |
| 46 | +- **Heap Management:** Native Image always uses a heap base. |
| 47 | + So, `UseCompressedOops` is always `true`, regardless of the actual reference size. |
| 48 | +- **Argument & Option Handling:** Argument parsing and option handling are different as Native Image needs to distinguish between hosted and runtime options. |
| 49 | + HotSpot options that are not relevant for Native Image are reduced to constants when the C++ sources are compiled. |
| 50 | +- **Stack Handling:** The C++ code does not understand the Native Image stack layout. |
| 51 | + Therefore, the GC must call into Native Image to retrieve stack information. |
| 52 | +- **Thread Management:** All Java threads are managed by Native Image. |
| 53 | + The GC is restricted to spawning only native (non-Java) worker threads. |
| 54 | +- **Metaspace & Class Loading:** Metaspace handling or class (un)loading are not supported at the moment. |
| 55 | + Project Crema recently added a metaspace to Native Image, but this C++ GC infrastructure is not yet aware of that. |
| 56 | +- **VM Operations & Safepoints:** The VM operation thread in Native Image is a Java thread. |
| 57 | + So, the handling of VM operations and safepoints is implemented completely differently than on HotSpot. |
| 58 | +- **Locking:** Only a subset of the HotSpot locks is used. |
| 59 | + However, more locks must be accessible to Java threads because the VM operation thread is a Java thread. |
| 60 | +- **Exception Handling:** Java exception support was entirely removed from the C++ code. |
| 61 | + For example, when the Java heap runs out of memory, the `OutOfMemoryError` must be thrown on the Native Image side (and not by the C++ code). |
| 62 | +- **JIT-Compiled Code:** The lifecycle and handling of JIT compiled code (`nmethods`) are fundamentally different between Native Image and HotSpot. |
| 63 | +- **Hybrid Objects:** Native Image supports hybrid objects (with both instance fields and primitive array elements). |
| 64 | + Methods like `oop::is_array()`, `oop::is_objArray()`, `oop::is_typeArray()`, `Klass::is_array_klass()`, `Klass::is_objArray_klass()`, and `Klass::is_typeArray_klass()` may return `false` for hybrid objects, so caution is required. |
| 65 | +- **Performance Data:** Code related to `UsePerfData` is different as Native Image is responsible for managing all related memory and data structures (the C++ may only update data in already existing data structures). |
| 66 | + |
| 67 | +## Current Status & Placeholders |
| 68 | + |
| 69 | +In some code parts, `Unimplemented()` serves as a placeholder for GC-specific functionality: |
| 70 | + |
| 71 | +- Core Functionality |
| 72 | + - `src/hotspot/svm/svmImageHeap.hpp` |
| 73 | + - `src/hotspot/svm/svmToGC.cpp` |
| 74 | + - `src/hotspot/share/gc/shared/gcConfig.cpp` |
| 75 | +- Only relevant if `UsePerfData` is enabled in Native Image |
| 76 | + - `src/hotspot/share/runtime/cpuTimeCounters.cpp` |
| 77 | + - `src/hotspot/share/gc/shared/gcPolicyCounters.cpp` |
| 78 | + - `src/hotspot/share/gc/shared/collectorCounters.cpp` |
| 79 | + - `src/hotspot/share/gc/shared/collectedHeap.cpp` |
| 80 | + - `src/hotspot/share/gc/shared/generationCounters.cpp` |
| 81 | + - `src/hotspot/share/gc/shared/hSpaceCounters.cpp` |
| 82 | + - `src/hotspot/share/gc/shared/ageTable.cpp` |
| 83 | + |
| 84 | +Besides that, the length of 0 for `GCThreadLocalData` in `src/hotspot/share/gc/shared/gcThreadLocalData.hpp` is a placeholder as well. |
| 85 | + |
| 86 | +## Build |
| 87 | + |
| 88 | +This branch uses a simple [Makefile](src/hotspot/Makefile) instead of the OpenJDK build system. |
| 89 | +The following build configurations are supported: |
| 90 | + |
| 91 | +- **Output formats**: Static (`.a`) or shared (`.so`) libraries |
| 92 | +- **Debug level**: `debug`, `fastdebug`, `notproduct`, `product` |
| 93 | +- **Reference size**: Compressed references (`cr`) or uncompressed references (`ur`) |
| 94 | + |
| 95 | +**To build all configurations:** |
| 96 | +```shell |
| 97 | +cd src/hotspot |
| 98 | +make -j16 build_all |
| 99 | +``` |
| 100 | + |
| 101 | +**To build a shared library for local debugging:** |
| 102 | +```shell |
| 103 | +cd src/hotspot |
| 104 | +make -j16 build_debug_ur_so |
| 105 | +``` |
| 106 | + |
0 commit comments