5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "classfile/stringTable.hpp"
26 #include "code/codeCache.hpp"
27 #include "gc/parallel/gcTaskManager.hpp"
28 #include "gc/parallel/parallelScavengeHeap.hpp"
29 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
30 #include "gc/parallel/psClosure.inline.hpp"
31 #include "gc/parallel/psMarkSweepProxy.hpp"
32 #include "gc/parallel/psParallelCompact.inline.hpp"
33 #include "gc/parallel/psPromotionManager.inline.hpp"
34 #include "gc/parallel/psScavenge.inline.hpp"
35 #include "gc/parallel/psTasks.hpp"
36 #include "gc/shared/gcCause.hpp"
37 #include "gc/shared/gcHeapSummary.hpp"
38 #include "gc/shared/gcId.hpp"
39 #include "gc/shared/gcLocker.hpp"
40 #include "gc/shared/gcTimer.hpp"
41 #include "gc/shared/gcTrace.hpp"
42 #include "gc/shared/gcTraceTime.inline.hpp"
43 #include "gc/shared/isGCActiveMark.hpp"
44 #include "gc/shared/referencePolicy.hpp"
45 #include "gc/shared/referenceProcessor.hpp"
46 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
47 #include "gc/shared/spaceDecorator.hpp"
48 #include "gc/shared/weakProcessor.hpp"
49 #include "gc/shared/workerPolicy.hpp"
50 #include "memory/resourceArea.hpp"
51 #include "memory/universe.hpp"
52 #include "logging/log.hpp"
53 #include "oops/access.inline.hpp"
54 #include "oops/compressedOops.inline.hpp"
55 #include "oops/oop.inline.hpp"
56 #include "runtime/biasedLocking.hpp"
57 #include "runtime/handles.inline.hpp"
58 #include "runtime/threadCritical.hpp"
59 #include "runtime/vmThread.hpp"
60 #include "runtime/vmOperations.hpp"
61 #include "services/memoryService.hpp"
62 #include "utilities/stack.inline.hpp"
63
64 HeapWord* PSScavenge::_to_space_top_before_gc = NULL;
65 int PSScavenge::_consecutive_skipped_scavenges = 0;
66 SpanSubjectToDiscoveryClosure PSScavenge::_span_based_discoverer;
67 ReferenceProcessor* PSScavenge::_ref_processor = NULL;
68 PSCardTable* PSScavenge::_card_table = NULL;
69 bool PSScavenge::_survivor_overflow = false;
70 uint PSScavenge::_tenuring_threshold = 0;
71 HeapWord* PSScavenge::_young_generation_boundary = NULL;
72 uintptr_t PSScavenge::_young_generation_boundary_compressed = 0;
73 elapsedTimer PSScavenge::_accumulated_time;
74 STWGCTimer PSScavenge::_gc_timer;
75 ParallelScavengeTracer PSScavenge::_gc_tracer;
76 CollectorCounters* PSScavenge::_counters = NULL;
77
78 // Define before use
79 class PSIsAliveClosure: public BoolObjectClosure {
80 public:
81 bool do_object_b(oop p) {
82 return (!PSScavenge::is_obj_in_young(p)) || p->is_forwarded();
83 }
84 };
85
86 PSIsAliveClosure PSScavenge::_is_alive_closure;
87
88 class PSKeepAliveClosure: public OopClosure {
89 protected:
90 MutableSpace* _to_space;
91 PSPromotionManager* _promotion_manager;
92
93 public:
94 PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) {
95 ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
96 _to_space = heap->young_gen()->to_space();
|
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "aot/aotLoader.hpp"
26 #include "classfile/classLoaderDataGraph.hpp"
27 #include "classfile/stringTable.hpp"
28 #include "code/codeCache.hpp"
29 #include "gc/parallel/gcTaskManager.hpp"
30 #include "gc/parallel/parallelScavengeHeap.hpp"
31 #include "gc/parallel/psAdaptiveSizePolicy.hpp"
32 #include "gc/parallel/psClosure.inline.hpp"
33 #include "gc/parallel/psMarkSweepProxy.hpp"
34 #include "gc/parallel/psParallelCompact.inline.hpp"
35 #include "gc/parallel/psPromotionManager.inline.hpp"
36 #include "gc/parallel/psRootType.inline.hpp"
37 #include "gc/parallel/psScavenge.inline.hpp"
38 #include "gc/parallel/psTasks.hpp"
39 #include "gc/shared/gcCause.hpp"
40 #include "gc/shared/gcHeapSummary.hpp"
41 #include "gc/shared/gcId.hpp"
42 #include "gc/shared/gcLocker.hpp"
43 #include "gc/shared/gcTimer.hpp"
44 #include "gc/shared/gcTrace.hpp"
45 #include "gc/shared/gcTraceTime.inline.hpp"
46 #include "gc/shared/isGCActiveMark.hpp"
47 #include "gc/shared/referencePolicy.hpp"
48 #include "gc/shared/referenceProcessor.hpp"
49 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
50 #include "gc/shared/scavengableNMethods.hpp"
51 #include "gc/shared/spaceDecorator.hpp"
52 #include "gc/shared/weakProcessor.hpp"
53 #include "gc/shared/workerPolicy.hpp"
54 #include "gc/shared/workgroup.hpp"
55 #if INCLUDE_JVMCI
56 #include "jvmci/jvmci.hpp"
57 #endif
58 #include "memory/resourceArea.hpp"
59 #include "memory/universe.hpp"
60 #include "logging/log.hpp"
61 #include "oops/access.inline.hpp"
62 #include "oops/compressedOops.inline.hpp"
63 #include "oops/oop.inline.hpp"
64 #include "runtime/biasedLocking.hpp"
65 #include "runtime/handles.inline.hpp"
66 #include "runtime/threadCritical.hpp"
67 #include "runtime/vmThread.hpp"
68 #include "runtime/vmOperations.hpp"
69 #include "services/management.hpp"
70 #include "services/memoryService.hpp"
71 #include "utilities/stack.inline.hpp"
72
73
74 HeapWord* PSScavenge::_to_space_top_before_gc = NULL;
75 int PSScavenge::_consecutive_skipped_scavenges = 0;
76 SpanSubjectToDiscoveryClosure PSScavenge::_span_based_discoverer;
77 ReferenceProcessor* PSScavenge::_ref_processor = NULL;
78 PSCardTable* PSScavenge::_card_table = NULL;
79 bool PSScavenge::_survivor_overflow = false;
80 uint PSScavenge::_tenuring_threshold = 0;
81 HeapWord* PSScavenge::_young_generation_boundary = NULL;
82 uintptr_t PSScavenge::_young_generation_boundary_compressed = 0;
83 elapsedTimer PSScavenge::_accumulated_time;
84 STWGCTimer PSScavenge::_gc_timer;
85 ParallelScavengeTracer PSScavenge::_gc_tracer;
86 CollectorCounters* PSScavenge::_counters = NULL;
87
88 void scavenge_roots_task(Parallel::RootType::Value root_type, uint which) {
89 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
90
91 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(which);
92 PSScavengeRootsClosure roots_closure(pm);
93 PSPromoteRootsClosure roots_to_old_closure(pm);
94
95 switch (root_type) {
96 case Parallel::RootType::universe:
97 Universe::oops_do(&roots_closure);
98 break;
99
100 case Parallel::RootType::jni_handles:
101 JNIHandles::oops_do(&roots_closure);
102 break;
103
104 case Parallel::RootType::object_synchronizer:
105 ObjectSynchronizer::oops_do(&roots_closure);
106 break;
107
108 case Parallel::RootType::system_dictionary:
109 SystemDictionary::oops_do(&roots_closure);
110 break;
111
112 case Parallel::RootType::class_loader_data:
113 {
114 PSScavengeCLDClosure cld_closure(pm);
115 ClassLoaderDataGraph::cld_do(&cld_closure);
116 }
117 break;
118
119 case Parallel::RootType::management:
120 Management::oops_do(&roots_closure);
121 break;
122
123 case Parallel::RootType::jvmti:
124 JvmtiExport::oops_do(&roots_closure);
125 break;
126
127 case Parallel::RootType::code_cache:
128 {
129 MarkingCodeBlobClosure code_closure(&roots_to_old_closure, CodeBlobToOopClosure::FixRelocations);
130 ScavengableNMethods::nmethods_do(&code_closure);
131 AOTLoader::oops_do(&roots_closure);
132 }
133 break;
134
135 #if INCLUDE_JVMCI
136 case Parallel::RootType::jvmci:
137 JVMCI::oops_do(&roots_closure);
138 break;
139 #endif
140
141 case Parallel::RootType::sentinel:
142 DEBUG_ONLY(default:) // DEBUG_ONLY hack will create compile error on release builds (-Wswitch) and runtime check on deb
143 fatal("Bad enumeration value: %u", root_type);
144 break;
145 }
146
147 // Do the real work
148 pm->drain_stacks(false);
149 }
150
151 void steal_task(ParallelTaskTerminator& terminator, uint worker_id) {
152 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
153
154 PSPromotionManager* pm =
155 PSPromotionManager::gc_thread_promotion_manager(worker_id);
156 pm->drain_stacks(true);
157 guarantee(pm->stacks_empty(),
158 "stacks should be empty at this point");
159
160 while (true) {
161 StarTask p;
162 if (PSPromotionManager::steal_depth(worker_id, p)) {
163 TASKQUEUE_STATS_ONLY(pm->record_steal(p));
164 pm->process_popped_location_depth(p);
165 pm->drain_stacks_depth(true);
166 } else {
167 if (terminator.offer_termination()) {
168 break;
169 }
170 }
171 }
172 guarantee(pm->stacks_empty(), "stacks should be empty at this point");
173 }
174
175 // Define before use
176 class PSIsAliveClosure: public BoolObjectClosure {
177 public:
178 bool do_object_b(oop p) {
179 return (!PSScavenge::is_obj_in_young(p)) || p->is_forwarded();
180 }
181 };
182
183 PSIsAliveClosure PSScavenge::_is_alive_closure;
184
185 class PSKeepAliveClosure: public OopClosure {
186 protected:
187 MutableSpace* _to_space;
188 PSPromotionManager* _promotion_manager;
189
190 public:
191 PSKeepAliveClosure(PSPromotionManager* pm) : _promotion_manager(pm) {
192 ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
193 _to_space = heap->young_gen()->to_space();
|
204 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters();
205 const int ffs_val = need_full_gc ? full_follows_scavenge : not_skipped;
206 counters->update_full_follows_scavenge(ffs_val);
207 }
208
209 if (need_full_gc) {
210 GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
211 SoftRefPolicy* srp = heap->soft_ref_policy();
212 const bool clear_all_softrefs = srp->should_clear_all_soft_refs();
213
214 if (UseParallelOldGC) {
215 full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
216 } else {
217 full_gc_done = PSMarkSweepProxy::invoke_no_policy(clear_all_softrefs);
218 }
219 }
220
221 return full_gc_done;
222 }
223
224 class PSAddThreadRootsTaskClosure : public ThreadClosure {
225 private:
226 GCTaskQueue* _q;
227
228 public:
229 PSAddThreadRootsTaskClosure(GCTaskQueue* q) : _q(q) { }
230 void do_thread(Thread* t) {
231 _q->enqueue(new ThreadRootsTask(t));
232 }
233 };
234
235 // This method contains no policy. You should probably
236 // be calling invoke() instead.
237 bool PSScavenge::invoke_no_policy() {
238 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
239 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
240
241 _gc_timer.register_gc_start();
242
243 TimeStamp scavenge_entry;
244 TimeStamp scavenge_midpoint;
245 TimeStamp scavenge_exit;
246
247 scavenge_entry.update();
248
249 if (GCLocker::check_active_before_gc()) {
250 return false;
|
301 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters();
302 const int ffs_val = need_full_gc ? full_follows_scavenge : not_skipped;
303 counters->update_full_follows_scavenge(ffs_val);
304 }
305
306 if (need_full_gc) {
307 GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy);
308 SoftRefPolicy* srp = heap->soft_ref_policy();
309 const bool clear_all_softrefs = srp->should_clear_all_soft_refs();
310
311 if (UseParallelOldGC) {
312 full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
313 } else {
314 full_gc_done = PSMarkSweepProxy::invoke_no_policy(clear_all_softrefs);
315 }
316 }
317
318 return full_gc_done;
319 }
320
321 class PSThreadRootsTaskClosure : public ThreadClosure {
322 uint _worker_id;
323 public:
324 PSThreadRootsTaskClosure(uint worker_id) : _worker_id(worker_id) { }
325 virtual void do_thread(Thread* thread) {
326 assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");
327
328 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(_worker_id);
329 PSScavengeRootsClosure roots_closure(pm);
330 MarkingCodeBlobClosure roots_in_blobs(&roots_closure, CodeBlobToOopClosure::FixRelocations);
331
332 thread->oops_do(&roots_closure, &roots_in_blobs);
333
334 // Do the real work
335 pm->drain_stacks(false);
336 }
337 };
338 //
339 // OldToYoungRootsTask
340 //
341 // This task is used to scan old to young roots in parallel
342 //
343 // A GC thread executing this tasks divides the generation (old gen)
344 // into slices and takes a stripe in the slice as its part of the
345 // work.
346 //
347 // +===============+ slice 0
348 // | stripe 0 |
349 // +---------------+
350 // | stripe 1 |
351 // +---------------+
352 // | stripe 2 |
353 // +---------------+
354 // | stripe 3 |
355 // +===============+ slice 1
356 // | stripe 0 |
357 // +---------------+
358 // | stripe 1 |
359 // +---------------+
360 // | stripe 2 |
361 // +---------------+
362 // | stripe 3 |
363 // +===============+ slice 2
364 // ...
365 //
366 // A task is created for each stripe. In this case there are 4 tasks
367 // created. A GC thread first works on its stripe within slice 0
368 // and then moves to its stripe in the next slice until all stripes
369 // exceed the top of the generation. Note that having fewer GC threads
370 // than stripes works because all the tasks are executed so all stripes
371 // will be covered. In this example if 4 tasks have been created to cover
372 // all the stripes and there are only 3 threads, one of the threads will
373 // get the tasks with the 4th stripe. However, there is a dependence in
374 // PSCardTable::scavenge_contents_parallel() on the number
375 // of tasks created. In scavenge_contents_parallel the distance
376 // to the next stripe is calculated based on the number of tasks.
377 // If the stripe width is ssize, a task's next stripe is at
378 // ssize * number_of_tasks (= slice_stride). In this case after
379 // finishing stripe 0 in slice 0, the thread finds the stripe 0 in slice1
380 // by adding slice_stride to the start of stripe 0 in slice 0 to get
381 // to the start of stride 0 in slice 1.
382
383 class ScavengeRootsTask : public AbstractGangTask {
384 StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do
385 EnumClaimer<Parallel::RootType::Value> _enum_claimer;
386 PSOldGen* _old_gen;
387 HeapWord* _gen_top;
388 uint _active_workers;
389 bool _is_empty;
390 TaskTerminator _terminator;
391
392 public:
393 ScavengeRootsTask(
394 PSOldGen* old_gen,
395 HeapWord* gen_top,
396 uint active_workers,
397 bool is_empty)
398 : AbstractGangTask("ScavengeRootsTask"),
399 _strong_roots_scope(active_workers),
400 _enum_claimer(Parallel::RootType::sentinel),
401 _old_gen(old_gen),
402 _gen_top(gen_top),
403 _active_workers(active_workers),
404 _is_empty(is_empty),
405 _terminator(active_workers, PSPromotionManager::vm_thread_promotion_manager()->stack_array_depth()) {
406 }
407
408 virtual void work(uint worker_id) {
409 ResourceMark rm;
410
411 if (!_is_empty) {
412 // There are only old-to-young pointers if there are objects
413 // in the old gen.
414
415 // There are not old-to-young pointers if the old gen is empty.
416 assert(!_old_gen->object_space()->is_empty(),
417 "Should not be called is there is no work");
418 assert(_old_gen != NULL, "Sanity");
419 assert(_old_gen->object_space()->contains(_gen_top) || _gen_top == _old_gen->object_space()->top(), "Sanity");
420 assert(worker_id < ParallelGCThreads, "Sanity");
421
422 {
423 PSPromotionManager* pm = PSPromotionManager::gc_thread_promotion_manager(worker_id);
424 PSCardTable* card_table = ParallelScavengeHeap::heap()->card_table();
425
426 card_table->scavenge_contents_parallel(_old_gen->start_array(),
427 _old_gen->object_space(),
428 _gen_top,
429 pm,
430 worker_id,
431 _active_workers);
432
433 // Do the real work
434 pm->drain_stacks(false);
435 }
436 }
437
438 for (Parallel::RootType::Value root_type; _enum_claimer.try_claim(root_type); /* empty */) {
439 scavenge_roots_task(root_type, worker_id);
440 }
441
442 PSThreadRootsTaskClosure closure(worker_id);
443 Threads::possibly_parallel_threads_do(true /*parallel */, &closure);
444
445
446 // If active_workers can exceed 1, add a StrealTask.
447 // PSPromotionManager::drain_stacks_depth() does not fully drain its
448 // stacks and expects a StealTask to complete the draining if
449 // ParallelGCThreads is > 1.
450
451 if (_active_workers > 1) {
452 steal_task(*_terminator.terminator() , worker_id);
453 }
454 }
455 };
456
457 // This method contains no policy. You should probably
458 // be calling invoke() instead.
459 bool PSScavenge::invoke_no_policy() {
460 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
461 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
462
463 _gc_timer.register_gc_start();
464
465 TimeStamp scavenge_entry;
466 TimeStamp scavenge_midpoint;
467 TimeStamp scavenge_exit;
468
469 scavenge_entry.update();
470
471 if (GCLocker::check_active_before_gc()) {
472 return false;
|
342 uint active_workers = ParallelScavengeHeap::heap()->workers().update_active_workers(WorkerPolicy::calc_active_workers(
343 ParallelScavengeHeap::heap()->workers().total_workers(),
344 ParallelScavengeHeap::heap()->workers().active_workers(),
345 Threads::number_of_non_daemon_threads()));
346
347 // Release all previously held resources
348 gc_task_manager()->release_all_resources();
349
350 // Set the number of GC threads to be used in this collection
351 gc_task_manager()->set_active_gang();
352 gc_task_manager()->task_idle_workers();
353
354 assert(active_workers == gc_task_manager()->active_workers(), "sanity, taskmanager and workgang ought to agree");
355
356 PSPromotionManager::pre_scavenge();
357
358 // We'll use the promotion manager again later.
359 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
360 {
361 GCTraceTime(Debug, gc, phases) tm("Scavenge", &_gc_timer);
362 ParallelScavengeHeap::ParStrongRootsScope psrs;
363
364 GCTaskQueue* q = GCTaskQueue::create();
365
366 if (!old_gen->object_space()->is_empty()) {
367 // There are only old-to-young pointers if there are objects
368 // in the old gen.
369 uint stripe_total = active_workers;
370 for(uint i=0; i < stripe_total; i++) {
371 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total));
372 }
373 }
374
375 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe));
376 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles));
377 // We scan the thread roots in parallel
378 PSAddThreadRootsTaskClosure cl(q);
379 Threads::java_threads_and_vm_thread_do(&cl);
380 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer));
381 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
382 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
383 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data));
384 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
385 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
386 JVMCI_ONLY(q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmci));)
387
388 TaskTerminator terminator(active_workers,
389 (TaskQueueSetSuper*) promotion_manager->stack_array_depth());
390 // If active_workers can exceed 1, add a StrealTask.
391 // PSPromotionManager::drain_stacks_depth() does not fully drain its
392 // stacks and expects a StealTask to complete the draining if
393 // ParallelGCThreads is > 1.
394 if (gc_task_manager()->workers() > 1) {
395 for (uint j = 0; j < active_workers; j++) {
396 q->enqueue(new StealTask(terminator.terminator()));
397 }
398 }
399
400 gc_task_manager()->execute_and_wait(q);
401 }
402
403 scavenge_midpoint.update();
404
405 // Process reference objects discovered during scavenge
406 {
407 GCTraceTime(Debug, gc, phases) tm("Reference Processing", &_gc_timer);
408
409 reference_processor()->setup_policy(false); // not always_clear
410 reference_processor()->set_active_mt_degree(active_workers);
411 PSKeepAliveClosure keep_alive(promotion_manager);
412 PSEvacuateFollowersClosure evac_followers(promotion_manager);
413 ReferenceProcessorStats stats;
414 ReferenceProcessorPhaseTimes pt(&_gc_timer, reference_processor()->max_num_queues());
415 if (reference_processor()->processing_is_mt()) {
416 PSRefProcTaskExecutor task_executor;
417 stats = reference_processor()->process_discovered_references(
418 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor,
419 &pt);
|
564 uint active_workers = ParallelScavengeHeap::heap()->workers().update_active_workers(WorkerPolicy::calc_active_workers(
565 ParallelScavengeHeap::heap()->workers().total_workers(),
566 ParallelScavengeHeap::heap()->workers().active_workers(),
567 Threads::number_of_non_daemon_threads()));
568
569 // Release all previously held resources
570 gc_task_manager()->release_all_resources();
571
572 // Set the number of GC threads to be used in this collection
573 gc_task_manager()->set_active_gang();
574 gc_task_manager()->task_idle_workers();
575
576 assert(active_workers == gc_task_manager()->active_workers(), "sanity, taskmanager and workgang ought to agree");
577
578 PSPromotionManager::pre_scavenge();
579
580 // We'll use the promotion manager again later.
581 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
582 {
583 GCTraceTime(Debug, gc, phases) tm("Scavenge", &_gc_timer);
584
585 ScavengeRootsTask task(old_gen, old_top, active_workers, old_gen->object_space()->is_empty());
586 ParallelScavengeHeap::heap()->workers().run_task(&task);
587 }
588
589 scavenge_midpoint.update();
590
591 // Process reference objects discovered during scavenge
592 {
593 GCTraceTime(Debug, gc, phases) tm("Reference Processing", &_gc_timer);
594
595 reference_processor()->setup_policy(false); // not always_clear
596 reference_processor()->set_active_mt_degree(active_workers);
597 PSKeepAliveClosure keep_alive(promotion_manager);
598 PSEvacuateFollowersClosure evac_followers(promotion_manager);
599 ReferenceProcessorStats stats;
600 ReferenceProcessorPhaseTimes pt(&_gc_timer, reference_processor()->max_num_queues());
601 if (reference_processor()->processing_is_mt()) {
602 PSRefProcTaskExecutor task_executor;
603 stats = reference_processor()->process_discovered_references(
604 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor,
605 &pt);
|