changeset 13407:2b40c29676e0

8185273: Test8004741.java crashes with SIGSEGV in JDK10-hs nightly Summary: Threads::parallel_java_threads_do() needs to call VMThread::claim_oops_do() to avoid causing a parallel GC to miss the VMThread. Reviewed-by: shade, rkennke, kvn, gthornbr
author dcubed
date Mon, 31 Jul 2017 12:37:34 -0700
parents 061ea88a858e
children 90b8a4e5f318
files src/share/vm/logging/logTag.hpp src/share/vm/runtime/synchronizer.cpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/vmThread.cpp
diffstat 4 files changed, 20 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/logging/logTag.hpp	Tue Jul 25 13:28:14 2017 -0400
+++ b/src/share/vm/logging/logTag.hpp	Mon Jul 31 12:37:34 2017 -0700
@@ -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
--- a/src/share/vm/runtime/synchronizer.cpp	Tue Jul 25 13:28:14 2017 -0400
+++ b/src/share/vm/runtime/synchronizer.cpp	Mon Jul 31 12:37:34 2017 -0700
@@ -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,
--- a/src/share/vm/runtime/thread.cpp	Tue Jul 25 13:28:14 2017 -0400
+++ b/src/share/vm/runtime/thread.cpp	Mon Jul 31 12:37:34 2017 -0700
@@ -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
 
--- a/src/share/vm/runtime/vmThread.cpp	Tue Jul 25 13:28:14 2017 -0400
+++ b/src/share/vm/runtime/vmThread.cpp	Mon Jul 31 12:37:34 2017 -0700
@@ -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