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 -}