29 #include "code/codeCache.hpp" |
29 #include "code/codeCache.hpp" |
30 #include "gc/parallel/gcTaskManager.hpp" |
30 #include "gc/parallel/gcTaskManager.hpp" |
31 #include "gc/parallel/parallelScavengeHeap.hpp" |
31 #include "gc/parallel/parallelScavengeHeap.hpp" |
32 #include "gc/parallel/psAdaptiveSizePolicy.hpp" |
32 #include "gc/parallel/psAdaptiveSizePolicy.hpp" |
33 #include "gc/parallel/psClosure.inline.hpp" |
33 #include "gc/parallel/psClosure.inline.hpp" |
|
34 #include "gc/parallel/psCompactionManager.hpp" |
34 #include "gc/parallel/psMarkSweepProxy.hpp" |
35 #include "gc/parallel/psMarkSweepProxy.hpp" |
35 #include "gc/parallel/psParallelCompact.inline.hpp" |
36 #include "gc/parallel/psParallelCompact.inline.hpp" |
36 #include "gc/parallel/psPromotionManager.inline.hpp" |
37 #include "gc/parallel/psPromotionManager.inline.hpp" |
37 #include "gc/parallel/psRootType.hpp" |
38 #include "gc/parallel/psRootType.hpp" |
38 #include "gc/parallel/psScavenge.inline.hpp" |
39 #include "gc/parallel/psScavenge.inline.hpp" |
39 #include "gc/parallel/psTasks.hpp" |
|
40 #include "gc/shared/gcCause.hpp" |
40 #include "gc/shared/gcCause.hpp" |
41 #include "gc/shared/gcHeapSummary.hpp" |
41 #include "gc/shared/gcHeapSummary.hpp" |
42 #include "gc/shared/gcId.hpp" |
42 #include "gc/shared/gcId.hpp" |
43 #include "gc/shared/gcLocker.hpp" |
43 #include "gc/shared/gcLocker.hpp" |
44 #include "gc/shared/gcTimer.hpp" |
44 #include "gc/shared/gcTimer.hpp" |
211 guarantee(_promotion_manager->stacks_empty(), |
211 guarantee(_promotion_manager->stacks_empty(), |
212 "stacks should be empty at this point"); |
212 "stacks should be empty at this point"); |
213 } |
213 } |
214 }; |
214 }; |
215 |
215 |
216 class PSRefProcTaskProxy: public GCTask { |
216 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { |
|
217 virtual void execute(ProcessTask& process_task, uint ergo_workers); |
|
218 }; |
|
219 |
|
220 class PSRefProcTask : public AbstractGangTask { |
217 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; |
221 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; |
218 ProcessTask & _rp_task; |
222 TaskTerminator _terminator; |
219 uint _work_id; |
223 ProcessTask& _task; |
|
224 uint _active_workers; |
|
225 |
220 public: |
226 public: |
221 PSRefProcTaskProxy(ProcessTask & rp_task, uint work_id) |
227 PSRefProcTask(ProcessTask& task, uint active_workers) |
222 : _rp_task(rp_task), |
228 : AbstractGangTask("PSRefProcTask"), |
223 _work_id(work_id) |
229 _terminator(active_workers, PSPromotionManager::stack_array_depth()), |
224 { } |
230 _task(task), |
225 |
231 _active_workers(active_workers) { |
226 private: |
232 } |
227 virtual char* name() { return (char *)"Process referents by policy in parallel"; } |
233 |
228 virtual void do_it(GCTaskManager* manager, uint which); |
234 virtual void work(uint worker_id) { |
|
235 PSPromotionManager* promotion_manager = |
|
236 PSPromotionManager::gc_thread_promotion_manager(worker_id); |
|
237 assert(promotion_manager != NULL, "sanity check"); |
|
238 PSKeepAliveClosure keep_alive(promotion_manager); |
|
239 PSEvacuateFollowersClosure evac_followers(promotion_manager); |
|
240 PSIsAliveClosure is_alive; |
|
241 _task.work(worker_id, is_alive, keep_alive, evac_followers); |
|
242 |
|
243 if (_task.marks_oops_alive() && _active_workers > 1) { |
|
244 steal_work(*_terminator.terminator(), worker_id); |
|
245 } |
|
246 } |
229 }; |
247 }; |
230 |
248 |
231 void PSRefProcTaskProxy::do_it(GCTaskManager* manager, uint which) |
249 void PSRefProcTaskExecutor::execute(ProcessTask& process_task, uint ergo_workers) { |
232 { |
250 PSRefProcTask task(process_task, ergo_workers); |
233 PSPromotionManager* promotion_manager = |
251 ParallelScavengeHeap::heap()->workers().run_task(&task); |
234 PSPromotionManager::gc_thread_promotion_manager(which); |
|
235 assert(promotion_manager != NULL, "sanity check"); |
|
236 PSKeepAliveClosure keep_alive(promotion_manager); |
|
237 PSEvacuateFollowersClosure evac_followers(promotion_manager); |
|
238 PSIsAliveClosure is_alive; |
|
239 _rp_task.work(_work_id, is_alive, keep_alive, evac_followers); |
|
240 } |
|
241 |
|
242 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { |
|
243 virtual void execute(ProcessTask& task, uint ergo_workers); |
|
244 }; |
|
245 |
|
246 void PSRefProcTaskExecutor::execute(ProcessTask& task, uint ergo_workers) |
|
247 { |
|
248 GCTaskQueue* q = GCTaskQueue::create(); |
|
249 GCTaskManager* manager = ParallelScavengeHeap::gc_task_manager(); |
|
250 uint active_workers = manager->active_workers(); |
|
251 |
|
252 assert(active_workers == ergo_workers, |
|
253 "Ergonomically chosen workers (%u) must be equal to active workers (%u)", |
|
254 ergo_workers, active_workers); |
|
255 |
|
256 for(uint i=0; i < active_workers; i++) { |
|
257 q->enqueue(new PSRefProcTaskProxy(task, i)); |
|
258 } |
|
259 TaskTerminator terminator(active_workers, |
|
260 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()); |
|
261 if (task.marks_oops_alive() && active_workers > 1) { |
|
262 for (uint j = 0; j < active_workers; j++) { |
|
263 q->enqueue(new StealTask(terminator.terminator())); |
|
264 } |
|
265 } |
|
266 manager->execute_and_wait(q); |
|
267 } |
252 } |
268 |
253 |
269 // This method contains all heap specific policy for invoking scavenge. |
254 // This method contains all heap specific policy for invoking scavenge. |
270 // PSScavenge::invoke_no_policy() will do nothing but attempt to |
255 // PSScavenge::invoke_no_policy() will do nothing but attempt to |
271 // scavenge. It will not clean up after failed promotions, bail out if |
256 // scavenge. It will not clean up after failed promotions, bail out if |