1 /* 2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PCTASKS_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PCTASKS_HPP 27 28 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp" 29 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" 30 #include "gc_implementation/parallelScavenge/psTasks.hpp" 31 32 33 // Tasks for parallel compaction of the old generation 34 // 35 // Tasks are created and enqueued on a task queue. The 36 // tasks for parallel old collector for marking objects 37 // are MarkFromRootsTask and ThreadRootsMarkingTask. 38 // 39 // MarkFromRootsTask's are created 40 // with a root group (e.g., jni_handles) and when the do_it() 41 // method of a MarkFromRootsTask is executed, it starts marking 42 // form it's root group. 43 // 44 // ThreadRootsMarkingTask's are created for each Java thread. When 45 // the do_it() method of a ThreadRootsMarkingTask is executed, it 46 // starts marking from the thread's roots. 47 // 48 // The enqueuing of the MarkFromRootsTask and ThreadRootsMarkingTask 49 // do little more than create the task and put it on a queue. The 50 // queue is a GCTaskQueue and threads steal tasks from this GCTaskQueue. 51 // 52 // In addition to the MarkFromRootsTask and ThreadRootsMarkingTask 53 // tasks there are StealMarkingTask tasks. The StealMarkingTask's 54 // steal a reference from the marking stack of another 55 // thread and transitively marks the object of the reference 56 // and internal references. After successfully stealing a reference 57 // and marking it, the StealMarkingTask drains its marking stack 58 // stack before attempting another steal. 59 // 60 // ThreadRootsMarkingTask 61 // 62 // This task marks from the roots of a single thread. This task 63 // enables marking of thread roots in parallel. 64 // 65 66 class ParallelTaskTerminator; 67 68 class ThreadRootsMarkingTask : public GCTask { 69 private: 70 JavaThread* _java_thread; 71 VMThread* _vm_thread; 72 public: 73 ThreadRootsMarkingTask(JavaThread* root) : _java_thread(root), _vm_thread(NULL) {} 74 ThreadRootsMarkingTask(VMThread* root) : _java_thread(NULL), _vm_thread(root) {} 75 76 char* name() { return (char *)"thread-roots-marking-task"; } 77 78 virtual void do_it(GCTaskManager* manager, uint which); 79 }; 80 81 82 // 83 // MarkFromRootsTask 84 // 85 // This task marks from all the roots to all live 86 // objects. 87 // 88 // 89 90 class MarkFromRootsTask : public GCTask { 91 public: 92 enum RootType { 93 universe = 1, 94 jni_handles = 2, 95 threads = 3, 96 object_synchronizer = 4, 97 flat_profiler = 5, 98 management = 6, 99 jvmti = 7, 100 system_dictionary = 8, 101 code_cache = 9 102 }; 103 private: 104 RootType _root_type; 105 public: 106 MarkFromRootsTask(RootType value) : _root_type(value) {} 107 108 char* name() { return (char *)"mark-from-roots-task"; } 109 110 virtual void do_it(GCTaskManager* manager, uint which); 111 }; 112 113 // 114 // RefProcTaskProxy 115 // 116 // This task is used as a proxy to parallel reference processing tasks . 117 // 118 119 class RefProcTaskProxy : public GCTask { 120 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; 121 ProcessTask & _rp_task; 122 uint _work_id; 123 public: 124 RefProcTaskProxy(ProcessTask & rp_task, uint work_id) 125 : _rp_task(rp_task), 126 _work_id(work_id) 127 { } 128 129 private: 130 virtual char* name() { return (char *)"Process referents by policy in parallel"; } 131 132 virtual void do_it(GCTaskManager* manager, uint which); 133 }; 134 135 136 137 // 138 // RefEnqueueTaskProxy 139 // 140 // This task is used as a proxy to parallel reference processing tasks . 141 // 142 143 class RefEnqueueTaskProxy: public GCTask { 144 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; 145 EnqueueTask& _enq_task; 146 uint _work_id; 147 148 public: 149 RefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id) 150 : _enq_task(enq_task), 151 _work_id(work_id) 152 { } 153 154 virtual char* name() { return (char *)"Enqueue reference objects in parallel"; } 155 virtual void do_it(GCTaskManager* manager, uint which) 156 { 157 _enq_task.work(_work_id); 158 } 159 }; 160 161 162 // 163 // RefProcTaskExecutor 164 // 165 // Task executor is an interface for the reference processor to run 166 // tasks using GCTaskManager. 167 // 168 169 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor { 170 virtual void execute(ProcessTask& task); 171 virtual void execute(EnqueueTask& task); 172 }; 173 174 175 // 176 // StealMarkingTask 177 // 178 // This task is used to distribute work to idle threads. 179 // 180 181 class StealMarkingTask : public GCTask { 182 private: 183 ParallelTaskTerminator* const _terminator; 184 private: 185 186 public: 187 char* name() { return (char *)"steal-marking-task"; } 188 189 StealMarkingTask(ParallelTaskTerminator* t); 190 191 ParallelTaskTerminator* terminator() { return _terminator; } 192 193 virtual void do_it(GCTaskManager* manager, uint which); 194 }; 195 196 // 197 // StealRegionCompactionTask 198 // 199 // This task is used to distribute work to idle threads. 200 // 201 202 class StealRegionCompactionTask : public GCTask { 203 private: 204 ParallelTaskTerminator* const _terminator; 205 public: 206 StealRegionCompactionTask(ParallelTaskTerminator* t); 207 208 char* name() { return (char *)"steal-region-task"; } 209 ParallelTaskTerminator* terminator() { return _terminator; } 210 211 virtual void do_it(GCTaskManager* manager, uint which); 212 }; 213 214 // 215 // UpdateDensePrefixTask 216 // 217 // This task is used to update the dense prefix 218 // of a space. 219 // 220 221 class UpdateDensePrefixTask : public GCTask { 222 private: 223 PSParallelCompact::SpaceId _space_id; 224 size_t _region_index_start; 225 size_t _region_index_end; 226 227 public: 228 char* name() { return (char *)"update-dense_prefix-task"; } 229 230 UpdateDensePrefixTask(PSParallelCompact::SpaceId space_id, 231 size_t region_index_start, 232 size_t region_index_end); 233 234 virtual void do_it(GCTaskManager* manager, uint which); 235 }; 236 237 // 238 // DrainStacksCompactionTask 239 // 240 // This task processes regions that have been added to the stacks of each 241 // compaction manager. 242 // 243 // Trying to use one draining thread does not work because there are no 244 // guarantees about which task will be picked up by which thread. For example, 245 // if thread A gets all the preloaded regions, thread A may not get a draining 246 // task (they may all be done by other threads). 247 // 248 249 class DrainStacksCompactionTask : public GCTask { 250 uint _stack_index; 251 uint stack_index() { return _stack_index; } 252 public: 253 DrainStacksCompactionTask(uint stack_index) : GCTask(), 254 _stack_index(stack_index) {}; 255 char* name() { return (char *)"drain-region-task"; } 256 virtual void do_it(GCTaskManager* manager, uint which); 257 }; 258 259 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PCTASKS_HPP