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 class_loader_data = 9, 102 code_cache = 10 103 }; 104 private: 105 RootType _root_type; 106 public: 107 MarkFromRootsTask(RootType value) : _root_type(value) {} 108 109 char* name() { return (char *)"mark-from-roots-task"; } 110 111 virtual void do_it(GCTaskManager* manager, uint which); 112 }; 113 114 // 115 // RefProcTaskProxy 116 // 117 // This task is used as a proxy to parallel reference processing tasks . 118 // 119 120 class RefProcTaskProxy : public GCTask { 121 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; 122 ProcessTask & _rp_task; 123 uint _work_id; 124 public: 125 RefProcTaskProxy(ProcessTask & rp_task, uint work_id) 126 : _rp_task(rp_task), 127 _work_id(work_id) 128 { } 129 130 private: 131 virtual char* name() { return (char *)"Process referents by policy in parallel"; } 132 133 virtual void do_it(GCTaskManager* manager, uint which); 134 }; 135 136 137 138 // 139 // RefEnqueueTaskProxy 140 // 141 // This task is used as a proxy to parallel reference processing tasks . 142 // 143 144 class RefEnqueueTaskProxy: public GCTask { 145 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; 146 EnqueueTask& _enq_task; 147 uint _work_id; 148 149 public: 150 RefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id) 151 : _enq_task(enq_task), 152 _work_id(work_id) 153 { } 154 155 virtual char* name() { return (char *)"Enqueue reference objects in parallel"; } 156 virtual void do_it(GCTaskManager* manager, uint which) 157 { 158 _enq_task.work(_work_id); 159 } 160 }; 161 162 163 // 164 // RefProcTaskExecutor 165 // 166 // Task executor is an interface for the reference processor to run 167 // tasks using GCTaskManager. 168 // 169 170 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor { 171 virtual void execute(ProcessTask& task); 172 virtual void execute(EnqueueTask& task); 173 }; 174 175 176 // 177 // StealMarkingTask 178 // 179 // This task is used to distribute work to idle threads. 180 // 181 182 class StealMarkingTask : public GCTask { 183 private: 184 ParallelTaskTerminator* const _terminator; 185 private: 186 187 public: 188 char* name() { return (char *)"steal-marking-task"; } 189 190 StealMarkingTask(ParallelTaskTerminator* t); 191 192 ParallelTaskTerminator* terminator() { return _terminator; } 193 194 virtual void do_it(GCTaskManager* manager, uint which); 195 }; 196 197 // 198 // StealRegionCompactionTask 199 // 200 // This task is used to distribute work to idle threads. 201 // 202 203 class StealRegionCompactionTask : public GCTask { 204 private: 205 ParallelTaskTerminator* const _terminator; 206 public: 207 StealRegionCompactionTask(ParallelTaskTerminator* t); 208 209 char* name() { return (char *)"steal-region-task"; } 210 ParallelTaskTerminator* terminator() { return _terminator; } 211 212 virtual void do_it(GCTaskManager* manager, uint which); 213 }; 214 215 // 216 // UpdateDensePrefixTask 217 // 218 // This task is used to update the dense prefix 219 // of a space. 220 // 221 222 class UpdateDensePrefixTask : public GCTask { 223 private: 224 PSParallelCompact::SpaceId _space_id; 225 size_t _region_index_start; 226 size_t _region_index_end; 227 228 public: 229 char* name() { return (char *)"update-dense_prefix-task"; } 230 231 UpdateDensePrefixTask(PSParallelCompact::SpaceId space_id, 232 size_t region_index_start, 233 size_t region_index_end); 234 235 virtual void do_it(GCTaskManager* manager, uint which); 236 }; 237 238 // 239 // DrainStacksCompactionTask 240 // 241 // This task processes regions that have been added to the stacks of each 242 // compaction manager. 243 // 244 // Trying to use one draining thread does not work because there are no 245 // guarantees about which task will be picked up by which thread. For example, 246 // if thread A gets all the preloaded regions, thread A may not get a draining 247 // task (they may all be done by other threads). 248 // 249 250 class DrainStacksCompactionTask : public GCTask { 251 uint _stack_index; 252 uint stack_index() { return _stack_index; } 253 public: 254 DrainStacksCompactionTask(uint stack_index) : GCTask(), 255 _stack_index(stack_index) {}; 256 char* name() { return (char *)"drain-region-task"; } 257 virtual void do_it(GCTaskManager* manager, uint which); 258 }; 259 260 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PCTASKS_HPP