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