JDK-8058737 : CodeCache::find_blob fails with 'unsafe access to zombie method'
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-09-18
  • Updated: 2017-07-26
  • Resolved: 2014-09-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
8u72Fixed 9 b35Fixed
Related Reports
Relates :  
Relates :  
Description
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/opt/jprt/T/P1/060452.tohartma/s/src/share/vm/code/codeCache.cpp:433), pid=31231, tid=139791443117824
#  guarantee(result == NULL || !result->is_zombie() || result->is_locked_by_vm() || is_error_reported()) failed: unsafe access to zombie method
#
# JRE version: Java(TM) SE Runtime Environment (9.0-b30) (build 1.9.0-ea-fastdebug-b30)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (1.9.0-fastdebug-internal-201409170604.tohartma.hotspot compiled mode linux-amd64 )
# Core dump written. Default location: /scratch/local/aurora/sandbox/results/workDir/closed/compiler/6440479/VirtualDispatch/core or core.31231
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x00007f2850118800):  VMThread [stack: 0x00007f23bb3f4000,0x00007f23bb4f5000] [id=31335]

Stack: [0x00007f23bb3f4000,0x00007f23bb4f5000],  sp=0x00007f23bb4f3810,  free space=1022k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x107ed01]  VMError::report_and_die()+0x151;;  VMError::report_and_die()+0x151
V  [libjvm.so+0x738efb]  report_vm_error(char const*, int, char const*, char const*)+0x7b;;  report_vm_error(char const*, int, char const*, char const*)+0x7b
V  [libjvm.so+0x670595]  CodeCache::find_nmethod(void*)+0x95;;  CodeCache::find_nmethod(void*)+0x95
V  [libjvm.so+0x909ac4]  ICStub::finalize()+0xa4;;  ICStub::finalize()+0xa4
V  [libjvm.so+0xf7f1a2]  StubQueue::remove_all()+0xc2;;  StubQueue::remove_all()+0xc2
V  [libjvm.so+0x90a561]  InlineCacheBuffer::update_inline_caches()+0x31;;  InlineCacheBuffer::update_inline_caches()+0x31
V  [libjvm.so+0xeef6c0]  SafepointSynchronize::do_cleanup_tasks()+0x50;;  SafepointSynchronize::do_cleanup_tasks()+0x50
V  [libjvm.so+0xef091c]  SafepointSynchronize::begin()+0x71c;;  SafepointSynchronize::begin()+0x71c
V  [libjvm.so+0x10a6c56]  VMThread::loop()+0x376;;  VMThread::loop()+0x376
V  [libjvm.so+0x10a6fc1]  VMThread::run()+0xb1;;  VMThread::run()+0xb1
V  [libjvm.so+0xdcf082]  java_start(Thread*)+0xf2;;  java_start(Thread*)+0xf2
Comments
The test closed/compiler/6440479/VirtualDispatch.java contains a method 'test' with many virtual calls that change the target during execution. Compilation of this method results in a high number of inline caches being created for the virtual calls. List of events that cause the bug: 1) nmethod [1] is converted to non-entrant. 2) The nmethod is processed by the sweeper. It is still active on the stack and can therefore not yet be converted to zombie. However, the sweeper cleans the inline caches of [1] (see line 553 of 'NMethodSweeper::process_nmethod'). CompiledIC::set_to_clean() creates a transition stub because a mt safe transition to the clean state is not possible (see 'InlineCacheBuffer::create_transition_stub'). Because the StubQueue is full, 'InlineCacheBuffer::new_ic_stub' forces a safepoint to back patch IC stubs and free space in the StubQueue. 3) The safepoint also performs stack scanning and [1] is not found on the stack. 4) 'nmethod::cleanup_inline_caches' continues and finishes. 5) The next traversal of the sweeper converts [1] to zombie (it was not found on the stack during the forced safepoint). 6) A safepoint occurs updating the inline caches of [1]. 'ICStub::finalize' tries to patch the IC but fails because the nmethod is a zombie (guarantee in 'CodeCache::find_blob'). See [2]. Summary: Usually, zombie nmethods do _not_ have an IC stub because the transition from non-entrant to zombie only happens after a safepoint that removes all IC stubs by back patching the corresponding ICs. In this case, a safepoint is triggered _while_ creating an IC stub and this safepoint also performs stack scanning allowing the nmethod to transition to zombie while having an IC stub.
25-09-2014