On Mon, 1 Jun 2026 21:58:42 GMT, Ioi Lam <[email protected]> wrote:
> Before this PR, you cannot use -XX:AOTCache in the training run:
>
>
> $ java -XX:AOTCache=foo.aot -cp HelloWorld.jar \
> -XX:AOTMode=record -XX:AOTConfiguration=hw.aotconfig \
> HelloWorld
> [...] AOTCache must not be specified when using -XX:AOTMode=record
>
>
> However, in some cases, it may be desirable to train the AOT cache in two or
> more steps. For example:
>
> ## Separate Training for Framework and Application:
>
> - First perform a training run to exercise commonly-used areas of the
> framework.
> - Second, perform a training run of a specific application.
>
> The idea is that important parts of the framework may not be covered by a
> single application training run, but they may still be used in the production
> run due to runtime-specific input.
>
>
> # Train the framework
> java -XX:AOTCacheOutput=first.aot -cp FrameWork.jar FrameWorkTraningHelper
>
> # Train the app
> java -XX:AOTCache=first.aot -XX:AOTCacheOutput=second.aot -cp
> FrameWork.jar:App.jar MyApp
>
> # Production run using second.aot, which contains artifacts from
> # the first and second training runs
> java -XX:AOTCache=second.aot -cp FrameWork.jar:App.jar MyApp
>
> Note that the classpaths of the training runs must be compatible. I.e., the
> classpath of an earlier training run must be the same as, or the prefix of,
> the classpath of a later training run.
>
> ## Train the Same Application in Multiple Runs:
>
> An application may perform 3 different operations. It's not easy to perform
> all 3 operations in a single training run, as the 3 operations are
> represented by 3 separate main classes (`WalkDog`, `FeedCat`, and
> `WaterPlants`). So, we perform 3 separate training runs and combine the
> results into a single AOT cache.
>
>
> # Training
> java -XX:AOTCacheOutput=tmp1.aot -cp MyApp.jar WalkDog
> java -XX:AOTCache=tmp1.aot -XX:AOTCacheOutput=tmp2.aot -cp MyApp.jar FeedCat
> java -XX:AOTCache=tmp2.aot -XX:AOTCacheOutput=final.aot -cp MyApp.jar
> WaterPlants
>
> # Production: final.aot contains artifacts for optimizing all 3 operations:
> java -XX:AOTCache=final.aot -cp MyApp.jar WalkDog
> java -XX:AOTCache=final.aot -cp MyApp.jar FeedCat
> java -XX:AOTCache=final.aot -cp MyApp.jar WaterPlants
>
>
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK
> Interim AI Policy](https://openjdk.org/legal/ai).
Few comments.
src/hotspot/share/cds/aotHeap.cpp line 1950:
> 1948: } else if (java_lang_Class::is_instance(orig_obj) && subgraph_info ==
> _dump_time_special_subgraph) {
> 1949: orig_obj = scratch_java_mirror(orig_obj);
> 1950: assert(orig_obj != nullptr, "must be archived");
Please add comment explaining why you need this check and code.
src/hotspot/share/cds/cdsConfig.cpp line 801:
> 799: // Re-training
> 800: FLAG_SET_ERGO_IF_DEFAULT(AOTReplayTraining, true);
> 801: AOTCodeCache::enable_caching();
AOTCodeCache::enable_caching() should depend on AOTReplayTraining which could
be switched off on command line.
src/hotspot/share/cds/cdsConfig.cpp line 816:
> 814: FLAG_SET_ERGO(AOTRecordTraining, false);
> 815: FLAG_SET_ERGO_IF_DEFAULT(AOTReplayTraining, true);
> 816: AOTCodeCache::enable_caching(); // Generate AOT code during assembly
> phase.
Here too: AOTCodeCache::enable_caching() should depend on AOTReplayTraining
which could be switched off on command line.
-------------
PR Review: https://git.openjdk.org/jdk/pull/31344#pullrequestreview-5591773516
PR Review Comment: https://git.openjdk.org/jdk/pull/31344#discussion_r4330348671
PR Review Comment: https://git.openjdk.org/jdk/pull/31344#discussion_r4330461330
PR Review Comment: https://git.openjdk.org/jdk/pull/31344#discussion_r4330495250