30 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
31 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
32 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
33 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
34 #include "gc_implementation/parallelScavenge/psTasks.hpp"
35 #include "memory/iterator.hpp"
36 #include "memory/universe.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "runtime/fprofiler.hpp"
39 #include "runtime/thread.hpp"
40 #include "runtime/vmThread.hpp"
41 #include "services/management.hpp"
42 #include "utilities/stack.inline.hpp"
43 #include "utilities/taskqueue.hpp"
44
45 //
46 // ScavengeRootsTask
47 //
48
49 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
50 assert(Universe::heap()->is_gc_active(), "called outside gc");
51
52 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
53 PSScavengeRootsClosure roots_closure(pm);
54 PSPromoteRootsClosure roots_to_old_closure(pm);
55
56 switch (_root_type) {
57 case universe:
58 Universe::oops_do(&roots_closure);
59 break;
60
61 case jni_handles:
62 JNIHandles::oops_do(&roots_closure);
63 break;
64
65 case threads:
66 {
67 ResourceMark rm;
68 CLDClosure* cld_closure = NULL; // Not needed. All CLDs are already visited.
69 Threads::oops_do(&roots_closure, cld_closure, NULL);
70 }
101 case code_cache:
102 {
103 MarkingCodeBlobClosure each_scavengable_code_blob(&roots_to_old_closure, CodeBlobToOopClosure::FixRelocations);
104 CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
105 }
106 break;
107
108 default:
109 fatal("Unknown root type");
110 }
111
112 // Do the real work
113 pm->drain_stacks(false);
114 }
115
116 //
117 // ThreadRootsTask
118 //
119
120 void ThreadRootsTask::do_it(GCTaskManager* manager, uint which) {
121 assert(Universe::heap()->is_gc_active(), "called outside gc");
122
123 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
124 PSScavengeRootsClosure roots_closure(pm);
125 CLDClosure* roots_from_clds = NULL; // Not needed. All CLDs are already visited.
126 MarkingCodeBlobClosure roots_in_blobs(&roots_closure, CodeBlobToOopClosure::FixRelocations);
127
128 if (_java_thread != NULL)
129 _java_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
130
131 if (_vm_thread != NULL)
132 _vm_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
133
134 // Do the real work
135 pm->drain_stacks(false);
136 }
137
138 //
139 // StealTask
140 //
141
142 StealTask::StealTask(ParallelTaskTerminator* t) :
143 _terminator(t) {}
144
145 void StealTask::do_it(GCTaskManager* manager, uint which) {
146 assert(Universe::heap()->is_gc_active(), "called outside gc");
147
148 PSPromotionManager* pm =
149 PSPromotionManager::gc_thread_promotion_manager(which);
150 pm->drain_stacks(true);
151 guarantee(pm->stacks_empty(),
152 "stacks should be empty at this point");
153
154 int random_seed = 17;
155 while(true) {
156 StarTask p;
157 if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
158 TASKQUEUE_STATS_ONLY(pm->record_steal(p));
159 pm->process_popped_location_depth(p);
160 pm->drain_stacks_depth(true);
161 } else {
162 if (terminator()->offer_termination()) {
163 break;
164 }
165 }
166 }
167 guarantee(pm->stacks_empty(), "stacks should be empty at this point");
168 }
169
170 //
171 // OldToYoungRootsTask
172 //
173
174 void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
175 // There are not old-to-young pointers if the old gen is empty.
176 assert(!_gen->object_space()->is_empty(),
177 "Should not be called is there is no work");
178 assert(_gen != NULL, "Sanity");
179 assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
180 assert(_stripe_number < ParallelGCThreads, "Sanity");
181
182 {
183 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
184
185 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
186 CardTableExtension* card_table =
187 barrier_set_cast<CardTableExtension>(Universe::heap()->barrier_set());
188
189 card_table->scavenge_contents_parallel(_gen->start_array(),
190 _gen->object_space(),
191 _gen_top,
192 pm,
193 _stripe_number,
194 _stripe_total);
195
196 // Do the real work
197 pm->drain_stacks(false);
198 }
199 }
|
30 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
31 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
32 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
33 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
34 #include "gc_implementation/parallelScavenge/psTasks.hpp"
35 #include "memory/iterator.hpp"
36 #include "memory/universe.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "runtime/fprofiler.hpp"
39 #include "runtime/thread.hpp"
40 #include "runtime/vmThread.hpp"
41 #include "services/management.hpp"
42 #include "utilities/stack.inline.hpp"
43 #include "utilities/taskqueue.hpp"
44
45 //
46 // ScavengeRootsTask
47 //
48
49 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
50 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
51
52 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
53 PSScavengeRootsClosure roots_closure(pm);
54 PSPromoteRootsClosure roots_to_old_closure(pm);
55
56 switch (_root_type) {
57 case universe:
58 Universe::oops_do(&roots_closure);
59 break;
60
61 case jni_handles:
62 JNIHandles::oops_do(&roots_closure);
63 break;
64
65 case threads:
66 {
67 ResourceMark rm;
68 CLDClosure* cld_closure = NULL; // Not needed. All CLDs are already visited.
69 Threads::oops_do(&roots_closure, cld_closure, NULL);
70 }
101 case code_cache:
102 {
103 MarkingCodeBlobClosure each_scavengable_code_blob(&roots_to_old_closure, CodeBlobToOopClosure::FixRelocations);
104 CodeCache::scavenge_root_nmethods_do(&each_scavengable_code_blob);
105 }
106 break;
107
108 default:
109 fatal("Unknown root type");
110 }
111
112 // Do the real work
113 pm->drain_stacks(false);
114 }
115
116 //
117 // ThreadRootsTask
118 //
119
120 void ThreadRootsTask::do_it(GCTaskManager* manager, uint which) {
121 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
122
123 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
124 PSScavengeRootsClosure roots_closure(pm);
125 CLDClosure* roots_from_clds = NULL; // Not needed. All CLDs are already visited.
126 MarkingCodeBlobClosure roots_in_blobs(&roots_closure, CodeBlobToOopClosure::FixRelocations);
127
128 if (_java_thread != NULL)
129 _java_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
130
131 if (_vm_thread != NULL)
132 _vm_thread->oops_do(&roots_closure, roots_from_clds, &roots_in_blobs);
133
134 // Do the real work
135 pm->drain_stacks(false);
136 }
137
138 //
139 // StealTask
140 //
141
142 StealTask::StealTask(ParallelTaskTerminator* t) :
143 _terminator(t) {}
144
145 void StealTask::do_it(GCTaskManager* manager, uint which) {
146 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
147
148 PSPromotionManager* pm =
149 PSPromotionManager::gc_thread_promotion_manager(which);
150 pm->drain_stacks(true);
151 guarantee(pm->stacks_empty(),
152 "stacks should be empty at this point");
153
154 int random_seed = 17;
155 while(true) {
156 StarTask p;
157 if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
158 TASKQUEUE_STATS_ONLY(pm->record_steal(p));
159 pm->process_popped_location_depth(p);
160 pm->drain_stacks_depth(true);
161 } else {
162 if (terminator()->offer_termination()) {
163 break;
164 }
165 }
166 }
167 guarantee(pm->stacks_empty(), "stacks should be empty at this point");
168 }
169
170 //
171 // OldToYoungRootsTask
172 //
173
174 void OldToYoungRootsTask::do_it(GCTaskManager* manager, uint which) {
175 // There are not old-to-young pointers if the old gen is empty.
176 assert(!_gen->object_space()->is_empty(),
177 "Should not be called is there is no work");
178 assert(_gen != NULL, "Sanity");
179 assert(_gen->object_space()->contains(_gen_top) || _gen_top == _gen->object_space()->top(), "Sanity");
180 assert(_stripe_number < ParallelGCThreads, "Sanity");
181
182 {
183 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
184 CardTableExtension* card_table =
185 barrier_set_cast<CardTableExtension>(ParallelScavengeHeap::heap()->barrier_set());
186
187 card_table->scavenge_contents_parallel(_gen->start_array(),
188 _gen->object_space(),
189 _gen_top,
190 pm,
191 _stripe_number,
192 _stripe_total);
193
194 // Do the real work
195 pm->drain_stacks(false);
196 }
197 }
|