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
37class ZStatisticsCounterTypeConstant : public JfrSerializer {
38public:
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
48class ZStatisticsSamplerTypeConstant : public JfrSerializer {
49public:
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
59static 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
71ZTracer* ZTracer::_tracer = NULL;
72
73ZTracer::ZTracer() :
74 GCTracer(Z) {}
75
76void 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
82void ZTracer::send_stat_counter(uint32_t counter_id, uint64_t increment, uint64_t value) {
83 NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
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
94void ZTracer::send_stat_sampler(uint32_t sampler_id, uint64_t value) {
95 NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
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
105void ZTracer::send_thread_phase(const char* name, const Ticks& start, const Ticks& end) {
106 NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
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
118void ZTracer::send_page_alloc(size_t size, size_t used, size_t free, size_t cache, bool nonblocking, bool noreserve) {
119 NoSafepointVerifier nsv(true, !SafepointSynchronize::is_at_safepoint());
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
133void ZTracer::report_stat_counter(const ZStatCounter& counter, uint64_t increment, uint64_t value) {
134 send_stat_counter(counter.id(), increment, value);
135}
136
137void ZTracer::report_stat_sampler(const ZStatSampler& sampler, uint64_t value) {
138 send_stat_sampler(sampler.id(), value);
139}
140
141void ZTracer::report_thread_phase(const ZStatPhase& phase, const Ticks& start, const Ticks& end) {
142 send_thread_phase(phase.name(), start, end);
143}
144
145void ZTracer::report_thread_phase(const char* name, const Ticks& start, const Ticks& end) {
146 send_thread_phase(name, start, end);
147}
148
149void 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}
152