29 #include "gc/shared/gcCause.hpp" |
29 #include "gc/shared/gcCause.hpp" |
30 #include "gc/shared/gcName.hpp" |
30 #include "gc/shared/gcName.hpp" |
31 #include "gc/shared/gcTrace.hpp" |
31 #include "gc/shared/gcTrace.hpp" |
32 #include "gc/shared/gcWhen.hpp" |
32 #include "gc/shared/gcWhen.hpp" |
33 #include "jfr/leakprofiler/leakProfiler.hpp" |
33 #include "jfr/leakprofiler/leakProfiler.hpp" |
34 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" |
34 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" |
35 #include "jfr/recorder/checkpoint/types/jfrType.hpp" |
35 #include "jfr/recorder/checkpoint/types/jfrType.hpp" |
36 #include "jfr/recorder/jfrRecorder.hpp" |
36 #include "jfr/recorder/jfrRecorder.hpp" |
37 #include "jfr/recorder/checkpoint/types/jfrThreadGroup.hpp" |
37 #include "jfr/recorder/checkpoint/types/jfrThreadGroup.hpp" |
38 #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp" |
38 #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp" |
39 #include "jfr/support/jfrThreadLocal.hpp" |
39 #include "jfr/support/jfrThreadLocal.hpp" |
40 #include "jfr/writers/jfrJavaEventWriter.hpp" |
40 #include "jfr/writers/jfrJavaEventWriter.hpp" |
41 #include "memory/metaspace.hpp" |
41 #include "memory/metaspace.hpp" |
42 #include "memory/metaspace/metaspaceEnums.hpp" |
42 #include "memory/metaspace/metaspaceEnums.hpp" |
|
43 #include "jfr/utilities/jfrThreadIterator.hpp" |
43 #include "memory/referenceType.hpp" |
44 #include "memory/referenceType.hpp" |
44 #include "memory/universe.hpp" |
45 #include "memory/universe.hpp" |
45 #include "oops/compressedOops.hpp" |
46 #include "oops/compressedOops.hpp" |
46 #include "runtime/flags/jvmFlag.hpp" |
47 #include "runtime/flags/jvmFlag.hpp" |
47 #include "runtime/mutexLocker.hpp" |
48 #include "runtime/mutexLocker.hpp" |
83 } |
84 } |
84 |
85 |
85 void do_thread(Thread* t); |
86 void do_thread(Thread* t); |
86 }; |
87 }; |
87 |
88 |
88 // Requires a ResourceMark for get_thread_name/as_utf8 |
|
89 void JfrCheckpointThreadClosure::do_thread(Thread* t) { |
89 void JfrCheckpointThreadClosure::do_thread(Thread* t) { |
90 assert(t != NULL, "invariant"); |
90 assert(t != NULL, "invariant"); |
91 assert_locked_or_safepoint(Threads_lock); |
|
92 const JfrThreadLocal* const tl = t->jfr_thread_local(); |
|
93 assert(tl != NULL, "invariant"); |
|
94 if (tl->is_dead()) { |
|
95 return; |
|
96 } |
|
97 ++_count; |
91 ++_count; |
98 _writer.write_key(tl->thread_id()); |
92 _writer.write_key(JfrThreadId::jfr_id(t)); |
99 _writer.write(t->name()); |
93 const char* const name = JfrThreadName::name(t); |
100 const OSThread* const os_thread = t->osthread(); |
94 assert(name != NULL, "invariant"); |
101 _writer.write<traceid>(os_thread != NULL ? os_thread->thread_id() : 0); |
95 _writer.write(name); |
|
96 _writer.write<traceid>(JfrThreadId::os_id(t)); |
102 if (t->is_Java_thread()) { |
97 if (t->is_Java_thread()) { |
103 JavaThread* const jt = (JavaThread*)t; |
98 _writer.write(name); |
104 _writer.write(jt->name()); |
99 _writer.write(JfrThreadId::id(t)); |
105 _writer.write(java_lang_Thread::thread_id(jt->threadObj())); |
100 _writer.write(JfrThreadGroup::thread_group_id((JavaThread*)t, _curthread)); |
106 _writer.write(JfrThreadGroup::thread_group_id(jt, _curthread)); |
|
107 // since we are iterating threads during a safepoint, also issue notification |
|
108 JfrJavaEventWriter::notify(jt); |
|
109 return; |
101 return; |
110 } |
102 } |
111 _writer.write((const char*)NULL); // java name |
103 _writer.write((const char*)NULL); // java name |
112 _writer.write((traceid)0); // java thread id |
104 _writer.write((traceid)0); // java thread id |
113 _writer.write((traceid)0); // java thread group |
105 _writer.write((traceid)0); // java thread group |
114 } |
106 } |
115 |
107 |
116 void JfrThreadConstantSet::serialize(JfrCheckpointWriter& writer) { |
108 void JfrThreadConstantSet::serialize(JfrCheckpointWriter& writer) { |
117 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
|
118 JfrCheckpointThreadClosure tc(writer); |
109 JfrCheckpointThreadClosure tc(writer); |
119 Threads::threads_do(&tc); |
110 JfrJavaThreadIterator javathreads; |
|
111 while (javathreads.has_next()) { |
|
112 tc.do_thread(javathreads.next()); |
|
113 } |
|
114 JfrNonJavaThreadIterator nonjavathreads; |
|
115 while (nonjavathreads.has_next()) { |
|
116 tc.do_thread(nonjavathreads.next()); |
|
117 } |
120 } |
118 } |
121 |
119 |
122 void JfrThreadGroupConstant::serialize(JfrCheckpointWriter& writer) { |
120 void JfrThreadGroupConstant::serialize(JfrCheckpointWriter& writer) { |
123 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
|
124 JfrThreadGroup::serialize(writer); |
121 JfrThreadGroup::serialize(writer); |
125 } |
122 } |
126 |
123 |
127 static const char* flag_value_origin_to_string(JVMFlag::Flags origin) { |
124 static const char* flag_value_origin_to_string(JVMFlag::Flags origin) { |
128 switch (origin) { |
125 switch (origin) { |
132 case JVMFlag::CONFIG_FILE: return "Config file"; |
129 case JVMFlag::CONFIG_FILE: return "Config file"; |
133 case JVMFlag::MANAGEMENT: return "Management"; |
130 case JVMFlag::MANAGEMENT: return "Management"; |
134 case JVMFlag::ERGONOMIC: return "Ergonomic"; |
131 case JVMFlag::ERGONOMIC: return "Ergonomic"; |
135 case JVMFlag::ATTACH_ON_DEMAND: return "Attach on demand"; |
132 case JVMFlag::ATTACH_ON_DEMAND: return "Attach on demand"; |
136 case JVMFlag::INTERNAL: return "Internal"; |
133 case JVMFlag::INTERNAL: return "Internal"; |
|
134 case JVMFlag::JIMAGE_RESOURCE: return "JImage resource"; |
137 default: ShouldNotReachHere(); return ""; |
135 default: ShouldNotReachHere(); return ""; |
138 } |
136 } |
139 } |
137 } |
140 |
138 |
141 void FlagValueOriginConstant::serialize(JfrCheckpointWriter& writer) { |
139 void FlagValueOriginConstant::serialize(JfrCheckpointWriter& writer) { |
276 } |
274 } |
277 |
275 |
278 void JfrThreadConstant::serialize(JfrCheckpointWriter& writer) { |
276 void JfrThreadConstant::serialize(JfrCheckpointWriter& writer) { |
279 assert(_thread != NULL, "invariant"); |
277 assert(_thread != NULL, "invariant"); |
280 assert(_thread == Thread::current(), "invariant"); |
278 assert(_thread == Thread::current(), "invariant"); |
281 assert(_thread->is_Java_thread(), "invariant"); |
|
282 ResourceMark rm(_thread); |
|
283 const oop threadObj = _thread->threadObj(); |
|
284 assert(threadObj != NULL, "invariant"); |
|
285 const u8 java_lang_thread_id = java_lang_Thread::thread_id(threadObj); |
|
286 const char* const thread_name = _thread->name(); |
|
287 const traceid thread_group_id = JfrThreadGroup::thread_group_id(_thread); |
|
288 writer.write_count(1); |
279 writer.write_count(1); |
289 writer.write_key(_thread->jfr_thread_local()->thread_id()); |
280 writer.write_key(JfrThreadId::jfr_id(_thread)); |
290 writer.write(thread_name); |
281 const char* const name = JfrThreadName::name(_thread); |
291 writer.write((traceid)_thread->osthread()->thread_id()); |
282 writer.write(name); |
292 writer.write(thread_name); |
283 writer.write(JfrThreadId::os_id(_thread)); |
293 writer.write(java_lang_thread_id); |
284 if (_thread->is_Java_thread()) { |
294 writer.write(thread_group_id); |
285 writer.write(name); |
295 JfrThreadGroup::serialize(&writer, thread_group_id); |
286 writer.write(JfrThreadId::id(_thread)); |
296 } |
287 JavaThread* const jt = (JavaThread*)_thread; |
|
288 const traceid thread_group_id = JfrThreadGroup::thread_group_id(jt, jt); |
|
289 writer.write(thread_group_id); |
|
290 JfrThreadGroup::serialize(&writer, thread_group_id); |
|
291 return; |
|
292 } |
|
293 writer.write((const char*)NULL); // java name |
|
294 writer.write((traceid)0); // java thread id |
|
295 writer.write((traceid)0); // java thread group |
|
296 } |