22 * |
22 * |
23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.inline.hpp" |
26 #include "classfile/javaClasses.inline.hpp" |
27 #include "jfr/recorder/jfrRecorder.hpp" |
27 #include "jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp" |
|
28 #include "jfr/leakprofiler/leakProfiler.hpp" |
28 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" |
29 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" |
29 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" |
30 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" |
30 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp" |
31 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp" |
|
32 #include "jfr/recorder/checkpoint/types/jfrTypeSet.hpp" |
31 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp" |
33 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp" |
|
34 #include "jfr/recorder/jfrRecorder.hpp" |
|
35 #include "jfr/recorder/repository/jfrChunkWriter.hpp" |
32 #include "jfr/recorder/service/jfrOptionSet.hpp" |
36 #include "jfr/recorder/service/jfrOptionSet.hpp" |
33 #include "jfr/recorder/storage/jfrMemorySpace.inline.hpp" |
37 #include "jfr/recorder/storage/jfrMemorySpace.inline.hpp" |
34 #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp" |
38 #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp" |
35 #include "jfr/recorder/repository/jfrChunkWriter.hpp" |
|
36 #include "jfr/utilities/jfrBigEndian.hpp" |
39 #include "jfr/utilities/jfrBigEndian.hpp" |
37 #include "jfr/utilities/jfrIterator.hpp" |
40 #include "jfr/utilities/jfrIterator.hpp" |
38 #include "jfr/utilities/jfrThreadIterator.hpp" |
41 #include "jfr/utilities/jfrThreadIterator.hpp" |
39 #include "jfr/utilities/jfrTypes.hpp" |
42 #include "jfr/utilities/jfrTypes.hpp" |
40 #include "jfr/writers/jfrJavaEventWriter.hpp" |
43 #include "jfr/writers/jfrJavaEventWriter.hpp" |
355 return wo.processed(); |
358 return wo.processed(); |
356 } |
359 } |
357 |
360 |
358 typedef DiscardOp<DefaultDiscarder<JfrBuffer> > DiscardOperation; |
361 typedef DiscardOp<DefaultDiscarder<JfrBuffer> > DiscardOperation; |
359 size_t JfrCheckpointManager::clear() { |
362 size_t JfrCheckpointManager::clear() { |
360 JfrTypeManager::clear(); |
363 JfrTypeSet::clear(); |
361 DiscardOperation discarder(mutexed); // mutexed discard mode |
364 DiscardOperation discarder(mutexed); // mutexed discard mode |
362 process_free_list(discarder, _free_list_mspace); |
365 process_free_list(discarder, _free_list_mspace); |
363 process_free_list(discarder, _epoch_transition_mspace); |
366 process_free_list(discarder, _epoch_transition_mspace); |
364 synchronize_epoch(); |
367 synchronize_epoch(); |
365 return discarder.elements(); |
368 return discarder.elements(); |
406 return write_epoch_transition_mspace(); |
409 return write_epoch_transition_mspace(); |
407 } |
410 } |
408 |
411 |
409 void JfrCheckpointManager::shift_epoch() { |
412 void JfrCheckpointManager::shift_epoch() { |
410 debug_only(const u1 current_epoch = JfrTraceIdEpoch::current();) |
413 debug_only(const u1 current_epoch = JfrTraceIdEpoch::current();) |
411 JfrTraceIdEpoch::shift_epoch(); |
414 JfrTraceIdEpoch::shift_epoch(); |
412 assert(current_epoch != JfrTraceIdEpoch::current(), "invariant"); |
415 assert(current_epoch != JfrTraceIdEpoch::current(), "invariant"); |
413 } |
416 } |
414 |
417 |
415 void JfrCheckpointManager::on_rotation() { |
418 void JfrCheckpointManager::on_rotation() { |
416 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
419 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
417 JfrTypeManager::on_rotation(); |
420 JfrTypeManager::on_rotation(); |
418 notify_threads(); |
421 notify_threads(); |
419 shift_epoch(); |
|
420 } |
422 } |
421 |
423 |
422 void JfrCheckpointManager::write_type_set() { |
424 void JfrCheckpointManager::write_type_set() { |
423 JfrTypeManager::write_type_set(); |
425 assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); |
|
426 if (LeakProfiler::is_running()) { |
|
427 Thread* const t = Thread::current(); |
|
428 // can safepoint here |
|
429 MutexLocker cld_lock(ClassLoaderDataGraph_lock); |
|
430 MutexLocker module_lock(Module_lock); |
|
431 JfrCheckpointWriter leakp_writer(t); |
|
432 JfrCheckpointWriter writer(t); |
|
433 JfrTypeSet::serialize(&writer, &leakp_writer, false, false); |
|
434 ObjectSampleCheckpoint::on_type_set(leakp_writer); |
|
435 } else { |
|
436 // can safepoint here |
|
437 MutexLocker cld_lock(ClassLoaderDataGraph_lock); |
|
438 MutexLocker module_lock(Module_lock); |
|
439 JfrCheckpointWriter writer(Thread::current()); |
|
440 JfrTypeSet::serialize(&writer, NULL, false, false); |
|
441 } |
424 write(); |
442 write(); |
425 } |
443 } |
426 |
444 |
427 void JfrCheckpointManager::write_type_set_for_unloaded_classes() { |
445 void JfrCheckpointManager::write_type_set_for_unloaded_classes() { |
428 JfrTypeManager::write_type_set_for_unloaded_classes(); |
446 assert_locked_or_safepoint(ClassLoaderDataGraph_lock); |
|
447 JfrCheckpointWriter writer(Thread::current()); |
|
448 const JfrCheckpointContext ctx = writer.context(); |
|
449 JfrTypeSet::serialize(&writer, NULL, true, false); |
|
450 if (LeakProfiler::is_running()) { |
|
451 ObjectSampleCheckpoint::on_type_set_unload(writer); |
|
452 } |
|
453 if (!JfrRecorder::is_recording()) { |
|
454 // discard by rewind |
|
455 writer.set_context(ctx); |
|
456 } |
429 } |
457 } |
430 |
458 |
431 bool JfrCheckpointManager::is_type_set_required() { |
459 bool JfrCheckpointManager::is_type_set_required() { |
432 return JfrTraceIdEpoch::has_changed_tag_state(); |
460 return JfrTraceIdEpoch::has_changed_tag_state(); |
433 } |
461 } |
434 |
462 |
435 size_t JfrCheckpointManager::flush_type_set() { |
463 size_t JfrCheckpointManager::flush_type_set() { |
436 const size_t elements = JfrTypeManager::flush_type_set(); |
464 assert(!SafepointSynchronize::is_at_safepoint(), "invariant"); |
|
465 size_t elements = 0; |
|
466 { |
|
467 JfrCheckpointWriter writer(Thread::current()); |
|
468 // can safepoint here |
|
469 MutexLocker cld_lock(ClassLoaderDataGraph_lock); |
|
470 MutexLocker module_lock(Module_lock); |
|
471 elements = JfrTypeSet::serialize(&writer, NULL, false, true); |
|
472 } |
437 flush(); |
473 flush(); |
438 return elements; |
474 return elements; |
439 } |
475 } |
440 |
476 |
441 void JfrCheckpointManager::flush_static_type_set() { |
477 void JfrCheckpointManager::flush_static_type_set() { |