JDK-8162540 : Crash in C2 escape analysis with assert: "node should be registered"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u161,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-07-26
  • Updated: 2020-09-01
  • Resolved: 2016-07-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u192Fixed 9 b131Fixed
Related Reports
Duplicate :  
Description
hotspot/src/share/vm/opto/escape.cpp:736), pid=29968, tid=30089
#  assert(adr_ptn != __null && adr_ptn->as_Field()->is_oop()) failed: node should be registered

Current thread (0x00007faeec5c4800):  JavaThread "C2 CompilerThread1" daemon [_thread_in_native, id=30089, stack(0x00007f9bad6d5000,0x00007f9bad7d6000)]


Current CompileTask:
C2:1669320 32087       4       org.apache.derby.impl.store.access.heap.HeapController::lockRow (27 bytes)

Stack: [0x00007f9bad6d5000,0x00007f9bad7d6000],  sp=0x00007f9bad7d04a0,  free space=1005k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x16a28a2]  VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x162
V  [libjvm.so+0x16a361f]  VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*)+0x2f
V  [libjvm.so+0xa67a9d]  report_vm_error(char const*, int, char const*, char const*, ...)+0xdd
V  [libjvm.so+0xb80f3d]  ConnectionGraph::add_final_edges(Node*)+0x76d
V  [libjvm.so+0xb89fcc]  ConnectionGraph::compute_escape()+0x5fc
V  [libjvm.so+0xb8b5a5]  ConnectionGraph::do_analysis(Compile*, PhaseIterGVN*)+0x185
V  [libjvm.so+0x9dc0ad]  Compile::Optimize()+0x7bd
V  [libjvm.so+0x9ddaee]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x123e
V  [libjvm.so+0x80ac52]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x2e2
V  [libjvm.so+0x9e9782]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x392
V  [libjvm.so+0x9ea2b1]  CompileBroker::compiler_thread_loop()+0x1f1
V  [libjvm.so+0x16075de]  JavaThread::thread_main_inner()+0x22e
V  [libjvm.so+0x160786e]  JavaThread::run()+0x1ce
V  [libjvm.so+0x1348cf2]  thread_native_entry(Thread*)+0x112
C  [libpthread.so.0+0x7df3]  start_thread+0xc3
Comments
The following change (against jdk8u-dev) fixes it in 8u: diff --git a/src/share/vm/opto/escape.cpp b/src/share/vm/opto/escape.cpp --- a/src/share/vm/opto/escape.cpp +++ b/src/share/vm/opto/escape.cpp @@ -2016,8 +2016,10 @@ // Check for unsafe oop field access for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { int opcode = n->fast_out(i)->Opcode(); - if (opcode == Op_StoreP || opcode == Op_LoadP || - opcode == Op_StoreN || opcode == Op_LoadN) { + if (opcode == Op_StoreP || opcode == Op_StoreN || + opcode == Op_LoadP || opcode == Op_LoadN || + opcode == Op_GetAndSetP || opcode == Op_GetAndSetN || + opcode == Op_CompareAndSwapP || opcode == Op_CompareAndSwapN) { bt = T_OBJECT; (*unsafe) = true; break; @@ -2037,8 +2039,10 @@ // Allocation initialization, ThreadLocal field access, unsafe access for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { int opcode = n->fast_out(i)->Opcode(); - if (opcode == Op_StoreP || opcode == Op_LoadP || - opcode == Op_StoreN || opcode == Op_LoadN) { + if (opcode == Op_StoreP || opcode == Op_StoreN || + opcode == Op_LoadP || opcode == Op_LoadN || + opcode == Op_GetAndSetP || opcode == Op_GetAndSetN || + opcode == Op_CompareAndSwapP || opcode == Op_CompareAndSwapN) { bt = T_OBJECT; break; }
11-05-2018

This bug is present in 8u as well and leads to erroneous code being generated (see JDK-8198543 for details). It's highly recommended to backport the fix to 8u.
11-05-2018

verified by nightly testing
26-07-2017

Comments above indicate that this failure mode is not reproducible in JDK9-hs-comp which means that whatever is tickling this bug is in JDK9-hs. Do we know which change in JDK9-hs is tickling this bug? There is mention of VarHandles intrinsics above, but nothing concrete...
27-07-2016

Prototype fix: http://cr.openjdk.java.net/~thartmann/8162540/webrev.00/
27-07-2016

ILW = Assert in escape analysis, several tests fail, no workaround = MHH = P2
27-07-2016

