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...

LGTM

-------------

Marked as reviewed by fparain (Committer).

PR Review: 
https://git.openjdk.org/valhalla/pull/2534#pullrequestreview-4470860557

Reply via email to