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" |
26 #include "jfr/metadata/jfrSerializer.hpp" |
29 #include "jfr/metadata/jfrSerializer.hpp" |
27 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" |
30 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" |
28 #include "jfr/recorder/checkpoint/types/jfrType.hpp" |
31 #include "jfr/recorder/checkpoint/types/jfrType.hpp" |
29 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp" |
32 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp" |
30 #include "jfr/utilities/jfrDoublyLinkedList.hpp" |
33 #include "jfr/utilities/jfrDoublyLinkedList.hpp" |
31 #include "jfr/utilities/jfrIterator.hpp" |
34 #include "jfr/utilities/jfrIterator.hpp" |
|
35 #include "memory/resourceArea.hpp" |
|
36 #include "runtime/handles.inline.hpp" |
32 #include "runtime/safepoint.hpp" |
37 #include "runtime/safepoint.hpp" |
33 #include "runtime/thread.inline.hpp" |
38 #include "runtime/thread.inline.hpp" |
34 #include "utilities/exceptions.hpp" |
39 #include "utilities/exceptions.hpp" |
35 #include "runtime/semaphore.hpp" |
40 #include "runtime/semaphore.hpp" |
36 |
41 |
37 class JfrSerializerRegistration : public JfrCHeapObj { |
42 class JfrSerializerRegistration : public JfrCHeapObj { |
38 private: |
43 private: |
39 JfrSerializerRegistration* _next; |
44 JfrSerializerRegistration* _next; |
40 JfrSerializerRegistration* _prev; |
45 JfrSerializerRegistration* _prev; |
41 JfrSerializer* _serializer; |
46 JfrSerializer* _serializer; |
42 mutable JfrCheckpointBlobHandle _cache; |
47 mutable JfrBlobHandle _cache; |
43 JfrTypeId _id; |
48 JfrTypeId _id; |
44 bool _permit_cache; |
49 bool _permit_cache; |
45 |
50 |
46 public: |
51 public: |
47 JfrSerializerRegistration(JfrTypeId id, bool permit_cache, JfrSerializer* serializer) : |
52 JfrSerializerRegistration(JfrTypeId id, bool permit_cache, JfrSerializer* serializer) : |
146 iter.next()->invoke(writer); |
151 iter.next()->invoke(writer); |
147 } |
152 } |
148 } |
153 } |
149 |
154 |
150 void JfrTypeManager::write_type_set() { |
155 void JfrTypeManager::write_type_set() { |
151 // can safepoint here because of Module_lock |
156 assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); |
152 MutexLocker cld_lock(SafepointSynchronize::is_at_safepoint() ? NULL : ClassLoaderDataGraph_lock); |
157 // can safepoint here |
153 MutexLocker lock(SafepointSynchronize::is_at_safepoint() ? NULL : Module_lock); |
158 MutexLocker cld_lock(ClassLoaderDataGraph_lock); |
154 |
159 MutexLocker module_lock(Module_lock); |
155 JfrCheckpointWriter writer(true, true, Thread::current()); |
160 if (!LeakProfiler::is_running()) { |
156 TypeSet set; |
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); |
157 set.serialize(writer); |
169 set.serialize(writer); |
|
170 ObjectSampleCheckpoint::on_type_set(leakp_writer); |
158 } |
171 } |
159 |
172 |
160 void JfrTypeManager::write_type_set_for_unloaded_classes() { |
173 void JfrTypeManager::write_type_set_for_unloaded_classes() { |
161 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
174 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
162 JfrCheckpointWriter writer(false, true, Thread::current()); |
175 JfrCheckpointWriter writer(false, true, Thread::current()); |
|
176 const JfrCheckpointContext ctx = writer.context(); |
163 ClassUnloadTypeSet class_unload_set; |
177 ClassUnloadTypeSet class_unload_set; |
164 class_unload_set.serialize(writer); |
178 class_unload_set.serialize(writer); |
165 } |
179 if (LeakProfiler::is_running()) { |
166 |
180 ObjectSampleCheckpoint::on_type_set_unload(writer); |
167 void JfrTypeManager::create_thread_checkpoint(JavaThread* jt) { |
181 } |
|
182 if (!Jfr::is_recording()) { |
|
183 // discard anything written |
|
184 writer.set_context(ctx); |
|
185 } |
|
186 } |
|
187 |
|
188 void JfrTypeManager::create_thread_blob(JavaThread* jt) { |
168 assert(jt != NULL, "invariant"); |
189 assert(jt != NULL, "invariant"); |
|
190 ResourceMark rm(jt); |
|
191 HandleMark hm(jt); |
169 JfrThreadConstant type_thread(jt); |
192 JfrThreadConstant type_thread(jt); |
170 JfrCheckpointWriter writer(false, true, jt); |
193 JfrCheckpointWriter writer(false, true, jt); |
171 writer.write_type(TYPE_THREAD); |
194 writer.write_type(TYPE_THREAD); |
172 type_thread.serialize(writer); |
195 type_thread.serialize(writer); |
173 // create and install a checkpoint blob |
196 // create and install a checkpoint blob |
174 jt->jfr_thread_local()->set_thread_checkpoint(writer.checkpoint_blob()); |
197 jt->jfr_thread_local()->set_thread_blob(writer.move()); |
175 assert(jt->jfr_thread_local()->has_thread_checkpoint(), "invariant"); |
198 assert(jt->jfr_thread_local()->has_thread_blob(), "invariant"); |
176 } |
199 } |
177 |
200 |
178 void JfrTypeManager::write_thread_checkpoint(JavaThread* jt) { |
201 void JfrTypeManager::write_thread_checkpoint(JavaThread* jt) { |
179 assert(jt != NULL, "JavaThread is NULL!"); |
202 assert(jt != NULL, "JavaThread is NULL!"); |
180 ResourceMark rm(jt); |
203 ResourceMark rm(jt); |
181 if (jt->jfr_thread_local()->has_thread_checkpoint()) { |
204 HandleMark hm(jt); |
182 JfrCheckpointWriter writer(false, false, jt); |
205 JfrThreadConstant type_thread(jt); |
183 jt->jfr_thread_local()->thread_checkpoint()->write(writer); |
206 JfrCheckpointWriter writer(false, true, jt); |
184 } else { |
207 writer.write_type(TYPE_THREAD); |
185 JfrThreadConstant type_thread(jt); |
208 type_thread.serialize(writer); |
186 JfrCheckpointWriter writer(false, true, jt); |
|
187 writer.write_type(TYPE_THREAD); |
|
188 type_thread.serialize(writer); |
|
189 } |
|
190 } |
209 } |
191 |
210 |
192 #ifdef ASSERT |
211 #ifdef ASSERT |
193 static void assert_not_registered_twice(JfrTypeId id, List& list) { |
212 static void assert_not_registered_twice(JfrTypeId id, List& list) { |
194 const Iterator iter(list); |
213 const Iterator iter(list); |