hotspot/src/share/vm/gc/shared/gcTraceSend.cpp
changeset 30764 fec48bf5a827
parent 28024 33102d6e1f06
child 31344 2316eb7a0358
equal deleted inserted replaced
30614:e45861098f5a 30764:fec48bf5a827
       
     1 /*
       
     2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "gc/shared/copyFailedInfo.hpp"
       
    27 #include "gc/shared/gcHeapSummary.hpp"
       
    28 #include "gc/shared/gcTimer.hpp"
       
    29 #include "gc/shared/gcTrace.hpp"
       
    30 #include "gc/shared/gcWhen.hpp"
       
    31 #include "runtime/os.hpp"
       
    32 #include "trace/traceBackend.hpp"
       
    33 #include "trace/tracing.hpp"
       
    34 #include "utilities/macros.hpp"
       
    35 #if INCLUDE_ALL_GCS
       
    36 #include "gc/g1/evacuationInfo.hpp"
       
    37 #include "gc/g1/g1YCTypes.hpp"
       
    38 #endif
       
    39 
       
    40 // All GC dependencies against the trace framework is contained within this file.
       
    41 
       
    42 typedef uintptr_t TraceAddress;
       
    43 
       
    44 void GCTracer::send_garbage_collection_event() const {
       
    45   EventGCGarbageCollection event(UNTIMED);
       
    46   if (event.should_commit()) {
       
    47     event.set_gcId(_shared_gc_info.gc_id().id());
       
    48     event.set_name(_shared_gc_info.name());
       
    49     event.set_cause((u2) _shared_gc_info.cause());
       
    50     event.set_sumOfPauses(_shared_gc_info.sum_of_pauses());
       
    51     event.set_longestPause(_shared_gc_info.longest_pause());
       
    52     event.set_starttime(_shared_gc_info.start_timestamp());
       
    53     event.set_endtime(_shared_gc_info.end_timestamp());
       
    54     event.commit();
       
    55   }
       
    56 }
       
    57 
       
    58 void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const {
       
    59   EventGCReferenceStatistics e;
       
    60   if (e.should_commit()) {
       
    61       e.set_gcId(_shared_gc_info.gc_id().id());
       
    62       e.set_type((u1)type);
       
    63       e.set_count(count);
       
    64       e.commit();
       
    65   }
       
    66 }
       
    67 
       
    68 void GCTracer::send_metaspace_chunk_free_list_summary(GCWhen::Type when, Metaspace::MetadataType mdtype,
       
    69                                                       const MetaspaceChunkFreeListSummary& summary) const {
       
    70   EventMetaspaceChunkFreeListSummary e;
       
    71   if (e.should_commit()) {
       
    72     e.set_gcId(_shared_gc_info.gc_id().id());
       
    73     e.set_when(when);
       
    74     e.set_metadataType(mdtype);
       
    75 
       
    76     e.set_specializedChunks(summary.num_specialized_chunks());
       
    77     e.set_specializedChunksTotalSize(summary.specialized_chunks_size_in_bytes());
       
    78 
       
    79     e.set_smallChunks(summary.num_small_chunks());
       
    80     e.set_smallChunksTotalSize(summary.small_chunks_size_in_bytes());
       
    81 
       
    82     e.set_mediumChunks(summary.num_medium_chunks());
       
    83     e.set_mediumChunksTotalSize(summary.medium_chunks_size_in_bytes());
       
    84 
       
    85     e.set_humongousChunks(summary.num_humongous_chunks());
       
    86     e.set_humongousChunksTotalSize(summary.humongous_chunks_size_in_bytes());
       
    87 
       
    88     e.commit();
       
    89   }
       
    90 }
       
    91 
       
    92 void ParallelOldTracer::send_parallel_old_event() const {
       
    93   EventGCParallelOld e(UNTIMED);
       
    94   if (e.should_commit()) {
       
    95     e.set_gcId(_shared_gc_info.gc_id().id());
       
    96     e.set_densePrefix((TraceAddress)_parallel_old_gc_info.dense_prefix());
       
    97     e.set_starttime(_shared_gc_info.start_timestamp());
       
    98     e.set_endtime(_shared_gc_info.end_timestamp());
       
    99     e.commit();
       
   100   }
       
   101 }
       
   102 
       
   103 void YoungGCTracer::send_young_gc_event() const {
       
   104   EventGCYoungGarbageCollection e(UNTIMED);
       
   105   if (e.should_commit()) {
       
   106     e.set_gcId(_shared_gc_info.gc_id().id());
       
   107     e.set_tenuringThreshold(_tenuring_threshold);
       
   108     e.set_starttime(_shared_gc_info.start_timestamp());
       
   109     e.set_endtime(_shared_gc_info.end_timestamp());
       
   110     e.commit();
       
   111   }
       
   112 }
       
   113 
       
   114 bool YoungGCTracer::should_send_promotion_in_new_plab_event() const {
       
   115   return EventPromoteObjectInNewPLAB::is_enabled();
       
   116 }
       
   117 
       
   118 bool YoungGCTracer::should_send_promotion_outside_plab_event() const {
       
   119   return EventPromoteObjectOutsidePLAB::is_enabled();
       
   120 }
       
   121 
       
   122 void YoungGCTracer::send_promotion_in_new_plab_event(Klass* klass, size_t obj_size,
       
   123                                                      uint age, bool tenured,
       
   124                                                      size_t plab_size) const {
       
   125 
       
   126   EventPromoteObjectInNewPLAB event;
       
   127   if (event.should_commit()) {
       
   128     event.set_gcId(_shared_gc_info.gc_id().id());
       
   129     event.set_class(klass);
       
   130     event.set_objectSize(obj_size);
       
   131     event.set_tenured(tenured);
       
   132     event.set_tenuringAge(age);
       
   133     event.set_plabSize(plab_size);
       
   134     event.commit();
       
   135   }
       
   136 }
       
   137 
       
   138 void YoungGCTracer::send_promotion_outside_plab_event(Klass* klass, size_t obj_size,
       
   139                                                       uint age, bool tenured) const {
       
   140 
       
   141   EventPromoteObjectOutsidePLAB event;
       
   142   if (event.should_commit()) {
       
   143     event.set_gcId(_shared_gc_info.gc_id().id());
       
   144     event.set_class(klass);
       
   145     event.set_objectSize(obj_size);
       
   146     event.set_tenured(tenured);
       
   147     event.set_tenuringAge(age);
       
   148     event.commit();
       
   149   }
       
   150 }
       
   151 
       
   152 void OldGCTracer::send_old_gc_event() const {
       
   153   EventGCOldGarbageCollection e(UNTIMED);
       
   154   if (e.should_commit()) {
       
   155     e.set_gcId(_shared_gc_info.gc_id().id());
       
   156     e.set_starttime(_shared_gc_info.start_timestamp());
       
   157     e.set_endtime(_shared_gc_info.end_timestamp());
       
   158     e.commit();
       
   159   }
       
   160 }
       
   161 
       
   162 static TraceStructCopyFailed to_trace_struct(const CopyFailedInfo& cf_info) {
       
   163   TraceStructCopyFailed failed_info;
       
   164   failed_info.set_objectCount(cf_info.failed_count());
       
   165   failed_info.set_firstSize(cf_info.first_size());
       
   166   failed_info.set_smallestSize(cf_info.smallest_size());
       
   167   failed_info.set_totalSize(cf_info.total_size());
       
   168   return failed_info;
       
   169 }
       
   170 
       
   171 void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const {
       
   172   EventPromotionFailed e;
       
   173   if (e.should_commit()) {
       
   174     e.set_gcId(_shared_gc_info.gc_id().id());
       
   175     e.set_data(to_trace_struct(pf_info));
       
   176     e.set_thread(pf_info.thread()->thread_id());
       
   177     e.commit();
       
   178   }
       
   179 }
       
   180 
       
   181 // Common to CMS and G1
       
   182 void OldGCTracer::send_concurrent_mode_failure_event() {
       
   183   EventConcurrentModeFailure e;
       
   184   if (e.should_commit()) {
       
   185     e.set_gcId(_shared_gc_info.gc_id().id());
       
   186     e.commit();
       
   187   }
       
   188 }
       
   189 
       
   190 #if INCLUDE_ALL_GCS
       
   191 void G1NewTracer::send_g1_young_gc_event() {
       
   192   EventGCG1GarbageCollection e(UNTIMED);
       
   193   if (e.should_commit()) {
       
   194     e.set_gcId(_shared_gc_info.gc_id().id());
       
   195     e.set_type(_g1_young_gc_info.type());
       
   196     e.set_starttime(_shared_gc_info.start_timestamp());
       
   197     e.set_endtime(_shared_gc_info.end_timestamp());
       
   198     e.commit();
       
   199   }
       
   200 }
       
   201 
       
   202 void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
       
   203   EventEvacuationInfo e;
       
   204   if (e.should_commit()) {
       
   205     e.set_gcId(_shared_gc_info.gc_id().id());
       
   206     e.set_cSetRegions(info->collectionset_regions());
       
   207     e.set_cSetUsedBefore(info->collectionset_used_before());
       
   208     e.set_cSetUsedAfter(info->collectionset_used_after());
       
   209     e.set_allocationRegions(info->allocation_regions());
       
   210     e.set_allocRegionsUsedBefore(info->alloc_regions_used_before());
       
   211     e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied());
       
   212     e.set_bytesCopied(info->bytes_copied());
       
   213     e.set_regionsFreed(info->regions_freed());
       
   214     e.commit();
       
   215   }
       
   216 }
       
   217 
       
   218 void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const {
       
   219   EventEvacuationFailed e;
       
   220   if (e.should_commit()) {
       
   221     e.set_gcId(_shared_gc_info.gc_id().id());
       
   222     e.set_data(to_trace_struct(ef_info));
       
   223     e.commit();
       
   224   }
       
   225 }
       
   226 #endif
       
   227 
       
   228 static TraceStructVirtualSpace to_trace_struct(const VirtualSpaceSummary& summary) {
       
   229   TraceStructVirtualSpace space;
       
   230   space.set_start((TraceAddress)summary.start());
       
   231   space.set_committedEnd((TraceAddress)summary.committed_end());
       
   232   space.set_committedSize(summary.committed_size());
       
   233   space.set_reservedEnd((TraceAddress)summary.reserved_end());
       
   234   space.set_reservedSize(summary.reserved_size());
       
   235   return space;
       
   236 }
       
   237 
       
   238 static TraceStructObjectSpace to_trace_struct(const SpaceSummary& summary) {
       
   239   TraceStructObjectSpace space;
       
   240   space.set_start((TraceAddress)summary.start());
       
   241   space.set_end((TraceAddress)summary.end());
       
   242   space.set_used(summary.used());
       
   243   space.set_size(summary.size());
       
   244   return space;
       
   245 }
       
   246 
       
   247 class GCHeapSummaryEventSender : public GCHeapSummaryVisitor {
       
   248   GCId _gc_id;
       
   249   GCWhen::Type _when;
       
   250  public:
       
   251   GCHeapSummaryEventSender(GCId gc_id, GCWhen::Type when) : _gc_id(gc_id), _when(when) {}
       
   252 
       
   253   void visit(const GCHeapSummary* heap_summary) const {
       
   254     const VirtualSpaceSummary& heap_space = heap_summary->heap();
       
   255 
       
   256     EventGCHeapSummary e;
       
   257     if (e.should_commit()) {
       
   258       e.set_gcId(_gc_id.id());
       
   259       e.set_when((u1)_when);
       
   260       e.set_heapSpace(to_trace_struct(heap_space));
       
   261       e.set_heapUsed(heap_summary->used());
       
   262       e.commit();
       
   263     }
       
   264   }
       
   265 
       
   266   void visit(const PSHeapSummary* ps_heap_summary) const {
       
   267     visit((GCHeapSummary*)ps_heap_summary);
       
   268 
       
   269     const VirtualSpaceSummary& old_summary = ps_heap_summary->old();
       
   270     const SpaceSummary& old_space = ps_heap_summary->old_space();
       
   271     const VirtualSpaceSummary& young_summary = ps_heap_summary->young();
       
   272     const SpaceSummary& eden_space = ps_heap_summary->eden();
       
   273     const SpaceSummary& from_space = ps_heap_summary->from();
       
   274     const SpaceSummary& to_space = ps_heap_summary->to();
       
   275 
       
   276     EventPSHeapSummary e;
       
   277     if (e.should_commit()) {
       
   278       e.set_gcId(_gc_id.id());
       
   279       e.set_when((u1)_when);
       
   280 
       
   281       e.set_oldSpace(to_trace_struct(ps_heap_summary->old()));
       
   282       e.set_oldObjectSpace(to_trace_struct(ps_heap_summary->old_space()));
       
   283       e.set_youngSpace(to_trace_struct(ps_heap_summary->young()));
       
   284       e.set_edenSpace(to_trace_struct(ps_heap_summary->eden()));
       
   285       e.set_fromSpace(to_trace_struct(ps_heap_summary->from()));
       
   286       e.set_toSpace(to_trace_struct(ps_heap_summary->to()));
       
   287       e.commit();
       
   288     }
       
   289   }
       
   290 };
       
   291 
       
   292 void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
       
   293   GCHeapSummaryEventSender visitor(_shared_gc_info.gc_id(), when);
       
   294   heap_summary.accept(&visitor);
       
   295 }
       
   296 
       
   297 static TraceStructMetaspaceSizes to_trace_struct(const MetaspaceSizes& sizes) {
       
   298   TraceStructMetaspaceSizes meta_sizes;
       
   299 
       
   300   meta_sizes.set_committed(sizes.committed());
       
   301   meta_sizes.set_used(sizes.used());
       
   302   meta_sizes.set_reserved(sizes.reserved());
       
   303 
       
   304   return meta_sizes;
       
   305 }
       
   306 
       
   307 void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const {
       
   308   EventMetaspaceSummary e;
       
   309   if (e.should_commit()) {
       
   310     e.set_gcId(_shared_gc_info.gc_id().id());
       
   311     e.set_when((u1) when);
       
   312     e.set_gcThreshold(meta_space_summary.capacity_until_GC());
       
   313     e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
       
   314     e.set_dataSpace(to_trace_struct(meta_space_summary.data_space()));
       
   315     e.set_classSpace(to_trace_struct(meta_space_summary.class_space()));
       
   316     e.commit();
       
   317   }
       
   318 }
       
   319 
       
   320 class PhaseSender : public PhaseVisitor {
       
   321   GCId _gc_id;
       
   322  public:
       
   323   PhaseSender(GCId gc_id) : _gc_id(gc_id) {}
       
   324 
       
   325   template<typename T>
       
   326   void send_phase(PausePhase* pause) {
       
   327     T event(UNTIMED);
       
   328     if (event.should_commit()) {
       
   329       event.set_gcId(_gc_id.id());
       
   330       event.set_name(pause->name());
       
   331       event.set_starttime(pause->start());
       
   332       event.set_endtime(pause->end());
       
   333       event.commit();
       
   334     }
       
   335   }
       
   336 
       
   337   void visit(GCPhase* pause) { ShouldNotReachHere(); }
       
   338   void visit(ConcurrentPhase* pause) { Unimplemented(); }
       
   339   void visit(PausePhase* pause) {
       
   340     assert(PhasesStack::PHASE_LEVELS == 5, "Need more event types");
       
   341 
       
   342     switch (pause->level()) {
       
   343       case 0: send_phase<EventGCPhasePause>(pause); break;
       
   344       case 1: send_phase<EventGCPhasePauseLevel1>(pause); break;
       
   345       case 2: send_phase<EventGCPhasePauseLevel2>(pause); break;
       
   346       case 3: send_phase<EventGCPhasePauseLevel3>(pause); break;
       
   347       default: /* Ignore sending this phase */ break;
       
   348     }
       
   349   }
       
   350 };
       
   351 
       
   352 void GCTracer::send_phase_events(TimePartitions* time_partitions) const {
       
   353   PhaseSender phase_reporter(_shared_gc_info.gc_id());
       
   354 
       
   355   TimePartitionPhasesIterator iter(time_partitions);
       
   356   while (iter.has_next()) {
       
   357     GCPhase* phase = iter.next();
       
   358     phase->accept(&phase_reporter);
       
   359   }
       
   360 }