< prev index next >
src/share/vm/gc/g1/dirtyCardQueue.cpp
Print this page
rev 13241 : imported patch 8183128-erikd-review
@@ -23,17 +23,36 @@
*/
#include "precompiled.hpp"
#include "gc/g1/dirtyCardQueue.hpp"
#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1RemSet.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/shared/workgroup.hpp"
#include "runtime/atomic.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.inline.hpp"
+// Closure used for updating remembered sets and recording references that
+// point into the collection set while the mutator is running.
+// Assumed to be only executed concurrently with the mutator. Yields via
+// SuspendibleThreadSet after every card.
+class G1RefineCardConcurrentlyClosure: public CardTableEntryClosure {
+public:
+ bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
+ G1CollectedHeap::heap()->g1_rem_set()->refine_card_concurrently(card_ptr, worker_i);
+
+ if (SuspendibleThreadSet::should_yield()) {
+ // Caller will actually yield.
+ return false;
+ }
+ // Otherwise, we finished successfully; return true.
+ return true;
+ }
+};
+
// Represents a set of free small integer ids.
class FreeIdSet : public CHeapObj<mtGC> {
enum {
end_of_list = UINT_MAX,
claimed = UINT_MAX - 1
@@ -110,11 +129,10 @@
}
}
DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
PtrQueueSet(notify_when_complete),
- _mut_process_closure(NULL),
_shared_dirty_card_queue(this, true /* permanent */),
_free_ids(NULL),
_processed_buffers_mut(0), _processed_buffers_rs_thread(0)
{
_all_active = true;
@@ -123,19 +141,17 @@
// Determines how many mutator threads can process the buffers in parallel.
uint DirtyCardQueueSet::num_par_ids() {
return (uint)os::initial_active_processor_count();
}
-void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
- Monitor* cbl_mon,
+void DirtyCardQueueSet::initialize(Monitor* cbl_mon,
Mutex* fl_lock,
int process_completed_threshold,
int max_completed_queue,
Mutex* lock,
DirtyCardQueueSet* fl_owner,
bool init_free_ids) {
- _mut_process_closure = cl;
PtrQueueSet::initialize(cbl_mon,
fl_lock,
process_completed_threshold,
max_completed_queue,
fl_owner);
@@ -190,11 +206,12 @@
bool DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
guarantee(_free_ids != NULL, "must be");
uint worker_i = _free_ids->claim_par_id(); // temporarily claim an id
- bool result = apply_closure_to_buffer(_mut_process_closure, node, true, worker_i);
+ G1RefineCardConcurrentlyClosure cl;
+ bool result = apply_closure_to_buffer(&cl, node, true, worker_i);
_free_ids->release_par_id(worker_i); // release the id
if (result) {
assert_fully_consumed(node, buffer_size());
Atomic::inc(&_processed_buffers_mut);
@@ -224,10 +241,20 @@
}
DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
return nd;
}
+bool DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_i, size_t stop_at) {
+ G1RefineCardConcurrentlyClosure cl;
+ return apply_closure_to_completed_buffer(&cl, worker_i, stop_at, false);
+}
+
+bool DirtyCardQueueSet::apply_closure_during_gc(CardTableEntryClosure* cl, uint worker_i) {
+ assert_at_safepoint(false);
+ return apply_closure_to_completed_buffer(cl, worker_i, 0, true);
+}
+
bool DirtyCardQueueSet::apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
uint worker_i,
size_t stop_at,
bool during_pause) {
assert(!during_pause || stop_at == 0, "Should not leave any completed buffers during a pause");
< prev index next >