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