src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp

changeset 9858
b985cbb00e68
child 9861
a248d0be1309
equal deleted inserted replaced
9727:c7a3e57fdf4a 9858:b985cbb00e68
1 /*
2 * Copyright (c) 2016, 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 "classfile/javaClasses.hpp"
27 #include "code/codeBlob.hpp"
28 #include "code/codeCache.hpp"
29 #include "gc_interface/gcCause.hpp"
30 #include "gc_interface/gcName.hpp"
31 #include "gc_implementation/shared/gcTrace.hpp"
32 #include "gc_implementation/shared/gcWhen.hpp"
33 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp"
34 #include "jfr/leakprofiler/leakProfiler.hpp"
35 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
36 #include "jfr/recorder/checkpoint/types/jfrType.hpp"
37 #include "jfr/recorder/jfrRecorder.hpp"
38 #include "jfr/recorder/checkpoint/types/jfrThreadGroup.hpp"
39 #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp"
40 #include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp"
41 #include "jfr/support/jfrThreadLocal.hpp"
42 #include "jfr/writers/jfrJavaEventWriter.hpp"
43 #include "memory/metaspaceGCThresholdUpdater.hpp"
44 #include "memory/referenceType.hpp"
45 #include "memory/universe.hpp"
46 #include "runtime/mutexLocker.hpp"
47 #include "runtime/osThread.hpp"
48 #include "runtime/safepoint.hpp"
49 #include "runtime/synchronizer.hpp"
50 #include "runtime/thread.inline.hpp"
51 #include "runtime/vm_operations.hpp"
52
53 #ifdef COMPILER2
54 #include "opto/compile.hpp"
55 #include "opto/node.hpp"
56 #endif
57 #if INCLUDE_ALL_GCS
58 //#include "gc_implementation/g1/g1HeapRegionTraceType.hpp"
59 #include "gc_implementation/g1/g1YCTypes.hpp"
60 #endif
61
62 // Requires a ResourceMark for get_thread_name/as_utf8
63 class JfrCheckpointThreadClosure : public ThreadClosure {
64 private:
65 JfrCheckpointWriter& _writer;
66 JfrCheckpointContext _ctx;
67 const intptr_t _count_position;
68 Thread* const _curthread;
69 u4 _count;
70
71 public:
72 JfrCheckpointThreadClosure(JfrCheckpointWriter& writer) : _writer(writer),
73 _ctx(writer.context()),
74 _count_position(writer.reserve(sizeof(u4))),
75 _curthread(Thread::current()),
76 _count(0) {
77 }
78
79 ~JfrCheckpointThreadClosure() {
80 if (_count == 0) {
81 // restore
82 _writer.set_context(_ctx);
83 return;
84 }
85 _writer.write_count(_count, _count_position);
86 }
87
88 void do_thread(Thread* t);
89 };
90
91 // Requires a ResourceMark for get_thread_name/as_utf8
92 void JfrCheckpointThreadClosure::do_thread(Thread* t) {
93 assert(t != NULL, "invariant");
94 assert_locked_or_safepoint(Threads_lock);
95 const JfrThreadLocal* const tl = t->jfr_thread_local();
96 assert(tl != NULL, "invariant");
97 if (tl->is_dead()) {
98 return;
99 }
100 ++_count;
101 _writer.write_key(tl->thread_id());
102 _writer.write(t->name());
103 const OSThread* const os_thread = t->osthread();
104 _writer.write<traceid>(os_thread != NULL ? os_thread->thread_id() : 0);
105 if (t->is_Java_thread()) {
106 JavaThread* const jt = (JavaThread*)t;
107 _writer.write(jt->name());
108 _writer.write(java_lang_Thread::thread_id(jt->threadObj()));
109 _writer.write(JfrThreadGroup::thread_group_id(jt, _curthread));
110 // since we are iterating threads during a safepoint, also issue notification
111 JfrJavaEventWriter::notify(jt);
112 return;
113 }
114 _writer.write((const char*)NULL); // java name
115 _writer.write((traceid)0); // java thread id
116 _writer.write((traceid)0); // java thread group
117 }
118
119 void JfrThreadConstantSet::serialize(JfrCheckpointWriter& writer) {
120 assert(SafepointSynchronize::is_at_safepoint(), "invariant");
121 JfrCheckpointThreadClosure tc(writer);
122 Threads::threads_do(&tc);
123 }
124
125 void JfrThreadGroupConstant::serialize(JfrCheckpointWriter& writer) {
126 assert(SafepointSynchronize::is_at_safepoint(), "invariant");
127 JfrThreadGroup::serialize(writer);
128 }
129
130 static const char* flag_value_origin_to_string(Flag::Flags origin) {
131 switch (origin) {
132 case Flag::DEFAULT: return "Default";
133 case Flag::COMMAND_LINE: return "Command line";
134 case Flag::ENVIRON_VAR: return "Environment variable";
135 case Flag::CONFIG_FILE: return "Config file";
136 case Flag::MANAGEMENT: return "Management";
137 case Flag::ERGONOMIC: return "Ergonomic";
138 case Flag::ATTACH_ON_DEMAND: return "Attach on demand";
139 case Flag::INTERNAL: return "Internal";
140 default: ShouldNotReachHere(); return "";
141 }
142 }
143
144 void FlagValueOriginConstant::serialize(JfrCheckpointWriter& writer) {
145 static const u4 nof_entries = Flag::LAST_VALUE_ORIGIN + 1;
146 writer.write_count(nof_entries);
147 for (u4 i = 0; i < nof_entries; ++i) {
148 writer.write_key(i);
149 writer.write(flag_value_origin_to_string((Flag::Flags)i));
150 }
151 }
152
153 void MonitorInflateCauseConstant::serialize(JfrCheckpointWriter& writer) {
154 // XXX no such counters. implement?
155 // static const u4 nof_entries = ObjectSynchronizer::inflate_cause_nof;
156 // writer.write_count(nof_entries);
157 // for (u4 i = 0; i < nof_entries; ++i) {
158 // writer.write_key(i);
159 // writer.write(ObjectSynchronizer::inflate_cause_name((ObjectSynchronizer::InflateCause)i));
160 // }
161 }
162
163 void GCCauseConstant::serialize(JfrCheckpointWriter& writer) {
164 static const u4 nof_entries = GCCause::_last_gc_cause;
165 writer.write_count(nof_entries);
166 for (u4 i = 0; i < nof_entries; ++i) {
167 writer.write_key(i);
168 writer.write(GCCause::to_string((GCCause::Cause)i));
169 }
170 }
171
172 void GCNameConstant::serialize(JfrCheckpointWriter& writer) {
173 static const u4 nof_entries = GCNameEndSentinel;
174 writer.write_count(nof_entries);
175 for (u4 i = 0; i < nof_entries; ++i) {
176 writer.write_key(i);
177 writer.write(GCNameHelper::to_string((GCName)i));
178 }
179 }
180
181 void GCWhenConstant::serialize(JfrCheckpointWriter& writer) {
182 static const u4 nof_entries = GCWhen::GCWhenEndSentinel;
183 writer.write_count(nof_entries);
184 for (u4 i = 0; i < nof_entries; ++i) {
185 writer.write_key(i);
186 writer.write(GCWhen::to_string((GCWhen::Type)i));
187 }
188 }
189
190 void G1HeapRegionTypeConstant::serialize(JfrCheckpointWriter& writer) {
191 // XXX TODO?
192 // static const u4 nof_entries = G1HeapRegionTraceType::G1HeapRegionTypeEndSentinel;
193 // writer.write_count(nof_entries);
194 // for (u4 i = 0; i < nof_entries; ++i) {
195 // writer.write_key(i);
196 // writer.write(G1HeapRegionTraceType::to_string((G1HeapRegionTraceType::Type)i));
197 // }
198 }
199
200 void GCThresholdUpdaterConstant::serialize(JfrCheckpointWriter& writer) {
201 static const u4 nof_entries = MetaspaceGCThresholdUpdater::Last;
202 writer.write_count(nof_entries);
203 for (u4 i = 0; i < nof_entries; ++i) {
204 writer.write_key(i);
205 writer.write(MetaspaceGCThresholdUpdater::to_string((MetaspaceGCThresholdUpdater::Type)i));
206 }
207 }
208
209 void MetadataTypeConstant::serialize(JfrCheckpointWriter& writer) {
210 static const u4 nof_entries = Metaspace::MetadataTypeCount;
211 writer.write_count(nof_entries);
212 for (u4 i = 0; i < nof_entries; ++i) {
213 writer.write_key(i);
214 writer.write(Metaspace::metadata_type_name((Metaspace::MetadataType)i));
215 }
216 }
217
218 void MetaspaceObjectTypeConstant::serialize(JfrCheckpointWriter& writer) {
219 static const u4 nof_entries = MetaspaceObj::_number_of_types;
220 writer.write_count(nof_entries);
221 for (u4 i = 0; i < nof_entries; ++i) {
222 writer.write_key(i);
223 writer.write(MetaspaceObj::type_name((MetaspaceObj::Type)i));
224 }
225 }
226
227 void G1YCTypeConstant::serialize(JfrCheckpointWriter& writer) {
228 #if INCLUDE_ALL_GCS
229 static const u4 nof_entries = G1YCTypeEndSentinel;
230 writer.write_count(nof_entries);
231 for (u4 i = 0; i < nof_entries; ++i) {
232 writer.write_key(i);
233 writer.write(G1YCTypeHelper::to_string((G1YCType)i));
234 }
235 #endif
236 }
237
238 static const char* reference_type_to_string(ReferenceType rt) {
239 switch (rt) {
240 case REF_NONE: return "None reference";
241 case REF_OTHER: return "Other reference";
242 case REF_SOFT: return "Soft reference";
243 case REF_WEAK: return "Weak reference";
244 case REF_FINAL: return "Final reference";
245 case REF_PHANTOM: return "Phantom reference";
246 default:
247 ShouldNotReachHere();
248 return NULL;
249 }
250 }
251
252 void ReferenceTypeConstant::serialize(JfrCheckpointWriter& writer) {
253 static const u4 nof_entries = REF_PHANTOM + 1;
254 writer.write_count(nof_entries);
255 for (u4 i = 0; i < nof_entries; ++i) {
256 writer.write_key(i);
257 writer.write(reference_type_to_string((ReferenceType)i));
258 }
259 }
260
261 void NarrowOopModeConstant::serialize(JfrCheckpointWriter& writer) {
262 static const u4 nof_entries = Universe::HeapBasedNarrowOop + 1;
263 writer.write_count(nof_entries);
264 for (u4 i = 0; i < nof_entries; ++i) {
265 writer.write_key(i);
266 writer.write(Universe::narrow_oop_mode_to_string((Universe::NARROW_OOP_MODE)i));
267 }
268 }
269
270 void CompilerPhaseTypeConstant::serialize(JfrCheckpointWriter& writer) {
271 #ifdef COMPILER2
272 static const u4 nof_entries = PHASE_NUM_TYPES;
273 writer.write_count(nof_entries);
274 for (u4 i = 0; i < nof_entries; ++i) {
275 writer.write_key(i);
276 writer.write(CompilerPhaseTypeHelper::to_string((CompilerPhaseType)i));
277 }
278 #endif
279 }
280
281 void CodeBlobTypeConstant::serialize(JfrCheckpointWriter& writer) {
282 // XXX no code blob types. need to send any stub value?
283 // static const u4 nof_entries = CodeBlobType::NumTypes;
284 // writer.write_count(nof_entries);
285 // for (u4 i = 0; i < nof_entries; ++i) {
286 // writer.write_key(i);
287 // writer.write(CodeCache::get_code_heap_name(i));
288 // }
289 };
290
291 void VMOperationTypeConstant::serialize(JfrCheckpointWriter& writer) {
292 static const u4 nof_entries = VM_Operation::VMOp_Terminating;
293 writer.write_count(nof_entries);
294 for (u4 i = 0; i < nof_entries; ++i) {
295 writer.write_key(i);
296 writer.write(VM_Operation::name(VM_Operation::VMOp_Type(i)));
297 }
298 }
299
300 class TypeSetSerialization {
301 private:
302 bool _class_unload;
303 public:
304 explicit TypeSetSerialization(bool class_unload) : _class_unload(class_unload) {}
305 void write(JfrCheckpointWriter& writer, JfrCheckpointWriter* leakp_writer) {
306 JfrTypeSet::serialize(&writer, leakp_writer, _class_unload);
307 }
308 };
309
310 void ClassUnloadTypeSet::serialize(JfrCheckpointWriter& writer) {
311 TypeSetSerialization type_set(true);
312 if (LeakProfiler::is_running()) {
313 JfrCheckpointWriter leakp_writer(false, true, Thread::current());
314 type_set.write(writer, &leakp_writer);
315 ObjectSampleCheckpoint::install(leakp_writer, true, true);
316 return;
317 }
318 type_set.write(writer, NULL);
319 };
320
321 void TypeSet::serialize(JfrCheckpointWriter& writer) {
322 TypeSetSerialization type_set(false);
323 if (LeakProfiler::is_suspended()) {
324 JfrCheckpointWriter leakp_writer(false, true, Thread::current());
325 type_set.write(writer, &leakp_writer);
326 ObjectSampleCheckpoint::install(leakp_writer, false, true);
327 return;
328 }
329 type_set.write(writer, NULL);
330 };
331
332 void ThreadStateConstant::serialize(JfrCheckpointWriter& writer) {
333 JfrThreadState::serialize(writer);
334 }
335
336 void JfrThreadConstant::serialize(JfrCheckpointWriter& writer) {
337 assert(_thread != NULL, "invariant");
338 assert(_thread == Thread::current(), "invariant");
339 assert(_thread->is_Java_thread(), "invariant");
340 assert(!_thread->jfr_thread_local()->has_thread_checkpoint(), "invariant");
341 ResourceMark rm(_thread);
342 const oop threadObj = _thread->threadObj();
343 assert(threadObj != NULL, "invariant");
344 const u8 java_lang_thread_id = java_lang_Thread::thread_id(threadObj);
345 const char* const thread_name = _thread->name();
346 const traceid thread_group_id = JfrThreadGroup::thread_group_id(_thread);
347 writer.write_count(1);
348 writer.write_key(_thread->jfr_thread_local()->thread_id());
349 writer.write(thread_name);
350 writer.write((traceid)_thread->osthread()->thread_id());
351 writer.write(thread_name);
352 writer.write(java_lang_thread_id);
353 writer.write(thread_group_id);
354 JfrThreadGroup::serialize(&writer, thread_group_id);
355 }

mercurial