375 _has_overflown(false), |
375 _has_overflown(false), |
376 _concurrent(false), |
376 _concurrent(false), |
377 _has_aborted(false), |
377 _has_aborted(false), |
378 _restart_for_overflow(false), |
378 _restart_for_overflow(false), |
379 _concurrent_marking_in_progress(false), |
379 _concurrent_marking_in_progress(false), |
380 _concurrent_phase_status(ConcPhaseNotStarted), |
380 _gc_timer_cm(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()), |
|
381 _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()), |
381 |
382 |
382 // _verbose_level set below |
383 // _verbose_level set below |
383 |
384 |
384 _init_times(), |
385 _init_times(), |
385 _remark_times(), _remark_mark_times(), _remark_weak_ref_times(), |
386 _remark_times(), _remark_mark_times(), _remark_weak_ref_times(), |
1009 // mainly used for sanity checking. |
1010 // mainly used for sanity checking. |
1010 root_regions()->scan_finished(); |
1011 root_regions()->scan_finished(); |
1011 } |
1012 } |
1012 } |
1013 } |
1013 |
1014 |
1014 void G1ConcurrentMark::register_concurrent_phase_start(const char* title) { |
1015 void G1ConcurrentMark::concurrent_cycle_start() { |
1015 uint old_val = 0; |
1016 _gc_timer_cm->register_gc_start(); |
1016 do { |
1017 |
1017 old_val = Atomic::cmpxchg(ConcPhaseStarted, &_concurrent_phase_status, ConcPhaseNotStarted); |
1018 _gc_tracer_cm->report_gc_start(GCCause::_no_gc /* first parameter is not used */, _gc_timer_cm->gc_start()); |
1018 } while (old_val != ConcPhaseNotStarted); |
1019 |
1019 _g1h->gc_timer_cm()->register_gc_concurrent_start(title); |
1020 _g1h->trace_heap_before_gc(_gc_tracer_cm); |
1020 } |
1021 } |
1021 |
1022 |
1022 void G1ConcurrentMark::register_concurrent_phase_end_common(bool end_timer) { |
1023 void G1ConcurrentMark::concurrent_cycle_end() { |
1023 if (_concurrent_phase_status == ConcPhaseNotStarted) { |
1024 _g1h->trace_heap_after_gc(_gc_tracer_cm); |
1024 return; |
1025 |
1025 } |
1026 if (has_aborted()) { |
1026 |
1027 _gc_tracer_cm->report_concurrent_mode_failure(); |
1027 uint old_val = Atomic::cmpxchg(ConcPhaseStopping, &_concurrent_phase_status, ConcPhaseStarted); |
1028 } |
1028 if (old_val == ConcPhaseStarted) { |
1029 |
1029 _g1h->gc_timer_cm()->register_gc_concurrent_end(); |
1030 _gc_timer_cm->register_gc_end(); |
1030 // If 'end_timer' is true, we came here to end timer which needs concurrent phase ended. |
1031 |
1031 // We need to end it before changing the status to 'ConcPhaseNotStarted' to prevent |
1032 _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); |
1032 // starting a new concurrent phase by 'ConcurrentMarkThread'. |
|
1033 if (end_timer) { |
|
1034 _g1h->gc_timer_cm()->register_gc_end(); |
|
1035 } |
|
1036 old_val = Atomic::cmpxchg(ConcPhaseNotStarted, &_concurrent_phase_status, ConcPhaseStopping); |
|
1037 assert(old_val == ConcPhaseStopping, "Should not have changed since we entered this scope."); |
|
1038 } else { |
|
1039 do { |
|
1040 // Let other thread finish changing '_concurrent_phase_status' to 'ConcPhaseNotStarted'. |
|
1041 os::naked_short_sleep(1); |
|
1042 } while (_concurrent_phase_status != ConcPhaseNotStarted); |
|
1043 } |
|
1044 } |
|
1045 |
|
1046 void G1ConcurrentMark::register_concurrent_phase_end() { |
|
1047 register_concurrent_phase_end_common(false); |
|
1048 } |
|
1049 |
|
1050 void G1ConcurrentMark::register_concurrent_gc_end_and_stop_timer() { |
|
1051 register_concurrent_phase_end_common(true); |
|
1052 } |
1033 } |
1053 |
1034 |
1054 void G1ConcurrentMark::mark_from_roots() { |
1035 void G1ConcurrentMark::mark_from_roots() { |
1055 // we might be tempted to assert that: |
1036 // we might be tempted to assert that: |
1056 // assert(asynch == !SafepointSynchronize::is_at_safepoint(), |
1037 // assert(asynch == !SafepointSynchronize::is_at_safepoint(), |
1125 // Clear the marking state because we will be restarting |
1106 // Clear the marking state because we will be restarting |
1126 // marking due to overflowing the global mark stack. |
1107 // marking due to overflowing the global mark stack. |
1127 reset_marking_state(); |
1108 reset_marking_state(); |
1128 } else { |
1109 } else { |
1129 { |
1110 { |
1130 GCTraceTime(Debug, gc) trace("Aggregate Data", g1h->gc_timer_cm()); |
1111 GCTraceTime(Debug, gc) trace("Aggregate Data", _gc_timer_cm); |
1131 |
1112 |
1132 // Aggregate the per-task counting data that we have accumulated |
1113 // Aggregate the per-task counting data that we have accumulated |
1133 // while marking. |
1114 // while marking. |
1134 aggregate_count_data(); |
1115 aggregate_count_data(); |
1135 } |
1116 } |
1164 _remark_times.add((now - start) * 1000.0); |
1145 _remark_times.add((now - start) * 1000.0); |
1165 |
1146 |
1166 g1p->record_concurrent_mark_remark_end(); |
1147 g1p->record_concurrent_mark_remark_end(); |
1167 |
1148 |
1168 G1CMIsAliveClosure is_alive(g1h); |
1149 G1CMIsAliveClosure is_alive(g1h); |
1169 g1h->gc_tracer_cm()->report_object_count_after_gc(&is_alive); |
1150 _gc_tracer_cm->report_object_count_after_gc(&is_alive); |
1170 } |
1151 } |
1171 |
1152 |
1172 // Base class of the closures that finalize and verify the |
1153 // Base class of the closures that finalize and verify the |
1173 // liveness counting data. |
1154 // liveness counting data. |
1174 class G1CMCountDataClosureBase: public HeapRegionClosure { |
1155 class G1CMCountDataClosureBase: public HeapRegionClosure { |
1753 |
1734 |
1754 // We reclaimed old regions so we should calculate the sizes to make |
1735 // We reclaimed old regions so we should calculate the sizes to make |
1755 // sure we update the old gen/space data. |
1736 // sure we update the old gen/space data. |
1756 g1h->g1mm()->update_sizes(); |
1737 g1h->g1mm()->update_sizes(); |
1757 g1h->allocation_context_stats().update_after_mark(); |
1738 g1h->allocation_context_stats().update_after_mark(); |
1758 |
|
1759 g1h->trace_heap_after_concurrent_cycle(); |
|
1760 } |
1739 } |
1761 |
1740 |
1762 void G1ConcurrentMark::complete_cleanup() { |
1741 void G1ConcurrentMark::complete_cleanup() { |
1763 if (has_aborted()) return; |
1742 if (has_aborted()) return; |
1764 |
1743 |
2046 G1CMIsAliveClosure g1_is_alive(g1h); |
2025 G1CMIsAliveClosure g1_is_alive(g1h); |
2047 |
2026 |
2048 // Inner scope to exclude the cleaning of the string and symbol |
2027 // Inner scope to exclude the cleaning of the string and symbol |
2049 // tables from the displayed time. |
2028 // tables from the displayed time. |
2050 { |
2029 { |
2051 GCTraceTime(Debug, gc) trace("Reference Processing", g1h->gc_timer_cm()); |
2030 GCTraceTime(Debug, gc) trace("Reference Processing", _gc_timer_cm); |
2052 |
2031 |
2053 ReferenceProcessor* rp = g1h->ref_processor_cm(); |
2032 ReferenceProcessor* rp = g1h->ref_processor_cm(); |
2054 |
2033 |
2055 // See the comment in G1CollectedHeap::ref_processing_init() |
2034 // See the comment in G1CollectedHeap::ref_processing_init() |
2056 // about how reference processing currently works in G1. |
2035 // about how reference processing currently works in G1. |
2103 const ReferenceProcessorStats& stats = |
2082 const ReferenceProcessorStats& stats = |
2104 rp->process_discovered_references(&g1_is_alive, |
2083 rp->process_discovered_references(&g1_is_alive, |
2105 &g1_keep_alive, |
2084 &g1_keep_alive, |
2106 &g1_drain_mark_stack, |
2085 &g1_drain_mark_stack, |
2107 executor, |
2086 executor, |
2108 g1h->gc_timer_cm()); |
2087 _gc_timer_cm); |
2109 g1h->gc_tracer_cm()->report_gc_reference_stats(stats); |
2088 _gc_tracer_cm->report_gc_reference_stats(stats); |
2110 |
2089 |
2111 // The do_oop work routines of the keep_alive and drain_marking_stack |
2090 // The do_oop work routines of the keep_alive and drain_marking_stack |
2112 // oop closures will set the has_overflown flag if we overflow the |
2091 // oop closures will set the has_overflown flag if we overflow the |
2113 // global marking stack. |
2092 // global marking stack. |
2114 |
2093 |
2136 |
2115 |
2137 assert(_markStack.isEmpty(), "Marking should have completed"); |
2116 assert(_markStack.isEmpty(), "Marking should have completed"); |
2138 |
2117 |
2139 // Unload Klasses, String, Symbols, Code Cache, etc. |
2118 // Unload Klasses, String, Symbols, Code Cache, etc. |
2140 { |
2119 { |
2141 GCTraceTime(Debug, gc) trace("Unloading", g1h->gc_timer_cm()); |
2120 GCTraceTime(Debug, gc) trace("Unloading", _gc_timer_cm); |
2142 |
2121 |
2143 if (ClassUnloadingWithConcurrentMark) { |
2122 if (ClassUnloadingWithConcurrentMark) { |
2144 bool purged_classes; |
2123 bool purged_classes; |
2145 |
2124 |
2146 { |
2125 { |
2147 GCTraceTime(Trace, gc) trace("System Dictionary Unloading", g1h->gc_timer_cm()); |
2126 GCTraceTime(Trace, gc) trace("System Dictionary Unloading", _gc_timer_cm); |
2148 purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */); |
2127 purged_classes = SystemDictionary::do_unloading(&g1_is_alive, false /* Defer klass cleaning */); |
2149 } |
2128 } |
2150 |
2129 |
2151 { |
2130 { |
2152 GCTraceTime(Trace, gc) trace("Parallel Unloading", g1h->gc_timer_cm()); |
2131 GCTraceTime(Trace, gc) trace("Parallel Unloading", _gc_timer_cm); |
2153 weakRefsWorkParallelPart(&g1_is_alive, purged_classes); |
2132 weakRefsWorkParallelPart(&g1_is_alive, purged_classes); |
2154 } |
2133 } |
2155 } |
2134 } |
2156 |
2135 |
2157 if (G1StringDedup::is_enabled()) { |
2136 if (G1StringDedup::is_enabled()) { |
2158 GCTraceTime(Trace, gc) trace("String Deduplication Unlink", g1h->gc_timer_cm()); |
2137 GCTraceTime(Trace, gc) trace("String Deduplication Unlink", _gc_timer_cm); |
2159 G1StringDedup::unlink(&g1_is_alive); |
2138 G1StringDedup::unlink(&g1_is_alive); |
2160 } |
2139 } |
2161 } |
2140 } |
2162 } |
2141 } |
2163 |
2142 |
2274 void G1ConcurrentMark::checkpointRootsFinalWork() { |
2253 void G1ConcurrentMark::checkpointRootsFinalWork() { |
2275 ResourceMark rm; |
2254 ResourceMark rm; |
2276 HandleMark hm; |
2255 HandleMark hm; |
2277 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2256 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2278 |
2257 |
2279 GCTraceTime(Debug, gc) trace("Finalize Marking", g1h->gc_timer_cm()); |
2258 GCTraceTime(Debug, gc) trace("Finalize Marking", _gc_timer_cm); |
2280 |
2259 |
2281 g1h->ensure_parsability(false); |
2260 g1h->ensure_parsability(false); |
2282 |
2261 |
2283 // this is remark, so we'll use up all active threads |
2262 // this is remark, so we'll use up all active threads |
2284 uint active_workers = g1h->workers()->active_workers(); |
2263 uint active_workers = g1h->workers()->active_workers(); |
2630 // This can be called either during or outside marking, we'll read |
2609 // This can be called either during or outside marking, we'll read |
2631 // the expected_active value from the SATB queue set. |
2610 // the expected_active value from the SATB queue set. |
2632 satb_mq_set.set_active_all_threads( |
2611 satb_mq_set.set_active_all_threads( |
2633 false, /* new active value */ |
2612 false, /* new active value */ |
2634 satb_mq_set.is_active() /* expected_active */); |
2613 satb_mq_set.is_active() /* expected_active */); |
2635 |
|
2636 _g1h->trace_heap_after_concurrent_cycle(); |
|
2637 |
|
2638 _g1h->register_concurrent_cycle_end(); |
|
2639 } |
2614 } |
2640 |
2615 |
2641 static void print_ms_time_info(const char* prefix, const char* name, |
2616 static void print_ms_time_info(const char* prefix, const char* name, |
2642 NumberSeq& ns) { |
2617 NumberSeq& ns) { |
2643 log_trace(gc, marking)("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).", |
2618 log_trace(gc, marking)("%s%5d %12s: total time = %8.2f s (avg = %8.2f ms).", |