--- old/src/share/vm/logging/logTag.hpp Mon Jul 31 10:00:12 2017 +++ new/src/share/vm/logging/logTag.hpp Mon Jul 31 10:00:11 2017 @@ -142,6 +142,7 @@ LOG_TAG(verification) \ LOG_TAG(verify) \ LOG_TAG(vmoperation) \ + LOG_TAG(vmthread) \ LOG_TAG(vtables) \ LOG_TAG(workgang) \ LOG_TAG_LIST_EXT --- old/src/share/vm/runtime/synchronizer.cpp Mon Jul 31 10:00:13 2017 +++ new/src/share/vm/runtime/synchronizer.cpp Mon Jul 31 10:00:13 2017 @@ -1670,7 +1670,7 @@ // process the same monitor lists concurrently. // // See also ParallelSPCleanupTask and -// SafepointSynchronizer::do_cleanup_tasks() in safepoint.cpp and +// SafepointSynchronize::do_cleanup_tasks() in safepoint.cpp and // Threads::parallel_java_threads_do() in thread.cpp. int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp, ObjectMonitor** freeHeadp, --- old/src/share/vm/runtime/thread.cpp Mon Jul 31 10:00:14 2017 +++ new/src/share/vm/runtime/thread.cpp Mon Jul 31 10:00:14 2017 @@ -3392,6 +3392,13 @@ tc->do_thread(p); } } + // Thread claiming protocol requires us to claim the same interesting + // threads on all paths. Notably, Threads::possibly_parallel_threads_do + // claims all Java threads *and* the VMThread. To avoid breaking the + // claiming protocol, we have to claim VMThread on this path too, even + // if we do not apply the closure to the VMThread. + VMThread* vmt = VMThread::vm_thread(); + (void)vmt->claim_oops_do(true, cp); } // The system initialization in the library has three phases. @@ -4357,6 +4364,10 @@ assert((thread_parity == _thread_claim_parity), "Thread " PTR_FORMAT " has incorrect parity %d != %d", p2i(p), thread_parity, _thread_claim_parity); } + VMThread* vmt = VMThread::vm_thread(); + const int thread_parity = vmt->oops_do_parity(); + assert((thread_parity == _thread_claim_parity), + "VMThread " PTR_FORMAT " has incorrect parity %d != %d", p2i(vmt), thread_parity, _thread_claim_parity); } #endif // ASSERT --- old/src/share/vm/runtime/vmThread.cpp Mon Jul 31 10:00:16 2017 +++ new/src/share/vm/runtime/vmThread.cpp Mon Jul 31 10:00:15 2017 @@ -25,6 +25,8 @@ #include "precompiled.hpp" #include "compiler/compileBroker.hpp" #include "gc/shared/collectedHeap.hpp" +#include "logging/log.hpp" +#include "logging/logConfiguration.hpp" #include "memory/resourceArea.hpp" #include "oops/method.hpp" #include "oops/oop.inline.hpp" @@ -484,6 +486,7 @@ // If we are at a safepoint we will evaluate all the operations that // follow that also require a safepoint if (_cur_vm_operation->evaluate_at_safepoint()) { + log_debug(vmthread)("Evaluating safepoint VM operation: %s", _cur_vm_operation->name()); _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned @@ -495,6 +498,7 @@ _cur_vm_operation = safepoint_ops; if (_cur_vm_operation != NULL) { do { + log_debug(vmthread)("Evaluating coalesced safepoint VM operation: %s", _cur_vm_operation->name()); // evaluate_operation deletes the op object so we have // to grab the next op now VM_Operation* next = _cur_vm_operation->next(); @@ -532,6 +536,7 @@ SafepointSynchronize::end(); } else { // not a safepoint operation + log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name()); if (TraceLongCompiles) { elapsedTimer t; t.start(); @@ -607,8 +612,9 @@ // to be queued up during a safepoint synchronization. { VMOperationQueue_lock->lock_without_safepoint_check(); + log_debug(vmthread)("Adding VM operation: %s", op->name()); bool ok = _vm_queue->add(op); - op->set_timestamp(os::javaTimeMillis()); + op->set_timestamp(os::javaTimeMillis()); VMOperationQueue_lock->notify(); VMOperationQueue_lock->unlock(); // VM_Operation got skipped