comparison src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp @ 794:315a5d70b295

6484957: G1: parallel concurrent refinement 6826318: G1: remove traversal-based refinement code Summary: Removed traversal-based refinement code as it's no longer used. Made the concurrent refinement (queue-based) parallel. Reviewed-by: tonyp
author iveresov
date Mon, 11 May 2009 16:30:56 -0700
parents 25e146966e7c
children 215f81b4d9b3
comparison
equal deleted inserted replaced
758:9b3a41ccc927 794:315a5d70b295
23 */ 23 */
24 24
25 #include "incls/_precompiled.incl" 25 #include "incls/_precompiled.incl"
26 #include "incls/_concurrentG1Refine.cpp.incl" 26 #include "incls/_concurrentG1Refine.cpp.incl"
27 27
28 bool ConcurrentG1Refine::_enabled = false;
29
30 ConcurrentG1Refine::ConcurrentG1Refine() : 28 ConcurrentG1Refine::ConcurrentG1Refine() :
31 _pya(PYA_continue), _last_pya(PYA_continue),
32 _last_cards_during(), _first_traversal(false),
33 _card_counts(NULL), _cur_card_count_histo(NULL), _cum_card_count_histo(NULL), 29 _card_counts(NULL), _cur_card_count_histo(NULL), _cum_card_count_histo(NULL),
34 _hot_cache(NULL), 30 _hot_cache(NULL),
35 _def_use_cache(false), _use_cache(false), 31 _def_use_cache(false), _use_cache(false),
36 _n_periods(0), _total_cards(0), _total_travs(0) 32 _n_periods(0), _total_cards(0), _total_travs(0),
33 _threads(NULL), _n_threads(0)
37 { 34 {
38 if (G1ConcRefine) { 35 if (G1ConcRefine) {
39 _cg1rThread = new ConcurrentG1RefineThread(this); 36 _n_threads = (G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads;
40 assert(cg1rThread() != NULL, "Conc refine should have been created"); 37 if (_n_threads > 0) {
41 assert(cg1rThread()->cg1r() == this, 38 _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
42 "Conc refine thread should refer to this"); 39 ConcurrentG1RefineThread *next = NULL;
43 } else { 40 for (int i = _n_threads - 1; i >= 0; i--) {
44 _cg1rThread = NULL; 41 ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, i);
42 assert(t != NULL, "Conc refine should have been created");
43 assert(t->cg1r() == this, "Conc refine thread should refer to this");
44 _threads[i] = t;
45 next = t;
46 }
47 }
45 } 48 }
46 } 49 }
47 50
48 void ConcurrentG1Refine::init() { 51 void ConcurrentG1Refine::init() {
49 if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) { 52 if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
73 _n_hot = 0; 76 _n_hot = 0;
74 _hot_cache_idx = 0; 77 _hot_cache_idx = 0;
75 } 78 }
76 } 79 }
77 80
81 void ConcurrentG1Refine::stop() {
82 if (_threads != NULL) {
83 for (int i = 0; i < _n_threads; i++) {
84 _threads[i]->stop();
85 }
86 }
87 }
88
78 ConcurrentG1Refine::~ConcurrentG1Refine() { 89 ConcurrentG1Refine::~ConcurrentG1Refine() {
79 if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) { 90 if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
80 assert(_card_counts != NULL, "Logic"); 91 assert(_card_counts != NULL, "Logic");
81 FREE_C_HEAP_ARRAY(unsigned char, _card_counts); 92 FREE_C_HEAP_ARRAY(unsigned char, _card_counts);
82 assert(_cur_card_count_histo != NULL, "Logic"); 93 assert(_cur_card_count_histo != NULL, "Logic");
86 } 97 }
87 if (G1ConcRSLogCacheSize > 0) { 98 if (G1ConcRSLogCacheSize > 0) {
88 assert(_hot_cache != NULL, "Logic"); 99 assert(_hot_cache != NULL, "Logic");
89 FREE_C_HEAP_ARRAY(jbyte*, _hot_cache); 100 FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
90 } 101 }
91 } 102 if (_threads != NULL) {
92 103 for (int i = 0; i < _n_threads; i++) {
93 bool ConcurrentG1Refine::refine() { 104 delete _threads[i];
94 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 105 }
95 unsigned cards_before = g1h->g1_rem_set()->conc_refine_cards(); 106 FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
96 clear_hot_cache(); // Any previous values in this are now invalid. 107 }
97 g1h->g1_rem_set()->concurrentRefinementPass(this); 108 }
98 _traversals++; 109
99 unsigned cards_after = g1h->g1_rem_set()->conc_refine_cards(); 110 void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
100 unsigned cards_during = cards_after-cards_before; 111 if (_threads != NULL) {
101 // If this is the first traversal in the current enabling 112 for (int i = 0; i < _n_threads; i++) {
102 // and we did some cards, or if the number of cards found is decreasing 113 tc->do_thread(_threads[i]);
103 // sufficiently quickly, then keep going. Otherwise, sleep a while. 114 }
104 bool res = 115 }
105 (_first_traversal && cards_during > 0) 116 }
106 || 117
107 (!_first_traversal && cards_during * 3 < _last_cards_during * 2);
108 _last_cards_during = cards_during;
109 _first_traversal = false;
110 return res;
111 }
112
113 void ConcurrentG1Refine::enable() {
114 MutexLocker x(G1ConcRefine_mon);
115 if (!_enabled) {
116 _enabled = true;
117 _first_traversal = true; _last_cards_during = 0;
118 G1ConcRefine_mon->notify_all();
119 }
120 }
121
122 unsigned ConcurrentG1Refine::disable() {
123 MutexLocker x(G1ConcRefine_mon);
124 if (_enabled) {
125 _enabled = false;
126 return _traversals;
127 } else {
128 return 0;
129 }
130 }
131
132 void ConcurrentG1Refine::wait_for_ConcurrentG1Refine_enabled() {
133 G1ConcRefine_mon->lock();
134 while (!_enabled) {
135 G1ConcRefine_mon->wait(Mutex::_no_safepoint_check_flag);
136 }
137 G1ConcRefine_mon->unlock();
138 _traversals = 0;
139 };
140
141 void ConcurrentG1Refine::set_pya_restart() {
142 // If we're using the log-based RS barrier, the above will cause
143 // in-progress traversals of completed log buffers to quit early; we will
144 // also abandon all other buffers.
145 if (G1RSBarrierUseQueue) {
146 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
147 dcqs.abandon_logs();
148 // Reset the post-yield actions.
149 _pya = PYA_continue;
150 _last_pya = PYA_continue;
151 } else {
152 _pya = PYA_restart;
153 }
154 }
155
156 void ConcurrentG1Refine::set_pya_cancel() {
157 _pya = PYA_cancel;
158 }
159
160 PostYieldAction ConcurrentG1Refine::get_pya() {
161 if (_pya != PYA_continue) {
162 jint val = _pya;
163 while (true) {
164 jint val_read = Atomic::cmpxchg(PYA_continue, &_pya, val);
165 if (val_read == val) {
166 PostYieldAction res = (PostYieldAction)val;
167 assert(res != PYA_continue, "Only the refine thread should reset.");
168 _last_pya = res;
169 return res;
170 } else {
171 val = val_read;
172 }
173 }
174 }
175 // QQQ WELL WHAT DO WE RETURN HERE???
176 // make up something!
177 return PYA_continue;
178 }
179
180 PostYieldAction ConcurrentG1Refine::get_last_pya() {
181 PostYieldAction res = _last_pya;
182 _last_pya = PYA_continue;
183 return res;
184 }
185
186 bool ConcurrentG1Refine::do_traversal() {
187 return _cg1rThread->do_traversal();
188 }
189 118
190 int ConcurrentG1Refine::add_card_count(jbyte* card_ptr) { 119 int ConcurrentG1Refine::add_card_count(jbyte* card_ptr) {
191 size_t card_num = (card_ptr - _ct_bot); 120 size_t card_num = (card_ptr - _ct_bot);
192 guarantee(0 <= card_num && card_num < _n_card_counts, "Bounds"); 121 guarantee(0 <= card_num && card_num < _n_card_counts, "Bounds");
193 unsigned char cnt = _card_counts[card_num]; 122 unsigned char cnt = _card_counts[card_num];