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