--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Nov 28 09:49:05 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Nov 17 12:40:15 2011 -0800
@@ -2906,8 +2906,10 @@
}
}
-class CSMarkOopClosure: public OopClosure {
- friend class CSMarkBitMapClosure;
+// Closures used by ConcurrentMark::complete_marking_in_collection_set().
+
+class CSetMarkOopClosure: public OopClosure {
+ friend class CSetMarkBitMapClosure;
G1CollectedHeap* _g1h;
CMBitMap* _bm;
@@ -2917,6 +2919,7 @@
int _ms_size;
int _ms_ind;
int _array_increment;
+ int _worker_i;
bool push(oop obj, int arr_ind = 0) {
if (_ms_ind == _ms_size) {
@@ -2957,7 +2960,6 @@
for (int j = arr_ind; j < lim; j++) {
do_oop(aobj->objArrayOopDesc::obj_at_addr<T>(j));
}
-
} else {
obj->oop_iterate(this);
}
@@ -2967,17 +2969,17 @@
}
public:
- CSMarkOopClosure(ConcurrentMark* cm, int ms_size) :
+ CSetMarkOopClosure(ConcurrentMark* cm, int ms_size, int worker_i) :
_g1h(G1CollectedHeap::heap()),
_cm(cm),
_bm(cm->nextMarkBitMap()),
_ms_size(ms_size), _ms_ind(0),
_ms(NEW_C_HEAP_ARRAY(oop, ms_size)),
_array_ind_stack(NEW_C_HEAP_ARRAY(jint, ms_size)),
- _array_increment(MAX2(ms_size/8, 16))
- {}
-
- ~CSMarkOopClosure() {
+ _array_increment(MAX2(ms_size/8, 16)),
+ _worker_i(worker_i) { }
+
+ ~CSetMarkOopClosure() {
FREE_C_HEAP_ARRAY(oop, _ms);
FREE_C_HEAP_ARRAY(jint, _array_ind_stack);
}
@@ -3000,10 +3002,11 @@
if (hr != NULL) {
if (hr->in_collection_set()) {
if (_g1h->is_obj_ill(obj)) {
- _bm->mark((HeapWord*)obj);
- if (!push(obj)) {
- gclog_or_tty->print_cr("Setting abort in CSMarkOopClosure because push failed.");
- set_abort();
+ if (_bm->parMark((HeapWord*)obj)) {
+ if (!push(obj)) {
+ gclog_or_tty->print_cr("Setting abort in CSetMarkOopClosure because push failed.");
+ set_abort();
+ }
}
}
} else {
@@ -3014,19 +3017,19 @@
}
};
-class CSMarkBitMapClosure: public BitMapClosure {
- G1CollectedHeap* _g1h;
- CMBitMap* _bitMap;
- ConcurrentMark* _cm;
- CSMarkOopClosure _oop_cl;
+class CSetMarkBitMapClosure: public BitMapClosure {
+ G1CollectedHeap* _g1h;
+ CMBitMap* _bitMap;
+ ConcurrentMark* _cm;
+ CSetMarkOopClosure _oop_cl;
+ int _worker_i;
+
public:
- CSMarkBitMapClosure(ConcurrentMark* cm, int ms_size) :
+ CSetMarkBitMapClosure(ConcurrentMark* cm, int ms_size, int worker_i) :
_g1h(G1CollectedHeap::heap()),
_bitMap(cm->nextMarkBitMap()),
- _oop_cl(cm, ms_size)
- {}
-
- ~CSMarkBitMapClosure() {}
+ _oop_cl(cm, ms_size, worker_i),
+ _worker_i(worker_i) { }
bool do_bit(size_t offset) {
// convert offset into a HeapWord*
@@ -3048,53 +3051,69 @@
}
};
-
-class CompleteMarkingInCSHRClosure: public HeapRegionClosure {
- CMBitMap* _bm;
- CSMarkBitMapClosure _bit_cl;
+class CompleteMarkingInCSetHRClosure: public HeapRegionClosure {
+ CMBitMap* _bm;
+ CSetMarkBitMapClosure _bit_cl;
+ int _worker_i;
+
enum SomePrivateConstants {
MSSize = 1000
};
- bool _completed;
+
public:
- CompleteMarkingInCSHRClosure(ConcurrentMark* cm) :
+ CompleteMarkingInCSetHRClosure(ConcurrentMark* cm, int worker_i) :
_bm(cm->nextMarkBitMap()),
- _bit_cl(cm, MSSize),
- _completed(true)
- {}
-
- ~CompleteMarkingInCSHRClosure() {}
-
- bool doHeapRegion(HeapRegion* r) {
- if (!r->evacuation_failed()) {
- MemRegion mr = MemRegion(r->bottom(), r->next_top_at_mark_start());
- if (!mr.is_empty()) {
- if (!_bm->iterate(&_bit_cl, mr)) {
- _completed = false;
- return true;
+ _bit_cl(cm, MSSize, worker_i),
+ _worker_i(worker_i) { }
+
+ bool doHeapRegion(HeapRegion* hr) {
+ if (hr->claimHeapRegion(HeapRegion::CompleteMarkCSetClaimValue)) {
+ // The current worker has successfully claimed the region.
+ if (!hr->evacuation_failed()) {
+ MemRegion mr = MemRegion(hr->bottom(), hr->next_top_at_mark_start());
+ if (!mr.is_empty()) {
+ bool done = false;
+ while (!done) {
+ done = _bm->iterate(&_bit_cl, mr);
+ }
}
}
}
return false;
}
-
- bool completed() { return _completed; }
};
-class ClearMarksInHRClosure: public HeapRegionClosure {
- CMBitMap* _bm;
+class SetClaimValuesInCSetHRClosure: public HeapRegionClosure {
+ jint _claim_value;
+
public:
- ClearMarksInHRClosure(CMBitMap* bm): _bm(bm) { }
-
- bool doHeapRegion(HeapRegion* r) {
- if (!r->used_region().is_empty() && !r->evacuation_failed()) {
- MemRegion usedMR = r->used_region();
- _bm->clearRange(r->used_region());
- }
+ SetClaimValuesInCSetHRClosure(jint claim_value) :
+ _claim_value(claim_value) { }
+
+ bool doHeapRegion(HeapRegion* hr) {
+ hr->set_claim_value(_claim_value);
return false;
}
};
+class G1ParCompleteMarkInCSetTask: public AbstractGangTask {
+protected:
+ G1CollectedHeap* _g1h;
+ ConcurrentMark* _cm;
+
+public:
+ G1ParCompleteMarkInCSetTask(G1CollectedHeap* g1h,
+ ConcurrentMark* cm) :
+ AbstractGangTask("Complete Mark in CSet"),
+ _g1h(g1h), _cm(cm) { }
+
+ void work(int worker_i) {
+ CompleteMarkingInCSetHRClosure cmplt(_cm, worker_i);
+ HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_i);
+ _g1h->collection_set_iterate_from(hr, &cmplt);
+ }
+};
+
void ConcurrentMark::complete_marking_in_collection_set() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
@@ -3103,17 +3122,28 @@
return;
}
- int i = 1;
double start = os::elapsedTime();
- while (true) {
- i++;
- CompleteMarkingInCSHRClosure cmplt(this);
- g1h->collection_set_iterate(&cmplt);
- if (cmplt.completed()) break;
+ int n_workers = g1h->workers()->total_workers();
+
+ G1ParCompleteMarkInCSetTask complete_mark_task(g1h, this);
+
+ assert(g1h->check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ g1h->set_par_threads(n_workers);
+ g1h->workers()->run_task(&complete_mark_task);
+ g1h->set_par_threads(0);
+ } else {
+ complete_mark_task.work(0);
}
- ClearMarksInHRClosure clr(nextMarkBitMap());
- g1h->collection_set_iterate(&clr);
+ assert(g1h->check_cset_heap_region_claim_values(HeapRegion::CompleteMarkCSetClaimValue), "sanity");
+
+ // Now reset the claim values in the regions in the collection set.
+ SetClaimValuesInCSetHRClosure set_cv_cl(HeapRegion::InitialClaimValue);
+ g1h->collection_set_iterate(&set_cv_cl);
+
+ assert(g1h->check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
double end_time = os::elapsedTime();
double elapsed_time_ms = (end_time - start) * 1000.0;