Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp
38922 views
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
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "jfr/jfrEvents.hpp"
27
#include "jfr/recorder/jfrRecorder.hpp"
28
#include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
29
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
30
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
31
#include "jfr/leakprofiler/chains/edgeStore.hpp"
32
#include "jfr/leakprofiler/chains/objectSampleMarker.hpp"
33
#include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
34
#include "jfr/leakprofiler/checkpoint/objectSampleWriter.hpp"
35
#include "jfr/leakprofiler/leakProfiler.hpp"
36
#include "jfr/leakprofiler/sampling/objectSample.hpp"
37
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
38
#include "jfr/leakprofiler/utilities/rootType.hpp"
39
#include "jfr/metadata/jfrSerializer.hpp"
40
#include "runtime/interfaceSupport.hpp"
41
#include "runtime/mutexLocker.hpp"
42
#include "runtime/thread.inline.hpp"
43
44
template <typename SampleProcessor>
45
static void do_samples(ObjectSample* sample, const ObjectSample* const end, SampleProcessor& processor) {
46
assert(sample != NULL, "invariant");
47
while (sample != end) {
48
processor.sample_do(sample);
49
sample = sample->next();
50
}
51
}
52
53
class RootSystemType : public JfrSerializer {
54
public:
55
void serialize(JfrCheckpointWriter& writer) {
56
const u4 nof_root_systems = OldObjectRoot::_number_of_systems;
57
writer.write_count(nof_root_systems);
58
for (u4 i = 0; i < nof_root_systems; ++i) {
59
writer.write_key(i);
60
writer.write(OldObjectRoot::system_description((OldObjectRoot::System)i));
61
}
62
}
63
};
64
65
class RootType : public JfrSerializer {
66
public:
67
void serialize(JfrCheckpointWriter& writer) {
68
const u4 nof_root_types = OldObjectRoot::_number_of_types;
69
writer.write_count(nof_root_types);
70
for (u4 i = 0; i < nof_root_types; ++i) {
71
writer.write_key(i);
72
writer.write(OldObjectRoot::type_description((OldObjectRoot::Type)i));
73
}
74
}
75
};
76
77
class CheckpointInstall {
78
private:
79
const JfrCheckpointBlobHandle& _cp;
80
public:
81
CheckpointInstall(const JfrCheckpointBlobHandle& cp) : _cp(cp) {}
82
void sample_do(ObjectSample* sample) {
83
assert(sample != NULL, "invariant");
84
if (!sample->is_dead()) {
85
sample->set_klass_checkpoint(_cp);
86
}
87
}
88
};
89
90
class CheckpointWrite {
91
private:
92
JfrCheckpointWriter& _writer;
93
const jlong _last_sweep;
94
public:
95
CheckpointWrite(JfrCheckpointWriter& writer, jlong last_sweep) : _writer(writer), _last_sweep(last_sweep) {}
96
void sample_do(ObjectSample* sample) {
97
assert(sample != NULL, "invariant");
98
if (sample->is_alive_and_older_than(_last_sweep)) {
99
if (sample->has_thread_checkpoint()) {
100
const JfrCheckpointBlobHandle& thread_cp = sample->thread_checkpoint();
101
thread_cp->exclusive_write(_writer);
102
}
103
if (sample->has_klass_checkpoint()) {
104
const JfrCheckpointBlobHandle& klass_cp = sample->klass_checkpoint();
105
klass_cp->exclusive_write(_writer);
106
}
107
}
108
}
109
};
110
111
class CheckpointStateReset {
112
private:
113
const jlong _last_sweep;
114
public:
115
CheckpointStateReset(jlong last_sweep) : _last_sweep(last_sweep) {}
116
void sample_do(ObjectSample* sample) {
117
assert(sample != NULL, "invariant");
118
if (sample->is_alive_and_older_than(_last_sweep)) {
119
if (sample->has_thread_checkpoint()) {
120
const JfrCheckpointBlobHandle& thread_cp = sample->thread_checkpoint();
121
thread_cp->reset_write_state();
122
}
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) {
172
assert(sample != NULL, "invariant");
173
if (sample->is_alive_and_older_than(_last_sweep)) {
174
_marker.mark(sample->object());
175
++_count;
176
}
177
}
178
179
int count() const {
180
return _count;
181
}
182
};
183
184
void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload, bool type_set) {
185
if (!writer.has_data()) {
186
return;
187
}
188
189
assert(writer.has_data(), "invariant");
190
const JfrCheckpointBlobHandle h_cp = writer.checkpoint_blob();
191
CheckpointInstall install(h_cp);
192
193
// Class unload implies a safepoint.
194
// Not class unload implies the object sampler is locked, because it was claimed exclusively earlier.
195
// Therefore: direct access the object sampler instance is safe.
196
ObjectSampler* const object_sampler = ObjectSampler::sampler();
197
assert(object_sampler != NULL, "invariant");
198
199
ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
200
const ObjectSample* const last_resolved = object_sampler->last_resolved();
201
202
// install only to new samples since last resolved checkpoint
203
if (last != last_resolved) {
204
do_samples(last, last_resolved, install);
205
if (class_unload) {
206
return;
207
}
208
if (type_set) {
209
object_sampler->set_last_resolved(last);
210
}
211
}
212
}
213
214
void ObjectSampleCheckpoint::write(ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) {
215
assert(sampler != NULL, "invariant");
216
assert(edge_store != NULL, "invariant");
217
assert(thread != NULL, "invariant");
218
219
static bool types_registered = false;
220
if (!types_registered) {
221
JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType());
222
JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType());
223
types_registered = true;
224
}
225
226
const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value();
227
ObjectSample* const last = const_cast<ObjectSample*>(sampler->last());
228
{
229
JfrCheckpointWriter writer(false, false, thread);
230
CheckpointWrite checkpoint_write(writer, last_sweep);
231
do_samples(last, NULL, checkpoint_write);
232
}
233
234
CheckpointStateReset state_reset(last_sweep);
235
do_samples(last, NULL, state_reset);
236
237
if (!edge_store->is_empty()) {
238
// java object and chain representations
239
JfrCheckpointWriter writer(false, true, thread);
240
ObjectSampleWriter osw(writer, edge_store);
241
edge_store->iterate(osw);
242
}
243
}
244
245
int ObjectSampleCheckpoint::mark(ObjectSampler* object_sampler, ObjectSampleMarker& marker, bool emit_all) {
246
assert(object_sampler != NULL, "invariant");
247
ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
248
if (last == NULL) {
249
return 0;
250
}
251
const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
252
SampleMark mark(marker, last_sweep);
253
do_samples(last, NULL, mark);
254
return mark.count();
255
}
256
257
WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(ObjectSampler* sampler, JfrStackTraceRepository& repo) :
258
_sampler(sampler), _stack_trace_repo(repo) {}
259
260
bool WriteObjectSampleStacktrace::process() {
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
}
294
295