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