src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp

Thu, 22 Sep 2011 10:57:37 -0700

author
johnc
date
Thu, 22 Sep 2011 10:57:37 -0700
changeset 3175
4dfb2df418f2
parent 3115
c2bf0120ee5d
child 5194
eda078b01c65
permissions
-rw-r--r--

6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp

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

mercurial