--- 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;