53 #include "gc/shared/referencePolicy.hpp" |
53 #include "gc/shared/referencePolicy.hpp" |
54 #include "gc/shared/referenceProcessor.hpp" |
54 #include "gc/shared/referenceProcessor.hpp" |
55 #include "gc/shared/referenceProcessorPhaseTimes.hpp" |
55 #include "gc/shared/referenceProcessorPhaseTimes.hpp" |
56 #include "gc/shared/spaceDecorator.hpp" |
56 #include "gc/shared/spaceDecorator.hpp" |
57 #include "gc/shared/weakProcessor.hpp" |
57 #include "gc/shared/weakProcessor.hpp" |
|
58 #include "gc/shared/workerPolicy.hpp" |
58 #include "logging/log.hpp" |
59 #include "logging/log.hpp" |
59 #include "memory/iterator.inline.hpp" |
60 #include "memory/iterator.inline.hpp" |
60 #include "memory/resourceArea.hpp" |
61 #include "memory/resourceArea.hpp" |
61 #include "memory/universe.hpp" |
62 #include "memory/universe.hpp" |
62 #include "oops/access.inline.hpp" |
63 #include "oops/access.inline.hpp" |
1787 |
1788 |
1788 { |
1789 { |
1789 ResourceMark rm; |
1790 ResourceMark rm; |
1790 HandleMark hm; |
1791 HandleMark hm; |
1791 |
1792 |
|
1793 const uint active_workers = |
|
1794 WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().total_workers(), |
|
1795 ParallelScavengeHeap::heap()->workers().active_workers(), |
|
1796 Threads::number_of_non_daemon_threads()); |
|
1797 ParallelScavengeHeap::heap()->workers().update_active_workers(active_workers); |
|
1798 |
1792 // Set the number of GC threads to be used in this collection |
1799 // Set the number of GC threads to be used in this collection |
1793 gc_task_manager()->set_active_gang(); |
1800 gc_task_manager()->set_active_gang(); |
1794 gc_task_manager()->task_idle_workers(); |
1801 gc_task_manager()->task_idle_workers(); |
1795 |
1802 |
1796 GCTraceCPUTime tcpu; |
1803 GCTraceCPUTime tcpu; |
2084 |
2091 |
2085 public: |
2092 public: |
2086 PCAddThreadRootsMarkingTaskClosure(GCTaskQueue* q) : _q(q) { } |
2093 PCAddThreadRootsMarkingTaskClosure(GCTaskQueue* q) : _q(q) { } |
2087 void do_thread(Thread* t) { |
2094 void do_thread(Thread* t) { |
2088 _q->enqueue(new ThreadRootsMarkingTask(t)); |
2095 _q->enqueue(new ThreadRootsMarkingTask(t)); |
|
2096 } |
|
2097 }; |
|
2098 |
|
2099 static void steal_marking_work(ParallelTaskTerminator& terminator, uint worker_id) { |
|
2100 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
|
2101 |
|
2102 ParCompactionManager* cm = |
|
2103 ParCompactionManager::gc_thread_compaction_manager(worker_id); |
|
2104 |
|
2105 oop obj = NULL; |
|
2106 ObjArrayTask task; |
|
2107 do { |
|
2108 while (ParCompactionManager::steal_objarray(worker_id, task)) { |
|
2109 cm->follow_array((objArrayOop)task.obj(), task.index()); |
|
2110 cm->follow_marking_stacks(); |
|
2111 } |
|
2112 while (ParCompactionManager::steal(worker_id, obj)) { |
|
2113 cm->follow_contents(obj); |
|
2114 cm->follow_marking_stacks(); |
|
2115 } |
|
2116 } while (!terminator.offer_termination()); |
|
2117 } |
|
2118 |
|
2119 class PCRefProcTask : public AbstractGangTask { |
|
2120 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; |
|
2121 ProcessTask& _task; |
|
2122 uint _ergo_workers; |
|
2123 TaskTerminator _terminator; |
|
2124 |
|
2125 public: |
|
2126 PCRefProcTask(ProcessTask& task, uint ergo_workers) : |
|
2127 AbstractGangTask("PCRefProcTask"), |
|
2128 _task(task), |
|
2129 _ergo_workers(ergo_workers), |
|
2130 _terminator(_ergo_workers, ParCompactionManager::stack_array()) { |
|
2131 } |
|
2132 |
|
2133 virtual void work(uint worker_id) { |
|
2134 ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); |
|
2135 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); |
|
2136 |
|
2137 ParCompactionManager* cm = |
|
2138 ParCompactionManager::gc_thread_compaction_manager(worker_id); |
|
2139 PCMarkAndPushClosure mark_and_push_closure(cm); |
|
2140 ParCompactionManager::FollowStackClosure follow_stack_closure(cm); |
|
2141 _task.work(worker_id, *PSParallelCompact::is_alive_closure(), |
|
2142 mark_and_push_closure, follow_stack_closure); |
|
2143 |
|
2144 steal_marking_work(*_terminator.terminator(), worker_id); |
|
2145 } |
|
2146 }; |
|
2147 |
|
2148 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor { |
|
2149 void execute(ProcessTask& process_task, uint ergo_workers) { |
|
2150 assert(ParallelScavengeHeap::heap()->workers().active_workers() == ergo_workers, |
|
2151 "Ergonomically chosen workers (%u) must be equal to active workers (%u)", |
|
2152 ergo_workers, ParallelScavengeHeap::heap()->workers().active_workers()); |
|
2153 |
|
2154 PCRefProcTask task(process_task, ergo_workers); |
|
2155 ParallelScavengeHeap::heap()->workers().run_task(&task); |
2089 } |
2156 } |
2090 }; |
2157 }; |
2091 |
2158 |
2092 void PSParallelCompact::marking_phase(ParCompactionManager* cm, |
2159 void PSParallelCompact::marking_phase(ParCompactionManager* cm, |
2093 bool maximum_heap_compaction, |
2160 bool maximum_heap_compaction, |