1/*
2 * Copyright (c) 2014, 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
25#include "precompiled.hpp"
26#include "jfr/leakprofiler/leakProfiler.hpp"
27#include "jfr/leakprofiler/startOperation.hpp"
28#include "jfr/leakprofiler/stopOperation.hpp"
29#include "jfr/leakprofiler/checkpoint/eventEmitter.hpp"
30#include "jfr/leakprofiler/sampling/objectSampler.hpp"
31#include "jfr/recorder/service/jfrOptionSet.hpp"
32#include "logging/log.hpp"
33#include "memory/iterator.hpp"
34#include "runtime/thread.inline.hpp"
35#include "runtime/vmThread.hpp"
36
37bool LeakProfiler::is_running() {
38 return ObjectSampler::is_created();
39}
40
41bool LeakProfiler::start(int sample_count) {
42 if (is_running()) {
43 return true;
44 }
45
46 // Allows user to disable leak profiler on command line by setting queue size to zero.
47 if (sample_count == 0) {
48 return false;
49 }
50
51 if (UseZGC) {
52 log_warning(jfr)("LeakProfiler is currently not supported in combination with ZGC");
53 return false;
54 }
55
56 if (UseShenandoahGC) {
57 log_warning(jfr)("LeakProfiler is currently not supported in combination with Shenandoah GC");
58 return false;
59 }
60
61 assert(!is_running(), "invariant");
62 assert(sample_count > 0, "invariant");
63
64 // schedule the safepoint operation for installing the object sampler
65 StartOperation op(sample_count);
66 VMThread::execute(&op);
67
68 if (!is_running()) {
69 log_trace(jfr, system)("Object sampling could not be started because the sampler could not be allocated");
70 return false;
71 }
72 assert(is_running(), "invariant");
73 log_trace(jfr, system)("Object sampling started");
74 return true;
75}
76
77bool LeakProfiler::stop() {
78 if (!is_running()) {
79 return false;
80 }
81
82 // schedule the safepoint operation for uninstalling and destroying the object sampler
83 StopOperation op;
84 VMThread::execute(&op);
85
86 assert(!is_running(), "invariant");
87 log_trace(jfr, system)("Object sampling stopped");
88 return true;
89}
90
91void LeakProfiler::emit_events(int64_t cutoff_ticks, bool emit_all) {
92 if (!is_running()) {
93 return;
94 }
95 // exclusive access to object sampler instance
96 ObjectSampler* const sampler = ObjectSampler::acquire();
97 assert(sampler != NULL, "invariant");
98 EventEmitter::emit(sampler, cutoff_ticks, emit_all);
99 ObjectSampler::release();
100}
101
102void LeakProfiler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
103 assert(SafepointSynchronize::is_at_safepoint(),
104 "Leak Profiler::oops_do(...) may only be called during safepoint");
105 if (is_running()) {
106 ObjectSampler::oops_do(is_alive, f);
107 }
108}
109
110void LeakProfiler::sample(HeapWord* object, size_t size, JavaThread* thread) {
111 assert(is_running(), "invariant");
112 assert(thread != NULL, "invariant");
113 assert(thread->thread_state() == _thread_in_vm, "invariant");
114
115 // exclude compiler threads and code sweeper thread
116 if (thread->is_hidden_from_external_view()) {
117 return;
118 }
119
120 ObjectSampler::sample(object, size, thread);
121}
122