Mon, 20 Sep 2010 14:38:38 -0700
6984287: Regularize how GC parallel workers are specified.
Summary: Associate number of GC workers with the workgang as opposed to the task.
Reviewed-by: johnc, ysr
1 /*
2 * Copyright (c) 2002, 2010, 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 */
25 #include "incls/_precompiled.incl"
26 #include "incls/_psTasks.cpp.incl"
28 //
29 // ScavengeRootsTask
30 //
32 // Define before use
33 class PSScavengeRootsClosure: public OopClosure {
34 private:
35 PSPromotionManager* _promotion_manager;
37 protected:
38 template <class T> void do_oop_work(T *p) {
39 if (PSScavenge::should_scavenge(p)) {
40 // We never card mark roots, maybe call a func without test?
41 PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
42 }
43 }
44 public:
45 PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
46 void do_oop(oop* p) { PSScavengeRootsClosure::do_oop_work(p); }
47 void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
48 };
50 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
51 assert(Universe::heap()->is_gc_active(), "called outside gc");
53 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
54 PSScavengeRootsClosure roots_closure(pm);
56 switch (_root_type) {
57 case universe:
58 Universe::oops_do(&roots_closure);
59 ReferenceProcessor::oops_do(&roots_closure);
60 break;
62 case jni_handles:
63 JNIHandles::oops_do(&roots_closure);
64 break;
66 case threads:
67 {
68 ResourceMark rm;
69 Threads::oops_do(&roots_closure, NULL);
70 }
71 break;
73 case object_synchronizer:
74 ObjectSynchronizer::oops_do(&roots_closure);
75 break;
77 case flat_profiler:
78 FlatProfiler::oops_do(&roots_closure);
79 break;
81 case system_dictionary:
82 SystemDictionary::oops_do(&roots_closure);
83 break;
85 case management:
86 Management::oops_do(&roots_closure);
87 break;
89 case jvmti:
90 JvmtiExport::oops_do(&roots_closure);
91 break;
94 case code_cache:
95 {
96 CodeBlobToOopClosure each_scavengable_code_blob(&roots_closure, /*do_marking=*/ true);
97 CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
98 }
99 break;
101 default:
102 fatal("Unknown root type");
103 }
105 // Do the real work
106 pm->drain_stacks(false);
107 }
109 //
110 // ThreadRootsTask
111 //
113 void ThreadRootsTask::do_it(GCTaskManager* manager, uint which) {
114 assert(Universe::heap()->is_gc_active(), "called outside gc");
116 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
117 PSScavengeRootsClosure roots_closure(pm);
118 CodeBlobToOopClosure roots_in_blobs(&roots_closure, /*do_marking=*/ true);
120 if (_java_thread != NULL)
121 _java_thread->oops_do(&roots_closure, &roots_in_blobs);
123 if (_vm_thread != NULL)
124 _vm_thread->oops_do(&roots_closure, &roots_in_blobs);
126 // Do the real work
127 pm->drain_stacks(false);
128 }
130 //
131 // StealTask
132 //
134 StealTask::StealTask(ParallelTaskTerminator* t) :
135 _terminator(t) {}
137 void StealTask::do_it(GCTaskManager* manager, uint which) {
138 assert(Universe::heap()->is_gc_active(), "called outside gc");
140 PSPromotionManager* pm =
141 PSPromotionManager::gc_thread_promotion_manager(which);
142 pm->drain_stacks(true);
143 guarantee(pm->stacks_empty(),
144 "stacks should be empty at this point");
146 int random_seed = 17;
147 while(true) {
148 StarTask p;
149 if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
150 TASKQUEUE_STATS_ONLY(pm->record_steal(p));
151 pm->process_popped_location_depth(p);
152 pm->drain_stacks_depth(true);
153 } else {
154 if (terminator()->offer_termination()) {
155 break;
156 }
157 }
158 }
159 guarantee(pm->stacks_empty(), "stacks should be empty at this point");
160 }
162 //
163 // SerialOldToYoungRootsTask
164 //
166 void SerialOldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
167 assert(_gen != NULL, "Sanity");
168 assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
170 {
171 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
173 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
174 CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
175 // FIX ME! Assert that card_table is the type we believe it to be.
177 card_table->scavenge_contents(_gen->start_array(),
178 _gen->object_space(),
179 _gen_top,
180 pm);
182 // Do the real work
183 pm->drain_stacks(false);
184 }
185 }
187 //
188 // OldToYoungRootsTask
189 //
191 void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
192 assert(_gen != NULL, "Sanity");
193 assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
194 assert(_stripe_number < ParallelGCThreads, "Sanity");
196 {
197 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
199 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
200 CardTableExtension* card_table = (CardTableExtension *)Universe::heap()->barrier_set();
201 // FIX ME! Assert that card_table is the type we believe it to be.
203 card_table->scavenge_contents_parallel(_gen->start_array(),
204 _gen->object_space(),
205 _gen_top,
206 pm,
207 _stripe_number);
209 // Do the real work
210 pm->drain_stacks(false);
211 }
212 }