1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)pcTasks.cpp 1.22 07/06/22 16:49:49 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 *
132 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
133 ParCompactionManager* cm =
134 ParCompactionManager::gc_thread_compaction_manager(which);
135 // cm->allocate_stacks();
136 assert(cm->stacks_have_been_allocated(),
137 "Stack space has not been allocated");
138 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
139 PSParallelCompact::FollowStackClosure follow_stack_closure(cm);
140 _rp_task.work(_work_id, *PSParallelCompact::is_alive_closure(),
141 mark_and_push_closure, follow_stack_closure);
142 }
143
144 //
145 // RefProcTaskExecutor
146 //
147
148 void RefProcTaskExecutor::execute(ProcessTask& task)
149 {
150 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
151 uint parallel_gc_threads = heap->gc_task_manager()->workers();
152 TaskQueueSetSuper* qset = ParCompactionManager::chunk_array();
153 ParallelTaskTerminator terminator(parallel_gc_threads, qset);
154 GCTaskQueue* q = GCTaskQueue::create();
155 for(uint i=0; i<parallel_gc_threads; i++) {
156 q->enqueue(new RefProcTaskProxy(task, i));
157 }
158 if (task.marks_oops_alive()) {
159 if (parallel_gc_threads>1) {
160 for (uint j=0; j<parallel_gc_threads; j++) {
161 q->enqueue(new StealMarkingTask(&terminator));
162 }
163 }
164 }
165 PSParallelCompact::gc_task_manager()->execute_and_wait(q);
166 }
167
168 void RefProcTaskExecutor::execute(EnqueueTask& task)
169 {
170 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
171 uint parallel_gc_threads = heap->gc_task_manager()->workers();
172 GCTaskQueue* q = GCTaskQueue::create();
191
192 ParCompactionManager* cm =
193 ParCompactionManager::gc_thread_compaction_manager(which);
194 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
195
196 oop obj = NULL;
197 int random_seed = 17;
198 while(true) {
199 if (ParCompactionManager::steal(which, &random_seed, obj)) {
200 obj->follow_contents(cm);
201 cm->drain_marking_stacks(&mark_and_push_closure);
202 } else {
203 if (terminator()->offer_termination()) {
204 break;
205 }
206 }
207 }
208 }
209
210 //
211 // StealChunkCompactionTask
212 //
213
214
215 StealChunkCompactionTask::StealChunkCompactionTask(ParallelTaskTerminator* t) :
216 _terminator(t) {};
217
218 void StealChunkCompactionTask::do_it(GCTaskManager* manager, uint which) {
219 assert(Universe::heap()->is_gc_active(), "called outside gc");
220
221 NOT_PRODUCT(TraceTime tm("StealChunkCompactionTask",
222 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
223
224 ParCompactionManager* cm =
225 ParCompactionManager::gc_thread_compaction_manager(which);
226
227 // Has to drain stacks first because there may be chunks on
228 // preloaded onto the stack and this thread may never have
229 // done a draining task. Are the draining tasks needed?
230
231 cm->drain_chunk_stacks();
232
233 size_t chunk_index = 0;
234 int random_seed = 17;
235
236 // If we're the termination task, try 10 rounds of stealing before
237 // setting the termination flag
238
239 while(true) {
240 if (ParCompactionManager::steal(which, &random_seed, chunk_index)) {
241 PSParallelCompact::fill_and_update_chunk(cm, chunk_index);
242 cm->drain_chunk_stacks();
243 } else {
244 if (terminator()->offer_termination()) {
245 break;
246 }
247 // Go around again.
248 }
249 }
250 return;
251 }
252
253 UpdateDensePrefixTask::UpdateDensePrefixTask(
254 PSParallelCompact::SpaceId space_id,
255 size_t chunk_index_start,
256 size_t chunk_index_end) :
257 _space_id(space_id), _chunk_index_start(chunk_index_start),
258 _chunk_index_end(chunk_index_end)
259 {}
260
261 void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
262
263 NOT_PRODUCT(TraceTime tm("UpdateDensePrefixTask",
264 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
265
266 ParCompactionManager* cm =
267 ParCompactionManager::gc_thread_compaction_manager(which);
268
269 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm,
270 _space_id,
271 _chunk_index_start,
272 _chunk_index_end);
273 }
274
275 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
276 assert(Universe::heap()->is_gc_active(), "called outside gc");
277
278 NOT_PRODUCT(TraceTime tm("DrainStacksCompactionTask",
279 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
280
281 ParCompactionManager* cm =
282 ParCompactionManager::gc_thread_compaction_manager(which);
283
284 // Process any chunks already in the compaction managers stacks.
285 cm->drain_chunk_stacks();
286 }
287
|
1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)pcTasks.cpp 1.22 07/06/22 16:49:49 JVM"
3 #endif
4 /*
5 * Copyright 2005-2008 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 *
132 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
133 ParCompactionManager* cm =
134 ParCompactionManager::gc_thread_compaction_manager(which);
135 // cm->allocate_stacks();
136 assert(cm->stacks_have_been_allocated(),
137 "Stack space has not been allocated");
138 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
139 PSParallelCompact::FollowStackClosure follow_stack_closure(cm);
140 _rp_task.work(_work_id, *PSParallelCompact::is_alive_closure(),
141 mark_and_push_closure, follow_stack_closure);
142 }
143
144 //
145 // RefProcTaskExecutor
146 //
147
148 void RefProcTaskExecutor::execute(ProcessTask& task)
149 {
150 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
151 uint parallel_gc_threads = heap->gc_task_manager()->workers();
152 RegionTaskQueueSet* qset = ParCompactionManager::region_array();
153 ParallelTaskTerminator terminator(parallel_gc_threads, qset);
154 GCTaskQueue* q = GCTaskQueue::create();
155 for(uint i=0; i<parallel_gc_threads; i++) {
156 q->enqueue(new RefProcTaskProxy(task, i));
157 }
158 if (task.marks_oops_alive()) {
159 if (parallel_gc_threads>1) {
160 for (uint j=0; j<parallel_gc_threads; j++) {
161 q->enqueue(new StealMarkingTask(&terminator));
162 }
163 }
164 }
165 PSParallelCompact::gc_task_manager()->execute_and_wait(q);
166 }
167
168 void RefProcTaskExecutor::execute(EnqueueTask& task)
169 {
170 ParallelScavengeHeap* heap = PSParallelCompact::gc_heap();
171 uint parallel_gc_threads = heap->gc_task_manager()->workers();
172 GCTaskQueue* q = GCTaskQueue::create();
191
192 ParCompactionManager* cm =
193 ParCompactionManager::gc_thread_compaction_manager(which);
194 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
195
196 oop obj = NULL;
197 int random_seed = 17;
198 while(true) {
199 if (ParCompactionManager::steal(which, &random_seed, obj)) {
200 obj->follow_contents(cm);
201 cm->drain_marking_stacks(&mark_and_push_closure);
202 } else {
203 if (terminator()->offer_termination()) {
204 break;
205 }
206 }
207 }
208 }
209
210 //
211 // StealRegionCompactionTask
212 //
213
214
215 StealRegionCompactionTask::StealRegionCompactionTask(ParallelTaskTerminator* t):
216 _terminator(t) {}
217
218 void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
219 assert(Universe::heap()->is_gc_active(), "called outside gc");
220
221 NOT_PRODUCT(TraceTime tm("StealRegionCompactionTask",
222 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
223
224 ParCompactionManager* cm =
225 ParCompactionManager::gc_thread_compaction_manager(which);
226
227 // Has to drain stacks first because there may be regions on
228 // preloaded onto the stack and this thread may never have
229 // done a draining task. Are the draining tasks needed?
230
231 cm->drain_region_stacks();
232
233 size_t region_index = 0;
234 int random_seed = 17;
235
236 // If we're the termination task, try 10 rounds of stealing before
237 // setting the termination flag
238
239 while(true) {
240 if (ParCompactionManager::steal(which, &random_seed, region_index)) {
241 PSParallelCompact::fill_and_update_region(cm, region_index);
242 cm->drain_region_stacks();
243 } else {
244 if (terminator()->offer_termination()) {
245 break;
246 }
247 // Go around again.
248 }
249 }
250 return;
251 }
252
253 UpdateDensePrefixTask::UpdateDensePrefixTask(
254 PSParallelCompact::SpaceId space_id,
255 size_t region_index_start,
256 size_t region_index_end) :
257 _space_id(space_id), _region_index_start(region_index_start),
258 _region_index_end(region_index_end) {}
259
260 void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
261
262 NOT_PRODUCT(TraceTime tm("UpdateDensePrefixTask",
263 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
264
265 ParCompactionManager* cm =
266 ParCompactionManager::gc_thread_compaction_manager(which);
267
268 PSParallelCompact::update_and_deadwood_in_dense_prefix(cm,
269 _space_id,
270 _region_index_start,
271 _region_index_end);
272 }
273
274 void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
275 assert(Universe::heap()->is_gc_active(), "called outside gc");
276
277 NOT_PRODUCT(TraceTime tm("DrainStacksCompactionTask",
278 PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
279
280 ParCompactionManager* cm =
281 ParCompactionManager::gc_thread_compaction_manager(which);
282
283 // Process any regions already in the compaction managers stacks.
284 cm->drain_region_stacks();
285 }
286
|