--- a/src/hotspot/share/runtime/java.cpp Mon May 06 18:07:55 2019 -0700
+++ b/src/hotspot/share/runtime/java.cpp Mon May 06 21:23:23 2019 -0400
@@ -526,11 +526,31 @@
vm_direct_exit(code);
}
+ // We'd like to add an entry to the XML log to show that the VM is
+ // terminating, but we can't safely do that here. The logic to make
+ // XML termination logging safe is tied to the termination of the
+ // VMThread, and it doesn't terminate on this exit path. See 8222534.
+
if (VMThread::vm_thread() != NULL) {
+ if (thread->is_Java_thread()) {
+ // We must be "in_vm" for the code below to work correctly.
+ // Historically there must have been some exit path for which
+ // that was not the case and so we set it explicitly - even
+ // though we no longer know what that path may be.
+ ((JavaThread*)thread)->set_thread_state(_thread_in_vm);
+ }
+
// Fire off a VM_Exit operation to bring VM to a safepoint and exit
VM_Exit op(code);
- if (thread->is_Java_thread())
- ((JavaThread*)thread)->set_thread_state(_thread_in_vm);
+
+ // 4945125 The vm thread comes to a safepoint during exit.
+ // GC vm_operations can get caught at the safepoint, and the
+ // heap is unparseable if they are caught. Grab the Heap_lock
+ // to prevent this. The GC vm_operations will not be able to
+ // queue until after we release it, but we never do that as we
+ // are terminating the VM process.
+ MutexLocker ml(Heap_lock);
+
VMThread::execute(&op);
// should never reach here; but in case something wrong with VM Thread.
vm_direct_exit(code);