src/share/vm/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp

changeset 9885
8e875c964f41
parent 9858
b985cbb00e68
     1.1 --- a/src/share/vm/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp	Fri Sep 27 13:23:32 2019 +0800
     1.2 +++ b/src/share/vm/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp	Wed Oct 09 16:11:58 2019 +0800
     1.3 @@ -181,102 +181,89 @@
     1.4    }
     1.5  };
     1.6  
     1.7 -void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload, bool resume) {
     1.8 -  assert(class_unload ? SafepointSynchronize::is_at_safepoint() : LeakProfiler::is_suspended(), "invariant");
     1.9 -
    1.10 +void ObjectSampleCheckpoint::install(JfrCheckpointWriter& writer, bool class_unload, bool type_set) {
    1.11    if (!writer.has_data()) {
    1.12 -    if (!class_unload) {
    1.13 -      LeakProfiler::resume();
    1.14 -    }
    1.15 -    assert(LeakProfiler::is_running(), "invariant");
    1.16      return;
    1.17    }
    1.18  
    1.19    assert(writer.has_data(), "invariant");
    1.20    const JfrCheckpointBlobHandle h_cp = writer.checkpoint_blob();
    1.21 +  CheckpointInstall install(h_cp);
    1.22  
    1.23 -  const ObjectSampler* const object_sampler = LeakProfiler::object_sampler();
    1.24 +  // Class unload implies a safepoint.
    1.25 +  // Not class unload implies the object sampler is locked, because it was claimed exclusively earlier.
    1.26 +  // Therefore: direct access the object sampler instance is safe.
    1.27 +  ObjectSampler* const object_sampler = ObjectSampler::sampler();
    1.28    assert(object_sampler != NULL, "invariant");
    1.29  
    1.30    ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
    1.31    const ObjectSample* const last_resolved = object_sampler->last_resolved();
    1.32 -  CheckpointInstall install(h_cp);
    1.33  
    1.34 -  if (class_unload) {
    1.35 -    if (last != NULL) {
    1.36 -      // all samples need the class unload information
    1.37 -      do_samples(last, NULL, install);
    1.38 -    }
    1.39 -    assert(LeakProfiler::is_running(), "invariant");
    1.40 -    return;
    1.41 -  }
    1.42 -
    1.43 -  // only new samples since last resolved checkpoint
    1.44 +  // install only to new samples since last resolved checkpoint
    1.45    if (last != last_resolved) {
    1.46      do_samples(last, last_resolved, install);
    1.47 -    if (resume) {
    1.48 -      const_cast<ObjectSampler*>(object_sampler)->set_last_resolved(last);
    1.49 +    if (class_unload) {
    1.50 +      return;
    1.51      }
    1.52 -  }
    1.53 -  assert(LeakProfiler::is_suspended(), "invariant");
    1.54 -  if (resume) {
    1.55 -    LeakProfiler::resume();
    1.56 -    assert(LeakProfiler::is_running(), "invariant");
    1.57 +    if (type_set) {
    1.58 +      object_sampler->set_last_resolved(last);
    1.59 +    }
    1.60    }
    1.61  }
    1.62  
    1.63 -void ObjectSampleCheckpoint::write(const EdgeStore* edge_store, bool emit_all, Thread* thread) {
    1.64 +void ObjectSampleCheckpoint::write(ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) {
    1.65 +  assert(sampler != NULL, "invariant");
    1.66    assert(edge_store != NULL, "invariant");
    1.67    assert(thread != NULL, "invariant");
    1.68 +
    1.69    static bool types_registered = false;
    1.70    if (!types_registered) {
    1.71      JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType());
    1.72      JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType());
    1.73      types_registered = true;
    1.74    }
    1.75 -  const ObjectSampler* const object_sampler = LeakProfiler::object_sampler();
    1.76 -  assert(object_sampler != NULL, "invariant");
    1.77 -  const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
    1.78 -  ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
    1.79 +
    1.80 +  const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value();
    1.81 +  ObjectSample* const last = const_cast<ObjectSample*>(sampler->last());
    1.82    {
    1.83      JfrCheckpointWriter writer(false, false, thread);
    1.84      CheckpointWrite checkpoint_write(writer, last_sweep);
    1.85      do_samples(last, NULL, checkpoint_write);
    1.86    }
    1.87 +
    1.88    CheckpointStateReset state_reset(last_sweep);
    1.89    do_samples(last, NULL, state_reset);
    1.90 +
    1.91    if (!edge_store->is_empty()) {
    1.92      // java object and chain representations
    1.93      JfrCheckpointWriter writer(false, true, thread);
    1.94      ObjectSampleWriter osw(writer, edge_store);
    1.95 -    edge_store->iterate_edges(osw);
    1.96 +    edge_store->iterate(osw);
    1.97    }
    1.98  }
    1.99  
   1.100 -WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(JfrStackTraceRepository& repo) :
   1.101 -  _stack_trace_repo(repo) {
   1.102 +int ObjectSampleCheckpoint::mark(ObjectSampler* object_sampler, ObjectSampleMarker& marker, bool emit_all) {
   1.103 +  assert(object_sampler != NULL, "invariant");
   1.104 +  ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
   1.105 +  if (last == NULL) {
   1.106 +    return 0;
   1.107 +  }
   1.108 +  const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
   1.109 +  SampleMark mark(marker, last_sweep);
   1.110 +  do_samples(last, NULL, mark);
   1.111 +  return mark.count();
   1.112  }
   1.113  
   1.114 +WriteObjectSampleStacktrace::WriteObjectSampleStacktrace(ObjectSampler* sampler, JfrStackTraceRepository& repo) :
   1.115 +  _sampler(sampler), _stack_trace_repo(repo) {}
   1.116 +
   1.117  bool WriteObjectSampleStacktrace::process() {
   1.118 -  assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   1.119 -  if (!LeakProfiler::is_running()) {
   1.120 -    return true;
   1.121 -  }
   1.122 -  // Suspend the LeakProfiler subsystem
   1.123 -  // to ensure stable samples even
   1.124 -  // after we return from the safepoint.
   1.125 -  LeakProfiler::suspend();
   1.126 -  assert(!LeakProfiler::is_running(), "invariant");
   1.127 -  assert(LeakProfiler::is_suspended(), "invariant");
   1.128 +  assert(LeakProfiler::is_running(), "invariant");
   1.129 +  assert(_sampler != NULL, "invariant");
   1.130  
   1.131 -  const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
   1.132 -  assert(object_sampler != NULL, "invariant");
   1.133 -  assert(LeakProfiler::is_suspended(), "invariant");
   1.134 -
   1.135 -  ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
   1.136 -  const ObjectSample* const last_resolved = object_sampler->last_resolved();
   1.137 +  ObjectSample* const last = const_cast<ObjectSample*>(_sampler->last());
   1.138 +  const ObjectSample* const last_resolved = _sampler->last_resolved();
   1.139    if (last == last_resolved) {
   1.140 -    assert(LeakProfiler::is_suspended(), "invariant");
   1.141      return true;
   1.142    }
   1.143  
   1.144 @@ -294,27 +281,13 @@
   1.145    }
   1.146    if (count == 0) {
   1.147      writer.set_context(ctx);
   1.148 -    assert(LeakProfiler::is_suspended(), "invariant");
   1.149      return true;
   1.150    }
   1.151    assert(count > 0, "invariant");
   1.152    writer.write_count((u4)count, count_offset);
   1.153    JfrStackTraceRepository::write_metadata(writer);
   1.154  
   1.155 +  // install the stacktrace checkpoint information to the candidates
   1.156    ObjectSampleCheckpoint::install(writer, false, false);
   1.157 -  assert(LeakProfiler::is_suspended(), "invariant");
   1.158    return true;
   1.159  }
   1.160 -
   1.161 -int ObjectSampleCheckpoint::mark(ObjectSampleMarker& marker, bool emit_all) {
   1.162 -  const ObjectSampler* object_sampler = LeakProfiler::object_sampler();
   1.163 -  assert(object_sampler != NULL, "invariant");
   1.164 -  ObjectSample* const last = const_cast<ObjectSample*>(object_sampler->last());
   1.165 -  if (last == NULL) {
   1.166 -    return 0;
   1.167 -  }
   1.168 -  const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
   1.169 -  SampleMark mark(marker, last_sweep);
   1.170 -  do_samples(last, NULL, mark);
   1.171 -  return mark.count();
   1.172 -}

mercurial