610 warning("Can't have more ConcGCThreads (" UINTX_FORMAT ") " |
610 warning("Can't have more ConcGCThreads (" UINTX_FORMAT ") " |
611 "than ParallelGCThreads (" UINTX_FORMAT ").", |
611 "than ParallelGCThreads (" UINTX_FORMAT ").", |
612 ConcGCThreads, ParallelGCThreads); |
612 ConcGCThreads, ParallelGCThreads); |
613 return; |
613 return; |
614 } |
614 } |
615 if (ParallelGCThreads == 0) { |
615 if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) { |
616 // if we are not running with any parallel GC threads we will not |
616 // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent |
617 // spawn any marking threads either |
617 // if both are set |
618 _parallel_marking_threads = 0; |
618 _sleep_factor = 0.0; |
619 _max_parallel_marking_threads = 0; |
619 _marking_task_overhead = 1.0; |
620 _sleep_factor = 0.0; |
620 } else if (G1MarkingOverheadPercent > 0) { |
621 _marking_task_overhead = 1.0; |
621 // We will calculate the number of parallel marking threads based |
|
622 // on a target overhead with respect to the soft real-time goal |
|
623 double marking_overhead = (double) G1MarkingOverheadPercent / 100.0; |
|
624 double overall_cm_overhead = |
|
625 (double) MaxGCPauseMillis * marking_overhead / |
|
626 (double) GCPauseIntervalMillis; |
|
627 double cpu_ratio = 1.0 / (double) os::processor_count(); |
|
628 double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio); |
|
629 double marking_task_overhead = |
|
630 overall_cm_overhead / marking_thread_num * |
|
631 (double) os::processor_count(); |
|
632 double sleep_factor = |
|
633 (1.0 - marking_task_overhead) / marking_task_overhead; |
|
634 |
|
635 FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num); |
|
636 _sleep_factor = sleep_factor; |
|
637 _marking_task_overhead = marking_task_overhead; |
622 } else { |
638 } else { |
623 if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) { |
639 // Calculate the number of parallel marking threads by scaling |
624 // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent |
640 // the number of parallel GC threads. |
625 // if both are set |
641 uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads); |
626 _sleep_factor = 0.0; |
642 FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num); |
627 _marking_task_overhead = 1.0; |
643 _sleep_factor = 0.0; |
628 } else if (G1MarkingOverheadPercent > 0) { |
644 _marking_task_overhead = 1.0; |
629 // We will calculate the number of parallel marking threads based |
645 } |
630 // on a target overhead with respect to the soft real-time goal |
646 |
631 double marking_overhead = (double) G1MarkingOverheadPercent / 100.0; |
647 assert(ConcGCThreads > 0, "Should have been set"); |
632 double overall_cm_overhead = |
648 _parallel_marking_threads = (uint) ConcGCThreads; |
633 (double) MaxGCPauseMillis * marking_overhead / |
649 _max_parallel_marking_threads = _parallel_marking_threads; |
634 (double) GCPauseIntervalMillis; |
650 |
635 double cpu_ratio = 1.0 / (double) os::processor_count(); |
651 if (parallel_marking_threads() > 1) { |
636 double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio); |
652 _cleanup_task_overhead = 1.0; |
637 double marking_task_overhead = |
653 } else { |
638 overall_cm_overhead / marking_thread_num * |
654 _cleanup_task_overhead = marking_task_overhead(); |
639 (double) os::processor_count(); |
655 } |
640 double sleep_factor = |
656 _cleanup_sleep_factor = |
641 (1.0 - marking_task_overhead) / marking_task_overhead; |
657 (1.0 - cleanup_task_overhead()) / cleanup_task_overhead(); |
642 |
|
643 FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num); |
|
644 _sleep_factor = sleep_factor; |
|
645 _marking_task_overhead = marking_task_overhead; |
|
646 } else { |
|
647 // Calculate the number of parallel marking threads by scaling |
|
648 // the number of parallel GC threads. |
|
649 uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads); |
|
650 FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num); |
|
651 _sleep_factor = 0.0; |
|
652 _marking_task_overhead = 1.0; |
|
653 } |
|
654 |
|
655 assert(ConcGCThreads > 0, "Should have been set"); |
|
656 _parallel_marking_threads = (uint) ConcGCThreads; |
|
657 _max_parallel_marking_threads = _parallel_marking_threads; |
|
658 |
|
659 if (parallel_marking_threads() > 1) { |
|
660 _cleanup_task_overhead = 1.0; |
|
661 } else { |
|
662 _cleanup_task_overhead = marking_task_overhead(); |
|
663 } |
|
664 _cleanup_sleep_factor = |
|
665 (1.0 - cleanup_task_overhead()) / cleanup_task_overhead(); |
|
666 |
658 |
667 #if 0 |
659 #if 0 |
668 gclog_or_tty->print_cr("Marking Threads %d", parallel_marking_threads()); |
660 gclog_or_tty->print_cr("Marking Threads %d", parallel_marking_threads()); |
669 gclog_or_tty->print_cr("CM Marking Task Overhead %1.4lf", marking_task_overhead()); |
661 gclog_or_tty->print_cr("CM Marking Task Overhead %1.4lf", marking_task_overhead()); |
670 gclog_or_tty->print_cr("CM Sleep Factor %1.4lf", sleep_factor()); |
662 gclog_or_tty->print_cr("CM Sleep Factor %1.4lf", sleep_factor()); |
671 gclog_or_tty->print_cr("CL Marking Task Overhead %1.4lf", cleanup_task_overhead()); |
663 gclog_or_tty->print_cr("CL Marking Task Overhead %1.4lf", cleanup_task_overhead()); |
672 gclog_or_tty->print_cr("CL Sleep Factor %1.4lf", cleanup_sleep_factor()); |
664 gclog_or_tty->print_cr("CL Sleep Factor %1.4lf", cleanup_sleep_factor()); |
673 #endif |
665 #endif |
674 |
666 |
675 guarantee(parallel_marking_threads() > 0, "peace of mind"); |
667 _parallel_workers = new FlexibleWorkGang("G1 Parallel Marking Threads", |
676 _parallel_workers = new FlexibleWorkGang("G1 Parallel Marking Threads", |
668 _max_parallel_marking_threads, false, true); |
677 _max_parallel_marking_threads, false, true); |
669 if (_parallel_workers == NULL) { |
678 if (_parallel_workers == NULL) { |
670 vm_exit_during_initialization("Failed necessary allocation."); |
679 vm_exit_during_initialization("Failed necessary allocation."); |
671 } else { |
680 } else { |
672 _parallel_workers->initialize_workers(); |
681 _parallel_workers->initialize_workers(); |
|
682 } |
|
683 } |
673 } |
684 |
674 |
685 if (FLAG_IS_DEFAULT(MarkStackSize)) { |
675 if (FLAG_IS_DEFAULT(MarkStackSize)) { |
686 uintx mark_stack_size = |
676 uintx mark_stack_size = |
687 MIN2(MarkStackSizeMax, |
677 MIN2(MarkStackSizeMax, |
1165 }; |
1155 }; |
1166 |
1156 |
1167 // Calculates the number of active workers for a concurrent |
1157 // Calculates the number of active workers for a concurrent |
1168 // phase. |
1158 // phase. |
1169 uint ConcurrentMark::calc_parallel_marking_threads() { |
1159 uint ConcurrentMark::calc_parallel_marking_threads() { |
1170 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1160 uint n_conc_workers = 0; |
1171 uint n_conc_workers = 0; |
1161 if (!UseDynamicNumberOfGCThreads || |
1172 if (!UseDynamicNumberOfGCThreads || |
1162 (!FLAG_IS_DEFAULT(ConcGCThreads) && |
1173 (!FLAG_IS_DEFAULT(ConcGCThreads) && |
1163 !ForceDynamicNumberOfGCThreads)) { |
1174 !ForceDynamicNumberOfGCThreads)) { |
1164 n_conc_workers = max_parallel_marking_threads(); |
1175 n_conc_workers = max_parallel_marking_threads(); |
1165 } else { |
1176 } else { |
1166 n_conc_workers = |
1177 n_conc_workers = |
1167 AdaptiveSizePolicy::calc_default_active_workers( |
1178 AdaptiveSizePolicy::calc_default_active_workers( |
1168 max_parallel_marking_threads(), |
1179 max_parallel_marking_threads(), |
1169 1, /* Minimum workers */ |
1180 1, /* Minimum workers */ |
1170 parallel_marking_threads(), |
1181 parallel_marking_threads(), |
1171 Threads::number_of_non_daemon_threads()); |
1182 Threads::number_of_non_daemon_threads()); |
1172 // Don't scale down "n_conc_workers" by scale_parallel_threads() because |
1183 // Don't scale down "n_conc_workers" by scale_parallel_threads() because |
1173 // that scaling has already gone into "_max_parallel_marking_threads". |
1184 // that scaling has already gone into "_max_parallel_marking_threads". |
1174 } |
1185 } |
1175 assert(n_conc_workers > 0, "Always need at least 1"); |
1186 assert(n_conc_workers > 0, "Always need at least 1"); |
1176 return n_conc_workers; |
1187 return n_conc_workers; |
|
1188 } |
|
1189 // If we are not running with any parallel GC threads we will not |
|
1190 // have spawned any marking threads either. Hence the number of |
|
1191 // concurrent workers should be 0. |
|
1192 return 0; |
|
1193 } |
1177 } |
1194 |
1178 |
1195 void ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) { |
1179 void ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) { |
1196 // Currently, only survivors can be root regions. |
1180 // Currently, only survivors can be root regions. |
1197 assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant"); |
1181 assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant"); |
1278 |
1258 |
1279 // Parallel task terminator is set in "set_concurrency_and_phase()" |
1259 // Parallel task terminator is set in "set_concurrency_and_phase()" |
1280 set_concurrency_and_phase(active_workers, true /* concurrent */); |
1260 set_concurrency_and_phase(active_workers, true /* concurrent */); |
1281 |
1261 |
1282 CMConcurrentMarkingTask markingTask(this, cmThread()); |
1262 CMConcurrentMarkingTask markingTask(this, cmThread()); |
1283 if (use_parallel_marking_threads()) { |
1263 _parallel_workers->set_active_workers(active_workers); |
1284 _parallel_workers->set_active_workers((int)active_workers); |
1264 // Don't set _n_par_threads because it affects MT in process_roots() |
1285 // Don't set _n_par_threads because it affects MT in process_roots() |
1265 // and the decisions on that MT processing is made elsewhere. |
1286 // and the decisions on that MT processing is made elsewhere. |
1266 assert(_parallel_workers->active_workers() > 0, "Should have been set"); |
1287 assert(_parallel_workers->active_workers() > 0, "Should have been set"); |
1267 _parallel_workers->run_task(&markingTask); |
1288 _parallel_workers->run_task(&markingTask); |
|
1289 } else { |
|
1290 markingTask.work(0); |
|
1291 } |
|
1292 print_stats(); |
1268 print_stats(); |
1293 } |
1269 } |
1294 |
1270 |
1295 // Helper class to get rid of some boilerplate code. |
1271 // Helper class to get rid of some boilerplate code. |
1296 class G1CMTraceTime : public GCTraceTime { |
1272 class G1CMTraceTime : public GCTraceTime { |
1921 double start = os::elapsedTime(); |
1889 double start = os::elapsedTime(); |
1922 FreeRegionList local_cleanup_list("Local Cleanup List"); |
1890 FreeRegionList local_cleanup_list("Local Cleanup List"); |
1923 HRRSCleanupTask hrrs_cleanup_task; |
1891 HRRSCleanupTask hrrs_cleanup_task; |
1924 G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list, |
1892 G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list, |
1925 &hrrs_cleanup_task); |
1893 &hrrs_cleanup_task); |
1926 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1894 _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer); |
1927 _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer); |
|
1928 } else { |
|
1929 _g1h->heap_region_iterate(&g1_note_end); |
|
1930 } |
|
1931 assert(g1_note_end.complete(), "Shouldn't have yielded!"); |
1895 assert(g1_note_end.complete(), "Shouldn't have yielded!"); |
1932 |
1896 |
1933 // Now update the lists |
1897 // Now update the lists |
1934 _g1h->remove_from_old_sets(g1_note_end.old_regions_removed(), g1_note_end.humongous_regions_removed()); |
1898 _g1h->remove_from_old_sets(g1_note_end.old_regions_removed(), g1_note_end.humongous_regions_removed()); |
1935 { |
1899 { |
2019 uint n_workers; |
1979 uint n_workers; |
2020 |
1980 |
2021 // Do counting once more with the world stopped for good measure. |
1981 // Do counting once more with the world stopped for good measure. |
2022 G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm); |
1982 G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm); |
2023 |
1983 |
2024 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1984 g1h->set_par_threads(); |
2025 g1h->set_par_threads(); |
1985 n_workers = g1h->n_par_threads(); |
2026 n_workers = g1h->n_par_threads(); |
1986 assert(g1h->n_par_threads() == n_workers, |
2027 assert(g1h->n_par_threads() == n_workers, |
1987 "Should not have been reset"); |
2028 "Should not have been reset"); |
1988 g1h->workers()->run_task(&g1_par_count_task); |
2029 g1h->workers()->run_task(&g1_par_count_task); |
1989 // Done with the parallel phase so reset to 0. |
2030 // Done with the parallel phase so reset to 0. |
1990 g1h->set_par_threads(0); |
2031 g1h->set_par_threads(0); |
|
2032 } else { |
|
2033 n_workers = 1; |
|
2034 g1_par_count_task.work(0); |
|
2035 } |
|
2036 |
1991 |
2037 if (VerifyDuringGC) { |
1992 if (VerifyDuringGC) { |
2038 // Verify that the counting data accumulated during marking matches |
1993 // Verify that the counting data accumulated during marking matches |
2039 // that calculated by walking the marking bitmap. |
1994 // that calculated by walking the marking bitmap. |
2040 |
1995 |
2098 // call below, since it affects the metric by which we sort the heap |
2045 // call below, since it affects the metric by which we sort the heap |
2099 // regions. |
2046 // regions. |
2100 if (G1ScrubRemSets) { |
2047 if (G1ScrubRemSets) { |
2101 double rs_scrub_start = os::elapsedTime(); |
2048 double rs_scrub_start = os::elapsedTime(); |
2102 G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm, n_workers); |
2049 G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm, n_workers); |
2103 if (G1CollectedHeap::use_parallel_gc_threads()) { |
2050 g1h->set_par_threads((int)n_workers); |
2104 g1h->set_par_threads((int)n_workers); |
2051 g1h->workers()->run_task(&g1_par_scrub_rs_task); |
2105 g1h->workers()->run_task(&g1_par_scrub_rs_task); |
2052 g1h->set_par_threads(0); |
2106 g1h->set_par_threads(0); |
|
2107 } else { |
|
2108 g1_par_scrub_rs_task.work(0); |
|
2109 } |
|
2110 |
2053 |
2111 double rs_scrub_end = os::elapsedTime(); |
2054 double rs_scrub_end = os::elapsedTime(); |
2112 double this_rs_scrub_time = (rs_scrub_end - rs_scrub_start); |
2055 double this_rs_scrub_time = (rs_scrub_end - rs_scrub_start); |
2113 _total_rs_scrub_time += this_rs_scrub_time; |
2056 _total_rs_scrub_time += this_rs_scrub_time; |
2114 } |
2057 } |
2620 class G1RemarkThreadsClosure : public ThreadClosure { |
2563 class G1RemarkThreadsClosure : public ThreadClosure { |
2621 CMObjectClosure _cm_obj; |
2564 CMObjectClosure _cm_obj; |
2622 G1CMOopClosure _cm_cl; |
2565 G1CMOopClosure _cm_cl; |
2623 MarkingCodeBlobClosure _code_cl; |
2566 MarkingCodeBlobClosure _code_cl; |
2624 int _thread_parity; |
2567 int _thread_parity; |
2625 bool _is_par; |
|
2626 |
2568 |
2627 public: |
2569 public: |
2628 G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task, bool is_par) : |
2570 G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task) : |
2629 _cm_obj(task), _cm_cl(g1h, g1h->concurrent_mark(), task), _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations), |
2571 _cm_obj(task), _cm_cl(g1h, g1h->concurrent_mark(), task), _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations), |
2630 _thread_parity(SharedHeap::heap()->strong_roots_parity()), _is_par(is_par) {} |
2572 _thread_parity(SharedHeap::heap()->strong_roots_parity()) {} |
2631 |
2573 |
2632 void do_thread(Thread* thread) { |
2574 void do_thread(Thread* thread) { |
2633 if (thread->is_Java_thread()) { |
2575 if (thread->is_Java_thread()) { |
2634 if (thread->claim_oops_do(_is_par, _thread_parity)) { |
2576 if (thread->claim_oops_do(true, _thread_parity)) { |
2635 JavaThread* jt = (JavaThread*)thread; |
2577 JavaThread* jt = (JavaThread*)thread; |
2636 |
2578 |
2637 // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking |
2579 // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking |
2638 // however the liveness of oops reachable from nmethods have very complex lifecycles: |
2580 // however the liveness of oops reachable from nmethods have very complex lifecycles: |
2639 // * Alive if on the stack of an executing method |
2581 // * Alive if on the stack of an executing method |
2665 task->record_start_time(); |
2606 task->record_start_time(); |
2666 { |
2607 { |
2667 ResourceMark rm; |
2608 ResourceMark rm; |
2668 HandleMark hm; |
2609 HandleMark hm; |
2669 |
2610 |
2670 G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task, !_is_serial); |
2611 G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task); |
2671 Threads::threads_do(&threads_f); |
2612 Threads::threads_do(&threads_f); |
2672 } |
2613 } |
2673 |
2614 |
2674 do { |
2615 do { |
2675 task->do_marking_step(1000000000.0 /* something very large */, |
2616 task->do_marking_step(1000000000.0 /* something very large */, |
2676 true /* do_termination */, |
2617 true /* do_termination */, |
2677 _is_serial); |
2618 false /* is_serial */); |
2678 } while (task->has_aborted() && !_cm->has_overflown()); |
2619 } while (task->has_aborted() && !_cm->has_overflown()); |
2679 // If we overflow, then we do not want to restart. We instead |
2620 // If we overflow, then we do not want to restart. We instead |
2680 // want to abort remark and do concurrent marking again. |
2621 // want to abort remark and do concurrent marking again. |
2681 task->record_end_time(); |
2622 task->record_end_time(); |
2682 } |
2623 } |
2683 } |
2624 } |
2684 |
2625 |
2685 CMRemarkTask(ConcurrentMark* cm, int active_workers, bool is_serial) : |
2626 CMRemarkTask(ConcurrentMark* cm, int active_workers) : |
2686 AbstractGangTask("Par Remark"), _cm(cm), _is_serial(is_serial) { |
2627 AbstractGangTask("Par Remark"), _cm(cm) { |
2687 _cm->terminator()->reset_for_reuse(active_workers); |
2628 _cm->terminator()->reset_for_reuse(active_workers); |
2688 } |
2629 } |
2689 }; |
2630 }; |
2690 |
2631 |
2691 void ConcurrentMark::checkpointRootsFinalWork() { |
2632 void ConcurrentMark::checkpointRootsFinalWork() { |
2695 |
2636 |
2696 G1CMTraceTime trace("Finalize Marking", G1Log::finer()); |
2637 G1CMTraceTime trace("Finalize Marking", G1Log::finer()); |
2697 |
2638 |
2698 g1h->ensure_parsability(false); |
2639 g1h->ensure_parsability(false); |
2699 |
2640 |
2700 if (G1CollectedHeap::use_parallel_gc_threads()) { |
2641 G1CollectedHeap::StrongRootsScope srs(g1h); |
2701 G1CollectedHeap::StrongRootsScope srs(g1h); |
2642 // this is remark, so we'll use up all active threads |
2702 // this is remark, so we'll use up all active threads |
2643 uint active_workers = g1h->workers()->active_workers(); |
2703 uint active_workers = g1h->workers()->active_workers(); |
2644 if (active_workers == 0) { |
2704 if (active_workers == 0) { |
2645 assert(active_workers > 0, "Should have been set earlier"); |
2705 assert(active_workers > 0, "Should have been set earlier"); |
2646 active_workers = (uint) ParallelGCThreads; |
2706 active_workers = (uint) ParallelGCThreads; |
2647 g1h->workers()->set_active_workers(active_workers); |
2707 g1h->workers()->set_active_workers(active_workers); |
2648 } |
2708 } |
2649 set_concurrency_and_phase(active_workers, false /* concurrent */); |
2709 set_concurrency_and_phase(active_workers, false /* concurrent */); |
2650 // Leave _parallel_marking_threads at it's |
2710 // Leave _parallel_marking_threads at it's |
2651 // value originally calculated in the ConcurrentMark |
2711 // value originally calculated in the ConcurrentMark |
2652 // constructor and pass values of the active workers |
2712 // constructor and pass values of the active workers |
2653 // through the gang in the task. |
2713 // through the gang in the task. |
2654 |
2714 |
2655 CMRemarkTask remarkTask(this, active_workers); |
2715 CMRemarkTask remarkTask(this, active_workers, false /* is_serial */); |
2656 // We will start all available threads, even if we decide that the |
2716 // We will start all available threads, even if we decide that the |
2657 // active_workers will be fewer. The extra ones will just bail out |
2717 // active_workers will be fewer. The extra ones will just bail out |
2658 // immediately. |
2718 // immediately. |
2659 g1h->set_par_threads(active_workers); |
2719 g1h->set_par_threads(active_workers); |
2660 g1h->workers()->run_task(&remarkTask); |
2720 g1h->workers()->run_task(&remarkTask); |
2661 g1h->set_par_threads(0); |
2721 g1h->set_par_threads(0); |
2662 |
2722 } else { |
|
2723 G1CollectedHeap::StrongRootsScope srs(g1h); |
|
2724 uint active_workers = 1; |
|
2725 set_concurrency_and_phase(active_workers, false /* concurrent */); |
|
2726 |
|
2727 // Note - if there's no work gang then the VMThread will be |
|
2728 // the thread to execute the remark - serially. We have |
|
2729 // to pass true for the is_serial parameter so that |
|
2730 // CMTask::do_marking_step() doesn't enter the sync |
|
2731 // barriers in the event of an overflow. Doing so will |
|
2732 // cause an assert that the current thread is not a |
|
2733 // concurrent GC thread. |
|
2734 CMRemarkTask remarkTask(this, active_workers, true /* is_serial*/); |
|
2735 remarkTask.work(0); |
|
2736 } |
|
2737 SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); |
2663 SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); |
2738 guarantee(has_overflown() || |
2664 guarantee(has_overflown() || |
2739 satb_mq_set.completed_buffers_num() == 0, |
2665 satb_mq_set.completed_buffers_num() == 0, |
2740 err_msg("Invariant: has_overflown = %s, num buffers = %d", |
2666 err_msg("Invariant: has_overflown = %s, num buffers = %d", |
2741 BOOL_TO_STR(has_overflown()), |
2667 BOOL_TO_STR(has_overflown()), |
3277 } |
3203 } |
3278 |
3204 |
3279 void work(uint worker_id) { |
3205 void work(uint worker_id) { |
3280 AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id); |
3206 AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id); |
3281 |
3207 |
3282 if (G1CollectedHeap::use_parallel_gc_threads()) { |
3208 _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer); |
3283 _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer); |
|
3284 } else { |
|
3285 _g1h->heap_region_iterate(&cl); |
|
3286 } |
|
3287 } |
3209 } |
3288 }; |
3210 }; |
3289 |
3211 |
3290 |
3212 |
3291 void ConcurrentMark::aggregate_count_data() { |
3213 void ConcurrentMark::aggregate_count_data() { |
3292 int n_workers = (G1CollectedHeap::use_parallel_gc_threads() ? |
3214 int n_workers = _g1h->workers()->active_workers(); |
3293 _g1h->workers()->active_workers() : |
|
3294 1); |
|
3295 |
3215 |
3296 G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm, |
3216 G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm, |
3297 _max_worker_id, n_workers); |
3217 _max_worker_id, n_workers); |
3298 |
3218 |
3299 if (G1CollectedHeap::use_parallel_gc_threads()) { |
3219 _g1h->set_par_threads(n_workers); |
3300 _g1h->set_par_threads(n_workers); |
3220 _g1h->workers()->run_task(&g1_par_agg_task); |
3301 _g1h->workers()->run_task(&g1_par_agg_task); |
3221 _g1h->set_par_threads(0); |
3302 _g1h->set_par_threads(0); |
|
3303 } else { |
|
3304 g1_par_agg_task.work(0); |
|
3305 } |
|
3306 _g1h->allocation_context_stats().update_at_remark(); |
3222 _g1h->allocation_context_stats().update_at_remark(); |
3307 } |
3223 } |
3308 |
3224 |
3309 // Clear the per-worker arrays used to store the per-region counting data |
3225 // Clear the per-worker arrays used to store the per-region counting data |
3310 void ConcurrentMark::clear_all_count_data() { |
3226 void ConcurrentMark::clear_all_count_data() { |
3951 // very counter productive if it did that. :-) |
3865 // very counter productive if it did that. :-) |
3952 _draining_satb_buffers = true; |
3866 _draining_satb_buffers = true; |
3953 |
3867 |
3954 CMObjectClosure oc(this); |
3868 CMObjectClosure oc(this); |
3955 SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); |
3869 SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); |
3956 if (G1CollectedHeap::use_parallel_gc_threads()) { |
3870 satb_mq_set.set_closure(_worker_id, &oc); |
3957 satb_mq_set.set_par_closure(_worker_id, &oc); |
|
3958 } else { |
|
3959 satb_mq_set.set_closure(&oc); |
|
3960 } |
|
3961 |
3871 |
3962 // This keeps claiming and applying the closure to completed buffers |
3872 // This keeps claiming and applying the closure to completed buffers |
3963 // until we run out of buffers or we need to abort. |
3873 // until we run out of buffers or we need to abort. |
3964 if (G1CollectedHeap::use_parallel_gc_threads()) { |
3874 while (!has_aborted() && |
3965 while (!has_aborted() && |
3875 satb_mq_set.apply_closure_to_completed_buffer(_worker_id)) { |
3966 satb_mq_set.par_apply_closure_to_completed_buffer(_worker_id)) { |
3876 if (_cm->verbose_medium()) { |
3967 if (_cm->verbose_medium()) { |
3877 gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id); |
3968 gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id); |
3878 } |
3969 } |
3879 statsOnly( ++_satb_buffers_processed ); |
3970 statsOnly( ++_satb_buffers_processed ); |
3880 regular_clock_call(); |
3971 regular_clock_call(); |
|
3972 } |
|
3973 } else { |
|
3974 while (!has_aborted() && |
|
3975 satb_mq_set.apply_closure_to_completed_buffer()) { |
|
3976 if (_cm->verbose_medium()) { |
|
3977 gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id); |
|
3978 } |
|
3979 statsOnly( ++_satb_buffers_processed ); |
|
3980 regular_clock_call(); |
|
3981 } |
|
3982 } |
3881 } |
3983 |
3882 |
3984 _draining_satb_buffers = false; |
3883 _draining_satb_buffers = false; |
3985 |
3884 |
3986 assert(has_aborted() || |
3885 assert(has_aborted() || |
3987 concurrent() || |
3886 concurrent() || |
3988 satb_mq_set.completed_buffers_num() == 0, "invariant"); |
3887 satb_mq_set.completed_buffers_num() == 0, "invariant"); |
3989 |
3888 |
3990 if (G1CollectedHeap::use_parallel_gc_threads()) { |
3889 satb_mq_set.set_closure(_worker_id, NULL); |
3991 satb_mq_set.set_par_closure(_worker_id, NULL); |
|
3992 } else { |
|
3993 satb_mq_set.set_closure(NULL); |
|
3994 } |
|
3995 |
3890 |
3996 // again, this was a potentially expensive operation, decrease the |
3891 // again, this was a potentially expensive operation, decrease the |
3997 // limits to get the regular clock call early |
3892 // limits to get the regular clock call early |
3998 decrease_limits(); |
3893 decrease_limits(); |
3999 } |
3894 } |