1 /*
2 * Copyright (c) 2014, 2018, 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 *
123 if (sample->has_klass_checkpoint()) {
124 const JfrCheckpointBlobHandle& klass_cp = sample->klass_checkpoint();
125 klass_cp->reset_write_state();
126 }
127 }
128 }
129 };
130
131 class StackTraceWrite {
132 private:
133 JfrStackTraceRepository& _stack_trace_repo;
134 JfrCheckpointWriter& _writer;
135 int _count;
136 public:
137 StackTraceWrite(JfrStackTraceRepository& stack_trace_repo, JfrCheckpointWriter& writer) :
138 _stack_trace_repo(stack_trace_repo), _writer(writer), _count(0) {
139 JfrStacktrace_lock->lock();
140 }
141 ~StackTraceWrite() {
142 assert(JfrStacktrace_lock->owned_by_self(), "invariant");
143 JfrStacktrace_lock->unlock();
144 }
145
146 void sample_do(ObjectSample* sample) {
147 assert(sample != NULL, "invariant");
148 if (!sample->is_dead()) {
149 if (sample->has_stack_trace()) {
150 JfrTraceId::use(sample->klass(), true);
151 _stack_trace_repo.write(_writer, sample->stack_trace_id(), sample->stack_trace_hash());
152 ++_count;
153 }
154 }
155 }
156
157 int count() const {
158 return _count;
159 }
160 };
161
162 class SampleMark {
163 private:
164 ObjectSampleMarker& _marker;
165 jlong _last_sweep;
166 int _count;
167 public:
168 SampleMark(ObjectSampleMarker& marker, jlong last_sweep) : _marker(marker),
169 _last_sweep(last_sweep),
170 _count(0) {}
171 void sample_do(ObjectSample* sample) {
261 assert(LeakProfiler::is_running(), "invariant");
262 assert(_sampler != NULL, "invariant");
263
264 ObjectSample* const last = const_cast<ObjectSample*>(_sampler->last());
265 const ObjectSample* const last_resolved = _sampler->last_resolved();
266 if (last == last_resolved) {
267 return true;
268 }
269
270 JfrCheckpointWriter writer(false, true, Thread::current());
271 const JfrCheckpointContext ctx = writer.context();
272
273 writer.write_type(TYPE_STACKTRACE);
274 const jlong count_offset = writer.reserve(sizeof(u4));
275
276 int count = 0;
277 {
278 StackTraceWrite stack_trace_write(_stack_trace_repo, writer); // JfrStacktrace_lock
279 do_samples(last, last_resolved, stack_trace_write);
280 count = stack_trace_write.count();
281 }
282 if (count == 0) {
283 writer.set_context(ctx);
284 return true;
285 }
286 assert(count > 0, "invariant");
287 writer.write_count((u4)count, count_offset);
288 JfrStackTraceRepository::write_metadata(writer);
289
290 // install the stacktrace checkpoint information to the candidates
291 ObjectSampleCheckpoint::install(writer, false, false);
292 return true;
293 }
|
1 /*
2 * Copyright (c) 2014, 2021, 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 *
123 if (sample->has_klass_checkpoint()) {
124 const JfrCheckpointBlobHandle& klass_cp = sample->klass_checkpoint();
125 klass_cp->reset_write_state();
126 }
127 }
128 }
129 };
130
131 class StackTraceWrite {
132 private:
133 JfrStackTraceRepository& _stack_trace_repo;
134 JfrCheckpointWriter& _writer;
135 int _count;
136 public:
137 StackTraceWrite(JfrStackTraceRepository& stack_trace_repo, JfrCheckpointWriter& writer) :
138 _stack_trace_repo(stack_trace_repo), _writer(writer), _count(0) {
139 JfrStacktrace_lock->lock();
140 }
141 ~StackTraceWrite() {
142 assert(JfrStacktrace_lock->owned_by_self(), "invariant");
143 // TODO: or after the unlock ?
144 JfrStacktrace_lock->unlock();
145 JfrStackTraceRepository::clear_leak_profiler();
146 }
147
148 void sample_do(ObjectSample* sample) {
149 assert(sample != NULL, "invariant");
150 if (!sample->is_dead()) {
151 if (sample->has_stack_trace()) {
152 JfrTraceId::use(sample->klass(), true);
153 traceid t = JfrStackTraceRepository::write_for_leak_profiler(_writer, sample->stack_trace_id(), sample->stack_trace_hash());
154 tty->print_cr("ObjectSampleCheckpoint.cpp| Write %ld stack trace id | traceid %ld", sample->stack_trace_id(), t);
155 ++_count;
156 }
157 }
158 }
159
160 int count() const {
161 return _count;
162 }
163 };
164
165 class SampleMark {
166 private:
167 ObjectSampleMarker& _marker;
168 jlong _last_sweep;
169 int _count;
170 public:
171 SampleMark(ObjectSampleMarker& marker, jlong last_sweep) : _marker(marker),
172 _last_sweep(last_sweep),
173 _count(0) {}
174 void sample_do(ObjectSample* sample) {
264 assert(LeakProfiler::is_running(), "invariant");
265 assert(_sampler != NULL, "invariant");
266
267 ObjectSample* const last = const_cast<ObjectSample*>(_sampler->last());
268 const ObjectSample* const last_resolved = _sampler->last_resolved();
269 if (last == last_resolved) {
270 return true;
271 }
272
273 JfrCheckpointWriter writer(false, true, Thread::current());
274 const JfrCheckpointContext ctx = writer.context();
275
276 writer.write_type(TYPE_STACKTRACE);
277 const jlong count_offset = writer.reserve(sizeof(u4));
278
279 int count = 0;
280 {
281 StackTraceWrite stack_trace_write(_stack_trace_repo, writer); // JfrStacktrace_lock
282 do_samples(last, last_resolved, stack_trace_write);
283 count = stack_trace_write.count();
284 tty->print_cr("ObjectSampleCheckpoint.cpp| Write %d stack traces", count);
285 }
286 if (count == 0) {
287 writer.set_context(ctx);
288 return true;
289 }
290 assert(count > 0, "invariant");
291 writer.write_count((u4)count, count_offset);
292 JfrStackTraceRepository::write_metadata(writer);
293
294 // install the stacktrace checkpoint information to the candidates
295 ObjectSampleCheckpoint::install(writer, false, false);
296 return true;
297 }
|