RFR: 8350209: Preserve adapters in AOT cache [v12]

Vladimir Ivanov vlivanov at openjdk.org
Wed Apr 30 23:04:51 UTC 2025


On Wed, 30 Apr 2025 02:05:41 GMT, Vladimir Kozlov <kvn at openjdk.org> wrote:

>> [JEP 483](https://bugs.openjdk.org/browse/JDK-8315737) preserves class information in AOT cache which helps Java startup performance.
>> 
>> We should also preserve adapters (i2c, c2i) to further improve performance of class linking where adapters are generated.
>> 
>> Short running Java application can see several percents improvement. I got 6% improvement when ran `HelloWorld.java` on Linux-x64 Ice Lake CPU (2.5Ghz):
>> 
>> 
>> (perf stat -r 100 java -XX:AOTCache=app.aotcache -cp hello.jar HelloWorld > /dev/null) 2>&1 | grep elapsed
>>          0.0299401 +- 0.0000504 seconds time elapsed  ( +-  0.17% )
>> 
>> (perf stat -r 100 java -XX:AOTCache=app.aotcache -XX:+UnlockDiagnosticVMOptions -XX:-AOTAdapterCaching -cp hello.jar HelloWorld > /dev/null) 2>&1 | grep elapsed
>>          0.0318654 +- 0.0000535 seconds time elapsed  ( +-  0.17% )
>> 
>> 
>> New diagnostic flags are introduced (use `-XX:+UnlockDiagnosticVMOptions` to unlock them):
>> 
>> 
>> -XX:+AOTAdapterCaching  - Enable or disable saving and restoring i2c2i adapters
>> -XX:AOTCodeMaxSize=10*M - buffer size in bytes for AOT code caching
>> -XX:+AbortVMOnAOTCodeFailure - Abort VM on the first occurrence of AOT code caching failure
>> 
>> By default `AOTAdapterCaching` is `false` and enabled ergonomically when `-XX:AOTCache` is specified.
>> This flag is ignored when `AOTCache` is not specified.
>> 
>> To use AOT adapters follow process described in JEP 483:
>> 
>> 
>> java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -cp app.jar App
>> java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -cp app.jar
>> java -XX:AOTCache=app.aot -cp app.jar App
>> 
>> 
>> There are several new UL flag combinations to trace the AOT code caching process:
>> 
>> 
>> -Xlog:aot+codecache+init -Xlog:aot+codecache+exit -Xlog:aot+codecache+stubs
>> 
>> 
>> @ashu-mehra is main author of changes. He implemented adapters caching.
>> I did main framework (`AOTCodeCache` class) for saving and loading AOT code.
>> 
>> Tested tier1-6,10, which includes tests with `AOTClassLinking` enabled. Also Xcomp,stress and JCK.
>
> Vladimir Kozlov has updated the pull request incrementally with one additional commit since the last revision:
> 
>   address Ioi's comments

src/hotspot/share/code/aotCodeCache.cpp line 60:

> 58:     vm_exit_during_initialization("Unable to use AOT Code Cache.", nullptr);
> 59:   }
> 60:   log_info(aot, codecache, init)("Unable to use AOT Code Cache.");

Should it be a warning instead?

src/hotspot/share/code/aotCodeCache.cpp line 69:

> 67:     vm_abort(false);
> 68:   }
> 69:   log_info(aot, codecache, exit)("Unable to create AOT Code Cache.");

Same here (`log_warning`?).

src/hotspot/share/code/aotCodeCache.hpp line 31:

> 29:  * AOT Code Cache collects code from Code Cache and corresponding metadata
> 30:  * during application training run.
> 31:  * In following "production" runs this code and data can me loaded into

s/me/be/

src/hotspot/share/code/codeBlob.hpp line 208:

> 206:   CodeBlob* as_codeblob() const               { return (CodeBlob*) this; }
> 207:   AdapterBlob* as_adapter_blob() const        { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; }
> 208:   ExceptionBlob* as_exception_blob() const    { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; }

`ExceptionBlob` is C2-specific, but `as_exception_blob()` is unused.

src/hotspot/share/code/relocInfo.hpp line 1292:

> 1290:   void pack_data_to(CodeSection * dest) override;
> 1291:   void unpack_data() override;
> 1292: #if defined(AARCH64)

It's unfortunate to see AArch64-specific code in shared code. 

But I don't see anything besides`pd_destination()` and `pd_set_destination()` declarations. Where're their bodies?

src/hotspot/share/runtime/sharedRuntime.cpp line 2780:

> 2778: 
> 2779: #ifndef PRODUCT
> 2780: void AdapterHandlerLibrary::print_adapter_handler_info(AdapterHandlerEntry* handler, AdapterBlob* adapter_blob) {

Suggestion: pass `tty` explicitly as `outputStream*`


void AdapterHandlerLibrary::print_adapter_handler_info_on(outptutStream* st, AdapterHandlerEntry* handler, AdapterBlob* adapter_blob) {

src/hotspot/share/runtime/sharedRuntime.cpp line 2852:

> 2850:     entry_offset[2] = handler->get_c2i_unverified_entry() - i2c_entry;
> 2851:     entry_offset[3] = handler->get_c2i_no_clinit_check_entry() - i2c_entry;
> 2852:     AOTCodeCache::store_code_blob(*adapter_blob, AOTCodeEntry::Adapter, id, name, AdapterHandlerEntry::ENTRIES_COUNT, entry_offset);

What the intended behavior here when `AOTCodeCache::store_code_blob` fails?

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/24740#discussion_r2069610692
PR Review Comment: https://git.openjdk.org/jdk/pull/24740#discussion_r2069611080
PR Review Comment: https://git.openjdk.org/jdk/pull/24740#discussion_r2069563790
PR Review Comment: https://git.openjdk.org/jdk/pull/24740#discussion_r2069585108
PR Review Comment: https://git.openjdk.org/jdk/pull/24740#discussion_r2069558227
PR Review Comment: https://git.openjdk.org/jdk/pull/24740#discussion_r2069547808
PR Review Comment: https://git.openjdk.org/jdk/pull/24740#discussion_r2069619002


More information about the build-dev mailing list