hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp
changeset 25491 70fb742e40aa
parent 25490 59f226da8d81
child 25492 d27050bdfb04
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp	Mon Jul 07 10:12:40 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp	Mon Jul 07 12:37:11 2014 +0200
@@ -285,6 +285,37 @@
   _par_closures[i] = par_closure;
 }
 
+void SATBMarkQueueSet::iterate_closure_all_threads() {
+  for(JavaThread* t = Threads::first(); t; t = t->next()) {
+    t->satb_mark_queue().apply_closure_and_empty(_closure);
+  }
+  shared_satb_queue()->apply_closure_and_empty(_closure);
+}
+
+void SATBMarkQueueSet::par_iterate_closure_all_threads(uint worker) {
+  SharedHeap* sh = SharedHeap::heap();
+  int parity = sh->strong_roots_parity();
+
+  for(JavaThread* t = Threads::first(); t; t = t->next()) {
+    if (t->claim_oops_do(true, parity)) {
+      t->satb_mark_queue().apply_closure_and_empty(_par_closures[worker]);
+    }
+  }
+
+  // We also need to claim the VMThread so that its parity is updated
+  // otherwise the next call to Thread::possibly_parallel_oops_do inside
+  // a StrongRootsScope might skip the VMThread because it has a stale
+  // parity that matches the parity set by the StrongRootsScope
+  //
+  // Whichever worker succeeds in claiming the VMThread gets to do
+  // the shared queue.
+
+  VMThread* vmt = VMThread::vm_thread();
+  if (vmt->claim_oops_do(true, parity)) {
+    shared_satb_queue()->apply_closure_and_empty(_par_closures[worker]);
+  }
+}
+
 bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
                                                               uint worker) {
   BufferNode* nd = NULL;