aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/gc_implementation
diff options
context:
space:
mode:
authoriveresov <none@none>2009-05-18 11:52:46 -0700
committeriveresov <none@none>2009-05-18 11:52:46 -0700
commitaf04ae94d44d26870ca8c8d8cebe8d04c64dac34 (patch)
tree882598c34c566388ba3019f5c04eea76024d448e /src/share/vm/gc_implementation
parent61f88286798fc89e45933802eb20edf19843d77a (diff)
downloadjdk8u_hotspot-af04ae94d44d26870ca8c8d8cebe8d04c64dac34.tar.gz
6841831: G1: assert(contains_reference(from),"We just added it!") fires
Summary: During parallel rset updating we have to make sure that the worker ids of the refinement threads do not intersect with the worker ids that can be claimed by the mutator threads. Reviewed-by: tonyp
Diffstat (limited to 'src/share/vm/gc_implementation')
-rw-r--r--src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp12
-rw-r--r--src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp3
-rw-r--r--src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp6
-rw-r--r--src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp4
-rw-r--r--src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp6
-rw-r--r--src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp7
-rw-r--r--src/share/vm/gc_implementation/includeDB_gc_g11
7 files changed, 26 insertions, 13 deletions
diff --git a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
index 2e58f40ad..89f2be956 100644
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
@@ -33,12 +33,13 @@ ConcurrentG1Refine::ConcurrentG1Refine() :
_threads(NULL), _n_threads(0)
{
if (G1ConcRefine) {
- _n_threads = (G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads;
+ _n_threads = (int)thread_num();
if (_n_threads > 0) {
_threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
+ int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
ConcurrentG1RefineThread *next = NULL;
for (int i = _n_threads - 1; i >= 0; i--) {
- ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, i);
+ ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, worker_id_offset, i);
assert(t != NULL, "Conc refine should have been created");
assert(t->cg1r() == this, "Conc refine thread should refer to this");
_threads[i] = t;
@@ -48,6 +49,13 @@ ConcurrentG1Refine::ConcurrentG1Refine() :
}
}
+size_t ConcurrentG1Refine::thread_num() {
+ if (G1ConcRefine) {
+ return (G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads;
+ }
+ return 0;
+}
+
void ConcurrentG1Refine::init() {
if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
diff --git a/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp b/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
index badd81fb3..830e19ee6 100644
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
@@ -29,7 +29,6 @@ class G1RemSet;
class ConcurrentG1Refine: public CHeapObj {
ConcurrentG1RefineThread** _threads;
int _n_threads;
-
// The cache for card refinement.
bool _use_cache;
bool _def_use_cache;
@@ -86,4 +85,6 @@ class ConcurrentG1Refine: public CHeapObj {
void clear_and_record_card_counts();
void print_final_card_counts();
+
+ static size_t thread_num();
};
diff --git a/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp b/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
index 428a535f6..a97a7c48a 100644
--- a/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
+++ b/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp
@@ -30,8 +30,10 @@
// The CM thread is created when the G1 garbage collector is used
ConcurrentG1RefineThread::
-ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next, int worker_id) :
+ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread *next,
+ int worker_id_offset, int worker_id) :
ConcurrentGCThread(),
+ _worker_id_offset(worker_id_offset),
_worker_id(worker_id),
_active(false),
_next(next),
@@ -114,7 +116,7 @@ void ConcurrentG1RefineThread::run() {
} else {
lower_limit = DCQBarrierProcessCompletedThreshold / 4; // For now.
}
- while (dcqs.apply_closure_to_completed_buffer(_worker_id, lower_limit)) {
+ while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, lower_limit)) {
double end_vtime_sec;
double elapsed_vtime_sec;
int elapsed_vtime_ms;
diff --git a/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp b/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
index 75f45a202..3ab9b1958 100644
--- a/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
+++ b/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp
@@ -34,6 +34,7 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
double _vtime_start; // Initial virtual time.
double _vtime_accum; // Initial virtual time.
int _worker_id;
+ int _worker_id_offset;
// The refinement threads collection is linked list. A predecessor can activate a successor
// when the number of the rset update buffer crosses a certain threshold. A successor
@@ -73,7 +74,8 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
public:
// Constructor
- ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next, int worker_id);
+ ConcurrentG1RefineThread(ConcurrentG1Refine* cg1r, ConcurrentG1RefineThread* next,
+ int worker_id_offset, int worker_id);
// Printing
void print();
diff --git a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
index 373da8b9f..5b0dfba70 100644
--- a/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
+++ b/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
@@ -71,11 +71,11 @@ DirtyCardQueueSet::DirtyCardQueueSet() :
_all_active = true;
}
+// Determines how many mutator threads can process the buffers in parallel.
size_t DirtyCardQueueSet::num_par_ids() {
- return MAX2(ParallelGCThreads, (size_t)2);
+ return os::processor_count();
}
-
void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
int max_completed_queue,
Mutex* lock, PtrQueueSet* fl_owner) {
@@ -85,8 +85,6 @@ void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
_shared_dirty_card_queue.set_lock(lock);
_free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
- bool b = _free_ids->claim_perm_id(0);
- guarantee(b, "Must reserve id zero for concurrent refinement thread.");
}
void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
diff --git a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
index 648a49c30..c4b4c7d9d 100644
--- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
+++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
@@ -1052,10 +1052,11 @@ bool OtherRegionsTable::contains_reference_locked(oop* from) const {
}
+// Determines how many threads can add records to an rset in parallel.
+// This can be done by either mutator threads together with the
+// concurrent refinement threads or GC threads.
int HeapRegionRemSet::num_par_rem_sets() {
- // We always have at least two, so that a mutator thread can claim an
- // id and add to a rem set.
- return (int) MAX2(ParallelGCThreads, (size_t)2);
+ return (int)MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads);
}
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
diff --git a/src/share/vm/gc_implementation/includeDB_gc_g1 b/src/share/vm/gc_implementation/includeDB_gc_g1
index 67f3932be..14c5057e9 100644
--- a/src/share/vm/gc_implementation/includeDB_gc_g1
+++ b/src/share/vm/gc_implementation/includeDB_gc_g1
@@ -282,6 +282,7 @@ heapRegionRemSet.hpp sparsePRT.hpp
heapRegionRemSet.cpp allocation.hpp
heapRegionRemSet.cpp bitMap.inline.hpp
+heapRegionRemSet.cpp concurrentG1Refine.hpp
heapRegionRemSet.cpp g1BlockOffsetTable.inline.hpp
heapRegionRemSet.cpp g1CollectedHeap.inline.hpp
heapRegionRemSet.cpp heapRegionRemSet.hpp