--- old/src/hotspot/share/runtime/thread.cpp 2018-03-26 21:44:48.000000000 -0400 +++ new/src/hotspot/share/runtime/thread.cpp 2018-03-26 21:44:48.000000000 -0400 @@ -4256,17 +4256,6 @@ VMThread::destroy(); } - // Remember the Thread that is shutting down the VM because it needs - // to be immune to some of the sanity checks and policies that have - // to happen at VM shutdown time. - VM_Exit::set_shutdown_thread(thread); - - // Clean up ideal graph printers after the VMThread has started - // the final safepoint which will block all the Compiler threads. -#if defined(COMPILER2) && !defined(PRODUCT) - IdealGraphPrinter::clean_up(); -#endif - // Now, all Java threads are gone except daemon threads. Daemon threads // running Java code or in VM are stopped by the Safepoint. However, // daemon threads executing native code are still running. But they @@ -4275,6 +4264,16 @@ VM_Exit::set_vm_exited(); + // Clean up ideal graph printers after the VMThread has started + // the final safepoint which will block all the Compiler threads. + // Note that this Thread has already logically exited so the + // clean_up() function's use of a JavaThreadIteratorWithHandle + // would be a problem except set_vm_exited() has remembered the + // shutdown thread which is granted a policy exception. +#if defined(COMPILER2) && !defined(PRODUCT) + IdealGraphPrinter::clean_up(); +#endif + notify_vm_shutdown(); // We are after VM_Exit::set_vm_exited() so we can't call --- old/src/hotspot/share/runtime/vm_operations.cpp 2018-03-26 21:44:50.000000000 -0400 +++ new/src/hotspot/share/runtime/vm_operations.cpp 2018-03-26 21:44:50.000000000 -0400 @@ -420,12 +420,14 @@ Thread * volatile VM_Exit::_shutdown_thread = NULL; int VM_Exit::set_vm_exited() { + Thread * thr_cur = Thread::current(); - assert(_shutdown_thread == thr_cur, "_shutdown_thread should be current thread"); + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); int num_active = 0; + _shutdown_thread = thr_cur; _vm_exited = true; // global flag for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { if (thr!=thr_cur && thr->thread_state() == _thread_in_native) { @@ -500,11 +502,6 @@ // running in native; the other 6% are quiescent within 250ms (Ultra 80). wait_for_threads_in_native_to_block(); - // Remember the Thread that is shutting down the VM because it needs - // to be immune to some of the sanity checks and policies that have - // to happen at VM shutdown time. - VM_Exit::set_shutdown_thread(Thread::current()); - set_vm_exited(); // cleanup globals resources before exiting. exit_globals() currently --- old/src/hotspot/share/runtime/vm_operations.hpp 2018-03-26 21:44:53.000000000 -0400 +++ new/src/hotspot/share/runtime/vm_operations.hpp 2018-03-26 21:44:53.000000000 -0400 @@ -467,9 +467,8 @@ } static int wait_for_threads_in_native_to_block(); static int set_vm_exited(); - static void set_shutdown_thread(Thread *t) { _shutdown_thread = t; } - static Thread * shutdown_thread() { return _shutdown_thread; } static bool vm_exited() { return _vm_exited; } + static Thread * shutdown_thread() { return _shutdown_thread; } static void block_if_vm_exited() { if (_vm_exited) { wait_if_vm_exited();