src/share/vm/gc_implementation/g1/satbQueue.cpp
Print this page
rev 2691 : [mq]: g1-reference-processing
@@ -27,10 +27,11 @@
#include "gc_implementation/g1/satbQueue.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/sharedHeap.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.hpp"
+#include "runtime/vmThread.hpp"
// This method removes entries from an SATB buffer that will not be
// useful to the concurrent marking threads. An entry is removed if it
// satisfies one of the following conditions:
//
@@ -250,13 +251,22 @@
for(JavaThread* t = Threads::first(); t; t = t->next()) {
if (t->claim_oops_do(true, parity)) {
t->satb_mark_queue().apply_closure(_par_closures[worker]);
}
}
- // We'll have worker 0 do this one.
- if (worker == 0) {
- shared_satb_queue()->apply_closure(_par_closures[0]);
+
+ // 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(_par_closures[worker]);
}
}
bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
int worker) {