8373591: C2: Fix the memory around some intrinsics nodes#28789
8373591: C2: Fix the memory around some intrinsics nodes#28789merykitty wants to merge 9 commits intoopenjdk:masterfrom
Conversation
|
👋 Welcome back qamai! A progress list of the required criteria for merging this PR into |
|
@eme64 I have extracted the fix of memory around intrinsics nodes in the other PR to this PR and added a unit test for the potential issue. |
|
@merykitty This change is no longer ready for integration - check the PR body for details. |
|
@merykitty The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
src/hotspot/share/opto/graphKit.cpp
Outdated
| Node* res_mem = _gvn.transform(new SCMemProjNode(_gvn.transform(str))); | ||
| set_memory(res_mem, TypeAryPtr::BYTES); | ||
| if (adr_type == TypePtr::BOTTOM) { | ||
| set_all_memory(res_mem); |
There was a problem hiding this comment.
I'm confused by this. Doesn't StrCompressedCopyNode only write to dst? So the only part of the memory state that it updates is the one for TypeAryPtr::BYTES?
There was a problem hiding this comment.
It is because if a node consumes more memory than it produces, we need to compute its anti-dependencies. And since we do not compute anti-dependencies of these nodes, it is safer to make them kill all the memory they consume. What do you think?
There was a problem hiding this comment.
Could this be fixed by appending a MemBarCPUOrderNode on the slice of src?
There was a problem hiding this comment.
That's a really great idea! I have implemented it.
|
@merykitty |
| // dependency: | ||
| // StoreC -> MemBar -> MergeMem -> compress_string -> MergeMem -> CharMem | ||
| // --------------------------------> | ||
| Node* all_mem = reset_memory(); |
There was a problem hiding this comment.
This code sequence is used several times. Would it make sense to factor it out in its own method?
|
/label remove shenandoah hotspot |
|
@merykitty The |
|
@merykitty this pull request can not be integrated into git checkout intrinsicsadrtype
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 |
|
So after looking at this PR I have learned that C2 can control reordering of memory operations in at least 3 ways: anti-dependencies, memory slices, or membars. Are there are rules-of-thumb on which is best to use? Using a membar seems the most conservative but probably allows fewer optimizations. By the way, I see that LibraryCallKit::inline_encodeISOArray and corresponding Java method do pretty much the same things a compress. So I tried adding a test for it in TestAntiDependency.java. But to my surprise, it passes, even without the fixes in this PR. I would expect it to fail, because the existing code uses TypeAryPtr::BYTES, so how does it prevent the movement of a char[] store in the test? |
|
Dumb question: why are these intrinsic nodes not implemented as MemNodes?
Why is that?
Why can't we use MergeMem and memory slices/aliases like regular load and store? |
|
This may be unrelated, but I checked to see if we treat Op_EncodeISOArray the same as Op_StrCompressedCopy everywhere. In two places in |
|
@dean-long Thanks for taking a look.
I have added a test for this method. If it does not fail then adding
I think it is because only
During During We may fix these places, but since it is a really rare occurrence that a node consumes some memory and produces some but the latter is different from the former, so it is more reasonable to fix the graph at these nodes.
Thanks to Roland's suggestion, now it only kills the 2 slices it concerns with and not the whole memory state. |
I believe it is because before this change, |
|
I'm still looking at this, but I'm getting confused by all the special cases. I wish C2 handling of memory was more uniform. |
|
It looks like we use SCMemProjNode for nodes that both read and write memory, so why is it not used for StrInflatedCopyNode in inflate_string? |
|
@dean-long |
Hi,
This is extracted from #28570 , there are 2 issues here:
adr_type. For example,AryEqNodereportsadr_typebeingTypeAryPtr::BYTES(it inherits this fromStrIntrinsicNode). This is incorrect, however, as it can acceptchar[]inputs, too. Another case isVectorizedHashCodeNode, which reports itsadr_typebeingTypePtr::BOTTOM, but it actually extracts a memory slice and does not consume the whole memory.StrInflatedCopyNode, as they consume more than they produce, during scheduling, we need to compute anti-dependencies. This is not the case, so we should fix it by making the nodes kill all the memory they consume. This issue is often not present because these intrinsics are not exposed bare to general usage.Testing:
Please kindly review, thanks a lot.
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28789/head:pull/28789$ git checkout pull/28789Update a local copy of the PR:
$ git checkout pull/28789$ git pull https://git.openjdk.org/jdk.git pull/28789/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 28789View PR using the GUI difftool:
$ git pr show -t 28789Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28789.diff
Using Webrev
Link to Webrev Comment