-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8350209: Preserve adapters in AOT cache #24740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
👋 Welcome back kvn! A progress list of the required criteria for merging this PR into |
@vnkozlov This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 14 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
/contributor add @ashu-mehra |
@vnkozlov |
Webrevs
|
@vnkozlov I forgot to remove |
Done. |
/cc hotspot-runtime |
@vnkozlov |
/label remove hotspot |
@vnkozlov |
@vnkozlov |
src/hotspot/share/cds/cdsConfig.cpp
Outdated
bool CDSConfig::is_dumping_aot_code_enabled() { | ||
return _is_dumping_aot_code_enabled; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other functions in CDSConfig don't have the _enabled()
suffix. E.g., is_dumping_method_handles()
. It doesn't mean we are doing method handle right now, but rather we have the ability to do so.
Since we rarely ask "am I in the middle of dumping X right now", I think adding _enabled()
will be redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay.
Added missing changes for Aarch64 to always generate far jumps in AOT code. |
} | ||
|
||
#ifndef PRODUCT | ||
void AdapterHandlerLibrary::print_adapter_handler_info(AdapterHandlerEntry* handler, AdapterBlob* adapter_blob) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: pass tty
explicitly as outputStream*
void AdapterHandlerLibrary::print_adapter_handler_info_on(outptutStream* st, AdapterHandlerEntry* handler, AdapterBlob* adapter_blob) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/hotspot/share/code/relocInfo.hpp
Outdated
@@ -1287,6 +1289,24 @@ class trampoline_stub_Relocation : public Relocation { | |||
|
|||
void pack_data_to(CodeSection * dest) override; | |||
void unpack_data() override; | |||
#if defined(AARCH64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unfortunate to see AArch64-specific code in shared code.
But I don't see anything besidespd_destination()
and pd_set_destination()
declarations. Where're their bodies?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I copied it from leyden/premain but it is used only for trampoline jump relocation for calls in nmethods on Aarch64. They are not present in adapters. I remove this code.
/* | ||
* AOT Code Cache collects code from Code Cache and corresponding metadata | ||
* during application training run. | ||
* In following "production" runs this code and data can me loaded into |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/me/be/
src/hotspot/share/code/codeBlob.hpp
Outdated
@@ -188,6 +204,8 @@ class CodeBlob { | |||
nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; } | |||
nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; } | |||
CodeBlob* as_codeblob() const { return (CodeBlob*) this; } | |||
AdapterBlob* as_adapter_blob() const { assert(is_adapter_blob(), "must be adapter blob"); return (AdapterBlob*) this; } | |||
ExceptionBlob* as_exception_blob() const { assert(is_exception_stub(), "must be exception stub"); return (ExceptionBlob*) this; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ExceptionBlob
is C2-specific, but as_exception_blob()
is unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
if (AbortVMOnAOTCodeFailure) { | ||
vm_exit_during_initialization("Unable to use AOT Code Cache.", nullptr); | ||
} | ||
log_info(aot, codecache, init)("Unable to use AOT Code Cache."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be a warning instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
tty->print_cr("Unable to create AOT Code Cache."); | ||
vm_abort(false); | ||
} | ||
log_info(aot, codecache, exit)("Unable to create AOT Code Cache."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here (log_warning
?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will remove exit_vm_on_
from these 2 methods to avoid confusion. And will add comment.
AOTAdapterCaching = false; | ||
} | ||
|
||
static void exit_vm_on_store_failure() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming (exit_vm_on_load_failure
and exit_vm_on_store_failure
) still look confusing to me. By default, they disable AOTAdapterCaching
and issue a message, but the name strongly suggests that execution halts there:
if (!open_cache(is_dumping, is_using)) {
if (is_using) {
exit_vm_on_load_failure();
} else {
exit_vm_on_store_failure();
}
return;
}
entry_offset[1] = handler->get_c2i_entry() - i2c_entry; | ||
entry_offset[2] = handler->get_c2i_unverified_entry() - i2c_entry; | ||
entry_offset[3] = handler->get_c2i_no_clinit_check_entry() - i2c_entry; | ||
AOTCodeCache::store_code_blob(*adapter_blob, AOTCodeEntry::Adapter, id, name, AdapterHandlerEntry::ENTRIES_COUNT, entry_offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What the intended behavior here when AOTCodeCache::store_code_blob
fails?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If something happened when we tried to store blob (adapter in this case) into buffer (for example, if reserved for AOT code buffer is too small) the next will be called:
set_failed();
exit_vm_on_store_failure();
So we either abort VM based on the flag or issue warning (as you suggested) and continue execution.
set_failed()
will prevent following attempts to cache blobs and prevent final dump any cached code into AOT cache:
bool for_dump() const { return _for_dump && !_failed; }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an assert here?
bool success = AOTCodeCache::store_code_blob(...);
assert(success || !AOTCodeCache::is_dumping_adapters(), "");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert(success || !AOTCodeCache::is_dumping_adapters(), "");
This condtion !AOTCodeCache::is_dumping_adapters()
in the assert is not very intuitive. I think what we need to assert is future stores in the aot code cache are disabled. So having a method like AOTCodeCache::is_store_disabled()
would better communicate the intent here. But I don't mind keeping this condition for this initial PR. I will just suggest to add a better assert message like:
assert(success || !AOTCodeCache::is_dumping_adapters(), "storing of adapter must be disabled");
And I think we should also be setting _adapter_caching
to false in report_load_failure
and report_store_failure
to be consistent, otherwise we may end up in a situation where AOTAdapterCaching
is false but _adapter_caching
is true. In fact, I feel we should only be setting _adapter_caching
and not AOTAdapterCaching
in report_load/store_failure
because _adapter_caching
is the flag used to gate store/load operations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @ashu-mehra. You have good points. I will work on them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FTR I suggested !AOTCodeCache::is_dumping_adapters()
because that's the guarding check for AOTCodeCache::store_code_blob()
call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add assert message but keep check.
AOTAdapterCaching = false; | ||
} | ||
|
||
static void exit_vm_on_store_failure() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting AOTAdapterCaching to false on failure is simple indication that adapter caching is switched off for someone who will look on final state of flag.
But how does it affect execution? What's the intended behavior when a failure happens during store attempt? What are the consistency guarantees for AOT code cache during dumping in presense of store failures? What I see right now is that errors reported by AOTCodeCache::store_code_blob()
are silently ignored. How does _cache
notice a store failure during dumping phase?
|
Thank you, @iwanowww, for review. I think I addressed your comments and answered your question. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Minor suggestions follow.
entry_offset[1] = handler->get_c2i_entry() - i2c_entry; | ||
entry_offset[2] = handler->get_c2i_unverified_entry() - i2c_entry; | ||
entry_offset[3] = handler->get_c2i_no_clinit_check_entry() - i2c_entry; | ||
AOTCodeCache::store_code_blob(*adapter_blob, AOTCodeEntry::Adapter, id, name, AdapterHandlerEntry::ENTRIES_COUNT, entry_offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an assert here?
bool success = AOTCodeCache::store_code_blob(...);
assert(success || !AOTCodeCache::is_dumping_adapters(), "");
#include <sys/stat.h> | ||
#include <errno.h> | ||
|
||
static void load_failure() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe on_(load|store)_failure()
or report_(load|store)_failure()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will use report_
Thank you, @iwanowww. I need 2 re-reviews so I asked @ashu-mehra to review again. |
I reverted back I removed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
/reviewers 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Thank you again, @iwanowww and @ashu-mehra |
/integrate |
Going to push as commit aae2bb6.
Your commit was automatically rebased without conflicts. |
JEP 483 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):New diagnostic flags are introduced (use
-XX:+UnlockDiagnosticVMOptions
to unlock them):By default
AOTAdapterCaching
isfalse
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:
There are several new UL flag combinations to trace the AOT code caching process:
@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.Progress
Issue
Reviewers
Contributors
<[email protected]>
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/24740/head:pull/24740
$ git checkout pull/24740
Update a local copy of the PR:
$ git checkout pull/24740
$ git pull https://git.openjdk.org/jdk.git pull/24740/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 24740
View PR using the GUI difftool:
$ git pr show -t 24740
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/24740.diff
Using Webrev
Link to Webrev Comment