src/share/vm/gc_implementation/shared/gcTraceSend.cpp

Tue, 26 Nov 2013 14:35:38 +0100

author
sjohanss
date
Tue, 26 Nov 2013 14:35:38 +0100
changeset 6148
55a0da3d420b
parent 5647
f175e3678be2
child 6131
86e6d691f2e1
permissions
-rw-r--r--

8027675: Full collections with Serial slower in JDK 8 compared to 7u40
Summary: Reduced the number of calls to follow_class_loader and instead marked and pushed the klass holder directly. Also removed unneeded calls to adjust_klass.
Reviewed-by: coleenp, jmasa, mgerdin, tschatzl

     1 /*
     2  * Copyright (c) 2012, 2013, 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  */
    25 #include "precompiled.hpp"
    26 #include "gc_implementation/shared/gcHeapSummary.hpp"
    27 #include "gc_implementation/shared/gcTimer.hpp"
    28 #include "gc_implementation/shared/gcTrace.hpp"
    29 #include "gc_implementation/shared/gcWhen.hpp"
    30 #include "gc_implementation/shared/copyFailedInfo.hpp"
    31 #include "runtime/os.hpp"
    32 #include "trace/tracing.hpp"
    33 #include "trace/traceBackend.hpp"
    34 #if INCLUDE_ALL_GCS
    35 #include "gc_implementation/g1/evacuationInfo.hpp"
    36 #include "gc_implementation/g1/g1YCTypes.hpp"
    37 #endif
    39 // All GC dependencies against the trace framework is contained within this file.
    41 typedef uintptr_t TraceAddress;
    43 void GCTracer::send_garbage_collection_event() const {
    44   EventGCGarbageCollection event(UNTIMED);
    45   if (event.should_commit()) {
    46     event.set_gcId(_shared_gc_info.id());
    47     event.set_name(_shared_gc_info.name());
    48     event.set_cause((u2) _shared_gc_info.cause());
    49     event.set_sumOfPauses(_shared_gc_info.sum_of_pauses());
    50     event.set_longestPause(_shared_gc_info.longest_pause());
    51     event.set_starttime(_shared_gc_info.start_timestamp());
    52     event.set_endtime(_shared_gc_info.end_timestamp());
    53     event.commit();
    54   }
    55 }
    57 void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const {
    58   EventGCReferenceStatistics e(UNTIMED);
    59   if (e.should_commit()) {
    60       e.set_gcId(_shared_gc_info.id());
    61       e.set_type((u1)type);
    62       e.set_count(count);
    63       e.set_endtime(os::elapsed_counter());
    64       e.commit();
    65   }
    66 }
    68 void ParallelOldTracer::send_parallel_old_event() const {
    69   EventGCParallelOld e(UNTIMED);
    70   if (e.should_commit()) {
    71     e.set_gcId(_shared_gc_info.id());
    72     e.set_densePrefix((TraceAddress)_parallel_old_gc_info.dense_prefix());
    73     e.set_starttime(_shared_gc_info.start_timestamp());
    74     e.set_endtime(_shared_gc_info.end_timestamp());
    75     e.commit();
    76   }
    77 }
    79 void YoungGCTracer::send_young_gc_event() const {
    80   EventGCYoungGarbageCollection e(UNTIMED);
    81   if (e.should_commit()) {
    82     e.set_gcId(_shared_gc_info.id());
    83     e.set_tenuringThreshold(_tenuring_threshold);
    84     e.set_starttime(_shared_gc_info.start_timestamp());
    85     e.set_endtime(_shared_gc_info.end_timestamp());
    86     e.commit();
    87   }
    88 }
    90 void OldGCTracer::send_old_gc_event() const {
    91   EventGCOldGarbageCollection e(UNTIMED);
    92   if (e.should_commit()) {
    93     e.set_gcId(_shared_gc_info.id());
    94     e.set_starttime(_shared_gc_info.start_timestamp());
    95     e.set_endtime(_shared_gc_info.end_timestamp());
    96     e.commit();
    97   }
    98 }
   100 static TraceStructCopyFailed to_trace_struct(const CopyFailedInfo& cf_info) {
   101   TraceStructCopyFailed failed_info;
   102   failed_info.set_objectCount(cf_info.failed_count());
   103   failed_info.set_firstSize(cf_info.first_size());
   104   failed_info.set_smallestSize(cf_info.smallest_size());
   105   failed_info.set_totalSize(cf_info.total_size());
   106   return failed_info;
   107 }
   109 void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const {
   110   EventPromotionFailed e(UNTIMED);
   111   if (e.should_commit()) {
   112     e.set_gcId(_shared_gc_info.id());
   113     e.set_data(to_trace_struct(pf_info));
   114     e.set_thread(pf_info.thread()->thread_id());
   115     e.set_endtime(os::elapsed_counter());
   116     e.commit();
   117   }
   118 }
   120 // Common to CMS and G1
   121 void OldGCTracer::send_concurrent_mode_failure_event() {
   122   EventConcurrentModeFailure e(UNTIMED);
   123   if (e.should_commit()) {
   124     e.set_gcId(_shared_gc_info.id());
   125     e.set_endtime(os::elapsed_counter());
   126     e.commit();
   127   }
   128 }
   130 #if INCLUDE_ALL_GCS
   131 void G1NewTracer::send_g1_young_gc_event() {
   132   EventGCG1GarbageCollection e(UNTIMED);
   133   if (e.should_commit()) {
   134     e.set_gcId(_shared_gc_info.id());
   135     e.set_type(_g1_young_gc_info.type());
   136     e.set_starttime(_shared_gc_info.start_timestamp());
   137     e.set_endtime(_shared_gc_info.end_timestamp());
   138     e.commit();
   139   }
   140 }
   142 void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
   143   EventEvacuationInfo e(UNTIMED);
   144   if (e.should_commit()) {
   145     e.set_gcId(_shared_gc_info.id());
   146     e.set_cSetRegions(info->collectionset_regions());
   147     e.set_cSetUsedBefore(info->collectionset_used_before());
   148     e.set_cSetUsedAfter(info->collectionset_used_after());
   149     e.set_allocationRegions(info->allocation_regions());
   150     e.set_allocRegionsUsedBefore(info->alloc_regions_used_before());
   151     e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied());
   152     e.set_bytesCopied(info->bytes_copied());
   153     e.set_regionsFreed(info->regions_freed());
   154     e.set_endtime(os::elapsed_counter());
   155     e.commit();
   156   }
   157 }
   159 void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const {
   160   EventEvacuationFailed e(UNTIMED);
   161   if (e.should_commit()) {
   162     e.set_gcId(_shared_gc_info.id());
   163     e.set_data(to_trace_struct(ef_info));
   164     e.set_endtime(os::elapsed_counter());
   165     e.commit();
   166   }
   167 }
   168 #endif
   170 static TraceStructVirtualSpace to_trace_struct(const VirtualSpaceSummary& summary) {
   171   TraceStructVirtualSpace space;
   172   space.set_start((TraceAddress)summary.start());
   173   space.set_committedEnd((TraceAddress)summary.committed_end());
   174   space.set_committedSize(summary.committed_size());
   175   space.set_reservedEnd((TraceAddress)summary.reserved_end());
   176   space.set_reservedSize(summary.reserved_size());
   177   return space;
   178 }
   180 static TraceStructObjectSpace to_trace_struct(const SpaceSummary& summary) {
   181   TraceStructObjectSpace space;
   182   space.set_start((TraceAddress)summary.start());
   183   space.set_end((TraceAddress)summary.end());
   184   space.set_used(summary.used());
   185   space.set_size(summary.size());
   186   return space;
   187 }
   189 class GCHeapSummaryEventSender : public GCHeapSummaryVisitor {
   190   GCId _id;
   191   GCWhen::Type _when;
   192  public:
   193   GCHeapSummaryEventSender(GCId id, GCWhen::Type when) : _id(id), _when(when) {}
   195   void visit(const GCHeapSummary* heap_summary) const {
   196     const VirtualSpaceSummary& heap_space = heap_summary->heap();
   198     EventGCHeapSummary e(UNTIMED);
   199     if (e.should_commit()) {
   200       e.set_gcId(_id);
   201       e.set_when((u1)_when);
   202       e.set_heapSpace(to_trace_struct(heap_space));
   203       e.set_heapUsed(heap_summary->used());
   204       e.set_endtime(os::elapsed_counter());
   205       e.commit();
   206     }
   207   }
   209   void visit(const PSHeapSummary* ps_heap_summary) const {
   210     visit((GCHeapSummary*)ps_heap_summary);
   212     const VirtualSpaceSummary& old_summary = ps_heap_summary->old();
   213     const SpaceSummary& old_space = ps_heap_summary->old_space();
   214     const VirtualSpaceSummary& young_summary = ps_heap_summary->young();
   215     const SpaceSummary& eden_space = ps_heap_summary->eden();
   216     const SpaceSummary& from_space = ps_heap_summary->from();
   217     const SpaceSummary& to_space = ps_heap_summary->to();
   219     EventPSHeapSummary e(UNTIMED);
   220     if (e.should_commit()) {
   221       e.set_gcId(_id);
   222       e.set_when((u1)_when);
   224       e.set_oldSpace(to_trace_struct(ps_heap_summary->old()));
   225       e.set_oldObjectSpace(to_trace_struct(ps_heap_summary->old_space()));
   226       e.set_youngSpace(to_trace_struct(ps_heap_summary->young()));
   227       e.set_edenSpace(to_trace_struct(ps_heap_summary->eden()));
   228       e.set_fromSpace(to_trace_struct(ps_heap_summary->from()));
   229       e.set_toSpace(to_trace_struct(ps_heap_summary->to()));
   230       e.set_endtime(os::elapsed_counter());
   231       e.commit();
   232     }
   233   }
   234 };
   236 void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
   237   GCHeapSummaryEventSender visitor(_shared_gc_info.id(), when);
   238   heap_summary.accept(&visitor);
   239 }
   241 static TraceStructMetaspaceSizes to_trace_struct(const MetaspaceSizes& sizes) {
   242   TraceStructMetaspaceSizes meta_sizes;
   244   meta_sizes.set_capacity(sizes.capacity());
   245   meta_sizes.set_used(sizes.used());
   246   meta_sizes.set_reserved(sizes.reserved());
   248   return meta_sizes;
   249 }
   251 void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const {
   252   EventMetaspaceSummary e(UNTIMED);
   253   if (e.should_commit()) {
   254     e.set_gcId(_shared_gc_info.id());
   255     e.set_when((u1) when);
   256     e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
   257     e.set_dataSpace(to_trace_struct(meta_space_summary.data_space()));
   258     e.set_classSpace(to_trace_struct(meta_space_summary.class_space()));
   259     e.set_endtime(os::elapsed_counter());
   260     e.commit();
   261   }
   262 }
   264 class PhaseSender : public PhaseVisitor {
   265   GCId _gc_id;
   266  public:
   267   PhaseSender(GCId gc_id) : _gc_id(gc_id) {}
   269   template<typename T>
   270   void send_phase(PausePhase* pause) {
   271     T event(UNTIMED);
   272     if (event.should_commit()) {
   273       event.set_gcId(_gc_id);
   274       event.set_name(pause->name());
   275       event.set_starttime(pause->start());
   276       event.set_endtime(pause->end());
   277       event.commit();
   278     }
   279   }
   281   void visit(GCPhase* pause) { ShouldNotReachHere(); }
   282   void visit(ConcurrentPhase* pause) { Unimplemented(); }
   283   void visit(PausePhase* pause) {
   284     assert(PhasesStack::PHASE_LEVELS == 5, "Need more event types");
   286     switch (pause->level()) {
   287       case 0: send_phase<EventGCPhasePause>(pause); break;
   288       case 1: send_phase<EventGCPhasePauseLevel1>(pause); break;
   289       case 2: send_phase<EventGCPhasePauseLevel2>(pause); break;
   290       case 3: send_phase<EventGCPhasePauseLevel3>(pause); break;
   291       default: /* Ignore sending this phase */ break;
   292     }
   293   }
   294 };
   296 void GCTracer::send_phase_events(TimePartitions* time_partitions) const {
   297   PhaseSender phase_reporter(_shared_gc_info.id());
   299   TimePartitionPhasesIterator iter(time_partitions);
   300   while (iter.has_next()) {
   301     GCPhase* phase = iter.next();
   302     phase->accept(&phase_reporter);
   303   }
   304 }

mercurial