394 stack_trace_id_set = resource_allocate_array<traceid>(set_size); |
394 stack_trace_id_set = resource_allocate_array<traceid>(set_size); |
395 id_set = resource_allocate_array<traceid>(set_size); |
395 id_set = resource_allocate_array<traceid>(set_size); |
396 sort_unloaded_klass_set(); |
396 sort_unloaded_klass_set(); |
397 } |
397 } |
398 |
398 |
399 static void resolve_stack_traces(JfrStackTraceRepository& stack_trace_repo) { |
399 static void resolve_stack_traces(ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo, const ObjectSample* last_resolved) { |
400 StackTraceResolver stack_trace_resolver(stack_trace_repo); |
400 assert(sampler != NULL, "invariant"); |
401 iterate_samples(stack_trace_resolver); |
401 const ObjectSample* const last = sampler->last(); |
|
402 if (last != last_resolved) { |
|
403 StackTraceResolver stack_trace_resolver(stack_trace_repo); |
|
404 iterate_samples(stack_trace_resolver); |
|
405 sampler->set_last_resolved(last); |
|
406 } |
402 } |
407 } |
403 |
408 |
404 // caller needs ResourceMark |
409 // caller needs ResourceMark |
405 void ObjectSampleCheckpoint::on_rotation(ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) { |
410 void ObjectSampleCheckpoint::on_rotation(ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) { |
406 assert(sampler != NULL, "invariant"); |
411 assert(sampler != NULL, "invariant"); |
407 assert(LeakProfiler::is_running(), "invariant"); |
412 assert(LeakProfiler::is_running(), "invariant"); |
408 const ObjectSample* const last = sampler->last(); |
|
409 if (last == NULL) { |
|
410 // nothing to process |
|
411 return; |
|
412 } |
|
413 ObjectSample* const last_resolved = const_cast<ObjectSample*>(sampler->last_resolved()); |
413 ObjectSample* const last_resolved = const_cast<ObjectSample*>(sampler->last_resolved()); |
414 if (last_resolved != NULL) { |
414 if (last_resolved != NULL) { |
415 allocate_traceid_working_sets(); |
415 allocate_traceid_working_sets(); |
416 tag_old_stack_traces(last_resolved, stack_trace_repo); |
416 tag_old_stack_traces(last_resolved, stack_trace_repo); |
417 } |
417 } |
418 if (last != last_resolved) { |
418 resolve_stack_traces(sampler, stack_trace_repo, last_resolved); |
419 resolve_stack_traces(stack_trace_repo); |
|
420 sampler->set_last_resolved(last); |
|
421 } |
|
422 } |
|
423 |
|
424 class RootSystemType : public JfrSerializer { |
|
425 public: |
|
426 void serialize(JfrCheckpointWriter& writer) { |
|
427 const u4 nof_root_systems = OldObjectRoot::_number_of_systems; |
|
428 writer.write_count(nof_root_systems); |
|
429 for (u4 i = 0; i < nof_root_systems; ++i) { |
|
430 writer.write_key(i); |
|
431 writer.write(OldObjectRoot::system_description((OldObjectRoot::System)i)); |
|
432 } |
|
433 } |
|
434 }; |
|
435 |
|
436 class RootType : public JfrSerializer { |
|
437 public: |
|
438 void serialize(JfrCheckpointWriter& writer) { |
|
439 const u4 nof_root_types = OldObjectRoot::_number_of_types; |
|
440 writer.write_count(nof_root_types); |
|
441 for (u4 i = 0; i < nof_root_types; ++i) { |
|
442 writer.write_key(i); |
|
443 writer.write(OldObjectRoot::type_description((OldObjectRoot::Type)i)); |
|
444 } |
|
445 } |
|
446 }; |
|
447 |
|
448 static void register_serializers() { |
|
449 static bool is_registered = false; |
|
450 if (!is_registered) { |
|
451 JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, true, new RootSystemType()); |
|
452 JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, true, new RootType()); |
|
453 is_registered = true; |
|
454 } |
|
455 } |
419 } |
456 |
420 |
457 static void reset_blob_write_state(const ObjectSample* sample) { |
421 static void reset_blob_write_state(const ObjectSample* sample) { |
458 assert(sample != NULL, "invariant"); |
422 assert(sample != NULL, "invariant"); |
459 if (sample->has_thread_checkpoint()) { |
423 if (sample->has_thread_checkpoint()) { |
544 int count() const { |
508 int count() const { |
545 return _count; |
509 return _count; |
546 } |
510 } |
547 }; |
511 }; |
548 |
512 |
549 static void write_and_tag_stack_traces(const ObjectSampler* sampler, JfrStackTraceRepository& repo, jlong last_sweep, Thread* thread) { |
513 static void write_stack_traces(ObjectSampler* sampler, JfrStackTraceRepository& repo, jlong last_sweep, Thread* thread) { |
550 assert(sampler != NULL, "invariant"); |
514 assert(sampler != NULL, "invariant"); |
551 allocate_traceid_working_sets(); |
515 ObjectSample* const last_resolved = const_cast<ObjectSample*>(sampler->last_resolved()); |
552 resolve_stack_traces(repo); |
516 if (last_resolved == NULL) { |
|
517 // no old traces |
|
518 return; |
|
519 } |
553 JfrCheckpointWriter writer(thread); |
520 JfrCheckpointWriter writer(thread); |
554 const JfrCheckpointContext ctx = writer.context(); |
521 const JfrCheckpointContext ctx = writer.context(); |
555 writer.write_type(TYPE_STACKTRACE); |
522 writer.write_type(TYPE_STACKTRACE); |
556 const jlong count_offset = writer.reserve(sizeof(u4)); |
523 const jlong count_offset = writer.reserve(sizeof(u4)); |
|
524 allocate_traceid_working_sets(); |
557 StackTraceWriter sw(repo, writer, last_sweep); |
525 StackTraceWriter sw(repo, writer, last_sweep); |
558 do_samples(sampler->last(), NULL, sw); |
526 do_samples(last_resolved, NULL, sw); |
559 if (sw.count() == 0) { |
527 if (sw.count() == 0) { |
560 writer.set_context(ctx); |
528 writer.set_context(ctx); |
561 return; |
529 return; |
562 } |
530 } |
563 writer.write_count((u4)sw.count(), count_offset); |
531 writer.write_count((u4)sw.count(), count_offset); |
564 } |
532 } |
565 |
533 |
566 void ObjectSampleCheckpoint::write(const ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) { |
534 void ObjectSampleCheckpoint::write(ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) { |
567 assert(sampler != NULL, "invariant"); |
535 assert(sampler != NULL, "invariant"); |
568 assert(edge_store != NULL, "invariant"); |
536 assert(edge_store != NULL, "invariant"); |
569 assert(thread != NULL, "invariant"); |
537 assert(thread != NULL, "invariant"); |
570 register_serializers(); |
|
571 // sample set is predicated on time of last sweep |
538 // sample set is predicated on time of last sweep |
572 const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value(); |
539 const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value(); |
573 write_and_tag_stack_traces(sampler, JfrStackTraceRepository::instance(), last_sweep, thread); |
540 JfrStackTraceRepository& repo = JfrStackTraceRepository::instance(); |
|
541 write_stack_traces(sampler, repo, last_sweep, thread); |
574 write_sample_blobs(sampler, last_sweep, thread); |
542 write_sample_blobs(sampler, last_sweep, thread); |
575 // write reference chains |
543 // write reference chains |
576 if (!edge_store->is_empty()) { |
544 if (!edge_store->is_empty()) { |
577 JfrCheckpointWriter writer(thread); |
545 JfrCheckpointWriter writer(thread); |
578 ObjectSampleWriter osw(writer, edge_store); |
546 ObjectSampleWriter osw(writer, edge_store); |