21 * questions. |
21 * questions. |
22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "jfr/jfr.hpp" |
|
27 #include "jfr/leakprofiler/leakProfiler.hpp" |
|
28 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" |
|
29 #include "jfr/metadata/jfrSerializer.hpp" |
26 #include "jfr/metadata/jfrSerializer.hpp" |
30 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" |
27 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" |
31 #include "jfr/recorder/checkpoint/types/jfrType.hpp" |
28 #include "jfr/recorder/checkpoint/types/jfrType.hpp" |
32 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp" |
29 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp" |
33 #include "jfr/utilities/jfrDoublyLinkedList.hpp" |
30 #include "jfr/utilities/jfrDoublyLinkedList.hpp" |
34 #include "jfr/utilities/jfrIterator.hpp" |
31 #include "jfr/utilities/jfrIterator.hpp" |
35 #include "memory/resourceArea.hpp" |
32 #include "memory/resourceArea.hpp" |
36 #include "runtime/handles.inline.hpp" |
33 #include "runtime/handles.inline.hpp" |
37 #include "runtime/safepoint.hpp" |
34 #include "runtime/safepoint.hpp" |
|
35 #include "runtime/semaphore.hpp" |
38 #include "runtime/thread.inline.hpp" |
36 #include "runtime/thread.inline.hpp" |
39 #include "utilities/exceptions.hpp" |
37 #include "utilities/exceptions.hpp" |
40 #include "runtime/semaphore.hpp" |
|
41 |
38 |
42 class JfrSerializerRegistration : public JfrCHeapObj { |
39 class JfrSerializerRegistration : public JfrCHeapObj { |
43 private: |
40 private: |
44 JfrSerializerRegistration* _next; |
41 JfrSerializerRegistration* _next; |
45 JfrSerializerRegistration* _prev; |
42 JfrSerializerRegistration* _prev; |
118 typedef JfrDoublyLinkedList<JfrSerializerRegistration> List; |
115 typedef JfrDoublyLinkedList<JfrSerializerRegistration> List; |
119 typedef StopOnNullIterator<const List> Iterator; |
116 typedef StopOnNullIterator<const List> Iterator; |
120 static List types; |
117 static List types; |
121 static List safepoint_types; |
118 static List safepoint_types; |
122 |
119 |
123 void JfrTypeManager::clear() { |
120 void JfrTypeManager::destroy() { |
124 SerializerRegistrationGuard guard; |
121 SerializerRegistrationGuard guard; |
125 Iterator iter(types); |
122 Iterator iter(types); |
126 JfrSerializerRegistration* registration; |
123 JfrSerializerRegistration* registration; |
127 while (iter.has_next()) { |
124 while (iter.has_next()) { |
128 registration = types.remove(iter.next()); |
125 registration = types.remove(iter.next()); |
147 void JfrTypeManager::write_safepoint_types(JfrCheckpointWriter& writer) { |
144 void JfrTypeManager::write_safepoint_types(JfrCheckpointWriter& writer) { |
148 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
145 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
149 const Iterator iter(safepoint_types); |
146 const Iterator iter(safepoint_types); |
150 while (iter.has_next()) { |
147 while (iter.has_next()) { |
151 iter.next()->invoke(writer); |
148 iter.next()->invoke(writer); |
152 } |
|
153 } |
|
154 |
|
155 void JfrTypeManager::write_type_set() { |
|
156 assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); |
|
157 // can safepoint here |
|
158 MutexLocker cld_lock(ClassLoaderDataGraph_lock); |
|
159 MutexLocker module_lock(Module_lock); |
|
160 if (!LeakProfiler::is_running()) { |
|
161 JfrCheckpointWriter writer(true, true, Thread::current()); |
|
162 TypeSet set; |
|
163 set.serialize(writer); |
|
164 return; |
|
165 } |
|
166 JfrCheckpointWriter leakp_writer(false, true, Thread::current()); |
|
167 JfrCheckpointWriter writer(false, true, Thread::current()); |
|
168 TypeSet set(&leakp_writer); |
|
169 set.serialize(writer); |
|
170 ObjectSampleCheckpoint::on_type_set(leakp_writer); |
|
171 } |
|
172 |
|
173 void JfrTypeManager::write_type_set_for_unloaded_classes() { |
|
174 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
|
175 JfrCheckpointWriter writer(false, true, Thread::current()); |
|
176 const JfrCheckpointContext ctx = writer.context(); |
|
177 ClassUnloadTypeSet class_unload_set; |
|
178 class_unload_set.serialize(writer); |
|
179 if (LeakProfiler::is_running()) { |
|
180 ObjectSampleCheckpoint::on_type_set_unload(writer); |
|
181 } |
|
182 if (!Jfr::is_recording()) { |
|
183 // discard anything written |
|
184 writer.set_context(ctx); |
|
185 } |
149 } |
186 } |
150 } |
187 |
151 |
188 void JfrTypeManager::create_thread_blob(JavaThread* jt) { |
152 void JfrTypeManager::create_thread_blob(JavaThread* jt) { |
189 assert(jt != NULL, "invariant"); |
153 assert(jt != NULL, "invariant"); |