void G1RootProcessor::process_strong_roots(OopClosure* oops, CLDClosure* clds, CodeBlobClosure* blobs) { process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0); process_vm_roots(oops, NULL, NULL, 0); _process_strong_tasks->all_tasks_completed(n_workers()); }
void G1RootProcessor::process_all_roots(OopClosure* oops, CLDClosure* clds, CodeBlobClosure* blobs) { process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0); process_vm_roots(oops, oops, NULL, 0); if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) { CodeCache::blobs_do(blobs); } _process_strong_tasks->all_tasks_completed(n_workers()); }
void G1RootProcessor::process_all_roots(OopClosure* oops, CLDClosure* clds, CodeBlobClosure* blobs, bool process_string_table) { AllRootsClosures closures(oops, clds); process_java_roots(&closures, NULL, 0); process_vm_roots(&closures, NULL, 0); if (process_string_table) { process_string_table_roots(&closures, NULL, 0); } process_code_cache_roots(blobs, NULL, 0); _process_strong_tasks.all_tasks_completed(n_workers()); }
void G1RootProcessor::evacuate_roots(G1EvacuationRootClosures* closures, uint worker_i) { double ext_roots_start = os::elapsedTime(); G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); process_java_roots(closures, phase_times, worker_i); // This is the point where this worker thread will not find more strong CLDs/nmethods. // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. if (closures->trace_metadata()) { worker_has_discovered_all_strong_classes(); } process_vm_roots(closures, phase_times, worker_i); process_string_table_roots(closures, phase_times, worker_i); { // Now the CM ref_processor roots. G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i); if (!_process_strong_tasks.is_task_claimed(G1RP_PS_refProcessor_oops_do)) { // We need to treat the discovered reference lists of the // concurrent mark ref processor as roots and keep entries // (which are added by the marking threads) on them live // until they can be processed at the end of marking. _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops()); } } if (closures->trace_metadata()) { { G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i); // Barrier to make sure all workers passed // the strong CLD and strong nmethods phases. wait_until_all_strong_classes_discovered(); } // Now take the complement of the strong CLDs. G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i); assert(closures->second_pass_weak_clds() != NULL, "Should be non-null if we are tracing metadata."); ClassLoaderDataGraph::roots_cld_do(NULL, closures->second_pass_weak_clds()); } else { phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0); phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0); assert(closures->second_pass_weak_clds() == NULL, "Should be null if not tracing metadata."); } // Finish up any enqueued closure apps (attributed as object copy time). closures->flush(); double obj_copy_time_sec = closures->closure_app_seconds(); phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec); double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec; phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec); // During conc marking we have to filter the per-thread SATB buffers // to make sure we remove any oops into the CSet (which will show up // as implicitly live). { G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i); if (!_process_strong_tasks.is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->collector_state()->mark_in_progress()) { JavaThread::satb_mark_queue_set().filter_thread_buffers(); } } _process_strong_tasks.all_tasks_completed(n_workers()); }
void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots, OopClosure* scan_non_heap_weak_roots, CLDClosure* scan_strong_clds, CLDClosure* scan_weak_clds, bool trace_metadata, uint worker_i) { // First scan the shared roots. double ext_roots_start = os::elapsedTime(); G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots); OopClosure* const weak_roots = &buf_scan_non_heap_weak_roots; OopClosure* const strong_roots = &buf_scan_non_heap_roots; // CodeBlobClosures are not interoperable with BufferingOopClosures G1CodeBlobClosure root_code_blobs(scan_non_heap_roots); process_java_roots(strong_roots, trace_metadata ? scan_strong_clds : NULL, scan_strong_clds, trace_metadata ? NULL : scan_weak_clds, &root_code_blobs, phase_times, worker_i); // This is the point where this worker thread will not find more strong CLDs/nmethods. // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. if (trace_metadata) { worker_has_discovered_all_strong_classes(); } process_vm_roots(strong_roots, weak_roots, phase_times, worker_i); { // Now the CM ref_processor roots. G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i); if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) { // We need to treat the discovered reference lists of the // concurrent mark ref processor as roots and keep entries // (which are added by the marking threads) on them live // until they can be processed at the end of marking. _g1h->ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots); } } if (trace_metadata) { { G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i); // Barrier to make sure all workers passed // the strong CLD and strong nmethods phases. wait_until_all_strong_classes_discovered(); } // Now take the complement of the strong CLDs. G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i); ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds); } else { phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0); phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0); } // Finish up any enqueued closure apps (attributed as object copy time). buf_scan_non_heap_roots.done(); buf_scan_non_heap_weak_roots.done(); double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds() + buf_scan_non_heap_weak_roots.closure_app_seconds(); phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec); double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec; phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec); // During conc marking we have to filter the per-thread SATB buffers // to make sure we remove any oops into the CSet (which will show up // as implicitly live). { G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i); if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->collector_state()->mark_in_progress()) { JavaThread::satb_mark_queue_set().filter_thread_buffers(); } } _process_strong_tasks->all_tasks_completed(n_workers()); }