2165 }
2166 while (ParCompactionManager::steal(worker_id, obj)) {
2167 cm->follow_contents(obj);
2168 cm->follow_marking_stacks();
2169 }
2170 } while (!terminator.offer_termination());
2171 }
2172
2173 class MarkFromRootsTask : public AbstractGangTask {
2174 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2175 StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do
2176 SequentialSubTasksDone _subtasks;
2177 TaskTerminator _terminator;
2178 uint _active_workers;
2179
2180 public:
2181 MarkFromRootsTask(uint active_workers) :
2182 AbstractGangTask("MarkFromRootsTask"),
2183 _strong_roots_scope(active_workers),
2184 _subtasks(),
2185 _terminator(active_workers, ParCompactionManager::stack_array()),
2186 _active_workers(active_workers) {
2187 _subtasks.set_n_threads(active_workers);
2188 _subtasks.set_n_tasks(ParallelRootType::sentinel);
2189 }
2190
2191 virtual void work(uint worker_id) {
2192 for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) {
2193 mark_from_roots_work(static_cast<ParallelRootType::Value>(task), worker_id);
2194 }
2195 _subtasks.all_tasks_completed();
2196
2197 PCAddThreadRootsMarkingTaskClosure closure(worker_id);
2198 Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
2199
2200 if (_active_workers > 1) {
2201 steal_marking_work(_terminator, worker_id);
2202 }
2203 }
2204 };
2205
2206 class PCRefProcTask : public AbstractGangTask {
2207 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2208 ProcessTask& _task;
2209 uint _ergo_workers;
2210 TaskTerminator _terminator;
2211
2212 public:
2213 PCRefProcTask(ProcessTask& task, uint ergo_workers) :
2214 AbstractGangTask("PCRefProcTask"),
2215 _task(task),
2216 _ergo_workers(ergo_workers),
2217 _terminator(_ergo_workers, ParCompactionManager::stack_array()) {
2218 }
2219
2220 virtual void work(uint worker_id) {
2221 ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
2222 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
2223
2224 ParCompactionManager* cm =
2225 ParCompactionManager::gc_thread_compaction_manager(worker_id);
2226 PCMarkAndPushClosure mark_and_push_closure(cm);
2227 ParCompactionManager::FollowStackClosure follow_stack_closure(cm);
2228 _task.work(worker_id, *PSParallelCompact::is_alive_closure(),
2229 mark_and_push_closure, follow_stack_closure);
2230
2231 steal_marking_work(_terminator, worker_id);
2232 }
2233 };
2234
2235 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor {
2236 void execute(ProcessTask& process_task, uint ergo_workers) {
2237 assert(ParallelScavengeHeap::heap()->workers().active_workers() == ergo_workers,
2613 } else {
2614 if (terminator->offer_termination()) {
2615 break;
2616 }
2617 // Go around again.
2618 }
2619 }
2620 return;
2621 }
2622
2623 class UpdateDensePrefixAndCompactionTask: public AbstractGangTask {
2624 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2625 TaskQueue& _tq;
2626 TaskTerminator _terminator;
2627 uint _active_workers;
2628
2629 public:
2630 UpdateDensePrefixAndCompactionTask(TaskQueue& tq, uint active_workers) :
2631 AbstractGangTask("UpdateDensePrefixAndCompactionTask"),
2632 _tq(tq),
2633 _terminator(active_workers, ParCompactionManager::region_array()),
2634 _active_workers(active_workers) {
2635 }
2636 virtual void work(uint worker_id) {
2637 ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id);
2638
2639 for (PSParallelCompact::UpdateDensePrefixTask task; _tq.try_claim(task); /* empty */) {
2640 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm,
2641 task._space_id,
2642 task._region_index_start,
2643 task._region_index_end);
2644 }
2645
2646 // Once a thread has drained it's stack, it should try to steal regions from
2647 // other threads.
2648 compaction_with_stealing_work(&_terminator, worker_id);
2649 }
2650 };
2651
2652 void PSParallelCompact::compact() {
2653 GCTraceTime(Info, gc, phases) tm("Compaction Phase", &_gc_timer);
|
2165 }
2166 while (ParCompactionManager::steal(worker_id, obj)) {
2167 cm->follow_contents(obj);
2168 cm->follow_marking_stacks();
2169 }
2170 } while (!terminator.offer_termination());
2171 }
2172
2173 class MarkFromRootsTask : public AbstractGangTask {
2174 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2175 StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do
2176 SequentialSubTasksDone _subtasks;
2177 TaskTerminator _terminator;
2178 uint _active_workers;
2179
2180 public:
2181 MarkFromRootsTask(uint active_workers) :
2182 AbstractGangTask("MarkFromRootsTask"),
2183 _strong_roots_scope(active_workers),
2184 _subtasks(),
2185 _terminator(active_workers, ParCompactionManager::oop_task_queues()),
2186 _active_workers(active_workers) {
2187 _subtasks.set_n_threads(active_workers);
2188 _subtasks.set_n_tasks(ParallelRootType::sentinel);
2189 }
2190
2191 virtual void work(uint worker_id) {
2192 for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) {
2193 mark_from_roots_work(static_cast<ParallelRootType::Value>(task), worker_id);
2194 }
2195 _subtasks.all_tasks_completed();
2196
2197 PCAddThreadRootsMarkingTaskClosure closure(worker_id);
2198 Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
2199
2200 if (_active_workers > 1) {
2201 steal_marking_work(_terminator, worker_id);
2202 }
2203 }
2204 };
2205
2206 class PCRefProcTask : public AbstractGangTask {
2207 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2208 ProcessTask& _task;
2209 uint _ergo_workers;
2210 TaskTerminator _terminator;
2211
2212 public:
2213 PCRefProcTask(ProcessTask& task, uint ergo_workers) :
2214 AbstractGangTask("PCRefProcTask"),
2215 _task(task),
2216 _ergo_workers(ergo_workers),
2217 _terminator(_ergo_workers, ParCompactionManager::oop_task_queues()) {
2218 }
2219
2220 virtual void work(uint worker_id) {
2221 ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
2222 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
2223
2224 ParCompactionManager* cm =
2225 ParCompactionManager::gc_thread_compaction_manager(worker_id);
2226 PCMarkAndPushClosure mark_and_push_closure(cm);
2227 ParCompactionManager::FollowStackClosure follow_stack_closure(cm);
2228 _task.work(worker_id, *PSParallelCompact::is_alive_closure(),
2229 mark_and_push_closure, follow_stack_closure);
2230
2231 steal_marking_work(_terminator, worker_id);
2232 }
2233 };
2234
2235 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor {
2236 void execute(ProcessTask& process_task, uint ergo_workers) {
2237 assert(ParallelScavengeHeap::heap()->workers().active_workers() == ergo_workers,
2613 } else {
2614 if (terminator->offer_termination()) {
2615 break;
2616 }
2617 // Go around again.
2618 }
2619 }
2620 return;
2621 }
2622
2623 class UpdateDensePrefixAndCompactionTask: public AbstractGangTask {
2624 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
2625 TaskQueue& _tq;
2626 TaskTerminator _terminator;
2627 uint _active_workers;
2628
2629 public:
2630 UpdateDensePrefixAndCompactionTask(TaskQueue& tq, uint active_workers) :
2631 AbstractGangTask("UpdateDensePrefixAndCompactionTask"),
2632 _tq(tq),
2633 _terminator(active_workers, ParCompactionManager::region_task_queues()),
2634 _active_workers(active_workers) {
2635 }
2636 virtual void work(uint worker_id) {
2637 ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id);
2638
2639 for (PSParallelCompact::UpdateDensePrefixTask task; _tq.try_claim(task); /* empty */) {
2640 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm,
2641 task._space_id,
2642 task._region_index_start,
2643 task._region_index_end);
2644 }
2645
2646 // Once a thread has drained it's stack, it should try to steal regions from
2647 // other threads.
2648 compaction_with_stealing_work(&_terminator, worker_id);
2649 }
2650 };
2651
2652 void PSParallelCompact::compact() {
2653 GCTraceTime(Info, gc, phases) tm("Compaction Phase", &_gc_timer);
|