230 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
230 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
231 |
231 |
232 ParCompactionManager* cm = |
232 ParCompactionManager* cm = |
233 ParCompactionManager::gc_thread_compaction_manager(which); |
233 ParCompactionManager::gc_thread_compaction_manager(which); |
234 |
234 |
235 |
235 // Drain the stacks that have been preloaded with regions |
236 // If not all threads are active, get a draining stack |
236 // that are ready to fill. |
237 // from the list. Else, just use this threads draining stack. |
|
238 uint which_stack_index; |
|
239 bool use_all_workers = manager->all_workers_active(); |
|
240 if (use_all_workers) { |
|
241 which_stack_index = which; |
|
242 assert(manager->active_workers() == ParallelGCThreads, |
|
243 "all_workers_active has been incorrectly set: " |
|
244 " active %d ParallelGCThreads %u", manager->active_workers(), |
|
245 ParallelGCThreads); |
|
246 } else { |
|
247 which_stack_index = ParCompactionManager::pop_recycled_stack_index(); |
|
248 } |
|
249 |
|
250 cm->set_region_stack_index(which_stack_index); |
|
251 cm->set_region_stack(ParCompactionManager::region_list(which_stack_index)); |
|
252 |
|
253 // Has to drain stacks first because there may be regions on |
|
254 // preloaded onto the stack and this thread may never have |
|
255 // done a draining task. Are the draining tasks needed? |
|
256 |
237 |
257 cm->drain_region_stacks(); |
238 cm->drain_region_stacks(); |
|
239 |
|
240 guarantee(cm->region_stack()->is_empty(), "Not empty"); |
258 |
241 |
259 size_t region_index = 0; |
242 size_t region_index = 0; |
260 int random_seed = 17; |
243 int random_seed = 17; |
261 |
|
262 // If we're the termination task, try 10 rounds of stealing before |
|
263 // setting the termination flag |
|
264 |
244 |
265 while(true) { |
245 while(true) { |
266 if (ParCompactionManager::steal(which, &random_seed, region_index)) { |
246 if (ParCompactionManager::steal(which, &random_seed, region_index)) { |
267 PSParallelCompact::fill_and_update_region(cm, region_index); |
247 PSParallelCompact::fill_and_update_region(cm, region_index); |
268 cm->drain_region_stacks(); |
248 cm->drain_region_stacks(); |
291 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm, |
271 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm, |
292 _space_id, |
272 _space_id, |
293 _region_index_start, |
273 _region_index_start, |
294 _region_index_end); |
274 _region_index_end); |
295 } |
275 } |
296 |
|
297 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) { |
|
298 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
|
299 |
|
300 ParCompactionManager* cm = |
|
301 ParCompactionManager::gc_thread_compaction_manager(which); |
|
302 |
|
303 uint which_stack_index; |
|
304 bool use_all_workers = manager->all_workers_active(); |
|
305 if (use_all_workers) { |
|
306 which_stack_index = which; |
|
307 assert(manager->active_workers() == ParallelGCThreads, |
|
308 "all_workers_active has been incorrectly set: " |
|
309 " active %d ParallelGCThreads %u", manager->active_workers(), |
|
310 ParallelGCThreads); |
|
311 } else { |
|
312 which_stack_index = stack_index(); |
|
313 } |
|
314 |
|
315 cm->set_region_stack(ParCompactionManager::region_list(which_stack_index)); |
|
316 |
|
317 cm->set_region_stack_index(which_stack_index); |
|
318 |
|
319 // Process any regions already in the compaction managers stacks. |
|
320 cm->drain_region_stacks(); |
|
321 |
|
322 assert(cm->region_stack()->is_empty(), "Not empty"); |
|
323 |
|
324 if (!use_all_workers) { |
|
325 // Always give up the region stack. |
|
326 assert(cm->region_stack() == |
|
327 ParCompactionManager::region_list(cm->region_stack_index()), |
|
328 "region_stack and region_stack_index are inconsistent"); |
|
329 ParCompactionManager::push_recycled_stack_index(cm->region_stack_index()); |
|
330 |
|
331 cm->set_region_stack(NULL); |
|
332 cm->set_region_stack_index((uint)max_uintx); |
|
333 } |
|
334 } |
|