151 _rp_task.work(_work_id, is_alive, keep_alive, evac_followers); 152 } 153 154 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { 155 virtual void execute(ProcessTask& task, uint ergo_workers); 156 }; 157 158 void PSRefProcTaskExecutor::execute(ProcessTask& task, uint ergo_workers) 159 { 160 GCTaskQueue* q = GCTaskQueue::create(); 161 GCTaskManager* manager = ParallelScavengeHeap::gc_task_manager(); 162 uint active_workers = manager->active_workers(); 163 164 assert(active_workers == ergo_workers, 165 "Ergonomically chosen workers (%u) must be equal to active workers (%u)", 166 ergo_workers, active_workers); 167 168 for(uint i=0; i < active_workers; i++) { 169 q->enqueue(new PSRefProcTaskProxy(task, i)); 170 } 171 ParallelTaskTerminator terminator(active_workers, 172 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()); 173 if (task.marks_oops_alive() && active_workers > 1) { 174 for (uint j = 0; j < active_workers; j++) { 175 q->enqueue(new StealTask(&terminator)); 176 } 177 } 178 manager->execute_and_wait(q); 179 } 180 181 // This method contains all heap specific policy for invoking scavenge. 182 // PSScavenge::invoke_no_policy() will do nothing but attempt to 183 // scavenge. It will not clean up after failed promotions, bail out if 184 // we've exceeded policy time limits, or any other special behavior. 185 // All such policy should be placed here. 186 // 187 // Note that this method should only be called from the vm_thread while 188 // at a safepoint! 189 bool PSScavenge::invoke() { 190 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); 191 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); 192 assert(!ParallelScavengeHeap::heap()->is_gc_active(), "not reentrant"); 193 194 ParallelScavengeHeap* const heap = ParallelScavengeHeap::heap(); 195 PSAdaptiveSizePolicy* policy = heap->size_policy(); 363 // There are only old-to-young pointers if there are objects 364 // in the old gen. 365 uint stripe_total = active_workers; 366 for(uint i=0; i < stripe_total; i++) { 367 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total)); 368 } 369 } 370 371 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); 372 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles)); 373 // We scan the thread roots in parallel 374 PSAddThreadRootsTaskClosure cl(q); 375 Threads::java_threads_and_vm_thread_do(&cl); 376 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer)); 377 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management)); 378 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary)); 379 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data)); 380 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti)); 381 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache)); 382 383 ParallelTaskTerminator terminator( 384 active_workers, 385 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()); 386 // If active_workers can exceed 1, add a StrealTask. 387 // PSPromotionManager::drain_stacks_depth() does not fully drain its 388 // stacks and expects a StealTask to complete the draining if 389 // ParallelGCThreads is > 1. 390 if (gc_task_manager()->workers() > 1) { 391 for (uint j = 0; j < active_workers; j++) { 392 q->enqueue(new StealTask(&terminator)); 393 } 394 } 395 396 gc_task_manager()->execute_and_wait(q); 397 } 398 399 scavenge_midpoint.update(); 400 401 // Process reference objects discovered during scavenge 402 { 403 GCTraceTime(Debug, gc, phases) tm("Reference Processing", &_gc_timer); 404 405 reference_processor()->setup_policy(false); // not always_clear 406 reference_processor()->set_active_mt_degree(active_workers); 407 PSKeepAliveClosure keep_alive(promotion_manager); 408 PSEvacuateFollowersClosure evac_followers(promotion_manager); 409 ReferenceProcessorStats stats; 410 ReferenceProcessorPhaseTimes pt(&_gc_timer, reference_processor()->max_num_queues()); 411 if (reference_processor()->processing_is_mt()) { 412 PSRefProcTaskExecutor task_executor; | 151 _rp_task.work(_work_id, is_alive, keep_alive, evac_followers); 152 } 153 154 class PSRefProcTaskExecutor: public AbstractRefProcTaskExecutor { 155 virtual void execute(ProcessTask& task, uint ergo_workers); 156 }; 157 158 void PSRefProcTaskExecutor::execute(ProcessTask& task, uint ergo_workers) 159 { 160 GCTaskQueue* q = GCTaskQueue::create(); 161 GCTaskManager* manager = ParallelScavengeHeap::gc_task_manager(); 162 uint active_workers = manager->active_workers(); 163 164 assert(active_workers == ergo_workers, 165 "Ergonomically chosen workers (%u) must be equal to active workers (%u)", 166 ergo_workers, active_workers); 167 168 for(uint i=0; i < active_workers; i++) { 169 q->enqueue(new PSRefProcTaskProxy(task, i)); 170 } 171 TaskTerminator terminator(active_workers, 172 (TaskQueueSetSuper*) PSPromotionManager::stack_array_depth()); 173 if (task.marks_oops_alive() && active_workers > 1) { 174 for (uint j = 0; j < active_workers; j++) { 175 q->enqueue(new StealTask(terminator.terminator())); 176 } 177 } 178 manager->execute_and_wait(q); 179 } 180 181 // This method contains all heap specific policy for invoking scavenge. 182 // PSScavenge::invoke_no_policy() will do nothing but attempt to 183 // scavenge. It will not clean up after failed promotions, bail out if 184 // we've exceeded policy time limits, or any other special behavior. 185 // All such policy should be placed here. 186 // 187 // Note that this method should only be called from the vm_thread while 188 // at a safepoint! 189 bool PSScavenge::invoke() { 190 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); 191 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); 192 assert(!ParallelScavengeHeap::heap()->is_gc_active(), "not reentrant"); 193 194 ParallelScavengeHeap* const heap = ParallelScavengeHeap::heap(); 195 PSAdaptiveSizePolicy* policy = heap->size_policy(); 363 // There are only old-to-young pointers if there are objects 364 // in the old gen. 365 uint stripe_total = active_workers; 366 for(uint i=0; i < stripe_total; i++) { 367 q->enqueue(new OldToYoungRootsTask(old_gen, old_top, i, stripe_total)); 368 } 369 } 370 371 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::universe)); 372 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jni_handles)); 373 // We scan the thread roots in parallel 374 PSAddThreadRootsTaskClosure cl(q); 375 Threads::java_threads_and_vm_thread_do(&cl); 376 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::object_synchronizer)); 377 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management)); 378 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary)); 379 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data)); 380 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti)); 381 q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache)); 382 383 TaskTerminator terminator( 384 active_workers, 385 (TaskQueueSetSuper*) promotion_manager->stack_array_depth()); 386 // If active_workers can exceed 1, add a StrealTask. 387 // PSPromotionManager::drain_stacks_depth() does not fully drain its 388 // stacks and expects a StealTask to complete the draining if 389 // ParallelGCThreads is > 1. 390 if (gc_task_manager()->workers() > 1) { 391 for (uint j = 0; j < active_workers; j++) { 392 q->enqueue(new StealTask(terminator.terminator())); 393 } 394 } 395 396 gc_task_manager()->execute_and_wait(q); 397 } 398 399 scavenge_midpoint.update(); 400 401 // Process reference objects discovered during scavenge 402 { 403 GCTraceTime(Debug, gc, phases) tm("Reference Processing", &_gc_timer); 404 405 reference_processor()->setup_policy(false); // not always_clear 406 reference_processor()->set_active_mt_degree(active_workers); 407 PSKeepAliveClosure keep_alive(promotion_manager); 408 PSEvacuateFollowersClosure evac_followers(promotion_manager); 409 ReferenceProcessorStats stats; 410 ReferenceProcessorPhaseTimes pt(&_gc_timer, reference_processor()->max_num_queues()); 411 if (reference_processor()->processing_is_mt()) { 412 PSRefProcTaskExecutor task_executor; |