Thu, 19 Jun 2014 13:31:14 +0200
8043607: Add a GC id as a log decoration similar to PrintGCTimeStamps
Reviewed-by: jwilhelm, ehelin, tschatzl
sla@5237 | 1 | /* |
sla@5237 | 2 | * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. |
sla@5237 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
sla@5237 | 4 | * |
sla@5237 | 5 | * This code is free software; you can redistribute it and/or modify it |
sla@5237 | 6 | * under the terms of the GNU General Public License version 2 only, as |
sla@5237 | 7 | * published by the Free Software Foundation. |
sla@5237 | 8 | * |
sla@5237 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
sla@5237 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
sla@5237 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
sla@5237 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
sla@5237 | 13 | * accompanied this code). |
sla@5237 | 14 | * |
sla@5237 | 15 | * You should have received a copy of the GNU General Public License version |
sla@5237 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
sla@5237 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
sla@5237 | 18 | * |
sla@5237 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
sla@5237 | 20 | * or visit www.oracle.com if you need additional information or have any |
sla@5237 | 21 | * questions. |
sla@5237 | 22 | * |
sla@5237 | 23 | */ |
sla@5237 | 24 | |
sla@5237 | 25 | #include "precompiled.hpp" |
ehelin@5386 | 26 | #include "gc_implementation/shared/copyFailedInfo.hpp" |
sla@5237 | 27 | #include "gc_implementation/shared/gcHeapSummary.hpp" |
brutisso@6904 | 28 | #include "gc_implementation/shared/gcId.hpp" |
sla@5237 | 29 | #include "gc_implementation/shared/gcTimer.hpp" |
sla@5237 | 30 | #include "gc_implementation/shared/gcTrace.hpp" |
ehelin@5386 | 31 | #include "gc_implementation/shared/objectCountEventSender.hpp" |
sla@5237 | 32 | #include "memory/heapInspection.hpp" |
sla@5237 | 33 | #include "memory/referenceProcessorStats.hpp" |
ehelin@5388 | 34 | #include "runtime/os.hpp" |
sla@5237 | 35 | #include "utilities/globalDefinitions.hpp" |
mgronlun@6131 | 36 | #include "utilities/ticks.inline.hpp" |
sla@5237 | 37 | |
sla@5237 | 38 | #if INCLUDE_ALL_GCS |
sla@5237 | 39 | #include "gc_implementation/g1/evacuationInfo.hpp" |
sla@5237 | 40 | #endif |
sla@5237 | 41 | |
brutisso@6904 | 42 | #define assert_unset_gc_id() assert(_shared_gc_info.gc_id().is_undefined(), "GC already started?") |
brutisso@6904 | 43 | #define assert_set_gc_id() assert(!_shared_gc_info.gc_id().is_undefined(), "GC not started?") |
sla@5237 | 44 | |
mgronlun@6131 | 45 | void GCTracer::report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp) { |
sla@5237 | 46 | assert_unset_gc_id(); |
sla@5237 | 47 | |
brutisso@6904 | 48 | GCId gc_id = GCId::create(); |
brutisso@6904 | 49 | _shared_gc_info.set_gc_id(gc_id); |
sla@5237 | 50 | _shared_gc_info.set_cause(cause); |
sla@5237 | 51 | _shared_gc_info.set_start_timestamp(timestamp); |
sla@5237 | 52 | } |
sla@5237 | 53 | |
mgronlun@6131 | 54 | void GCTracer::report_gc_start(GCCause::Cause cause, const Ticks& timestamp) { |
sla@5237 | 55 | assert_unset_gc_id(); |
sla@5237 | 56 | |
sla@5237 | 57 | report_gc_start_impl(cause, timestamp); |
sla@5237 | 58 | } |
sla@5237 | 59 | |
sla@5237 | 60 | bool GCTracer::has_reported_gc_start() const { |
brutisso@6904 | 61 | return !_shared_gc_info.gc_id().is_undefined(); |
sla@5237 | 62 | } |
sla@5237 | 63 | |
mgronlun@6131 | 64 | void GCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { |
sla@5237 | 65 | assert_set_gc_id(); |
sla@5237 | 66 | |
sla@5237 | 67 | _shared_gc_info.set_sum_of_pauses(time_partitions->sum_of_pauses()); |
sla@5237 | 68 | _shared_gc_info.set_longest_pause(time_partitions->longest_pause()); |
sla@5237 | 69 | _shared_gc_info.set_end_timestamp(timestamp); |
sla@5237 | 70 | |
sla@5237 | 71 | send_phase_events(time_partitions); |
sla@5237 | 72 | send_garbage_collection_event(); |
sla@5237 | 73 | } |
sla@5237 | 74 | |
mgronlun@6131 | 75 | void GCTracer::report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions) { |
sla@5237 | 76 | assert_set_gc_id(); |
sla@5237 | 77 | |
sla@5237 | 78 | report_gc_end_impl(timestamp, time_partitions); |
sla@5237 | 79 | |
brutisso@6904 | 80 | _shared_gc_info.set_gc_id(GCId::undefined()); |
sla@5237 | 81 | } |
sla@5237 | 82 | |
sla@5237 | 83 | void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) const { |
sla@5237 | 84 | assert_set_gc_id(); |
sla@5237 | 85 | |
sla@5237 | 86 | send_reference_stats_event(REF_SOFT, rps.soft_count()); |
sla@5237 | 87 | send_reference_stats_event(REF_WEAK, rps.weak_count()); |
sla@5237 | 88 | send_reference_stats_event(REF_FINAL, rps.final_count()); |
sla@5237 | 89 | send_reference_stats_event(REF_PHANTOM, rps.phantom_count()); |
sla@5237 | 90 | } |
sla@5237 | 91 | |
sla@5237 | 92 | #if INCLUDE_SERVICES |
ehelin@5386 | 93 | class ObjectCountEventSenderClosure : public KlassInfoClosure { |
ehelin@5386 | 94 | const GCId _gc_id; |
ehelin@5386 | 95 | const double _size_threshold_percentage; |
ehelin@5386 | 96 | const size_t _total_size_in_words; |
mgronlun@6131 | 97 | const Ticks _timestamp; |
ehelin@5386 | 98 | |
ehelin@5386 | 99 | public: |
mgronlun@6131 | 100 | ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, const Ticks& timestamp) : |
ehelin@5386 | 101 | _gc_id(gc_id), |
ehelin@5386 | 102 | _size_threshold_percentage(ObjectCountCutOffPercent / 100), |
ehelin@5388 | 103 | _total_size_in_words(total_size_in_words), |
ehelin@5388 | 104 | _timestamp(timestamp) |
ehelin@5386 | 105 | {} |
ehelin@5386 | 106 | |
ehelin@5386 | 107 | virtual void do_cinfo(KlassInfoEntry* entry) { |
ehelin@5386 | 108 | if (should_send_event(entry)) { |
ehelin@5388 | 109 | ObjectCountEventSender::send(entry, _gc_id, _timestamp); |
ehelin@5386 | 110 | } |
sla@5237 | 111 | } |
sla@5237 | 112 | |
ehelin@5386 | 113 | private: |
ehelin@5386 | 114 | bool should_send_event(const KlassInfoEntry* entry) const { |
ehelin@5386 | 115 | double percentage_of_heap = ((double) entry->words()) / _total_size_in_words; |
ehelin@5386 | 116 | return percentage_of_heap >= _size_threshold_percentage; |
ehelin@5386 | 117 | } |
ehelin@5386 | 118 | }; |
sla@5237 | 119 | |
sla@5237 | 120 | void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) { |
sla@5237 | 121 | assert_set_gc_id(); |
ehelin@5386 | 122 | assert(is_alive_cl != NULL, "Must supply function to check liveness"); |
sla@5237 | 123 | |
ehelin@5386 | 124 | if (ObjectCountEventSender::should_send_event()) { |
sla@5237 | 125 | ResourceMark rm; |
sla@5237 | 126 | |
sla@5237 | 127 | KlassInfoTable cit(false); |
sla@5237 | 128 | if (!cit.allocation_failed()) { |
sla@5237 | 129 | HeapInspection hi(false, false, false, NULL); |
sla@5237 | 130 | hi.populate_table(&cit, is_alive_cl); |
brutisso@6904 | 131 | ObjectCountEventSenderClosure event_sender(_shared_gc_info.gc_id(), cit.size_of_instances_in_words(), Ticks::now()); |
sla@5237 | 132 | cit.iterate(&event_sender); |
sla@5237 | 133 | } |
sla@5237 | 134 | } |
sla@5237 | 135 | } |
ehelin@5386 | 136 | #endif // INCLUDE_SERVICES |
sla@5237 | 137 | |
ehelin@6420 | 138 | void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary) const { |
sla@5237 | 139 | assert_set_gc_id(); |
sla@5237 | 140 | |
sla@5237 | 141 | send_gc_heap_summary_event(when, heap_summary); |
ehelin@6420 | 142 | } |
ehelin@6420 | 143 | |
ehelin@6420 | 144 | void GCTracer::report_metaspace_summary(GCWhen::Type when, const MetaspaceSummary& summary) const { |
ehelin@6420 | 145 | assert_set_gc_id(); |
ehelin@6420 | 146 | |
ehelin@6420 | 147 | send_meta_space_summary_event(when, summary); |
ehelin@6420 | 148 | |
ehelin@6420 | 149 | send_metaspace_chunk_free_list_summary(when, Metaspace::NonClassType, summary.metaspace_chunk_free_list_summary()); |
ehelin@6420 | 150 | if (UseCompressedClassPointers) { |
ehelin@6420 | 151 | send_metaspace_chunk_free_list_summary(when, Metaspace::ClassType, summary.class_chunk_free_list_summary()); |
ehelin@6420 | 152 | } |
sla@5237 | 153 | } |
sla@5237 | 154 | |
mgronlun@6131 | 155 | void YoungGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { |
sla@5237 | 156 | assert_set_gc_id(); |
sla@5237 | 157 | assert(_tenuring_threshold != UNSET_TENURING_THRESHOLD, "Tenuring threshold has not been reported"); |
sla@5237 | 158 | |
sla@5237 | 159 | GCTracer::report_gc_end_impl(timestamp, time_partitions); |
sla@5237 | 160 | send_young_gc_event(); |
sla@5237 | 161 | |
sla@5237 | 162 | _tenuring_threshold = UNSET_TENURING_THRESHOLD; |
sla@5237 | 163 | } |
sla@5237 | 164 | |
sla@5237 | 165 | void YoungGCTracer::report_promotion_failed(const PromotionFailedInfo& pf_info) { |
sla@5237 | 166 | assert_set_gc_id(); |
sla@5237 | 167 | |
sla@5237 | 168 | send_promotion_failed_event(pf_info); |
sla@5237 | 169 | } |
sla@5237 | 170 | |
sla@5237 | 171 | void YoungGCTracer::report_tenuring_threshold(const uint tenuring_threshold) { |
sla@5237 | 172 | _tenuring_threshold = tenuring_threshold; |
sla@5237 | 173 | } |
sla@5237 | 174 | |
mgronlun@6131 | 175 | void OldGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { |
sla@5237 | 176 | assert_set_gc_id(); |
sla@5237 | 177 | |
sla@5237 | 178 | GCTracer::report_gc_end_impl(timestamp, time_partitions); |
sla@5237 | 179 | send_old_gc_event(); |
sla@5237 | 180 | } |
sla@5237 | 181 | |
mgronlun@6131 | 182 | void ParallelOldTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { |
sla@5237 | 183 | assert_set_gc_id(); |
sla@5237 | 184 | |
sla@5237 | 185 | OldGCTracer::report_gc_end_impl(timestamp, time_partitions); |
sla@5237 | 186 | send_parallel_old_event(); |
sla@5237 | 187 | } |
sla@5237 | 188 | |
sla@5237 | 189 | void ParallelOldTracer::report_dense_prefix(void* dense_prefix) { |
sla@5237 | 190 | assert_set_gc_id(); |
sla@5237 | 191 | |
sla@5237 | 192 | _parallel_old_gc_info.report_dense_prefix(dense_prefix); |
sla@5237 | 193 | } |
sla@5237 | 194 | |
sla@5237 | 195 | void OldGCTracer::report_concurrent_mode_failure() { |
sla@5237 | 196 | assert_set_gc_id(); |
sla@5237 | 197 | |
sla@5237 | 198 | send_concurrent_mode_failure_event(); |
sla@5237 | 199 | } |
sla@5237 | 200 | |
sla@5237 | 201 | #if INCLUDE_ALL_GCS |
sla@5237 | 202 | void G1NewTracer::report_yc_type(G1YCType type) { |
sla@5237 | 203 | assert_set_gc_id(); |
sla@5237 | 204 | |
sla@5237 | 205 | _g1_young_gc_info.set_type(type); |
sla@5237 | 206 | } |
sla@5237 | 207 | |
mgronlun@6131 | 208 | void G1NewTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { |
sla@5237 | 209 | assert_set_gc_id(); |
sla@5237 | 210 | |
sla@5237 | 211 | YoungGCTracer::report_gc_end_impl(timestamp, time_partitions); |
sla@5237 | 212 | send_g1_young_gc_event(); |
sla@5237 | 213 | } |
sla@5237 | 214 | |
sla@5237 | 215 | void G1NewTracer::report_evacuation_info(EvacuationInfo* info) { |
sla@5237 | 216 | assert_set_gc_id(); |
sla@5237 | 217 | |
sla@5237 | 218 | send_evacuation_info_event(info); |
sla@5237 | 219 | } |
sla@5237 | 220 | |
sla@5237 | 221 | void G1NewTracer::report_evacuation_failed(EvacuationFailedInfo& ef_info) { |
sla@5237 | 222 | assert_set_gc_id(); |
sla@5237 | 223 | |
sla@5237 | 224 | send_evacuation_failed_event(ef_info); |
sla@5237 | 225 | ef_info.reset(); |
sla@5237 | 226 | } |
sla@5237 | 227 | #endif |