-
Bug
-
Resolution: Fixed
-
P2
-
23
-
b16
-
aarch64
-
linux
# Failure analysis
The assert in question, added inJDK-8310524, is too strong. It holds in the vast majority of cases, but there are exceptions due to the GVN transformation at https://github.com/openjdk/jdk/blob/8cb9b479c529c058aee50f83920db650b0c18045/src/hotspot/share/opto/memnode.cpp#L973.
The attached file `graph.png` illustrates the exceptional case identified in this issue. Two inlined method calls produce two LoadNs which merge and are then passed to two DecodeNs. The merging Phi node, separating the LoadNs and DecodeNs, triggers the assert.
The compiler proves that, in the context at the inlining location, the object for the inlined method belongs to one of two possible classes. Inlining both possible method versions (and guarding them with appropriate class checks) is cheap and therefore likely considered a good option by the compiler.
# Original description
Stack: [0x00004000d5c01000,0x00004000d5dff000], sp=0x00004000d5df7d80, free space=2011k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0xc571c8] GraphKit::make_load(Node*, Node*, Type const*, BasicType, int, MemNode::MemOrd, LoadNode::ControlDependency, bool, bool, bool, bool, unsigned char)+0x268 (graphKit.cpp:1567)
V [libjvm.so+0x5d69e0] BarrierSetC2::load_at_resolved(C2Access&, Type const*) const+0x140
V [libjvm.so+0x5d9870] BarrierSetC2::load_at(C2Access&, Type const*) const+0xd0
V [libjvm.so+0xc66db0] GraphKit::access_load_at(Node*, Node*, TypePtr const*, Type const*, BasicType, unsigned long)+0xb0
V [libjvm.so+0x10b1304] LibraryCallKit::inline_unsafe_access(bool, BasicType, LibraryCallKit::AccessKind, bool)+0xb40
V [libjvm.so+0x10d828c] LibraryIntrinsic::generate(JVMState*)+0x18c
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0x74b6c0] CallGenerator::do_late_inline_helper()+0x8d0
V [libjvm.so+0x8e308c] Compile::inline_incrementally_one()+0xd8
V [libjvm.so+0x8e3d40] Compile::inline_incrementally(PhaseIterGVN&)+0x260
V [libjvm.so+0x8e5aac] Compile::Optimize()+0x2bc
V [libjvm.so+0x8e8e4c] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x14c8
V [libjvm.so+0x743e30] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x17c
V [libjvm.so+0x8f4b8c] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x7dc
V [libjvm.so+0x8f5764] CompileBroker::compiler_thread_loop()+0x584
V [libjvm.so+0xd7486c] JavaThread::thread_main_inner()+0xcc
V [libjvm.so+0x15b62b0] Thread::call_run()+0xac
V [libjvm.so+0x13275ac] thread_native_entry(Thread*)+0x12c
C [libpthread.so.0+0x7928] start_thread+0x188
The assert in question, added in
The attached file `graph.png` illustrates the exceptional case identified in this issue. Two inlined method calls produce two LoadNs which merge and are then passed to two DecodeNs. The merging Phi node, separating the LoadNs and DecodeNs, triggers the assert.
The compiler proves that, in the context at the inlining location, the object for the inlined method belongs to one of two possible classes. Inlining both possible method versions (and guarding them with appropriate class checks) is cheap and therefore likely considered a good option by the compiler.
# Original description
Stack: [0x00004000d5c01000,0x00004000d5dff000], sp=0x00004000d5df7d80, free space=2011k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0xc571c8] GraphKit::make_load(Node*, Node*, Type const*, BasicType, int, MemNode::MemOrd, LoadNode::ControlDependency, bool, bool, bool, bool, unsigned char)+0x268 (graphKit.cpp:1567)
V [libjvm.so+0x5d69e0] BarrierSetC2::load_at_resolved(C2Access&, Type const*) const+0x140
V [libjvm.so+0x5d9870] BarrierSetC2::load_at(C2Access&, Type const*) const+0xd0
V [libjvm.so+0xc66db0] GraphKit::access_load_at(Node*, Node*, TypePtr const*, Type const*, BasicType, unsigned long)+0xb0
V [libjvm.so+0x10b1304] LibraryCallKit::inline_unsafe_access(bool, BasicType, LibraryCallKit::AccessKind, bool)+0xb40
V [libjvm.so+0x10d828c] LibraryIntrinsic::generate(JVMState*)+0x18c
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0xa5bf50] Parse::do_call()+0x280
V [libjvm.so+0x138404c] Parse::do_one_bytecode()+0x37c
V [libjvm.so+0x1372dec] Parse::do_one_block()+0x1ec
V [libjvm.so+0x137427c] Parse::do_all_blocks()+0x13c
V [libjvm.so+0x137799c] Parse::Parse(JVMState*, ciMethod*, float)+0x9dc
V [libjvm.so+0x7460d4] ParseGenerator::generate(JVMState*)+0x174
V [libjvm.so+0x74b6c0] CallGenerator::do_late_inline_helper()+0x8d0
V [libjvm.so+0x8e308c] Compile::inline_incrementally_one()+0xd8
V [libjvm.so+0x8e3d40] Compile::inline_incrementally(PhaseIterGVN&)+0x260
V [libjvm.so+0x8e5aac] Compile::Optimize()+0x2bc
V [libjvm.so+0x8e8e4c] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x14c8
V [libjvm.so+0x743e30] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x17c
V [libjvm.so+0x8f4b8c] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x7dc
V [libjvm.so+0x8f5764] CompileBroker::compiler_thread_loop()+0x584
V [libjvm.so+0xd7486c] JavaThread::thread_main_inner()+0xcc
V [libjvm.so+0x15b62b0] Thread::call_run()+0xac
V [libjvm.so+0x13275ac] thread_native_entry(Thread*)+0x12c
C [libpthread.so.0+0x7928] start_thread+0x188
- relates to
-
JDK-8310524 C2: record parser-generated LoadN nodes for IGVN
- Resolved