--- old/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2019-11-03 00:50:42.804220400 +0900 +++ new/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp 2019-11-03 00:50:42.171262600 +0900 @@ -334,8 +334,7 @@ * We are just about to exit the VM, so we will be very aggressive * at this point in order to increase overall success of dumping jfr data: * -* 1. if the thread state is not "_thread_in_vm", we will quick transition -* it to "_thread_in_vm". +* 1. if current thread is JavaThread, thread state need to be set to "_thread_in_vm". * 2. if the thread is the owner of some critical lock(s), unlock them. * * If we end up deadlocking in the attempt of dumping out jfr data, @@ -355,9 +354,7 @@ return false; } - if (thread->is_Java_thread()) { - ((JavaThread*)thread)->set_thread_state(_thread_in_vm); - } + assert(thread->is_Java_thread() && (((JavaThread*)thread)->thread_state() == _thread_in_vm), "invariant"); #ifdef ASSERT Mutex* owned_lock = thread->owned_locks(); @@ -428,7 +425,37 @@ return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0; } -void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) { +class ThreadInVMForJFR : public StackObj { + private: + JavaThread* _jt; + JavaThreadState _original_state; + + public: + + ThreadInVMForJFR(Thread* thread) : _jt(NULL), + _original_state(_thread_max_state) { + if ((thread != NULL) && thread->is_Java_thread()) { + _jt = (JavaThread*)thread; + _original_state = _jt->thread_state(); + _jt->set_thread_state(_thread_in_vm); + } + } + + ~ThreadInVMForJFR() { + if (_jt != NULL) { + _jt->set_thread_state(_original_state); + } + } + +}; + +void JfrEmergencyDump::on_vm_shutdown(Thread* thread, bool exception_handler) { + /* + * if the thread state is not "_thread_in_vm", we will quick transition + * it to "_thread_in_vm" via ThreadInVMForJFR. + */ + ThreadInVMForJFR tiv(thread); + if (!(guard_reentrancy() && prepare_for_emergency_dump())) { return; }