RFR: 8320308: C2 compilation crashes in LibraryCallKit::inline_unsafe_access
Roland Westrelin
roland at openjdk.org
Thu Sep 5 12:38:52 UTC 2024
On Mon, 26 Aug 2024 12:34:57 GMT, Roland Westrelin <roland at openjdk.org> wrote:
>> We failed in `LibraryCallKit::inline_unsafe_access()` while trying to inline `Unsafe::getShortUnaligned`.
>> https://github.com/openjdk/jdk/blob/34c6e0deac567c0f4ed08aa2824671551d843e95/test/hotspot/jtreg/compiler/parsing/TestUnsafeArrayAccessWithNullBase.java#L86
>> The reason is that base (the array) is `ConP #null` hidden behind two `CheckCastPP` with `speculative=byte[int:>=0]`
>>
>> We call `Node* adr = make_unsafe_address(base, offset, type, kind == Relaxed);`
>> https://github.com/openjdk/jdk/blob/34c6e0deac567c0f4ed08aa2824671551d843e95/src/hotspot/share/opto/library_call.cpp#L2361
>> - with **base** = `147 CheckCastPP`
>> - `118 ConP === 0 [[[ 106 101 71 ] #null`
>> <img width="470" alt="type" src="https://github.com/user-attachments/assets/cbe5497e-cb0c-4f8e-a5d5-7a6ee1157778">
>>
>> Depending on the **offset** we go two different paths in `LibraryCallKit::make_unsafe_address` which both lead to the same error in the end.
>> 1. For `UNSAFE.getShortUnaligned(array, 1_049_000)` we get kind = `Type::AnyPtr` because `offset >= os::vm_page_size()`. Since we assume base can't be null we insert an assert:
>> https://github.com/openjdk/jdk/blob/34c6e0deac567c0f4ed08aa2824671551d843e95/src/hotspot/share/opto/library_call.cpp#L2111
>>
>> 2. whereas for `UNSAFE.getShortUnaligned(array, 1)` we get kind = `Type:: OopPtr`
>> https://github.com/openjdk/jdk/blob/c17fa910cf3bad48547a3f0d68a30795ec3194e6/src/hotspot/share/opto/library_call.cpp#L2078
>> and insert a null check
>> https://github.com/openjdk/jdk/blob/34c6e0deac567c0f4ed08aa2824671551d843e95/src/hotspot/share/opto/library_call.cpp#L2090
>> In both cases we return call `basic_plus_adr(..)` on a base being `top()` which returns **adr** = `1 Con === 0 [[ ]] #top`
>>
>> https://github.com/openjdk/jdk/blob/3d5d51e228c19aa216451f647023101ae8bdbc79/src/hotspot/share/opto/library_call.cpp#L2386 => `_gvn.type(adr)` is _top_
>>
>> https://github.com/openjdk/jdk/blob/3d5d51e228c19aa216451f647023101ae8bdbc79/src/hotspot/share/opto/library_call.cpp#L2394 => `adr_type` is _nullptr_
>>
>> https://github.com/openjdk/jdk/blob/3d5d51e228c19aa216451f647023101ae8bdbc79/src/hotspot/share/opto/library_call.cpp#L2405-L2406 => `BasicType bt` is _T_ILLEGAL_
>>
>> https://github.com/openjdk/jdk/blob/3d5d51e228c19aa216451f647023101ae8bdbc79/src/hotspot/share/opto/library_call.cpp#L2424 => we fail here with `SIGSEGV: null pointer dereference` because `alias_type->adr_type()` is _nullptr_
>>
>> ### Fix
>> the fix is to bailed out in ...
>
> Thanks for the extra details.
> Is igvn run between incremental inlining and the crash? Or is that all part of a single incremental inlining sequence?
> In `LibraryCallKit::make_unsafe_address`, `base` is the `CheckCastPP`. What I don't quite understand is how we can get `top` out of `basic_plus_adr` if the `base` input is a `CheckCastPP`.
> It doesn't look like `NULL_PTR` is affected (since `TypePtr::cleanup_speculative()` unconditionally drops speculative part for it), but `Type*::BOTTOM`/`Type*::NOTNULL` et all seem susceptible to the problem. @rwestrel, what do you think?
Something like:
TypePtr::NOTNULL == ptr
would indeed be a problem. So it would make sense to go over the uses of `Type*::BOTTOM`/`Type*::NOTNULL` and check they are not tested with pointer equality. Is that one what you're suggesting, Vladimir?
-------------
PR Comment: https://git.openjdk.org/jdk/pull/20033#issuecomment-2331470042
More information about the hotspot-compiler-dev
mailing list