src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp
branchJEP-349-branch
changeset 57936 1b2d0f4c1e38
parent 57934 9c150f2b1fea
child 57937 c72ed9929e02
equal deleted inserted replaced
57935:123705b84980 57936:1b2d0f4c1e38
   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);