8382226: [lworld] C2: Fix _copyOf/_copyOfRange intrinsic for flat abstract value class arrays#2569
8382226: [lworld] C2: Fix _copyOf/_copyOfRange intrinsic for flat abstract value class arrays#2569chhagedorn wants to merge 4 commits into
Conversation
|
👋 Welcome back chagedorn! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
Webrevs
|
| const TypeAryPtr* orig_t = _gvn.type(original)->isa_aryptr(); | ||
| const TypeKlassPtr* tklass = _gvn.type(klass_node)->is_klassptr(); | ||
| bool exclude_flat = UseArrayFlattening && bs->array_copy_requires_gc_barriers(true, T_OBJECT, false, false, BarrierSetC2::Parsing) && | ||
| const bool is_src_abstract_flat_value_array = orig_t != nullptr && !orig_t->elem()->is_inlinetypeptr() && orig_t->is_flat(); |
There was a problem hiding this comment.
Should we check for !orig_t->is_not_flat() instead?
There was a problem hiding this comment.
That's a good idea to cover all the cases where it could be flat. Updated this and the check for tklass as well accordingly.
| (orig_t == nullptr || (!orig_t->is_not_flat() && (!orig_t->is_flat() || orig_t->elem()->inline_klass()->contains_oops()))) && | ||
| // Can dest array be flat and contain oops? | ||
| tklass->can_be_inline_array() && (!tklass->is_flat() || tklass->is_aryklassptr()->elem()->is_instklassptr()->instance_klass()->as_inline_klass()->contains_oops()); | ||
| can_dest_be_value_class_array && (!tklass->is_flat() || tklass->is_aryklassptr()->elem()->is_instklassptr()->instance_klass()->as_inline_klass()->contains_oops()))); |
There was a problem hiding this comment.
This should also check for tklass->is_not_flat() instead.
There was a problem hiding this comment.
I agree. I also took another look at the code again and refactored it a bit to make exclude_flat easier to understand. Let me know, what you think.
| tklass->can_be_inline_array() && (!tklass->is_flat() || tklass->is_aryklassptr()->elem()->is_instklassptr()->instance_klass()->as_inline_klass()->contains_oops()); | ||
| const TypeAryKlassPtr* dest_klass_t = _gvn.type(klass_node)->is_klassptr()->isa_aryklassptr(); | ||
| const bool can_src_be_abstract_flat_value_class_array = orig_t != nullptr && !orig_t->elem()->is_inlinetypeptr() && !orig_t->is_not_flat(); | ||
| const bool can_dest_be_value_class_array = dest_klass_t != nullptr && dest_klass_t->can_be_inline_array(); |
There was a problem hiding this comment.
What if dest is not an aryklassptr? I think in that case this should also be true, right?
| // Can dest array be flat and contain oops? | ||
| tklass->can_be_inline_array() && (!tklass->is_flat() || tklass->is_aryklassptr()->elem()->is_instklassptr()->instance_klass()->as_inline_klass()->contains_oops()); | ||
| const TypeAryKlassPtr* dest_klass_t = _gvn.type(klass_node)->is_klassptr()->isa_aryklassptr(); | ||
| const bool can_src_be_abstract_flat_value_class_array = orig_t != nullptr && !orig_t->elem()->is_inlinetypeptr() && !orig_t->is_not_flat(); |
There was a problem hiding this comment.
This name is a little misleading, I think you want to catch the case orig_t == nullptr below, but if the static type is j.l.O, the runtime type can still be an abstract flat array.
The provided test cases fail when inlining the
Array.copyOf/copyOfRange()intrinsics where the source array is flat and from an abstract value class.The current code checks whether the source array or the destination array klass contain oops by assuming that a flat value class array is always concrete and thus an
InlineKlass(i.e. can callinline_klass()). However, we could also have abstract value class arrays that are known to be flat (see test cases). This leads to a cast assertion failure because abstract value classes are represented by anInstanceKlassand not anInlineKlass.To fix this, I added a simple bailout when detecting an abstract flat value class array. This is a conservative correctness fix and should be revisited again post-Valhalla-integration. We have JDK-8251971 in place for that which should also tackle other issues around the arraycopy intrinsics and also address performance problems.
Thanks,
Christian
Progress
Issue
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/valhalla.git pull/2569/head:pull/2569$ git checkout pull/2569Update a local copy of the PR:
$ git checkout pull/2569$ git pull https://git.openjdk.org/valhalla.git pull/2569/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 2569View PR using the GUI difftool:
$ git pr show -t 2569Using diff file
Download this PR as a diff file:
https://git.openjdk.org/valhalla/pull/2569.diff
Using Webrev
Link to Webrev Comment