-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8372617: Save and restore stubgen stubs when using an AOT code cache #28433
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
base: master
Are you sure you want to change the base?
Conversation
|
👋 Welcome back adinn! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
|
This PR still needs to ensure that pre-universe stub entries are registered in the AOT address table. These stubs cannot be saved and restored because the AOT cache does not exist before universe init. As a consequence their addresses cannot be registered using the normal generate time mechanism. The required fix will be to add them via special case handling as soon as the AOT cache and address table have been initialised (preferably at the point where the majority of external addresses are registered). This omission is not a problem for this patch i.e. as far as reference from existing stubs is concerned since none of the saved stubs targets to a pre-universe stub entry. However, they ought to be registered in case that situation changes or in case an nmethod that gets saved to and reloaded from the AOT cache needs at some point to target a pre-universe stub. |
| int entry_count = StubInfo::entry_count(stub_id); | ||
| assert(entry_count == 1, "sanity check"); | ||
| if (find_archive_data(stub_id)) { | ||
| address start = nullptr; | ||
| address end = nullptr; | ||
| load_archive_data(stub_id, start, end); | ||
| return start; | ||
| } | ||
|
|
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.
This code pattern repeats a lot. Can we move it into load_archive_data()?
address start = load_archive_data(stub_id);
if (start != nullptr) {
return start;
}
And have an other specialized load_archive_data if you need end value.
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.
Yes, I think I can probably refactor this to make it simpler and avoid returning end. I'll push a revised version soon. Return of end is mostly a hangover from an older version but it does still serve a purpose (see below). Originally, it was not clear what all the other specialized cases were going to be but I thinkit is now fairly clear that we only need to cater for:
- multiple entries other than the start address
- multiple extra addresses
- both the above.
n.b. entries and extras are distinguished by one simple criterion: the former can be accessed from AOT code while the latter cannot. So, entries need to be registered with the AOT address table beneath load_entry while extras can be omitted (although they almost certainly need to be registered with the current runtime by the caller). That distinction ought to be written down in a comment somewhere, also the acceptable values for both:
start clearly must be non-null. Additional entries may be nullptr or in the range [start, end). Extra addresses may be nullptr or in the range [start, end] i.e. extras can address the first byte after the end of the stub.
This is needed so that an extra can be used to mark the (exclusive) end address of a range that covers the tail of a stub. So far, it has always been the case that extra addresses occur in triples identifying UnsafeMemoryAccess handler regions, (open, close, handler). I'm leaving it open as to whether any other uses might turn up which is why processing of extras happens in the caller rather than under load_entry.
load_entry now knows and verifies how many entries it ought to be retrieving and accepts an extras array if and only if there are extra addresses in the archive. It also range checks the entry/extra addresses. So, all a caller needs to do is assign extra entries to the outputs passed by the caller then validate the extras count and process them appropriate to whatever the stub understands them to mean.
end was originally being returned by load_entry to allow the caller to range check both entry and extra addresses but that check is now redundant. It is still needed because of an unnecessary complication in the current code. Addresses are converted to offsets before saving in the archive and translated back to addresses when loading. store_entry does ensure that all entry or extra offsets addresses lie within the range [start, end) and [start, end] respectively. However, nullptr and end both get saved to the archive as start - end. That means both of them get restored as nullptr. Clients are expected to know whether a restored nullptr at some offset in the extras array is really an end address and substitute end in its place (e.g. in the case where close == nullptr really means close == end). Because of that load_entry has to make end visible to the caller. If I change things so that nullptr is saved as UINT_MAX in that will avoid the ambiguity, allowing the client to use the value without an extra check.
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.
@vnkozlov ^^
| void StubGenerator_AOTAddressTable_init() { | ||
| ResourceMark rm; | ||
| GrowableArray<address> external_addresses; | ||
| // publish static addresses referred to by aarch64 generator | ||
| StubGenerator::init_AOTAddressTable(external_addresses); | ||
| // publish external data addresses defined in nested aarch64 class | ||
| StubRoutines::aarch64::init_AOTAddressTable(external_addresses); | ||
| AOTCodeCache::publish_external_addresses(external_addresses); | ||
| } |
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.
This and *init_AOTAddressTable() methods should be under #if INCLUDE_CDS
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
|
|
||
| // Non-generated init method | ||
|
|
||
| void StubRoutines::init_AOTAddressTable() { |
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.
Can this body be in platform specific file.
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.
Yes, I'll add an implementation to file stubRoutines_xxx.cpp for each platform.
|
I noticed that we have to add a lot of local data tables addresses for stubs (math intrinsics). |
|
@adinn this pull request can not be integrated into git checkout save-stubgen-stubs
git fetch https://git.openjdk.org/jdk.git master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
ashu-mehra
left a comment
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. I only have minor comments, some typos and unused code.
| // handler pc may be null in which case it defaults to the | ||
| // default_handler. | ||
|
|
||
| void StubCodeGenerator::register_unsafe_access_handlers(GrowableArray<address> &entries, int begin, int count) { |
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.
Is there a case or is it possible that begin is non -zero? I think it is same to assume we need to register all the values in entries in the UnsafeMemoryAccess::_table, right?
| static void init_early_stubs_table() NOT_CDS_RETURN; | ||
| static void init_shared_blobs_table() NOT_CDS_RETURN; | ||
| static void init_early_c1_table() NOT_CDS_RETURN; | ||
| static void set_shared_stubs_complete() NOT_CDS_RETURN; |
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 don't see set_shared_stubs_complete, set_c1_stubs_complete and set_c2_stubs_complete called from anywhere.
|
|
||
| ~AOTStubData() CDS_ONLY({FREE_C_HEAP_ARRAY(StubAddrRange, _ranges);}) NOT_CDS({}) | ||
|
|
||
| bool is_open() CDS_ONLY({ return (_flags & OPEN) != 0; }) NOT_CDS_RETURN_(false); |
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.
extra indentation
| _complete = true; | ||
| void AOTCodeAddressTable::set_c1_stubs_complete() { | ||
| assert(!_c1_stubs_complete, "repeated close for c1 stubs!"); | ||
| _c2_stubs_complete = true; |
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 be setting _c1_stubs_complete
| for (int i = 0; i < addresses.length(); i++) { | ||
| SET_ADDRESS(_extrs, addresses.at(i)); | ||
| } | ||
| log_debug(aot, codecache, init)("External addresses recorded"); |
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.
This log message is not very helpful. Following the code I now know it refers to the step where arch specific external address are added. So it does seem relevant, however the current message does not convey the context. But I don't know how to improve it either :).
| @@ -2383,6 +2736,9 @@ class StubGenerator: public StubCodeGenerator { | |||
| __ leave(); // required for proper stackwalking of RuntimeStub frame | |||
| __ ret(lr); | |||
|
|
|||
| // record the stub entry and end plus any no_push entry | |||
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 as before, comments refers to "no_push entry".
| vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); // PSHUFFLE_BYTE_FLIP_MASK wrt rip | ||
| assert(pshuffle_byte_flip_mask_addr + 32 == StubRoutines::x86::pshuffle_byte_flip_mask_ymm_lo_addr_sha512(), "sanity"); | ||
|
|
||
| vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); // PSHUFFLE_BYTE_FLIP_MASK wrt rip |
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.
Indentation is off
| assert(pshuffle_byte_flip_mask_addr + 64 == StubRoutines::x86::pshuffle_byte_flip_mask_dc00_addr(), "sanity"); | ||
|
|
||
| vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); // [PSHUFFLE_BYTE_FLIP_MASK wrt rip] | ||
| vmovdqu(SHUF_00BA, ExternalAddress(pshuffle_byte_flip_mask_addr + 32)); // [_SHUF_00BA wrt rip] |
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.
Now that we have StubRoutines::x86::pshuffle_byte_flip_mask_00ba_addr(), I think it should replace pshuffle_byte_flip_mask_addr + 32. Makes the usage of these addresses explicit.
| address StubRoutines::crc32c_table_addr() { ShouldNotCallThis(); return nullptr; } | ||
|
|
||
| #if INCLUDE_CDS | ||
| // nothing to do for xero |
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.
xero->zero
|
|
||
| // Disable stubs caching until JDK-8357398 is fixed. | ||
| FLAG_SET_ERGO(AOTStubCaching, false); | ||
| // FLAG_SET_ERGO(AOTStubCaching, false); |
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 can't seem to access JDK-8357398. I am not sure if that bug is fixed or not. But if it is not fixed yet, I think we should keep this un-commented. I guess this was commented out for testing purpose.
This PR adds save and restore of all generated stubs to the AOT code cache on x86 and aarch64. Other arches are modified to deal with the related generic PAI changes.
Small changes were required to the aarch64 and x86_64 generator code in order to meet two key constraints:
Progress
Issue
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28433/head:pull/28433$ git checkout pull/28433Update a local copy of the PR:
$ git checkout pull/28433$ git pull https://git.openjdk.org/jdk.git pull/28433/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 28433View PR using the GUI difftool:
$ git pr show -t 28433Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28433.diff
Using Webrev
Link to Webrev Comment