JDK-8297933 added code that relies on lazy initialization of the `TypeAryPtr::_klass` field. However, there are cases when the field is not yet initialized, leading to a null pointer dereference at C2 compilation time.
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f13e88b11b4, pid=3086758, tid=3086774
#
# JRE version: Java(TM) SE Runtime Environment (22.0+26) (build 22-ea+26-2088)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (22-ea+26-2088, mixed mode, sharing, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x5ae1b4] ciKlass::is_subtype_of(ciKlass*)+0xb4
Current CompileTask:
C2:85 12 b TestUninitializedKlassField::test (27 bytes)
Stack: [0x00007f13be74e000,0x00007f13be84f000], sp=0x00007f13be84a860, free space=1010k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x5ae1b4] ciKlass::is_subtype_of(ciKlass*)+0xb4
V [libjvm.so+0xe3e7eb] CmpPNode::sub(Type const*, Type const*) const+0x13b
V [libjvm.so+0xd24c7f] PhaseIterGVN::transform_old(Node*)+0x13f
V [libjvm.so+0xd1f47c] PhaseIterGVN::optimize()+0x6c
V [libjvm.so+0x641d72] Compile::Optimize()+0x1c2
V [libjvm.so+0x643afd] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0xedd
V [libjvm.so+0x56acd1] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x1f1
V [libjvm.so+0x6494b1] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xae1
V [libjvm.so+0x64c558] CompileBroker::compiler_thread_loop()+0x498
V [libjvm.so+0x904868] JavaThread::thread_main_inner() [clone .part.0]+0xb8
V [libjvm.so+0xead2df] Thread::call_run()+0x9f
V [libjvm.so+0xcd12d5] thread_native_entry(Thread*)+0xd5
The issue only reproduces with release builds because additional verification code in Type::meet_helper in debug builds calls klass() which leads to eager initialization of the _klass field. When disabling the verification code, the issue also reproduces with debug builds and we hit:
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/oracle/valhalla/open/src/hotspot/share/opto/type.cpp:6895), pid=3089473, tid=3089490
# Error: assert(this_one->_klass != nullptr && other->_klass != nullptr) failed
#
# JRE version: Java(TM) SE Runtime Environment (22.0) (fastdebug build 22-lworld4ea-2023-11-20-1024510.tobias...)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 22-lworld4ea-2023-11-20-1024510.tobias..., mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x1838e42] TypeAryPtr::is_same_java_type_as_helper(TypeOopPtr const*) const+0x232
Current CompileTask:
C2: 371 29 b TestUninitializedKlassField::test (27 bytes)
Stack: [0x00007f685c628000,0x00007f685c729000], sp=0x00007f685c7243e0, free space=1008k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x1838e42] TypeAryPtr::is_same_java_type_as_helper(TypeOopPtr const*) const+0x232 (type.cpp:6895)
V [libjvm.so+0x1763660] CmpPNode::sub(Type const*, Type const*) const+0x1b0 (type.hpp:1201)
V [libjvm.so+0x1587e0f] PhaseIterGVN::transform_old(Node*)+0x30f (phaseX.cpp:1241)
V [libjvm.so+0x157e8b8] PhaseIterGVN::optimize()+0x88 (phaseX.cpp:1051)
V [libjvm.so+0xa24b2e] Compile::Optimize()+0x1de (compile.cpp:2725)
V [libjvm.so+0xa28d81] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x1b61 (compile.cpp:867)
V [libjvm.so+0x87268b] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x13b (c2compiler.cpp:119)
V [libjvm.so+0xa34750] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x980 (compileBroker.cpp:2285)
V [libjvm.so+0xa35438] CompileBroker::compiler_thread_loop()+0x4a8 (compileBroker.cpp:1946)
V [libjvm.so+0xefa3fc] JavaThread::thread_main_inner()+0xcc (javaThread.cpp:721)
V [libjvm.so+0x1809e8a] Thread::call_run()+0xba (thread.cpp:220)
V [libjvm.so+0x14eff5a] thread_native_entry(Thread*)+0x12a (os_linux.cpp:785)
Thanks to [~mowerfel] for reporting!