-
Notifications
You must be signed in to change notification settings - Fork 146
8268362: [REDO] C2 crash when compile negative Arrays.copyOf length after loop #49
Conversation
👋 Welcome back hshi! A progress list of the required criteria for merging this PR into |
@huishi-hs 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
|
I tested your changes and there were no related failures. |
@dean-long Thanks! |
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.
Few comments.
src/hotspot/share/opto/graphKit.cpp
Outdated
Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn); | ||
if (ccast != alen) { | ||
alen = _gvn.transform(ccast); | ||
_gvn.set_type_bottom(ccast); | ||
record_for_igvn(ccast); | ||
alen = ccast; |
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 think we need GraphKit wrapper method which execute this code to avoid duplication here, in arraycopy_move_allocation_here()
and in new_array()
.
Add comment why we can't do transform()
.
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 Thanks for your review!
GraphKit::load_array_length code is different with new_array() and arraycopy_move_allocation_here(), it doesn't replace_in_map. Currently GraphKit::cast_replace_array_length_post_allocation warpper is used in new_array() and arraycopy_move_allocation_here().
Would you prefer a wrapper for all these three places? It would be like following code.
Node* GraphKit::cast_array_length_post_allocation(AllocateArrayNode* alloc, const TypeOopPtr* oop_type, bool replace_map /false in load_array_length/) {
Node* length = alloc->in(AllocateNode::ALength);
if (replace_map == false || map()->find_edge(length) >= 0) {
Node* ccast = alloc->make_ideal_length(oop_type, &_gvn);
if (ccast != length) {
_gvn.set_type_bottom(ccast);
record_for_igvn(ccast);
if (replace_map) {
replace_in_map(length, ccast);
}
return cast;
}
}
return length;
}
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.
All places, please. I prefer different names for this method and its parameters GraphKit::array_ideal_length(alloc , ary_type, replace_length_in_map)
. No need for parameter's comment in declaration - it is clear from name.
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, new wrapper is added, all 3 places: 1) new_array 2) arraycopy_move_allocation_here 3) load_array_length use GraphKit::array_ideal_length(alloc , ary_type, replace_length_in_map)
Node* prev_cast = NULL; | ||
#endif | ||
for (uint i = 0; i < init_control->outcnt(); i++) { | ||
Node *init_out = init_control->raw_out(i); |
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.
Style: Node* init_out
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
Node *init_out = init_control->raw_out(i); | ||
if (init_out->is_CastII() && init_out->in(0) == init_control && init_out->in(1) == alloc_length) { | ||
#ifdef ASSERT | ||
if (prev_cast == NULL) { |
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.
Add comment why multiply CastII
could be here (because each load_array_length() call in guard checks will generate now separate CastII nodes). All these CastII nodes are replaced here with one: original alloc_length
.
I am wondering if will affect result of guard checks in runtime.
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.
Would you share more detail about your concern for "if will affect result of guard checks in runtime."?
Node* ccast = alloc->make_ideal_length(ary_type, &_gvn); | ||
if (ccast != length) { | ||
_gvn.set_type_bottom(ccast); | ||
record_for_igvn(ccast); |
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.
Use wrapper method to avoid duplication.
…ocation & add more comments
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 forgot to say that tests should be in compiler/arraycopy/ directory.
src/hotspot/share/opto/graphKit.cpp
Outdated
Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn); | ||
if (ccast != alen) { | ||
alen = _gvn.transform(ccast); | ||
_gvn.set_type_bottom(ccast); | ||
record_for_igvn(ccast); | ||
alen = ccast; |
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.
All places, please. I prefer different names for this method and its parameters GraphKit::array_ideal_length(alloc , ary_type, replace_length_in_map)
. No need for parameter's comment in declaration - it is clear from name.
…n after array allocation. Update comments.
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. Let me test it.
@huishi-hs 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 56 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 |
Testing looks good. |
@vnkozlov thanks! |
May I have a second review for this PR? |
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 to me.
Thanks again! @rwestrel |
/integrate |
Going to push as commit 22ebd19.
Your commit was automatically rebased without conflicts. |
@huishi-hs Pushed as commit 22ebd19. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
This redos PR openjdk/jdk#4238
Some closed tests fail due to original PR, the main reasons are:
8268325/8268345
CastIINode created in AllocateArrayNode::make_ideal_length apply on a negative array length. GVN transform converts these CastIINode to top. This breaks assumptions, eg., array index node type is TypeInt.
8268345
Some CastIINode is created in LoadRange::Ideal, which doesn't apply GVN transform. CastIINode can not be found in GVN hashtable and cause assertion failure.
Based on previous PR #4238, this PR unifies CastIINode processing post AllocateArrayNode::make_ideal_length. Setup type and add into igvn worklist. Avoid apply GVN transform to break different assumptions in parser.
Based on closed test failrue message, two new tests are added
TestNegArrayLengthAsIndex1 : fail in debug build even without previous PR #4238, it loads a negative array length and apply GVN transform (In GraphKit::load_array_length) which covert length to top node. It also assert in Parse::array_addressing.
TestNegArrayLengthAsIndex2 : similar with failrue in https://bugs.openjdk.java.net/browse/JDK-8268301
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk17 pull/49/head:pull/49
$ git checkout pull/49
Update a local copy of the PR:
$ git checkout pull/49
$ git pull https://git.openjdk.java.net/jdk17 pull/49/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 49
View PR using the GUI difftool:
$ git pr show -t 49
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk17/pull/49.diff