On Wed, 10 Jun 2026 09:23:54 GMT, Marc Chevalier <[email protected]> wrote:
> The crash happens in the call to `flat_log_elem_size` in > `TypeAryPtr::add_field_offset_and_offset` > > https://github.com/openjdk/valhalla/blob/95bef16235d88773081e16e2093c5c1adca82757/src/hotspot/share/opto/type.cpp#L5796 > > in `flat_log_elem_size` > > https://github.com/openjdk/valhalla/blob/95bef16235d88773081e16e2093c5c1adca82757/src/hotspot/share/opto/type.cpp#L5227-L5229 > > `as_flat_array_klass()` fails with a "bad cast" assert because > `exact_klass()` returns something that is not a flat array. This method uses > `ciObjArrayKlass::make` to find the right kind of array: > > https://github.com/openjdk/valhalla/blob/95bef16235d88773081e16e2093c5c1adca82757/src/hotspot/share/opto/type.cpp#L6822-L6841 > > which then goes to `ciObjArrayKlass::make_impl`, > `ObjArrayKlass::klass_with_properties` and eventually > `ObjArrayKlass::array_layout_selection` that is the source of truth for > selection of array layout (isn't it well-named?!). > > The problem is that in `TypeAryPtr::exact_klass_helper`, the described array > has properties that must be represented by a reference array, and thus > `flat_log_elem_size` fails to find a flat array. But how is that possible!? > From `CheckCastPP` nodes. > > The first `CheckCastPP` to enter the graph comes from `Parse::array_load` -> > `InlineTypeNode::make_from_flat_array`. This one will make some control flow > to split cases whether the array is nullable or not, atomic or not... and for > each branch, insert a cast to the right kind of array before the actual load. > At this step, if a combination is impossible, we should already be able to > detect it. > > The second `CheckCastPP` comes from the intrinsicalization of a flavor of > `newArray` in `LibraryCallKit::inline_newArray`. Eventually, this function > will create an `AllocateArrayNode` with a `CheckCastPPNode` just under. In my > case, because of late inlining, when this node is added, the `CheckCastPP` > nodes from the `array_load` are already there, and all the `CheckCastPPNode` > describes array shapes that `array_layout_selection` would allow. At this > point, the first`CheckCastPP` is an output of the second, because late > inlining managed to rewire the access directly to the allocation. > > The tragedy happens during IGVN: the lower `CheckCastPP` (the first added) > gets a refined type that is the intersection of its own type, and the type of > its input. One type is "null-free /\ atomic-unknown /\ flat" and the other > one is "null-unknown /\ atomic /\ flat". The intersection is "null-free /\ > atomic /\ flat" that is impossibl... Looks good to me. ------------- Marked as reviewed by qamai (Committer). PR Review: https://git.openjdk.org/valhalla/pull/2534#pullrequestreview-4467107817