Able to reproduce with "java/util/logging/LogManager/Configuration/TestConfigurationLock.java" and a recent jdk9/hs build. Not able to reproduce with hs-comp, so this is triggered by a change in main. The assert is triggered by the following field in the connection graph: Field NoEscape(NoEscape) +24 ( 5610 )[ [ ]] 5370 AddP === _ 5610 5610 1498 [[ 5060 6247 ]] Oop:java/lang/Object+24 * [narrow] !jvms: LogManager::initializeGlobalHandlers @ bci:-1 LogManager::access$1800 @ bci:1 LogManager$RootLogger::accessCheckedHandlers @ bci:4 Logger::getHandlers @ bci:1 LogManager::closeHandlers @ bci:1 LogManager::resetLogger @ bci:2 LogManager::resetLoggerContext @ bci:39 The problem is that the field is not marked as "oop" but the address points to "Oop:java/lang/Object+24". The graph looks like this: 4295 EncodeP === _ 1637 [[ 3846 3845 5060 ]] #narrowoop: java/util/concurrent/locks/AbstractQueuedSynchronizer$Node:NotNull:exact * !jvms: ReentrantLock$Sync::tryRelease @ bci:28 AbstractQueuedSynchronizer::release @ bci:2 ReentrantLock::unlock @ bci:5 LogManager::initializeGlobalHandlers @ bci:34 LogManager::access$1800 @ bci:1 LogManager$RootLogger::accessCheckedHandlers @ bci:4 Logger::getHandlers @ bci:1 LogManager::closeHandlers @ bci:1 LogManager::resetLogger @ bci:2 LogManager::resetLoggerContext @ bci:39 2870 EncodeP === _ 619 [[ 2313 6297 5060 ]] #narrowoop: java/util/concurrent/locks/AbstractQueuedSynchronizer$Node:NotNull:exact * !jvms: AbstractOwnableSynchronizer::setExclusiveOwnerThread @ bci:2 ReentrantLock$Sync::nonfairTryAcquire @ bci:24 ReentrantLock$NonfairSync::tryAcquire @ bci:2 AbstractQueuedSynchronizer::acquire @ bci:2 ReentrantLock::lock @ bci:5 LogManager::initializeGlobalHandlers @ bci:19 LogManager::access$1800 @ bci:1 LogManager$RootLogger::accessCheckedHandlers @ bci:4 Logger::getHandlers @ bci:1 LogManager::closeHandlers @ bci:1 LogManager::resetLogger @ bci:2 LogManager::resetLoggerContext @ bci:39 5370 AddP === _ 5610 5610 1498 [[ 5060 6247 ]] Oop:java/lang/Object+24 * [narrow] !jvms: LogManager::initializeGlobalHandlers @ bci:-1 LogManager::access$1800 @ bci:1 LogManager$RootLogger::accessCheckedHandlers @ bci:4 Logger::getHandlers @ bci:1 LogManager::closeHandlers @ bci:1 LogManager::resetLogger @ bci:2 LogManager::resetLoggerContext @ bci:39 5369 Proj === 5609 [[ 5062 6117 6201 6128 5060 6251 5615 6053 5937 ]] #2 Memory: @BotPTR *+bot, idx=Bot; !jvms: LogManager::initializeGlobalHandlers @ bci:-1 LogManager::access$1800 @ bci:1 LogManager$RootLogger::accessCheckedHandlers @ bci:4 Logger::getHandlers @ bci:1 LogManager::closeHandlers @ bci:1 LogManager::resetLogger @ bci:2 LogManager::resetLoggerContext @ bci:39 5368 Region === 5368 5607 5608 [[ 5368 5613 5615 5060 ]] !jvms: LogManager::initializeGlobalHandlers @ bci:-1 LogManager::access$1800 @ bci:1 LogManager$RootLogger::accessCheckedHandlers @ bci:4 Logger::getHandlers @ bci:1 LogManager::closeHandlers @ bci:1 LogManager::resetLogger @ bci:2 LogManager::resetLoggerContext @ bci:39 5060 CompareAndSwapN === 5368 5369 5370 2870 4295 [[ 4696 6191 5374 ]] !jvms: AbstractQueuedSynchronizer::setState @ bci:2 ReentrantLock$Sync::tryRelease @ bci:40 AbstractQueuedSynchronizer::release @ bci:2 ReentrantLock::unlock @ bci:5 LogManager::initializeGlobalHandlers @ bci:74 LogManager::access$1800 @ bci:1 LogManager$RootLogger::accessCheckedHandlers @ bci:4 Logger::getHandlers @ bci:1 LogManager::closeHandlers @ bci:1 LogManager::resetLogger @ bci:2 LogManager::resetLoggerContext @ bci:39 The AddP is used as input to the CompareAndSwapN intrinsic. I think the problem is that ConnectionGraph::is_oop_field() misses the special cases for VarHandles intrinsics emitting unsafe accesses to oop fields.
27-07-2016

Rickard, since you're the JDK9-hs-comp GK for July, please find someone to checkout this integration_blocker.
26-07-2016

Might be related to JDK-8148146 and triggered by recent changes in jdk9/dev because we didn't touch escape analysis recently.
26-07-2016