1 /*
   2  * Copyright (c) 2016, 2017, 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 #include "precompiled.hpp"
  25 #include "gc/z/zStat.hpp"
  26 #include "gc/z/zTracer.hpp"
  27 #include "gc/shared/gcId.hpp"
  28 #include "gc/shared/gcLocker.hpp"
  29 #include "jfr/jfrEvents.hpp"
  30 #include "runtime/safepointVerifiers.hpp"
  31 #if INCLUDE_JFR
  32 #include "jfr/metadata/jfrSerializer.hpp"
  33 #endif
  34 
  35 #if INCLUDE_JFR
  36 class ZStatisticsCounterTypeConstant : public JfrSerializer {
  37 public:
  38   virtual void serialize(JfrCheckpointWriter& writer) {
  39     writer.write_count(ZStatCounter::count());
  40     for (ZStatCounter* counter = ZStatCounter::first(); counter != NULL; counter = counter->next()) {
  41       writer.write_key(counter->id());
  42       writer.write(counter->name());
  43     }
  44   }
  45 };
  46 
  47 class ZStatisticsSamplerTypeConstant : public JfrSerializer {
  48 public:
  49   virtual void serialize(JfrCheckpointWriter& writer) {
  50     writer.write_count(ZStatSampler::count());
  51     for (ZStatSampler* sampler = ZStatSampler::first(); sampler != NULL; sampler = sampler->next()) {
  52       writer.write_key(sampler->id());
  53       writer.write(sampler->name());
  54     }
  55   }
  56 };
  57 
  58 static void register_jfr_type_serializers() {
  59   JfrSerializer::register_serializer(TYPE_ZSTATISTICSCOUNTERTYPE,
  60                                      false /* require_safepoint */,
  61                                      true /* permit_cache */,
  62                                      new ZStatisticsCounterTypeConstant());
  63   JfrSerializer::register_serializer(TYPE_ZSTATISTICSSAMPLERTYPE,
  64                                      false /* require_safepoint */,
  65                                      true /* permit_cache */,
  66                                      new ZStatisticsSamplerTypeConstant());
  67 }
  68 #endif
  69 
  70 ZTracer* ZTracer::_tracer = NULL;
  71 
  72 ZTracer::ZTracer() :
  73     GCTracer(Z) {}
  74 
  75 void ZTracer::initialize() {
  76   assert(_tracer == NULL, "Already initialized");
  77   _tracer = new (ResourceObj::C_HEAP, mtGC) ZTracer();
  78   JFR_ONLY(register_jfr_type_serializers());
  79 }
  80 
  81 void ZTracer::send_stat_counter(uint32_t counter_id, uint64_t increment, uint64_t value) {
  82   NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
  83 
  84   EventZStatisticsCounter e;
  85   if (e.should_commit()) {
  86     e.set_id(counter_id);
  87     e.set_increment(increment);
  88     e.set_value(value);
  89     e.commit();
  90   }
  91 }
  92 
  93 void ZTracer::send_stat_sampler(uint32_t sampler_id, uint64_t value) {
  94   NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
  95 
  96   EventZStatisticsSampler e;
  97   if (e.should_commit()) {
  98     e.set_id(sampler_id);
  99     e.set_value(value);
 100     e.commit();
 101   }
 102 }
 103 
 104 void ZTracer::send_thread_phase(const char* name, const Ticks& start, const Ticks& end) {
 105   NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
 106 
 107   EventZThreadPhase e(UNTIMED);
 108   if (e.should_commit()) {
 109     e.set_gcId(GCId::current_or_undefined());
 110     e.set_name(name);
 111     e.set_starttime(start);
 112     e.set_endtime(end);
 113     e.commit();
 114   }
 115 }
 116 
 117 void ZTracer::send_page_alloc(size_t size, size_t used, size_t free, size_t cache, bool nonblocking, bool noreserve) {
 118   NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
 119 
 120   EventZPageAllocation e;
 121   if (e.should_commit()) {
 122     e.set_pageSize(size);
 123     e.set_usedAfter(used);
 124     e.set_freeAfter(free);
 125     e.set_inCacheAfter(cache);
 126     e.set_nonBlocking(nonblocking);
 127     e.set_noReserve(noreserve);
 128     e.commit();
 129   }
 130 }
 131 
 132 void ZTracer::report_stat_counter(const ZStatCounter& counter, uint64_t increment, uint64_t value) {
 133   send_stat_counter(counter.id(), increment, value);
 134 }
 135 
 136 void ZTracer::report_stat_sampler(const ZStatSampler& sampler, uint64_t value) {
 137   send_stat_sampler(sampler.id(), value);
 138 }
 139 
 140 void ZTracer::report_thread_phase(const ZStatPhase& phase, const Ticks& start, const Ticks& end) {
 141   send_thread_phase(phase.name(), start, end);
 142 }
 143 
 144 void ZTracer::report_thread_phase(const char* name, const Ticks& start, const Ticks& end) {
 145   send_thread_phase(name, start, end);
 146 }
 147 
 148 void ZTracer::report_page_alloc(size_t size, size_t used, size_t free, size_t cache, ZAllocationFlags flags) {
 149   send_page_alloc(size, used, free, cache, flags.non_blocking(), flags.no_reserve());
 150 }